def getinfo(self): r = OrderedDict() r['hash'] = hexlify(self.hash).decode() if self.hash else None try: if self.work_hash is None: update_work_hash(self) r['work_hash'] = hexlify(self.work_hash).decode() except Exception as e: import traceback traceback.print_exc() print(e) r['work_hash'] = None r['previous_hash'] = hexlify( self.previous_hash).decode() if self.previous_hash else None r['next_hash'] = hexlify( self.next_hash).decode() if self.next_hash else None r['f_orphan'] = self.f_orphan r['f_on_memory'] = self.f_on_memory r['height'] = self.height r['difficulty'] = self.difficulty r['fixed_difficulty'] = round(self.difficulty / self.bias, 8) r['score'] = round(self.score, 8) r['flag'] = C.consensus2name[self.flag] r['merkleroot'] = hexlify( self.merkleroot).decode() if self.merkleroot else None r['time'] = V.BLOCK_GENESIS_TIME + self.time r['bits'] = self.bits r['bias'] = round(self.bias, 8) r['nonce'] = hexlify(self.nonce).decode() if self.nonce else None r['txs'] = [hexlify(tx.hash).decode() for tx in self.txs] return r
def getinfo(self, f_with_tx_info=False): r = dict() r['hash'] = self.hash.hex() if self.hash else None try: if self.work_hash is None: update_work_hash(self) r['work_hash'] = self.work_hash.hex() except Exception as e: traceback.print_exc() print(e) r['work_hash'] = None r['previous_hash'] = self.previous_hash.hex() if self.previous_hash else None r['next_hash'] = self.next_hash.hex() if self.next_hash else None r['f_orphan'] = self.f_orphan r['recode_flag'] = self.recode_flag r['height'] = self.height r['difficulty'] = round(self.difficulty, 8) r['fixed_difficulty'] = round(self.difficulty / self.bias, 8) r['score'] = round(self.score, 8) r['flag'] = C.consensus2name[self.flag] r['merkleroot'] = self.merkleroot.hex() if self.merkleroot else None r['time'] = V.BLOCK_GENESIS_TIME + self.time r['bits'] = self.bits r['bias'] = round(self.bias, 8) r['nonce'] = self.nonce.hex() if self.nonce else None if f_with_tx_info: r['txs'] = [tx.getinfo() for tx in self.txs] else: r['txs'] = [tx.hash.hex() for tx in self.txs] r['create_time'] = self.create_time r['size'] = self.size return r
def pow_check(self, extra_target=None): if extra_target: assert isinstance(extra_target, int) target_int = extra_target else: if not self.target_hash: self.bits2target() target_int = int.from_bytes(self.target_hash, 'little') if not self.work_hash: update_work_hash(self) return target_int > int.from_bytes(self.work_hash, 'little')
def get_submit_data(job: Job, extranonce1: bytes, extranonce2: bytes, nonce: bytes, difficulty: float) \ -> (Optional[bytes], bytes, bool, bool): """check client submit data and generate node submit data""" assert len(extranonce1) == 4 and len(extranonce2) == 4 coinbase = job.coinbase1 + extranonce1 + extranonce2 + job.coinbase2 coinbase_hash = sha256d_hash(coinbase) merkleroot_list = [coinbase_hash] + [tx[0] for tx in job.unconfirmed] merkleroot = merkleroot_hash(merkleroot_list) block = Block.from_dict({ 'version': job.version, 'previous_hash': job.previous_hash, 'merkleroot': merkleroot, 'time': job.ntime, 'bits': int.from_bytes(job.bits, 'big'), 'nonce': nonce, # meta 'height': job.height, 'flag': job.algorithm, }) # check fulfill target or share update_work_hash(block) f_mined = block.pow_check() f_shared = block.pow_check(int(DEFAULT_TARGET / difficulty)) log.debug(f"block -> {block.height} {block.hash.hex()}") log.debug(f"coinbase -> {coinbase.hex()}") log.debug(f"header -> {block.b.hex()}") log.debug(f"merkleroot -> {len(merkleroot_list)} {merkleroot.hex()}") log.debug( f"workhash -> {block.work_hash.hex()} mined:{f_mined} shared:{f_shared}" ) # generate submit data when mined if f_mined: submit_data = block.b tx_len = len(job.unconfirmed) + 1 if tx_len < 0xfd: submit_data += tx_len.to_bytes(1, 'little') elif tx_len <= 0xffff: submit_data += b'\xfd' + tx_len.to_bytes(2, 'little') elif tx_len <= 0xffffffff: submit_data += b'\xfe' + tx_len.to_bytes(4, 'little') elif tx_len <= 0xffffffffffffffff: # == 0xff submit_data += b'\xff' + tx_len.to_bytes(8, 'little') else: raise Exception(f"overflowed tx length {tx_len}") submit_data += coinbase for tx in job.unconfirmed: submit_data += tx[1] else: submit_data = None return submit_data, block, f_mined, f_shared
def update_pow(self): update_work_hash(self)