def validate_block(self, block: BlockAPI) -> None: if not isinstance(block, self.get_block_class()): raise ValidationError( f"This vm ({self!r}) is not equipped to validate a block of type {block!r}" ) if block.is_genesis: validate_length_lte(block.header.extra_data, self.extra_data_max_bytes, title="BlockHeader.extra_data") else: parent_header = get_parent_header(block.header, self.chaindb) self.validate_header(block.header, parent_header) tx_root_hash, _ = make_trie_root_and_nodes(block.transactions) if tx_root_hash != block.header.transaction_root: raise ValidationError( f"Block's transaction_root ({block.header.transaction_root!r}) " f"does not match expected value: {tx_root_hash!r}") if len(block.uncles) > MAX_UNCLES: raise ValidationError( f"Blocks may have a maximum of {MAX_UNCLES} uncles. " f"Found {len(block.uncles)}.") if not self.chaindb.exists(block.header.state_root): raise ValidationError("`state_root` was not found in the db.\n" f"- state_root: {block.header.state_root!r}") local_uncle_hash = keccak(rlp.encode(block.uncles)) if local_uncle_hash != block.header.uncles_hash: raise ValidationError( "`uncles_hash` and block `uncles` do not match.\n" f" - num_uncles : {len(block.uncles)}\n" f" - block uncle_hash : {local_uncle_hash!r}\n" f" - header uncle_hash: {block.header.uncles_hash!r}")
def normalize_result( msg: Tuple[BlockBody, ...]) -> Iterable[BlockBodyBundle]: for body in msg: uncle_hashes = keccak(rlp.encode(body.uncles)) transaction_root_and_nodes = make_trie_root_and_nodes( body.transactions) yield body, transaction_root_and_nodes, uncle_hashes
def normalize_result(self, cmd: BlockBodiesV65) -> Iterable[BlockBodyBundle]: for body in cmd.payload: uncle_hashes = keccak(rlp.encode(body.uncles)) transaction_root_and_nodes = make_trie_root_and_nodes( body.transactions) yield body, transaction_root_and_nodes, uncle_hashes
def set_block_transactions(self, base_block, new_header, transactions, receipts): tx_root_hash, tx_kv_nodes = make_trie_root_and_nodes(transactions) self.chaindb.persist_trie_data_dict(tx_kv_nodes) receipt_root_hash, receipt_kv_nodes = make_trie_root_and_nodes( receipts) self.chaindb.persist_trie_data_dict(receipt_kv_nodes) return base_block.copy( transactions=transactions, header=new_header.copy( transaction_root=tx_root_hash, receipt_root=receipt_root_hash, ), )
def set_block_transactions(self, base_block: BlockAPI, new_header: BlockHeaderAPI, transactions: Sequence[SignedTransactionAPI], receipts: Sequence[ReceiptAPI]) -> BlockAPI: tx_root_hash, tx_kv_nodes = make_trie_root_and_nodes(transactions) self.chaindb.persist_trie_data_dict(tx_kv_nodes) receipt_root_hash, receipt_kv_nodes = make_trie_root_and_nodes( receipts) self.chaindb.persist_trie_data_dict(receipt_kv_nodes) return base_block.copy( transactions=transactions, header=new_header.copy( transaction_root=tx_root_hash, receipt_root=receipt_root_hash, ), )
def set_block_transactions(self, base_block: BaseBlock, new_header: BlockHeader, transactions: Tuple[BaseTransaction, ...], receipts: Tuple[Receipt, ...]) -> BaseBlock: tx_root_hash, tx_kv_nodes = make_trie_root_and_nodes(transactions) self.chaindb.persist_trie_data_dict(tx_kv_nodes) receipt_root_hash, receipt_kv_nodes = make_trie_root_and_nodes(receipts) self.chaindb.persist_trie_data_dict(receipt_kv_nodes) return base_block.copy( transactions=transactions, header=new_header.copy( transaction_root=tx_root_hash, receipt_root=receipt_root_hash, ), )
def mk_header_and_receipts(block_number, num_receipts): receipts = mk_receipts(num_receipts) root_hash, trie_root_and_data = make_trie_root_and_nodes(receipts) header = BlockHeader( difficulty=1000000, block_number=block_number, gas_limit=3141592, timestamp=int(time.time()), receipt_root=root_hash, ) return header, receipts, (root_hash, trie_root_and_data)
def set_block_xmessage_sent( self, base_block: StretchBlock, xmessage_sent: Tuple[StretchXMessage, ...]) -> StretchBlock: tx_root_hash, tx_kv_nodes = make_trie_root_and_nodes(xmessage_sent) self.chaindb.persist_trie_data_dict(tx_kv_nodes) return base_block.copy( xmessage_sent=xmessage_sent, header=base_block.header.copy(xmessage_sent_root=tx_root_hash, ), )
def set_block_xmessages_received(self, base_block: StretchBlock, new_header: StretchBlockHeader, xmessages_received: Tuple[StretchXMessage, ...]) -> StretchBlock: tx_root_hash, tx_kv_nodes = make_trie_root_and_nodes(xmessages_received) self.chaindb.persist_trie_data_dict(tx_kv_nodes) return base_block.copy( xmessages_received=xmessages_received, header=new_header.copy( xmessage_received_root=tx_root_hash, ), )
def validate_block(self, block: BaseBlock) -> None: """ Validate the the given block. """ if not isinstance(block, self.get_block_class()): raise ValidationError( "This vm ({0!r}) is not equipped to validate a block of type {1!r}".format( self, block, ) ) if block.is_genesis: validate_length_lte(block.header.extra_data, 32, title="BlockHeader.extra_data") else: parent_header = get_parent_header(block.header, self.chaindb) self.validate_header(block.header, parent_header) tx_root_hash, _ = make_trie_root_and_nodes(block.transactions) if tx_root_hash != block.header.transaction_root: raise ValidationError( "Block's transaction_root ({0}) does not match expected value: {1}".format( block.header.transaction_root, tx_root_hash)) if len(block.uncles) > MAX_UNCLES: raise ValidationError( "Blocks may have a maximum of {0} uncles. Found " "{1}.".format(MAX_UNCLES, len(block.uncles)) ) if not self.chaindb.exists(block.header.state_root): raise ValidationError( "`state_root` was not found in the db.\n" "- state_root: {0}".format( block.header.state_root, ) ) local_uncle_hash = keccak(rlp.encode(block.uncles)) if local_uncle_hash != block.header.uncles_hash: raise ValidationError( "`uncles_hash` and block `uncles` do not match.\n" " - num_uncles : {0}\n" " - block uncle_hash : {1}\n" " - header uncle_hash: {2}".format( len(block.uncles), local_uncle_hash, block.header.uncles_hash, ) )
def mk_header_and_body(block_number, num_transactions, num_uncles): transactions = tuple(mk_transaction() for _ in range(num_transactions)) uncles = tuple(mk_uncle(block_number - 1) for _ in range(num_uncles)) transaction_root, trie_data = make_trie_root_and_nodes(transactions) uncles_hash = keccak(rlp.encode(uncles)) body = BlockBody(transactions=transactions, uncles=uncles) header = BlockHeader( difficulty=1000000, block_number=block_number, gas_limit=3141592, timestamp=int(time.time()), transaction_root=transaction_root, uncles_hash=uncles_hash, ) return header, body, transaction_root, trie_data, uncles_hash
def trie_root(txs_or_receipts): return make_trie_root_and_nodes(txs_or_receipts)[0]