def add_receipt_to_header(self, old_header: BlockHeaderAPI, receipt: ReceiptAPI) -> BlockHeaderAPI: return old_header.copy( bloom=int(BloomFilter(old_header.bloom) | receipt.bloom), gas_used=receipt.gas_used, state_root=self.state.make_state_root(), )
def add_receipt_to_header(self, old_header: BlockHeaderAPI, receipt: ReceiptAPI) -> BlockHeaderAPI: # Skip merkelizing the account data and persisting it to disk on every transaction. # Starting in Byzantium, this is no longer necessary, because the state root isn't # in the receipt anymore. return old_header.copy( bloom=int(BloomFilter(old_header.bloom) | receipt.bloom), gas_used=receipt.gas_used, )
def sign_block_header(header: BlockHeaderAPI, private_key: PrivateKey) -> BlockHeaderAPI: signature_hash = get_signature_hash(header) signature = private_key.sign_msg_hash(signature_hash) signers = get_signers_at_checkpoint(header) signed_extra_data = b''.join(( header.extra_data[:VANITY_LENGTH], b''.join(signers), signature.to_bytes(), )) return header.copy(extra_data=signed_extra_data)
def get_signature_hash(header: BlockHeaderAPI) -> Hash32: """ Return the hash that is signed by the block producer. It is defined as the hash of the ``header`` except that the last 65 bytes of the ``extra_data`` (the signature) are removed before calculating the hash. """ if len(header.extra_data) < SIGNATURE_LENGTH: raise ValueError("header.extra_data too short to contain signature") signature_header = header.copy( extra_data=header.extra_data[:len(header.extra_data) - SIGNATURE_LENGTH]) return signature_header.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, ), )
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)