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.
This commit is contained in:
parent
fb08fd334a
commit
ade7515c81
|
@ -233,6 +233,12 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, vm.BlockContext{}, nil, nil, err
|
return nil, vm.BlockContext{}, nil, nil, err
|
||||||
}
|
}
|
||||||
|
// Insert parent beacon block root in the state as per EIP-4788.
|
||||||
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
|
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
|
||||||
|
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, eth.blockchain.Config(), vm.Config{})
|
||||||
|
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
|
||||||
|
}
|
||||||
if txIndex == 0 && len(block.Transactions()) == 0 {
|
if txIndex == 0 && len(block.Transactions()) == 0 {
|
||||||
return nil, vm.BlockContext{}, statedb, release, nil
|
return nil, vm.BlockContext{}, statedb, release, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,6 +376,13 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
failed = err
|
failed = err
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
// Insert block's parent beacon block root in the state
|
||||||
|
// as per EIP-4788.
|
||||||
|
if beaconRoot := next.BeaconRoot(); beaconRoot != nil {
|
||||||
|
context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil)
|
||||||
|
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{})
|
||||||
|
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
|
||||||
|
}
|
||||||
// Clean out any pending release functions of trace state. Note this
|
// Clean out any pending release functions of trace state. Note this
|
||||||
// step must be done after constructing tracing state, because the
|
// step must be done after constructing tracing state, because the
|
||||||
// tracing state of block next depends on the parent state and construction
|
// tracing state of block next depends on the parent state and construction
|
||||||
|
@ -517,7 +524,6 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
roots []common.Hash
|
roots []common.Hash
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||||
|
@ -525,6 +531,10 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
||||||
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
||||||
)
|
)
|
||||||
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
|
vmenv := vm.NewEVM(vmctx, vm.TxContext{}, statedb, chainConfig, vm.Config{})
|
||||||
|
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
|
||||||
|
}
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -584,7 +594,6 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
// JS tracers have high overhead. In this case run a parallel
|
// JS tracers have high overhead. In this case run a parallel
|
||||||
// process that generates states in one thread and traces txes
|
// process that generates states in one thread and traces txes
|
||||||
// in separate worker threads.
|
// in separate worker threads.
|
||||||
|
@ -601,6 +610,10 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||||
results = make([]*txTraceResult, len(txs))
|
results = make([]*txTraceResult, len(txs))
|
||||||
)
|
)
|
||||||
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
|
vmenv := vm.NewEVM(blockCtx, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{})
|
||||||
|
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
|
||||||
|
}
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
// Generate the next state snapshot fast without tracing
|
// Generate the next state snapshot fast without tracing
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||||
|
@ -727,7 +740,6 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
// Retrieve the tracing configurations, or use default values
|
// Retrieve the tracing configurations, or use default values
|
||||||
var (
|
var (
|
||||||
logConfig logger.Config
|
logConfig logger.Config
|
||||||
|
@ -756,6 +768,10 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
||||||
// Note: This copies the config, to not screw up the main config
|
// Note: This copies the config, to not screw up the main config
|
||||||
chainConfig, canon = overrideConfig(chainConfig, config.Overrides)
|
chainConfig, canon = overrideConfig(chainConfig, config.Overrides)
|
||||||
}
|
}
|
||||||
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
|
vmenv := vm.NewEVM(vmctx, vm.TxContext{}, statedb, chainConfig, vm.Config{})
|
||||||
|
core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
|
||||||
|
}
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
// Prepare the transaction for un-traced execution
|
// Prepare the transaction for un-traced execution
|
||||||
var (
|
var (
|
||||||
|
|
Loading…
Reference in New Issue