def mine(cls, block: Block, mine_interrupt: threading.Event = None) -> Union[Block, None]: start = time.time() nonce = 0 target = (1 << (256 - block.bits)) mine_interrupt.clear() logger.info(f'[consensus] mining after block {block.prev_block_hash}') while int(Utils.sha256d(block.header(nonce)), 16) >= target: nonce += 1 if mine_interrupt.is_set(): logger.info(f'[consensus] mining interrupted +++ {nonce}') mine_interrupt.clear() return None block = block._replace(nonce=nonce) duration = max(time.time() - start, 0.0001) khs = (block.nonce // duration) // 1000 logger.info( f'[consensus] mining block found at nonce={nonce} using {round(duration, 4)} s at rate {khs} KH/s: {block.id}' ) return block
def assemble_and_solve_block(self, txns=None) -> Block: """ Construct a Block by pulling transactions from the mempool, then mine it. """ with self.chain_lock: #chain_use_id = [str(number).split('.')[0] + '.' + str(number).split('.')[1][:5] for number in [random.random()]][0] #logger.info(f'####### into chain_lock: {chain_use_id} of assemble_and_solve_block') prev_block_hash = self.active_chain.chain[ -1].id if self.active_chain.chain else None block = Block( version=0, prev_block_hash=prev_block_hash, merkle_hash='', timestamp=int(time.time()), bits=Block.get_next_work_required(prev_block_hash, self.active_chain, self.side_branches), nonce=0, txns=[None, *txns] if txns else [None], ) if block.bits is None: #logger.info(f'####### out of chain_lock: {chain_use_id} of assemble_and_solve_block') return None if not block.txns[1:]: block = self.mempool.select_from_mempool(block, self.utxo_set) # print("EdgenceChain 113: build block with txn:", end="") # print(block) if len(block.txns[1:]) > 0: logger.info( f'{len(block.txns[1:])} transactions selected from mempool to construct this block' ) # print("EdgenceChain 117: build txn:") # print(block) fees = block.calculate_fees(self.utxo_set) # print("fee is: ", end="") # print(fees) my_address = self.wallet()[2] coinbase_txn = Transaction.create_coinbase( my_address, Block.get_block_subsidy(self.active_chain) + fees, self.active_chain.height) #logger.info(f'####### out of chain_lock: {chain_use_id} of assemble_and_solve_block') block.txns[0] = coinbase_txn block = block._replace( merkle_hash=MerkleNode.get_merkle_root_of_txns(block.txns).val) if len(Utils.serialize(block)) > Params.MAX_BLOCK_SERIALIZED_SIZE: raise ValueError('txns specified create a block too large') block = PoW.mine(block, self.mine_interrupt) # print("EdgenceChain 138: after mine: ") # print(block) return block
def mine(block: Block) -> Block: """ A minimal function for calculating genisis_block nonce. """ start = time.time() nonce = 0 target = 1 << (256 - block.bits) while int(Utils.sha256d(block.header(nonce)), 16) >= target: nonce += 1 block = block._replace(nonce=nonce) duration = max(time.time() - start, 0.0001) khs = (block.nonce // duration) // 1_000 print( f"genesis_block found at nonce={nonce} using {round(duration, 4)}s at rate {khs}KH/s" ) print(f"blockid={block.id}") return block