Skip to content

Commit ade7515

Browse files
authored
eth, eth/tracers: process beacon root before transactions (#29402)
The beacon root when applied in `state_processor.go` is performed right before executing transaction. That means that contract reliying on this value would query the same value found in the block header. In that spirit, it means that any tracing/operation relying on state data which touches transaction must have updated the beacon root before any transaction processing.
1 parent fb08fd3 commit ade7515

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

eth/state_accessor.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
233233
if err != nil {
234234
return nil, vm.BlockContext{}, nil, nil, err
235235
}
236+
// Insert parent beacon block root in the state as per EIP-4788.
237+
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
238+
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
239+
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, eth.blockchain.Config(), vm.Config{})
240+
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
241+
}
236242
if txIndex == 0 && len(block.Transactions()) == 0 {
237243
return nil, vm.BlockContext{}, statedb, release, nil
238244
}

eth/tracers/api.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,13 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
376376
failed = err
377377
break
378378
}
379+
// Insert block's parent beacon block root in the state
380+
// as per EIP-4788.
381+
if beaconRoot := next.BeaconRoot(); beaconRoot != nil {
382+
context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil)
383+
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{})
384+
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
385+
}
379386
// Clean out any pending release functions of trace state. Note this
380387
// step must be done after constructing tracing state, because the
381388
// tracing state of block next depends on the parent state and construction
@@ -517,14 +524,17 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
517524
return nil, err
518525
}
519526
defer release()
520-
521527
var (
522528
roots []common.Hash
523529
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
524530
chainConfig = api.backend.ChainConfig()
525531
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
526532
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
527533
)
534+
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
535+
vmenv := vm.NewEVM(vmctx, vm.TxContext{}, statedb, chainConfig, vm.Config{})
536+
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
537+
}
528538
for i, tx := range block.Transactions() {
529539
if err := ctx.Err(); err != nil {
530540
return nil, err
@@ -584,7 +594,6 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
584594
return nil, err
585595
}
586596
defer release()
587-
588597
// JS tracers have high overhead. In this case run a parallel
589598
// process that generates states in one thread and traces txes
590599
// in separate worker threads.
@@ -601,6 +610,10 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
601610
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
602611
results = make([]*txTraceResult, len(txs))
603612
)
613+
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
614+
vmenv := vm.NewEVM(blockCtx, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{})
615+
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
616+
}
604617
for i, tx := range txs {
605618
// Generate the next state snapshot fast without tracing
606619
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
@@ -727,7 +740,6 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
727740
return nil, err
728741
}
729742
defer release()
730-
731743
// Retrieve the tracing configurations, or use default values
732744
var (
733745
logConfig logger.Config
@@ -756,6 +768,10 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
756768
// Note: This copies the config, to not screw up the main config
757769
chainConfig, canon = overrideConfig(chainConfig, config.Overrides)
758770
}
771+
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
772+
vmenv := vm.NewEVM(vmctx, vm.TxContext{}, statedb, chainConfig, vm.Config{})
773+
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
774+
}
759775
for i, tx := range block.Transactions() {
760776
// Prepare the transaction for un-traced execution
761777
var (

0 commit comments

Comments
 (0)