From 713fc8c2541baba44f11f5e7e195782a88174856 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:48:37 +0800 Subject: [PATCH] feat: feevault (#614) * update core/blockchain.go * update core/vm/evm.go * update core/evm.go * fix bugs * update core/vm/instructions.go --- accounts/abi/bind/backends/simulated.go | 2 +- core/blockchain.go | 4 ++++ core/chain_makers.go | 2 +- core/evm.go | 8 +++++--- core/state_prefetcher.go | 2 +- core/state_processor.go | 4 ++-- core/vm/evm.go | 5 +++++ core/vm/instructions.go | 2 +- eth/api_backend.go | 2 +- eth/state_accessor.go | 2 +- eth/tracers/api.go | 12 ++++++------ eth/tracers/api_test.go | 2 +- internal/ethapi/api.go | 4 ++-- internal/ethapi/api_test.go | 2 +- les/api_backend.go | 2 +- les/odr_test.go | 4 ++-- les/state_accessor.go | 2 +- light/odr_test.go | 2 +- miner/worker.go | 14 +++++++------- tests/state_test.go | 2 +- tests/state_test_util.go | 2 +- 21 files changed, 46 insertions(+), 35 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index fb385e241acc..1350b8416d7e 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -702,7 +702,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. txContext := core.NewEVMTxContext(msg) - evmContext := core.NewEVMBlockContext(header, b.blockchain, nil) + evmContext := core.NewEVMBlockContext(header, b.blockchain, b.config, nil) vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true}) gasPool := new(core.GasPool).AddGas(math.MaxUint64) signer := types.MakeSigner(b.blockchain.Config(), header.Number, header.Time) diff --git a/core/blockchain.go b/core/blockchain.go index 04677ca90078..b1f583022bf5 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -285,6 +285,10 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis log.Info(strings.Repeat("-", 153)) log.Info("") + if chainConfig.Scroll.FeeVaultEnabled() { + log.Warn("Using fee vault address", "FeeVaultAddress", *chainConfig.Scroll.FeeVaultAddress) + } + bc := &BlockChain{ chainConfig: chainConfig, cacheConfig: cacheConfig, diff --git a/core/chain_makers.go b/core/chain_makers.go index 0f445ab3f046..25979fbb2429 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -93,7 +93,7 @@ func (b *BlockGen) SetPoS() { func (b *BlockGen) SetParentBeaconRoot(root common.Hash) { b.header.ParentBeaconRoot = &root var ( - blockContext = NewEVMBlockContext(b.header, nil, &b.header.Coinbase) + blockContext = NewEVMBlockContext(b.header, nil, b.config, &b.header.Coinbase) vmenv = vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.config, vm.Config{}) ) ProcessBeaconBlockRoot(root, vmenv, b.statedb) diff --git a/core/evm.go b/core/evm.go index 46dcb3146260..72345b6c07ea 100644 --- a/core/evm.go +++ b/core/evm.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" ) // ChainContext supports retrieving headers and consensus parameters from the @@ -37,7 +38,7 @@ type ChainContext interface { } // NewEVMBlockContext creates a new context for use in the EVM. -func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address) vm.BlockContext { +func NewEVMBlockContext(header *types.Header, chain ChainContext, chainConfig *params.ChainConfig, author *common.Address) vm.BlockContext { var ( beneficiary common.Address baseFee *big.Int @@ -45,8 +46,9 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common random *common.Hash ) - // If we don't have an explicit author (i.e. not mining), extract from the header - if author == nil { + if chainConfig.Scroll.FeeVaultEnabled() { // If we enable the feevault feature, use the feevault address + beneficiary = *chainConfig.Scroll.FeeVaultAddress + } else if author == nil { // If we don't have an explicit author (i.e. not mining), extract from the header beneficiary, _ = chain.Engine().Author(header) // Ignore error, we're past header validation } else { beneficiary = *author diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index eaba6063010a..a7ee63eff1a7 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -53,7 +53,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c var ( header = block.Header() gaspool = new(GasPool).AddGas(block.GasLimit()) - blockContext = NewEVMBlockContext(header, p.bc, nil) + blockContext = NewEVMBlockContext(header, p.bc, p.config, nil) evm = vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) signer = types.MakeSigner(p.config, header.Number, header.Time) ) diff --git a/core/state_processor.go b/core/state_processor.go index 0c7b0e1c111b..a816192d42d1 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -73,7 +73,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg misc.ApplyDAOHardFork(statedb) } var ( - context = NewEVMBlockContext(header, p.bc, nil) + context = NewEVMBlockContext(header, p.bc, p.config, nil) vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg) signer = types.MakeSigner(p.config, header.Number, header.Time) ) @@ -171,7 +171,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo return nil, err } // Create a new context to be used in the EVM environment - blockContext := NewEVMBlockContext(header, bc, author) + blockContext := NewEVMBlockContext(header, bc, config, author) vmenv := vm.NewEVM(blockContext, vm.TxContext{BlobHashes: tx.BlobHashes()}, statedb, config, cfg) return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv) } diff --git a/core/vm/evm.go b/core/vm/evm.go index 39c1fe99b5c4..94c7bdf547cf 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -526,3 +526,8 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment * // ChainConfig returns the environment's chain configuration func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } + +// FeeRecipient returns the environment's transaction fee recipient address. +func (evm *EVM) FeeRecipient() common.Address { + return evm.Context.Coinbase +} diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 35c23031bd99..05daf2a44528 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -473,7 +473,7 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( } func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes())) + scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.FeeRecipient().Bytes())) return nil, nil } diff --git a/eth/api_backend.go b/eth/api_backend.go index f1cfa5df590f..1374a352c834 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -274,7 +274,7 @@ 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) + context = core.NewEVMBlockContext(header, b.eth.BlockChain(), b.ChainConfig(), nil) } return vm.NewEVM(context, txContext, state, b.eth.blockchain.Config(), *vmConfig), state.Error } diff --git a/eth/state_accessor.go b/eth/state_accessor.go index f825ac3eb28e..9f1609adbe1a 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -242,7 +242,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, // Assemble the transaction call message and return if the requested offset msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil) + context := core.NewEVMBlockContext(block.Header(), eth.blockchain, eth.blockchain.Config(), nil) if idx == txIndex { return msg, context, statedb, release, nil } diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 03cc1c6322e1..aee189ed7386 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -267,7 +267,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed 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) + blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), api.backend.ChainConfig(), nil) ) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { @@ -531,7 +531,7 @@ 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) + vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), api.backend.ChainConfig(), nil) deleteEmptyObjects = chainConfig.IsEIP158(block.Number()) ) for i, tx := range block.Transactions() { @@ -612,7 +612,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac txs = block.Transactions() blockHash = block.Hash() is158 = api.backend.ChainConfig().IsEIP158(block.Number()) - blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), api.backend.ChainConfig(), nil) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) results = make([]*txTraceResult, len(txs)) ) @@ -649,7 +649,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat var ( txs = block.Transactions() blockHash = block.Hash() - blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), api.backend.ChainConfig(), nil) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) results = make([]*txTraceResult, len(txs)) pend sync.WaitGroup @@ -772,7 +772,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block 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) + vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), api.backend.ChainConfig(), nil) canon = true ) // Check if there are any overrides: the caller may wish to enable a future @@ -934,7 +934,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc } defer release() - vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), api.backend.ChainConfig(), nil) // Apply the customization rules if required. if config != nil { if err := config.StateOverrides.Apply(statedb); err != nil { diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 1824bb1fb43c..760112994e2e 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -173,7 +173,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block for idx, tx := range block.Transactions() { msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), b.chain, nil) + context := core.NewEVMBlockContext(block.Header(), b.chain, b.chainConfig, nil) if idx == txIndex { return msg, context, statedb, release, nil } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 1deb29feb34f..aa86878ff36c 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1085,7 +1085,7 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S if err != nil { return nil, err } - blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) + blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), b.ChainConfig(), nil) if blockOverrides != nil { blockOverrides.Apply(&blockCtx) } @@ -1207,7 +1207,7 @@ func EstimateL1MsgFee(ctx context.Context, b Backend, args TransactionArgs, bloc if err != nil { return nil, err } - blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) + blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), b.ChainConfig(), nil) evm, _ := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}, &blockCtx) // Wait for the context to be done and cancel the evm. Even if the // EVM has finished, cancelling may be done (repeatedly) diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 59882cd6bb54..a7f370f0b4f1 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -542,7 +542,7 @@ func (b testBackend) GetEVM(ctx context.Context, msg *core.Message, state *state vmConfig = b.chain.GetVMConfig() } txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(header, b.chain, nil) + context := core.NewEVMBlockContext(header, b.chain, b.chain.Config(), nil) if blockContext != nil { context = *blockContext } diff --git a/les/api_backend.go b/les/api_backend.go index 6660c6c4870b..0347b43c3541 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -188,7 +188,7 @@ func (b *LesApiBackend) GetEVM(ctx context.Context, msg *core.Message, state *st vmConfig = new(vm.Config) } txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(header, b.eth.blockchain, nil) + context := core.NewEVMBlockContext(header, b.eth.blockchain, b.eth.chainConfig, nil) if blockCtx != nil { context = *blockCtx } diff --git a/les/odr_test.go b/les/odr_test.go index 69824a92dd08..db6fe5b81676 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -148,7 +148,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai SkipAccountChecks: true, } - context := core.NewEVMBlockContext(header, bc, nil) + context := core.NewEVMBlockContext(header, bc, config, nil) txContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(context, txContext, statedb, config, vm.Config{NoBaseFee: true}) @@ -172,7 +172,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai Data: data, SkipAccountChecks: true, } - context := core.NewEVMBlockContext(header, lc, nil) + context := core.NewEVMBlockContext(header, lc, config, nil) txContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true}) gp := new(core.GasPool).AddGas(math.MaxUint64) diff --git a/les/state_accessor.go b/les/state_accessor.go index d8ca6bee9af9..b966f5198ea5 100644 --- a/les/state_accessor.go +++ b/les/state_accessor.go @@ -63,7 +63,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types. // Assemble the transaction call message and return if the requested offset msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), leth.blockchain, nil) + context := core.NewEVMBlockContext(block.Header(), leth.blockchain, leth.blockchain.Config(), nil) statedb.SetTxContext(tx.Hash(), idx) if idx == txIndex { return msg, context, statedb, release, nil diff --git a/light/odr_test.go b/light/odr_test.go index 25544e3ae29d..6596e16c95b0 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -215,7 +215,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain SkipAccountChecks: true, } txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(header, chain, nil) + context := core.NewEVMBlockContext(header, chain, config, nil) vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true}) gp := new(core.GasPool).AddGas(math.MaxUint64) signer := types.MakeSigner(config, header.Number, header.Time) diff --git a/miner/worker.go b/miner/worker.go index 165467264528..96eccd2d3b60 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -82,12 +82,12 @@ var ( // environment is the worker's current environment and holds all // information of the sealing block generation. type environment struct { - signer types.Signer - state *state.StateDB // apply state changes here - tcount int // tx count in cycle - blockSize uint64 // approximate size of tx payload in bytes - gasPool *core.GasPool // available gas used to pack transactions - coinbase common.Address + signer types.Signer + state *state.StateDB // apply state changes here + tcount int // tx count in cycle + blockSize uint64 // approximate size of tx payload in bytes + gasPool *core.GasPool // available gas used to pack transactions + coinbase common.Address header *types.Header txs []*types.Transaction @@ -994,7 +994,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { return nil, err } if header.ParentBeaconRoot != nil { - context := core.NewEVMBlockContext(header, w.chain, nil) + context := core.NewEVMBlockContext(header, w.chain, w.chainConfig, nil) vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, w.chainConfig, vm.Config{}) core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, env.state) } diff --git a/tests/state_test.go b/tests/state_test.go index 094dafcafd7a..38db331b2a09 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -259,7 +259,7 @@ func runBenchmark(b *testing.B, t *StateTest) { // Prepare the EVM. txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) + context := core.NewEVMBlockContext(block.Header(), nil, config, &t.json.Env.Coinbase) context.GetHash = vmTestBlockHash context.BaseFee = baseFee evm := vm.NewEVM(context, txContext, statedb, config, vmconfig) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 0e3c54576bc6..f90d6d2d70c5 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -272,7 +272,7 @@ 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) + context := core.NewEVMBlockContext(block.Header(), nil, config, &t.json.Env.Coinbase) context.GetHash = vmTestBlockHash context.BaseFee = baseFee context.Random = nil