def _connect_block(block: Block, active_chain: BlockChain, utxo_set: UTXO_Set) -> bool: """ Add block after current chain. Return True if block added successfully, else False. """ if block.validate_block(active_chain, utxo_set) is None: return False logger.info( f"connecting the {len(active_chain.chain)+1}th block {block.id} to chain {active_chain.idx}" ) active_chain.chain.append(block) # Minipulate transactions in this block. # Remove txin from utxo_set, add txout to utxo_set. for tx in block.txns: if not tx.is_coinbase: for txin in tx.txins: utxo_set.rm_from_utxo(*txin.to_spend) for i, txout in enumerate(tx.txouts): utxo_set.add_to_utxo( txout, tx, i, tx.is_coinbase, len(active_chain.chain) ) return True
def check_block_place( cls, block: Block, active_chain: BlockChain, utxo_set: BaseUTXO_Set, mempool: BaseMemPool, side_branches: Iterable[BlockChain], ) -> int: if Block.locate_block(block.id, active_chain, side_branches)[0]: logger.debug( f"[p2p] ignore block that already be seen: {block.id}") return None # already seen block try: chain_idx = block.validate_block(active_chain, utxo_set, mempool, side_branches) except BlockValidationError as e: if e.to_orphan: logger.info( f"[p2p] block {block.id} failed validation as an orphan block" ) return -1 # orphan block else: logger.exception( f"[p2p] block {block.id} failed validation due to internal error in this block" ) return -2 # Internal error in this block if chain_idx != Params.ACTIVE_CHAIN_IDX and len( side_branches) < chain_idx: logger.info( f"[p2p] creating a new side branch (idx {chain_idx}) for block {block.id}" ) side_branches.append(BlockChain(idx=chain_idx, chain=[])) prev_block, prev_block_height, prev_block_chain_idx = Block.locate_block( block.prev_block_hash, active_chain, side_branches) if prev_block_chain_idx != Params.ACTIVE_CHAIN_IDX: # branch of a branch logger.info( f"[p2p] branch (idx {chain_idx}) of an existing side branch (idx {prev_block_chain_idx}) for block {block.id}" ) branch_fork_height = Block.locate_block( block.prev_block_hash, side_branches[prev_block_chain_idx - 1])[1] side_branches[chain_idx - 1].chain = list( side_branches[prev_block_chain_idx - 1].chain[:branch_fork_height]) return chain_idx
def _connect_block(block: Block, active_chain: BlockChain, utxo_set: UTXO_Set) -> bool: if block.validate_block(active_chain, utxo_set) is None: return False logger.info( f'connecting the {len(active_chain.chain)+1}th block {block.id} to chain {active_chain.idx}' ) active_chain.chain.append(block) for tx in block.txns: if not tx.is_coinbase: for txin in tx.txins: utxo_set.rm_from_utxo(*txin.to_spend) for i, txout in enumerate(tx.txouts): utxo_set.add_to_utxo(txout, tx, i, tx.is_coinbase, len(active_chain.chain)) return True