@@ -33,6 +33,7 @@ import (
3333 "github.com/ethereum/go-ethereum/common"
3434 "github.com/ethereum/go-ethereum/common/hexutil"
3535 "github.com/ethereum/go-ethereum/common/math"
36+ "github.com/ethereum/go-ethereum/consensus"
3637 "github.com/ethereum/go-ethereum/consensus/ethash"
3738 "github.com/ethereum/go-ethereum/consensus/misc"
3839 "github.com/ethereum/go-ethereum/core"
@@ -955,7 +956,39 @@ func (diff *BlockOverrides) Apply(blockCtx *vm.BlockContext) {
955956 }
956957}
957958
958- func DoCall (ctx context.Context , b Backend , args TransactionArgs , blockNrOrHash rpc.BlockNumberOrHash , overrides * StateOverride , timeout time.Duration , globalGasCap uint64 ) (* core.ExecutionResult , error ) {
959+ // ChainContextBackend provides methods required to implement ChainContext.
960+ type ChainContextBackend interface {
961+ Engine () consensus.Engine
962+ HeaderByNumber (context.Context , rpc.BlockNumber ) (* types.Header , error )
963+ }
964+
965+ // ChainContext is an implementation of core.ChainContext. It's main use-case
966+ // is instantiating a vm.BlockContext without having access to the BlockChain object.
967+ type ChainContext struct {
968+ b ChainContextBackend
969+ ctx context.Context
970+ }
971+
972+ // NewChainContext creates a new ChainContext object.
973+ func NewChainContext (ctx context.Context , backend ChainContextBackend ) * ChainContext {
974+ return & ChainContext {ctx : ctx , b : backend }
975+ }
976+
977+ func (context * ChainContext ) Engine () consensus.Engine {
978+ return context .b .Engine ()
979+ }
980+
981+ func (context * ChainContext ) GetHeader (hash common.Hash , number uint64 ) * types.Header {
982+ // This method is called to get the hash for a block number when executing the BLOCKHASH
983+ // opcode. Hence no need to search for non-canonical blocks.
984+ header , err := context .b .HeaderByNumber (context .ctx , rpc .BlockNumber (number ))
985+ if err != nil || header .Hash () != hash {
986+ return nil
987+ }
988+ return header
989+ }
990+
991+ func DoCall (ctx context.Context , b Backend , args TransactionArgs , blockNrOrHash rpc.BlockNumberOrHash , overrides * StateOverride , blockOverrides * BlockOverrides , timeout time.Duration , globalGasCap uint64 ) (* core.ExecutionResult , error ) {
959992 defer func (start time.Time ) { log .Debug ("Executing EVM call finished" , "runtime" , time .Since (start )) }(time .Now ())
960993
961994 state , header , err := b .StateAndHeaderByNumberOrHash (ctx , blockNrOrHash )
@@ -982,7 +1015,11 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash
9821015 if err != nil {
9831016 return nil , err
9841017 }
985- evm , vmError , err := b .GetEVM (ctx , msg , state , header , & vm.Config {NoBaseFee : true })
1018+ blockCtx := core .NewEVMBlockContext (header , NewChainContext (ctx , b ), nil )
1019+ if blockOverrides != nil {
1020+ blockOverrides .Apply (& blockCtx )
1021+ }
1022+ evm , vmError , err := b .GetEVM (ctx , msg , state , header , & vm.Config {NoBaseFee : true }, & blockCtx )
9861023 if err != nil {
9871024 return nil , err
9881025 }
@@ -1046,8 +1083,8 @@ func (e *revertError) ErrorData() interface{} {
10461083//
10471084// Note, this function doesn't make and changes in the state/blockchain and is
10481085// useful to execute and retrieve values.
1049- func (s * BlockChainAPI ) Call (ctx context.Context , args TransactionArgs , blockNrOrHash rpc.BlockNumberOrHash , overrides * StateOverride ) (hexutil.Bytes , error ) {
1050- result , err := DoCall (ctx , s .b , args , blockNrOrHash , overrides , s .b .RPCEVMTimeout (), s .b .RPCGasCap ())
1086+ func (s * BlockChainAPI ) Call (ctx context.Context , args TransactionArgs , blockNrOrHash rpc.BlockNumberOrHash , overrides * StateOverride , blockOverrides * BlockOverrides ) (hexutil.Bytes , error ) {
1087+ result , err := DoCall (ctx , s .b , args , blockNrOrHash , overrides , blockOverrides , s .b .RPCEVMTimeout (), s .b .RPCGasCap ())
10511088 if err != nil {
10521089 return nil , err
10531090 }
@@ -1132,7 +1169,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
11321169 executable := func (gas uint64 ) (bool , * core.ExecutionResult , error ) {
11331170 args .Gas = (* hexutil .Uint64 )(& gas )
11341171
1135- result , err := DoCall (ctx , b , args , blockNrOrHash , nil , 0 , gasCap )
1172+ result , err := DoCall (ctx , b , args , blockNrOrHash , nil , nil , 0 , gasCap )
11361173 if err != nil {
11371174 if errors .Is (err , core .ErrIntrinsicGas ) {
11381175 return true , nil , nil // Special case, raise gas limit
@@ -1478,7 +1515,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
14781515 // Apply the transaction with the access list tracer
14791516 tracer := logger .NewAccessListTracer (accessList , args .from (), to , precompiles )
14801517 config := vm.Config {Tracer : tracer , NoBaseFee : true }
1481- vmenv , _ , err := b .GetEVM (ctx , msg , statedb , header , & config )
1518+ vmenv , _ , err := b .GetEVM (ctx , msg , statedb , header , & config , nil )
14821519 if err != nil {
14831520 return nil , 0 , nil , err
14841521 }
0 commit comments