def logShare(share): if '_origdata' in share: share['solution'] = share['_origdata'] else: share['solution'] = b2a_hex(swap32(share['data'])).decode('utf8') for i in loggersShare: i.logShare(share)
def logShare(share): if "_origdata" in share: share["solution"] = share["_origdata"] else: share["solution"] = b2a_hex(swap32(share["data"])).decode("utf8") for i in loggersShare: i.logShare(share)
def doJSON_getwork(self, data=None): if not data is None: return self.doJSON_submitwork(data) rv = dict(self.getwork_rv_template) (hdr, x, target) = self.server.getBlockHeader(self.Username) # FIXME: this assumption breaks with internal rollntime # NOTE: noncerange needs to set nonce to start value at least global _CheckForDupesHACK uhdr = hdr[:68] + hdr[72:] if uhdr in _CheckForDupesHACK: _RealDupes[uhdr] = (_CheckForDupesHACK[uhdr], (hdr, x)) raise self.server.RaiseRedFlags(RuntimeError('issuing duplicate work')) _CheckForDupesHACK[uhdr] = (hdr, x) data = b2a_hex(swap32(hdr)).decode('utf8') + rv['data'] # TODO: endian shuffle etc rv['data'] = data if midstate and 'midstate' not in self.extensions and 'midstate' not in self.quirks: h = midstate.SHA256(hdr)[:8] rv['midstate'] = b2a_hex(pack('<LLLLLLLL', *h)).decode('ascii') ShareTargetHex = '%064x' % (target,) ShareTargetHexLE = b2a_hex(bytes.fromhex(ShareTargetHex)[::-1]).decode('ascii') rv['target'] = ShareTargetHexLE self._JSONHeaders['X-Roll-NTime'] = 'expire=%d' % (self.server.StaleWorkTimeout,) return rv
def doJSON_getwork(self, data=None): if not data is None: return self.doJSON_submitwork(data) rv = dict(self.getwork_rv_template) (hdr, x, target) = self.server.getBlockHeader(self.Username) # FIXME: this assumption breaks with internal rollntime # NOTE: noncerange needs to set nonce to start value at least global _CheckForDupesHACK uhdr = hdr[:68] + hdr[72:] if uhdr in _CheckForDupesHACK: _RealDupes[uhdr] = (_CheckForDupesHACK[uhdr], (hdr, x)) raise self.server.RaiseRedFlags( RuntimeError('issuing duplicate work')) _CheckForDupesHACK[uhdr] = (hdr, x) data = b2a_hex(swap32(hdr)).decode('utf8') + rv['data'] # TODO: endian shuffle etc rv['data'] = data if midstate and 'midstate' not in self.extensions and 'midstate' not in self.quirks: h = midstate.SHA256(hdr)[:8] rv['midstate'] = b2a_hex(pack('<LLLLLLLL', *h)).decode('ascii') ShareTargetHex = '%064x' % (target, ) ShareTargetHexLE = b2a_hex( bytes.fromhex(ShareTargetHex)[::-1]).decode('ascii') rv['target'] = ShareTargetHexLE self._JSONHeaders['X-Roll-NTime'] = 'expire=120' return rv
def updateJobOnly(self, wantClear=False, forceClean=False, triggeredByRskGetWork=False, rskLog=True): self._JobId += 1 JobId = '%d_%d' % (time(), self._JobId) (MC, wld) = self.getStratumJob(JobId, wantClear=wantClear) (height, merkleTree, cb, prevBlock, bits) = MC[:5] if len(cb) > 96 - len(self.extranonce1null) - 4: if not self.rejecting: self.logger.warning('Coinbase too big for stratum: disabling') self.rejecting = True self.boot_all() self.UpdateTask = self.schedule(self.updateJob, time() + 10) return elif self.rejecting: self.rejecting = False self.logger.info( 'Coinbase small enough for stratum again: reenabling') txn = deepcopy(merkleTree.data[0]) cb += self.extranonce1null + b'Eloi' txn.setCoinbase(cb) txn.assemble() pos = txn.data.index(cb) + len(cb) steps = list(b2a_hex(h).decode('ascii') for h in merkleTree._steps) tim = int(time()) if rskLog: if triggeredByRskGetWork: self.logger.info( 'ROOTSTOCK: getwork: notime, notime, {}'.format(JobId)) elif self.getLogGbtCall(): self.logger.info( 'ROOTSTOCK: getblocktemplate: {}, {}, {}'.format( merkleTree.start_time, merkleTree.finish_time, JobId)) self.JobBytes = json.dumps({ 'id': None, 'method': 'mining.notify', 'params': [ JobId, b2a_hex(swap32(prevBlock)).decode('ascii'), b2a_hex(txn.data[:pos - len(self.extranonce1null) - 4]).decode('ascii'), b2a_hex(txn.data[pos:]).decode('ascii'), steps, '%08x' % (merkleTree.MP['version'], ), b2a_hex(bits[::-1]).decode('ascii'), b2a_hex(struct.pack('>L', int(time()))).decode('ascii'), forceClean or not self.IsJobValid(self.JobId) ], }).encode('ascii') + b"\n" self.JobId = JobId
def endian_swap(self): """swap the endian-ness of all values""" if self.width == 32: self.buf = [util.swap32(x) for x in self.buf] elif self.width == 16: self.buf = [util.swap16(x) for x in self.buf] elif self.width == 8: # nothing to do return else: assert False, 'endian swap error: width %d' % self.width
def updateJob(self, wantClear=False): if self.UpdateTask: try: self.rmSchedule(self.UpdateTask) except: pass self._JobId += 1 JobId = '%d %d' % (time(), self._JobId) (MC, wld) = self.getStratumJob(JobId, wantClear=wantClear) (height, merkleTree, cb, prevBlock, bits) = MC[:5] if len(cb) > 96 - len(self.extranonce1null) - 4: if not self.rejecting: self.logger.warning('Coinbase too big for stratum: disabling') self.rejecting = True self.boot_all() self.UpdateTask = self.schedule(self.updateJob, time() + 10) return elif self.rejecting: self.rejecting = False self.logger.info( 'Coinbase small enough for stratum again: reenabling') txn = deepcopy(merkleTree.data[0]) cb += self.extranonce1null + b'Eloi' txn.setCoinbase(cb) txn.assemble() pos = txn.data.index(cb) + len(cb) steps = list(b2a_hex(h).decode('ascii') for h in merkleTree._steps) self.JobBytes = json.dumps({ 'id': None, 'method': 'mining.notify', 'params': [ JobId, b2a_hex(swap32(prevBlock)).decode('ascii'), b2a_hex(txn.data[:pos - len(self.extranonce1null) - 4]).decode('ascii'), b2a_hex(txn.data[pos:]).decode('ascii'), steps, '00000002', b2a_hex(bits[::-1]).decode('ascii'), b2a_hex(struct.pack('>L', int(time()))).decode('ascii'), not self.IsJobValid(self.JobId) ], }).encode('ascii') + b"\n" self.JobId = JobId self.WakeRequest = 1 self.wakeup() self.UpdateTask = self.schedule(self.updateJob, time() + 55)
def updateJob(self, wantClear = False): if self.UpdateTask: try: self.rmSchedule(self.UpdateTask) except: pass self._JobId += 1 JobId = '%d %d' % (time(), self._JobId) (MC, wld) = self.getStratumJob(JobId, wantClear=wantClear) (height, merkleTree, cb, prevBlock, bits) = MC[:5] if len(cb) > 96 - len(self.extranonce1null) - 4: if not self.rejecting: self.logger.warning('Coinbase too big for stratum: disabling') self.rejecting = True self.boot_all() self.UpdateTask = self.schedule(self.updateJob, time() + 10) return elif self.rejecting: self.rejecting = False self.logger.info('Coinbase small enough for stratum again: reenabling') txn = deepcopy(merkleTree.data[0]) cb += self.extranonce1null + b'Eloi' txn.setCoinbase(cb) txn.assemble() pos = txn.data.index(cb) + len(cb) steps = list(b2a_hex(h).decode('ascii') for h in merkleTree._steps) self.JobBytes = json.dumps({ 'id': None, 'method': 'mining.notify', 'params': [ JobId, b2a_hex(swap32(prevBlock)).decode('ascii'), b2a_hex(txn.data[:pos - len(self.extranonce1null) - 4]).decode('ascii'), b2a_hex(txn.data[pos:]).decode('ascii'), steps, '00000002', b2a_hex(bits[::-1]).decode('ascii'), b2a_hex(struct.pack('>L', int(time()))).decode('ascii'), not self.IsJobValid(self.JobId) ], }).encode('ascii') + b"\n" self.JobId = JobId self.WakeRequest = 1 self.wakeup() self.UpdateTask = self.schedule(self.updateJob, time() + 55)
def doJSON_submitwork(self, datax): data = swap32(bytes.fromhex(datax))[:80] share = { 'data': data, '_origdata': datax, 'username': self.Username, 'remoteHost': self.remoteHost, } try: self.server.receiveShare(share) except RejectedShare as rej: self._JSONHeaders['X-Reject-Reason'] = str(rej) return False return True
def receiveShare(share): # TODO: username => userid try: checkShare(share) except RejectedShare as rej: share['rejectReason'] = str(rej) raise finally: if '_origdata' in share: share['solution'] = share['_origdata'] else: share['solution'] = b2a_hex(swap32(share['data'])).decode('utf8') for i in loggersShare: i(share)
def doJSON_submitwork(self, datax): data = swap32(bytes.fromhex(datax))[:80] share = { 'data': data, '_origdata' : datax, 'username': self.Username, 'remoteHost': self.remoteHost, } try: self.server.receiveShare(share) except RejectedShare as rej: self._JSONHeaders['X-Reject-Reason'] = str(rej) return False return True
def updateJobOnly(self, wantClear=False, forceClean=False): self._JobId += 1 JobId = "%d %d" % (time(), self._JobId) (MC, wld) = self.getStratumJob(JobId, wantClear=wantClear) (height, merkleTree, cb, prevBlock, bits) = MC[:5] if len(cb) > 96 - len(self.extranonce1null) - 4: if not self.rejecting: self.logger.warning("Coinbase too big for stratum: disabling") self.rejecting = True self.boot_all() self.UpdateTask = self.schedule(self.updateJob, time() + 10) return elif self.rejecting: self.rejecting = False self.logger.info("Coinbase small enough for stratum again: reenabling") txn = deepcopy(merkleTree.data[0]) cb += self.extranonce1null + b"Eloi" txn.setCoinbase(cb) txn.assemble() pos = txn.data.index(cb) + len(cb) steps = list(b2a_hex(h).decode("ascii") for h in merkleTree._steps) self.JobBytes = ( json.dumps( { "id": None, "method": "mining.notify", "params": [ JobId, b2a_hex(swap32(prevBlock)).decode("ascii"), b2a_hex(txn.data[: pos - len(self.extranonce1null) - 4]).decode("ascii"), b2a_hex(txn.data[pos:]).decode("ascii"), steps, "%08x" % (merkleTree.MP["version"],), b2a_hex(bits[::-1]).decode("ascii"), b2a_hex(struct.pack(">L", int(time()))).decode("ascii"), forceClean or not self.IsJobValid(self.JobId), ], } ).encode("ascii") + b"\n" ) self.JobId = JobId
def doJSON_submitwork(self, datax): data = swap32(bytes.fromhex(datax))[:80] share = { 'data': data, '_origdata' : datax, 'username': self.Username, 'remoteHost': self.remoteHost, 'userAgent': self.UA, 'submitProtocol': 'getwork', } if hasattr(self, 'XStratumHeader') and 'brokenstratum' not in self.quirks: self._JSONHeaders['X-Stratum'] = self.XStratumHeader try: self.server.receiveShare(share) except RejectedShare as rej: self._JSONHeaders['X-Reject-Reason'] = str(rej) return False return True
def doJSON_submitwork(self, datax): data = swap32(bytes.fromhex(datax))[:80] share = { 'data': data, '_origdata': datax, 'username': self.Username, 'remoteHost': self.remoteHost, 'userAgent': self.UA, 'submitProtocol': 'getwork', } if hasattr(self, 'XStratumHeader') and 'brokenstratum' not in self.quirks: self._JSONHeaders['X-Stratum'] = self.XStratumHeader try: self.server.receiveShare(share) except RejectedShare as rej: self._JSONHeaders['X-Reject-Reason'] = str(rej) return False return True
def logShare(share): if '_origdata' in share: share['solution'] = share['_origdata'] else: share['solution'] = b2a_hex(swap32(share['data'])).decode('utf8') try: share['solution_safe'] = b2a_hex(share['blkhash']).decode('utf8') except: pass users = share['username'].split(".") share['username_safe'] = 'invalid' try: if users[0].startswith('V'): share['username_safe'] = users[0] if users[1].startswith('V'): share['username_safe'] = users[1] if users[2].startswith('V'): share['username_safe'] = users[2] except IndexError: pass for i in loggersShare: i.logShare(share)