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 validate_header(cls, header: BlockHeaderAPI, parent_header: BlockHeaderAPI, check_seal: bool = True) -> None: """ :raise eth.exceptions.ValidationError: if the header is not valid """ if parent_header is None: # to validate genesis header, check if it equals canonical header at block number 0 raise ValidationError( "Must have access to parent header to validate current header") else: validate_length_lte(header.extra_data, 32, title="BlockHeader.extra_data") validate_gas_limit(header.gas_limit, parent_header.gas_limit) if header.block_number != parent_header.block_number + 1: raise ValidationError( "Blocks must be numbered consecutively. " f"Block number #{header.block_number} " f"has parent #{parent_header.block_number}") # timestamp if header.timestamp <= parent_header.timestamp: raise ValidationError( "timestamp must be strictly later than parent, " f"but is {parent_header.timestamp - header.timestamp} seconds before.\n" f"- child : {header.timestamp}\n" f"- parent : {parent_header.timestamp}. ") if check_seal: try: cls.validate_seal(header) except ValidationError: cls.cls_logger.warning( "Failed to validate header proof of work on header: %r", header.as_dict()) raise
async def preview_transactions( self, header: BlockHeaderAPI, transactions: Tuple[SignedTransactionAPI, ...], parent_state_root: Hash32, lagging: bool = True) -> None: if not self.manager.is_running: # If the service is shutting down, we can ignore preview requests return self.manager.run_task(self._preview_address_load, header, parent_state_root, transactions) # This is a hack, so that preview executions can load ancestor block-hashes self._db[header.hash] = rlp.encode(header) # Always broadcast, to start previewing transactions that are further ahead in the block old_state_header = header.copy(state_root=parent_state_root) self._event_bus.broadcast_nowait( DoStatelessBlockPreview(old_state_header, transactions), FIRE_AND_FORGET_BROADCASTING ) self._backfiller.set_root_hash(header, parent_state_root)
def _custom_header(base_header: BlockHeaderAPI, **kwargs: Any) -> BlockHeaderAPI: header_fields = {'coinbase'} header_params = {k: v for k, v in kwargs.items() if k in header_fields} return base_header.copy(**header_params)
def serialize(cls, obj: BlockHeaderAPI) -> List[bytes]: return obj.serialize(obj)