Skip to content

Commit 718391d

Browse files
authored
Merge pull request #1950 from carver/transaction-apply-hook
Call a new hook when a transaction is applied
2 parents 5ad5df3 + 078621c commit 718391d

File tree

4 files changed

+41
-4
lines changed

4 files changed

+41
-4
lines changed

eth/abc.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,6 +2666,25 @@ def get_block(self) -> BlockAPI:
26662666
"""
26672667
...
26682668

2669+
#
2670+
# Hooks
2671+
#
2672+
2673+
def transaction_applied_hook(
2674+
self,
2675+
transaction_index: int,
2676+
transactions: Sequence[SignedTransactionAPI],
2677+
base_header: BlockHeaderAPI,
2678+
partial_header: BlockHeaderAPI,
2679+
computation: ComputationAPI,
2680+
receipt: ReceiptAPI) -> None:
2681+
"""
2682+
A hook for a subclass to use as a way to note that a transaction was applied.
2683+
This only gets triggered as part of `apply_all_transactions`, which is called
2684+
by `block_import`.
2685+
"""
2686+
pass
2687+
26692688
#
26702689
# Execution
26712690
#

eth/chains/base.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,10 @@ def import_block(self,
468468
)
469469

470470
base_header_for_import = self.create_header_from_parent(parent_header)
471-
block_result = self.get_vm(base_header_for_import).import_block(block)
471+
# Make a copy of the empty header, adding in the expected amount of gas used. This
472+
# allows for richer logging in the VM.
473+
annotated_header = base_header_for_import.copy(gas_used=block.header.gas_used)
474+
block_result = self.get_vm(annotated_header).import_block(block)
472475
imported_block = block_result.block
473476

474477
# Validate the imported block.

eth/vm/base.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ def apply_all_transactions(
227227
transactions: Sequence[SignedTransactionAPI],
228228
base_header: BlockHeaderAPI
229229
) -> Tuple[BlockHeaderAPI, Tuple[ReceiptAPI, ...], Tuple[ComputationAPI, ...]]:
230-
if base_header.block_number != self.get_header().block_number:
230+
vm_header = self.get_header()
231+
if base_header.block_number != vm_header.block_number:
231232
raise ValidationError(
232233
f"This VM instance must only work on block #{self.get_header().block_number}, "
233234
f"but the target header has block #{base_header.block_number}"
@@ -238,7 +239,7 @@ def apply_all_transactions(
238239
previous_header = base_header
239240
result_header = base_header
240241

241-
for transaction in transactions:
242+
for transaction_index, transaction in enumerate(transactions):
242243
try:
243244
snapshot = self.state.snapshot()
244245
receipt, computation = self.apply_transaction(
@@ -254,6 +255,15 @@ def apply_all_transactions(
254255
receipts.append(receipt)
255256
computations.append(computation)
256257

258+
self.transaction_applied_hook(
259+
transaction_index,
260+
transactions,
261+
vm_header,
262+
result_header,
263+
computation,
264+
receipt,
265+
)
266+
257267
receipts_tuple = tuple(receipts)
258268
computations_tuple = tuple(computations)
259269

@@ -286,7 +296,9 @@ def import_block(self, block: BlockAPI) -> BlockAndMetaWitness:
286296
execution_context = self.create_execution_context(
287297
block.header, self.previous_hashes, self.chain_context)
288298

289-
header = self.get_header()
299+
# Zero out the gas_used before applying transactions. Each applied transaction will
300+
# increase the gas used in the final new_header.
301+
header = self.get_header().copy(gas_used=0)
290302
# we need to re-initialize the `state` to update the execution context.
291303
self._state = self.get_state_class()(self.chaindb.db, execution_context, header.state_root)
292304

newsfragments/1950.feature.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add a new hook :meth:`eth.abc.VirtualMachineAPI.transaction_applied_hook` which is triggered after
2+
each transaction in ``apply_all_transactions``, which is called by ``import_block``. The first use
3+
case is reporting progress in the middle of Beam Sync.

0 commit comments

Comments
 (0)