diff --git a/core/block_access_list_creation.go b/core/block_access_list_creation.go index 06038938a0..c84c0754b3 100644 --- a/core/block_access_list_creation.go +++ b/core/block_access_list_creation.go @@ -27,6 +27,7 @@ type BlockAccessListTracer struct { balIdx uint16 accessListBuilder *bal.AccessListBuilder + // mutations and state reads from currently-executing bal index idxMutations *bal.StateDiff idxReads bal.StateAccesses } @@ -39,8 +40,9 @@ func NewBlockAccessListTracer(startIdx int) (*BlockAccessListTracer, *tracing.Ho accessListBuilder: bal.NewAccessListBuilder(), } hooks := &tracing.Hooks{ - OnTxEnd: balTracer.TxEndHook, + OnTxExecutionEnd: balTracer.OnTxExecutionEnd, OnTxStart: balTracer.TxStartHook, + OnTxEnd: balTracer.TxEndHook, OnEnter: balTracer.OnEnter, OnExit: balTracer.OnExit, OnCodeChangeV2: balTracer.OnCodeChange, @@ -112,6 +114,21 @@ func (a *BlockAccessListTracer) OnSelfDestruct(addr common.Address) { a.accessListBuilder.SelfDestruct(addr) } +func (a *BlockAccessListTracer) OnTxExecutionEnd() { + // this is a terrible hack: in the case where the block has zero txs, we need + // a way to signal that the post-tx block operations are being executed (set the + // bal idx to a correct value). + // + // if the block had transactions, the end of the last tx would have bumped the balIdx + // to the correct value. + if a.balIdx == 0 { + diff, reads := a.accessListBuilder.FinaliseIdxChanges() + a.accessList.Apply(a.balIdx, diff, reads) + a.accessListBuilder = bal.NewAccessListBuilder() + a.balIdx++ + } +} + func (a *BlockAccessListTracer) OnBalanceChange(addr common.Address, prevBalance, newBalance *big.Int, _ tracing.BalanceChangeReason) { newU256 := new(uint256.Int).SetBytes(newBalance.Bytes()) prevU256 := new(uint256.Int).SetBytes(prevBalance.Bytes()) diff --git a/core/state_processor.go b/core/state_processor.go index 9783fa2c7f..f0514f70aa 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -105,6 +105,12 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg allLogs = append(allLogs, receipt.Logs...) } + if hooks := cfg.Tracer; hooks != nil { + hooks.OnTxExecutionEnd() + } + // TODO: how do we signal to the BAL tracer that we are computing post-tx state changes here? + // if there are no txs in the block, then it will just record these state diffs at idx 0 + // Read requests if Prague is enabled. var requests [][]byte if p.config.IsPrague(block.Number(), block.Time()) { diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 5818fac4c8..806e5af03e 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -217,6 +217,7 @@ type Hooks struct { OnSystemCallStart OnSystemCallStartHook OnSystemCallStartV2 OnSystemCallStartHookV2 OnSystemCallEnd OnSystemCallEndHook + OnTxExecutionEnd func() // State events OnBalanceChange BalanceChangeHook