Skip to content

Commit a09a610

Browse files
maouehs1na
andauthored
core/tracing: add system call callback when performing ProcessBeaconBlockRoot (#29355)
Added a start/end system where tracer can be notified that processing of some Ethereum system calls is starting processing and also notifies it when the processing has completed. Doing a start/end for system call will enable tracers to "route" incoming next tracing events to go to a separate bucket than other EVM calls. Those not interested by this fact can simply avoid registering the hooks. The EVM call is going to be traced normally afterward between the signals provided by those 2 new hooks but outside of a transaction context OnTxStart/End. That something implementors of live tracers will need to be aware of (since only "trx tracers" are not concerned by ProcessBeaconRoot). --------- Co-authored-by: Sina Mahmoodi <[email protected]>
1 parent 905e325 commit a09a610

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

core/state_processor.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,13 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
186186
// ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root
187187
// contract. This method is exported to be used in tests.
188188
func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *state.StateDB) {
189+
if vmenv.Config.Tracer != nil && vmenv.Config.Tracer.OnSystemCallStart != nil {
190+
vmenv.Config.Tracer.OnSystemCallStart()
191+
}
192+
if vmenv.Config.Tracer != nil && vmenv.Config.Tracer.OnSystemCallEnd != nil {
193+
defer vmenv.Config.Tracer.OnSystemCallEnd()
194+
}
195+
189196
// If EIP-4788 is enabled, we need to invoke the beaconroot storage contract with
190197
// the new root
191198
msg := &Message{

core/tracing/CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to the tracing interface will be documented in this file.
44

55
## [Unreleased]
66

7+
There have been minor backwards-compatible changes to the tracing interface to explicitly mark the execution of **system** contracts. As of now the only system call updates the parent beacon block root as per [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788). Other system calls are being considered for the future hardfork.
8+
9+
### New methods
10+
11+
- `OnSystemCallStart()`: This hook is called when EVM starts processing a system call. Note system calls happen outside the scope of a transaction. This event will be followed by normal EVM execution events.
12+
- `OnSystemCallEnd()`: This hook is called when EVM finishes processing a system call.
13+
14+
## [v1.14.0]
15+
716
There has been a major breaking change in the tracing interface for custom native tracers. JS and built-in tracers are not affected by this change and tracing API methods may be used as before. This overhaul has been done as part of the new live tracing feature ([#29189](https://github.com/ethereum/go-ethereum/pull/29189)). To learn more about live tracing please refer to the [docs](https://geth.ethereum.org/docs/developers/evm-tracing/live-tracing).
817

918
**The `EVMLogger` interface which the tracers implemented has been removed.** It has been replaced by a new struct `tracing.Hooks`. `Hooks` keeps pointers to event listening functions. Internally the EVM will use these function pointers to emit events and can skip an event if the tracer has opted not to implement it. In fact this is the main reason for this change of approach. Another benefit is the ease of adding new hooks in future, and dynamically assigning event receivers.
@@ -66,4 +75,5 @@ The hooks `CaptureStart` and `CaptureEnd` have been removed. These hooks signale
6675
- `CaptureState` -> `OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error)`. `op` is of type `byte` which can be cast to `vm.OpCode` when necessary. A `*vm.ScopeContext` is not passed anymore. It is replaced by `tracing.OpContext` which offers access to the memory, stack and current contract.
6776
- `CaptureFault` -> `OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error)`. Similar to above.
6877

69-
[unreleased]: https://github.com/ethereum/go-ethereum/compare/v1.13.14...master
78+
[unreleased]: https://github.com/ethereum/go-ethereum/compare/v1.14.0...master
79+
[v1.14.0]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.0

core/tracing/hooks.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ type (
8181
TxEndHook = func(receipt *types.Receipt, err error)
8282

8383
// EnterHook is invoked when the processing of a message starts.
84+
//
85+
// Take note that EnterHook, when in the context of a live tracer, can be invoked
86+
// outside of the `OnTxStart` and `OnTxEnd` hooks when dealing with system calls,
87+
// see [OnSystemCallStartHook] and [OnSystemCallEndHook] for more information.
8488
EnterHook = func(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int)
8589

8690
// ExitHook is invoked when the processing of a message ends.
@@ -89,6 +93,10 @@ type (
8993
// ran out of gas when attempting to persist the code to database did not
9094
// count as a call failure and did not cause a revert of the call. This will
9195
// be indicated by `reverted == false` and `err == ErrCodeStoreOutOfGas`.
96+
//
97+
// Take note that ExitHook, when in the context of a live tracer, can be invoked
98+
// outside of the `OnTxStart` and `OnTxEnd` hooks when dealing with system calls,
99+
// see [OnSystemCallStartHook] and [OnSystemCallEndHook] for more information.
92100
ExitHook = func(depth int, output []byte, gasUsed uint64, err error, reverted bool)
93101

94102
// OpcodeHook is invoked just prior to the execution of an opcode.
@@ -125,6 +133,22 @@ type (
125133
// GenesisBlockHook is called when the genesis block is being processed.
126134
GenesisBlockHook = func(genesis *types.Block, alloc types.GenesisAlloc)
127135

136+
// OnSystemCallStartHook is called when a system call is about to be executed. Today,
137+
// this hook is invoked when the EIP-4788 system call is about to be executed to set the
138+
// beacon block root.
139+
//
140+
// After this hook, the EVM call tracing will happened as usual so you will receive a `OnEnter/OnExit`
141+
// as well as state hooks between this hook and the `OnSystemCallEndHook`.
142+
//
143+
// Note that system call happens outside normal transaction execution, so the `OnTxStart/OnTxEnd` hooks
144+
// will not be invoked.
145+
OnSystemCallStartHook = func()
146+
147+
// OnSystemCallEndHook is called when a system call has finished executing. Today,
148+
// this hook is invoked when the EIP-4788 system call is about to be executed to set the
149+
// beacon block root.
150+
OnSystemCallEndHook = func()
151+
128152
/*
129153
- State events -
130154
*/
@@ -155,12 +179,14 @@ type Hooks struct {
155179
OnFault FaultHook
156180
OnGasChange GasChangeHook
157181
// Chain events
158-
OnBlockchainInit BlockchainInitHook
159-
OnClose CloseHook
160-
OnBlockStart BlockStartHook
161-
OnBlockEnd BlockEndHook
162-
OnSkippedBlock SkippedBlockHook
163-
OnGenesisBlock GenesisBlockHook
182+
OnBlockchainInit BlockchainInitHook
183+
OnClose CloseHook
184+
OnBlockStart BlockStartHook
185+
OnBlockEnd BlockEndHook
186+
OnSkippedBlock SkippedBlockHook
187+
OnGenesisBlock GenesisBlockHook
188+
OnSystemCallStart OnSystemCallStartHook
189+
OnSystemCallEnd OnSystemCallEndHook
164190
// State events
165191
OnBalanceChange BalanceChangeHook
166192
OnNonceChange NonceChangeHook

0 commit comments

Comments
 (0)