diff --git a/core/celo_evm.go b/core/celo_evm.go index aba5eb41f6..3858f30aee 100644 --- a/core/celo_evm.go +++ b/core/celo_evm.go @@ -9,9 +9,9 @@ import ( "github.com/ethereum/go-ethereum/params" ) -func setCeloFieldsInBlockContext(blockContext *vm.BlockContext, header *types.Header, config *params.ChainConfig, statedb vm.StateDB) { +func GetFeeCurrencyContext(header *types.Header, config *params.ChainConfig, statedb vm.StateDB) *common.FeeCurrencyContext { if !config.IsCel2(header.Time) { - return + return &common.FeeCurrencyContext{} } caller := &contracts.CeloBackend{ChainConfig: config, State: statedb} @@ -20,7 +20,7 @@ func setCeloFieldsInBlockContext(blockContext *vm.BlockContext, header *types.He if err != nil { log.Error("Error fetching exchange rates!", "err", err) } - blockContext.FeeCurrencyContext = feeCurrencyContext + return &feeCurrencyContext } func GetExchangeRates(header *types.Header, config *params.ChainConfig, statedb vm.StateDB) common.ExchangeRates { diff --git a/core/chain_makers.go b/core/chain_makers.go index 149134fbe7..479e5cfa47 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -39,11 +39,12 @@ import ( // BlockGen creates blocks for testing. // See GenerateChain for a detailed explanation. type BlockGen struct { - i int - cm *chainMaker - parent *types.Block - header *types.Header - statedb *state.StateDB + i int + cm *chainMaker + parent *types.Block + header *types.Header + statedb *state.StateDB + feeCurrencyContext *common.FeeCurrencyContext gasPool *GasPool txs []*types.Transaction @@ -54,6 +55,10 @@ type BlockGen struct { engine consensus.Engine } +func (b *BlockGen) updateFeeCurrencyContext() { + b.feeCurrencyContext = GetFeeCurrencyContext(b.header, b.cm.config, b.statedb) +} + // SetCoinbase sets the coinbase of the generated block. // It can be called at most once. func (b *BlockGen) SetCoinbase(addr common.Address) { @@ -99,7 +104,7 @@ func (b *BlockGen) Difficulty() *big.Int { func (b *BlockGen) SetParentBeaconRoot(root common.Hash) { b.header.ParentBeaconRoot = &root var ( - blockContext = NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase, b.cm.config, b.statedb) + blockContext = NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase, b.cm.config, b.statedb, b.feeCurrencyContext) vmenv = vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.cm.config, vm.Config{}) ) ProcessBeaconBlockRoot(root, vmenv, b.statedb) @@ -117,7 +122,7 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti b.SetCoinbase(common.Address{}) } b.statedb.SetTxContext(tx.Hash(), len(b.txs)) - receipt, err := ApplyTransaction(b.cm.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig) + receipt, err := ApplyTransaction(b.cm.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig, b.feeCurrencyContext) if err != nil { panic(err) } @@ -329,6 +334,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse b.header.Difficulty = big.NewInt(0) } } + b.updateFeeCurrencyContext() + // Mutate the state and block according to any hard-fork specs if daoBlock := config.DAOForkBlock; daoBlock != nil { limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) @@ -430,6 +437,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine genblock := func(i int, parent *types.Block, triedb *triedb.Database, statedb *state.StateDB) (*types.Block, types.Receipts) { b := &BlockGen{i: i, cm: cm, parent: parent, statedb: statedb, engine: engine} b.header = cm.makeHeader(parent, statedb, b.engine) + b.updateFeeCurrencyContext() // TODO uncomment when proof generation is merged // Save pre state for proof generation diff --git a/core/evm.go b/core/evm.go index 721d72afdb..11a665b4f7 100644 --- a/core/evm.go +++ b/core/evm.go @@ -40,7 +40,7 @@ type ChainContext interface { } // NewEVMBlockContext creates a new context for use in the EVM. -func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address, config *params.ChainConfig, statedb vm.StateDB) vm.BlockContext { +func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address, config *params.ChainConfig, statedb vm.StateDB, feeCurrencyContext *common.FeeCurrencyContext) vm.BlockContext { var ( beneficiary common.Address baseFee *big.Int @@ -78,7 +78,9 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common L1CostFunc: types.NewL1CostFunc(config, statedb), } - setCeloFieldsInBlockContext(&blockContext, header, config, statedb) + if config.IsCel2(header.Time) { + blockContext.FeeCurrencyContext = *feeCurrencyContext + } return blockContext } diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 8f46ca6224..52f988c44a 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -46,11 +46,12 @@ func newStatePrefetcher(config *params.ChainConfig, chain *HeaderChain) *statePr // only goal is to pre-cache transaction signatures and state trie nodes. func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, cfg vm.Config, interrupt *atomic.Bool) { var ( - header = block.Header() - gaspool = new(GasPool).AddGas(block.GasLimit()) - blockContext = NewEVMBlockContext(header, p.chain, nil, p.config, statedb) - evm = vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) - signer = types.MakeSigner(p.config, header.Number, header.Time) + header = block.Header() + gaspool = new(GasPool).AddGas(block.GasLimit()) + feeCurrencyContext = GetFeeCurrencyContext(header, p.config, statedb) + blockContext = NewEVMBlockContext(header, p.chain, nil, p.config, statedb, feeCurrencyContext) + evm = vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) + signer = types.MakeSigner(p.config, header.Number, header.Time) ) // Iterate over and process the individual transactions byzantium := p.config.IsByzantium(block.Number()) diff --git a/core/state_processor.go b/core/state_processor.go index 3314a65d9c..47d89343aa 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -75,7 +75,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg context vm.BlockContext signer = types.MakeSigner(p.config, header.Number, header.Time) ) - context = NewEVMBlockContext(header, p.chain, nil, p.config, statedb) + feeCurrencyContext := GetFeeCurrencyContext(header, p.config, statedb) + context = NewEVMBlockContext(header, p.chain, nil, p.config, statedb, feeCurrencyContext) vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg) if beaconRoot := block.BeaconRoot(); beaconRoot != nil { ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) @@ -197,13 +198,13 @@ func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPo // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { - // Create a new context to be used in the EVM environment - blockContext := NewEVMBlockContext(header, bc, author, config, statedb) - msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee, blockContext.FeeCurrencyContext.ExchangeRates) +func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config, feeCurrencyContext *common.FeeCurrencyContext) (*types.Receipt, error) { + msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee, feeCurrencyContext.ExchangeRates) if err != nil { return nil, err } + // Create a new context to be used in the EVM environment + blockContext := NewEVMBlockContext(header, bc, author, config, statedb, feeCurrencyContext) txContext := NewEVMTxContext(msg) vmenv := vm.NewEVM(blockContext, txContext, statedb, config, cfg) return ApplyTransactionWithEVM(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv) diff --git a/eth/api_backend.go b/eth/api_backend.go index bd1b623c36..d03bc146a8 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -263,7 +263,8 @@ func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *st if blockCtx != nil { context = *blockCtx } else { - context = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil, b.eth.blockchain.Config(), state) + feeCurrencyContext := core.GetFeeCurrencyContext(header, b.eth.blockchain.Config(), state) + context = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil, b.eth.blockchain.Config(), state, feeCurrencyContext) } return vm.NewEVM(context, txContext, state, b.ChainConfig(), *vmConfig) } diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go index a5626f0beb..f35a33eea9 100644 --- a/eth/gasestimator/gasestimator.go +++ b/eth/gasestimator/gasestimator.go @@ -235,8 +235,9 @@ func execute(ctx context.Context, call *core.Message, opts *Options, gasLimit ui func run(ctx context.Context, call *core.Message, opts *Options) (*core.ExecutionResult, error) { // Assemble the call and the call context var ( - msgContext = core.NewEVMTxContext(call) - evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil, opts.Config, opts.State) + feeCurrencyContext = core.GetFeeCurrencyContext(opts.Header, opts.Config, opts.State) + msgContext = core.NewEVMTxContext(call) + evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil, opts.Config, opts.State, feeCurrencyContext) dirtyState = opts.State.Copy() evm = vm.NewEVM(evmContext, msgContext, dirtyState, opts.Config, vm.Config{NoBaseFee: true}) diff --git a/eth/state_accessor.go b/eth/state_accessor.go index cfff3049f8..ba4405a797 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -233,9 +233,10 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, if err != nil { return nil, vm.BlockContext{}, nil, nil, err } + feeCurrencyContext := core.GetFeeCurrencyContext(block.Header(), eth.blockchain.Config(), statedb) // 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, eth.blockchain.Config(), statedb) + context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil, eth.blockchain.Config(), statedb, feeCurrencyContext) vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, eth.blockchain.Config(), vm.Config{}) core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) } @@ -245,7 +246,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, // Recompute transactions up to the target index. signer := types.MakeSigner(eth.blockchain.Config(), block.Number(), block.Time()) for idx, tx := range block.Transactions() { - context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil, eth.blockchain.Config(), statedb) + context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil, eth.blockchain.Config(), statedb, feeCurrencyContext) // Assemble the transaction call message and return if the requested offset msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), context.FeeCurrencyContext.ExchangeRates) txContext := core.NewEVMTxContext(msg) diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 3079eb68c4..776c067c72 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -266,12 +266,13 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed // Fetch and execute the block trace taskCh for task := range taskCh { var ( - signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time()) - blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) + feeCurrencyContext = core.GetFeeCurrencyContext(end.Header(), api.backend.ChainConfig(), task.statedb) + signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time()) + blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb, feeCurrencyContext) ) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { - msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee(), blockCtx.FeeCurrencyContext.ExchangeRates) + msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee(), feeCurrencyContext.ExchangeRates) txctx := &Context{ BlockHash: task.block.Hash(), BlockNumber: task.block.Number(), @@ -379,7 +380,8 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed // 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, api.backend.ChainConfig(), statedb) + feeCurrencyContext := core.GetFeeCurrencyContext(end.Header(), api.backend.ChainConfig(), statedb) + context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb, feeCurrencyContext) vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{}) core.ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) } @@ -557,7 +559,8 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config roots []common.Hash signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) chainConfig = api.backend.ChainConfig() - vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb) + feeCurrencyContext = core.GetFeeCurrencyContext(block.Header(), chainConfig, statedb) + vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb, feeCurrencyContext) deleteEmptyObjects = chainConfig.IsEIP158(block.Number()) ) if beaconRoot := block.BeaconRoot(); beaconRoot != nil { @@ -633,11 +636,12 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac } // Native tracers have low overhead var ( - txs = block.Transactions() - blockHash = block.Hash() - blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) - signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) - results = make([]*txTraceResult, len(txs)) + txs = block.Transactions() + blockHash = block.Hash() + feeCurrencyContext = core.GetFeeCurrencyContext(block.Header(), api.backend.ChainConfig(), statedb) + blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb, feeCurrencyContext) + signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) + results = make([]*txTraceResult, len(txs)) ) if beaconRoot := block.BeaconRoot(); beaconRoot != nil { vmenv := vm.NewEVM(blockCtx, vm.TxContext{}, statedb, api.backend.ChainConfig(), vm.Config{}) @@ -645,7 +649,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac } for i, tx := range txs { // Generate the next state snapshot fast without tracing - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), blockCtx.FeeCurrencyContext.ExchangeRates) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), feeCurrencyContext.ExchangeRates) txctx := &Context{ BlockHash: blockHash, BlockNumber: block.Number(), @@ -678,6 +682,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat threads = len(txs) } exchangeRates := core.GetExchangeRates(block.Header(), api.backend.ChainConfig(), statedb) + feeCurrencyContext := core.GetFeeCurrencyContext(block.Header(), api.backend.ChainConfig(), statedb) jobs := make(chan *txTraceTask, threads) for th := 0; th < threads; th++ { pend.Add(1) @@ -696,7 +701,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat // as the GetHash function of BlockContext is not safe for // concurrent use. // See: https://github.com/ethereum/go-ethereum/issues/29114 - blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) + blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb, feeCurrencyContext) res, err := api.traceTx(ctx, txs[task.index], msg, txctx, blockCtx, task.statedb, config) if err != nil { results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Error: err.Error()} @@ -709,7 +714,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat // Feed the transactions into the tracers and return var failed error - blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) + blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb, feeCurrencyContext) txloop: for i, tx := range txs { // Send the trace task over for execution @@ -783,11 +788,12 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block // Execute transaction, either tracing all or just the requested one var ( - dumps []string - signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) - chainConfig = api.backend.ChainConfig() - vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb) - canon = true + dumps []string + signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) + chainConfig = api.backend.ChainConfig() + feeCurrencyContext = core.GetFeeCurrencyContext(block.Header(), chainConfig, statedb) + vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb, feeCurrencyContext) + canon = true ) // Check if there are any overrides: the caller may wish to enable a future // fork when executing this block. Note, such overrides are only applicable to the @@ -989,7 +995,8 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc } defer release() - vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) + feeCurrencyContext := core.GetFeeCurrencyContext(block.Header(), api.backend.ChainConfig(), statedb) + vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb, feeCurrencyContext) // Apply the customization rules if required. if config != nil { if err := config.StateOverrides.Apply(statedb); err != nil { @@ -1002,7 +1009,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc return nil, err } var ( - msg = args.ToMessage(vmctx.BaseFee, vmctx.FeeCurrencyContext.ExchangeRates) + msg = args.ToMessage(vmctx.BaseFee, feeCurrencyContext.ExchangeRates) tx = args.ToTransaction() traceConfig *TraceConfig ) diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 9dc98efc6f..5b4ba2eb72 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -246,10 +246,11 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block if txIndex == 0 && len(block.Transactions()) == 0 { return nil, vm.BlockContext{}, statedb, release, nil } + feeCurrencyContext := core.GetFeeCurrencyContext(block.Header(), b.chainConfig, statedb) // Recompute transactions up to the target index. signer := types.MakeSigner(b.chainConfig, block.Number(), block.Time()) + context := core.NewEVMBlockContext(block.Header(), b.chain, nil, b.chainConfig, statedb, feeCurrencyContext) for idx, tx := range block.Transactions() { - context := core.NewEVMBlockContext(block.Header(), b.chain, nil, b.chainConfig, statedb) msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), context.FeeCurrencyContext.ExchangeRates) txContext := core.NewEVMTxContext(msg) if idx == txIndex { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 9c7ca9a24f..2beda7caf9 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1199,8 +1199,9 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S // this makes sure resources are cleaned up. defer cancel() + feeCurrencyContext := core.GetFeeCurrencyContext(header, b.ChainConfig(), state) // Get a new instance of the EVM. - blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil, b.ChainConfig(), state) + blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil, b.ChainConfig(), state, feeCurrencyContext) if blockOverrides != nil { blockOverrides.Apply(&blockCtx) } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 7f64a7fd10..0693c3bb7d 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -772,8 +772,9 @@ func (b testBackend) GetEVM(ctx context.Context, msg *core.Message, state *state if vmConfig == nil { vmConfig = b.chain.GetVMConfig() } + feeCurrencyContext := core.GetFeeCurrencyContext(header, b.ChainConfig(), state) txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(header, b.chain, nil, b.ChainConfig(), state) + context := core.NewEVMBlockContext(header, b.chain, nil, b.ChainConfig(), state, feeCurrencyContext) if blockContext != nil { context = *blockContext } diff --git a/miner/worker.go b/miner/worker.go index f4a2bf0431..0f59a688c6 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -62,8 +62,8 @@ type environment struct { gasPool *core.GasPool // available gas used to pack transactions multiGasPool *core.MultiGasPool // available per-fee-currency gas used to pack transactions feeCurrencyAllowlist common.AddressSet - exchangeRates common.ExchangeRates coinbase common.Address + feeCurrencyContext *common.FeeCurrencyContext header *types.Header txs []*types.Transaction @@ -128,7 +128,6 @@ func (miner *Miner) generateWork(params *generateParams) *newPayloadResult { miner.config.FeeCurrencyLimits, ) } - misc.EnsureCreate2Deployer(miner.chainConfig, work.header.Time, work.state) for _, tx := range params.txs { @@ -262,7 +261,7 @@ func (miner *Miner) prepareWork(genParams *generateParams) (*environment, error) log.Error("Failed to create sealing context", "err", err) return nil, err } - context := core.NewEVMBlockContext(header, miner.chain, nil, miner.chainConfig, env.state) + context := core.NewEVMBlockContext(header, miner.chain, nil, miner.chainConfig, env.state, env.feeCurrencyContext) if evicted := miner.feeCurrencyBlocklist.Evict(parent); len(evicted) > 0 { log.Warn( "Evicted temporarily blocked fee-currencies from local block-list", @@ -271,10 +270,10 @@ func (miner *Miner) prepareWork(genParams *generateParams) (*environment, error) ) } env.feeCurrencyAllowlist = miner.feeCurrencyBlocklist.FilterAllowlist( - common.CurrencyAllowlist(context.FeeCurrencyContext.ExchangeRates), + common.CurrencyAllowlist(env.feeCurrencyContext.ExchangeRates), header, ) - env.exchangeRates = context.FeeCurrencyContext.ExchangeRates + if header.ParentBeaconRoot != nil { vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, miner.chainConfig, vm.Config{}) core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, env.state) @@ -301,13 +300,15 @@ func (miner *Miner) makeEnv(parent *types.Header, header *types.Header, coinbase release() } } + feeCurrencyContext := core.GetFeeCurrencyContext(header, miner.chainConfig, state) // Note the passed coinbase may be different with header.Coinbase. return &environment{ - signer: types.MakeSigner(miner.chainConfig, header.Number, header.Time), - state: state, - coinbase: coinbase, - header: header, + signer: types.MakeSigner(miner.chainConfig, header.Number, header.Time), + state: state, + coinbase: coinbase, + header: header, + feeCurrencyContext: feeCurrencyContext, }, nil } @@ -365,7 +366,7 @@ func (miner *Miner) applyTransaction(env *environment, tx *types.Transaction) (* snap = env.state.Snapshot() gp = env.gasPool.Gas() ) - receipt, err := core.ApplyTransaction(miner.chainConfig, miner.chain, &env.coinbase, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, vm.Config{}) + receipt, err := core.ApplyTransaction(miner.chainConfig, miner.chain, &env.coinbase, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, vm.Config{}, env.feeCurrencyContext) if err != nil { env.state.RevertToSnapshot(snap) env.gasPool.SetGas(gp) @@ -556,16 +557,16 @@ func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment) } // Fill the block with all available pending transactions. if len(localPlainTxs) > 0 || len(localBlobTxs) > 0 { - plainTxs := newTransactionsByPriceAndNonce(env.signer, localPlainTxs, env.header.BaseFee, env.exchangeRates) - blobTxs := newTransactionsByPriceAndNonce(env.signer, localBlobTxs, env.header.BaseFee, env.exchangeRates) + plainTxs := newTransactionsByPriceAndNonce(env.signer, localPlainTxs, env.header.BaseFee, env.feeCurrencyContext.ExchangeRates) + blobTxs := newTransactionsByPriceAndNonce(env.signer, localBlobTxs, env.header.BaseFee, env.feeCurrencyContext.ExchangeRates) if err := miner.commitTransactions(env, plainTxs, blobTxs, interrupt); err != nil { return err } } if len(remotePlainTxs) > 0 || len(remoteBlobTxs) > 0 { - plainTxs := newTransactionsByPriceAndNonce(env.signer, remotePlainTxs, env.header.BaseFee, env.exchangeRates) - blobTxs := newTransactionsByPriceAndNonce(env.signer, remoteBlobTxs, env.header.BaseFee, env.exchangeRates) + plainTxs := newTransactionsByPriceAndNonce(env.signer, remotePlainTxs, env.header.BaseFee, env.feeCurrencyContext.ExchangeRates) + blobTxs := newTransactionsByPriceAndNonce(env.signer, remoteBlobTxs, env.header.BaseFee, env.feeCurrencyContext.ExchangeRates) if err := miner.commitTransactions(env, plainTxs, blobTxs, interrupt); err != nil { return err diff --git a/tests/state_test.go b/tests/state_test.go index 1de69c6c76..dd77c7e021 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -310,7 +310,8 @@ func runBenchmark(b *testing.B, t *StateTest) { // Prepare the EVM. txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase, config, state.StateDB) + feeCurrencyContext := core.GetFeeCurrencyContext(block.Header(), config, state.StateDB) + context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase, config, state.StateDB, feeCurrencyContext) context.GetHash = vmTestBlockHash context.BaseFee = baseFee evm := vm.NewEVM(context, txContext, state.StateDB, config, vmconfig) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 420206dec5..d3bef4f94b 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -278,7 +278,8 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh // Prepare the EVM. txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase, config, st.StateDB) + feeCurrencyContext := core.GetFeeCurrencyContext(block.Header(), config, st.StateDB) + context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase, config, st.StateDB, feeCurrencyContext) context.GetHash = vmTestBlockHash context.BaseFee = baseFee context.Random = nil