feat: feevault (#614)

* update core/blockchain.go

* update core/vm/evm.go

* update core/evm.go

* fix bugs

* update core/vm/instructions.go
This commit is contained in:
HAOYUatHZ 2024-01-11 12:48:37 +08:00 committed by GitHub
parent 07d5fddde8
commit 713fc8c254
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 46 additions and 35 deletions

View file

@ -702,7 +702,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
// Create a new environment which holds all relevant information // Create a new environment which holds all relevant information
// about the transaction and calling mechanisms. // about the transaction and calling mechanisms.
txContext := core.NewEVMTxContext(msg) 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}) vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
gasPool := new(core.GasPool).AddGas(math.MaxUint64) gasPool := new(core.GasPool).AddGas(math.MaxUint64)
signer := types.MakeSigner(b.blockchain.Config(), header.Number, header.Time) signer := types.MakeSigner(b.blockchain.Config(), header.Number, header.Time)

View file

@ -285,6 +285,10 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
log.Info(strings.Repeat("-", 153)) log.Info(strings.Repeat("-", 153))
log.Info("") log.Info("")
if chainConfig.Scroll.FeeVaultEnabled() {
log.Warn("Using fee vault address", "FeeVaultAddress", *chainConfig.Scroll.FeeVaultAddress)
}
bc := &BlockChain{ bc := &BlockChain{
chainConfig: chainConfig, chainConfig: chainConfig,
cacheConfig: cacheConfig, cacheConfig: cacheConfig,

View file

@ -93,7 +93,7 @@ func (b *BlockGen) SetPoS() {
func (b *BlockGen) SetParentBeaconRoot(root common.Hash) { func (b *BlockGen) SetParentBeaconRoot(root common.Hash) {
b.header.ParentBeaconRoot = &root b.header.ParentBeaconRoot = &root
var ( 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{}) vmenv = vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.config, vm.Config{})
) )
ProcessBeaconBlockRoot(root, vmenv, b.statedb) ProcessBeaconBlockRoot(root, vmenv, b.statedb)

View file

@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
) )
// ChainContext supports retrieving headers and consensus parameters from the // 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. // 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 ( var (
beneficiary common.Address beneficiary common.Address
baseFee *big.Int baseFee *big.Int
@ -45,8 +46,9 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
random *common.Hash random *common.Hash
) )
// If we don't have an explicit author (i.e. not mining), extract from the header if chainConfig.Scroll.FeeVaultEnabled() { // If we enable the feevault feature, use the feevault address
if author == nil { 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 beneficiary, _ = chain.Engine().Author(header) // Ignore error, we're past header validation
} else { } else {
beneficiary = *author beneficiary = *author

View file

@ -53,7 +53,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
var ( var (
header = block.Header() header = block.Header()
gaspool = new(GasPool).AddGas(block.GasLimit()) 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) evm = vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
signer = types.MakeSigner(p.config, header.Number, header.Time) signer = types.MakeSigner(p.config, header.Number, header.Time)
) )

View file

@ -73,7 +73,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
misc.ApplyDAOHardFork(statedb) misc.ApplyDAOHardFork(statedb)
} }
var ( 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) vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg)
signer = types.MakeSigner(p.config, header.Number, header.Time) 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 return nil, err
} }
// Create a new context to be used in the EVM environment // 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) 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) return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
} }

View file

@ -526,3 +526,8 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *
// ChainConfig returns the environment's chain configuration // ChainConfig returns the environment's chain configuration
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } 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
}

View file

@ -473,7 +473,7 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
} }
func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 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 return nil, nil
} }

View file

@ -274,7 +274,7 @@ func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *st
if blockCtx != nil { if blockCtx != nil {
context = *blockCtx context = *blockCtx
} else { } 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 return vm.NewEVM(context, txContext, state, b.eth.blockchain.Config(), *vmConfig), state.Error
} }

View file

@ -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 // Assemble the transaction call message and return if the requested offset
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
txContext := core.NewEVMTxContext(msg) 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 { if idx == txIndex {
return msg, context, statedb, release, nil return msg, context, statedb, release, nil
} }

View file

@ -267,7 +267,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
for task := range taskCh { for task := range taskCh {
var ( var (
signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time()) 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 // Trace all the transactions contained within
for i, tx := range task.block.Transactions() { 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 roots []common.Hash
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
chainConfig = api.backend.ChainConfig() 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()) deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
) )
for i, tx := range block.Transactions() { 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() txs = block.Transactions()
blockHash = block.Hash() blockHash = block.Hash()
is158 = api.backend.ChainConfig().IsEIP158(block.Number()) 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()) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
results = make([]*txTraceResult, len(txs)) results = make([]*txTraceResult, len(txs))
) )
@ -649,7 +649,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
var ( var (
txs = block.Transactions() txs = block.Transactions()
blockHash = block.Hash() 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()) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
results = make([]*txTraceResult, len(txs)) results = make([]*txTraceResult, len(txs))
pend sync.WaitGroup pend sync.WaitGroup
@ -772,7 +772,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
dumps []string dumps []string
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
chainConfig = api.backend.ChainConfig() 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 canon = true
) )
// Check if there are any overrides: the caller may wish to enable a future // 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() 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. // Apply the customization rules if required.
if config != nil { if config != nil {
if err := config.StateOverrides.Apply(statedb); err != nil { if err := config.StateOverrides.Apply(statedb); err != nil {

View file

@ -173,7 +173,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
for idx, tx := range block.Transactions() { for idx, tx := range block.Transactions() {
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
txContext := core.NewEVMTxContext(msg) 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 { if idx == txIndex {
return msg, context, statedb, release, nil return msg, context, statedb, release, nil
} }

View file

@ -1085,7 +1085,7 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S
if err != nil { if err != nil {
return nil, err return nil, err
} }
blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), b.ChainConfig(), nil)
if blockOverrides != nil { if blockOverrides != nil {
blockOverrides.Apply(&blockCtx) blockOverrides.Apply(&blockCtx)
} }
@ -1207,7 +1207,7 @@ func EstimateL1MsgFee(ctx context.Context, b Backend, args TransactionArgs, bloc
if err != nil { if err != nil {
return nil, err 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) 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 // Wait for the context to be done and cancel the evm. Even if the
// EVM has finished, cancelling may be done (repeatedly) // EVM has finished, cancelling may be done (repeatedly)

View file

@ -542,7 +542,7 @@ func (b testBackend) GetEVM(ctx context.Context, msg *core.Message, state *state
vmConfig = b.chain.GetVMConfig() vmConfig = b.chain.GetVMConfig()
} }
txContext := core.NewEVMTxContext(msg) txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(header, b.chain, nil) context := core.NewEVMBlockContext(header, b.chain, b.chain.Config(), nil)
if blockContext != nil { if blockContext != nil {
context = *blockContext context = *blockContext
} }

View file

@ -188,7 +188,7 @@ func (b *LesApiBackend) GetEVM(ctx context.Context, msg *core.Message, state *st
vmConfig = new(vm.Config) vmConfig = new(vm.Config)
} }
txContext := core.NewEVMTxContext(msg) 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 { if blockCtx != nil {
context = *blockCtx context = *blockCtx
} }

View file

@ -148,7 +148,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
SkipAccountChecks: true, SkipAccountChecks: true,
} }
context := core.NewEVMBlockContext(header, bc, nil) context := core.NewEVMBlockContext(header, bc, config, nil)
txContext := core.NewEVMTxContext(msg) txContext := core.NewEVMTxContext(msg)
vmenv := vm.NewEVM(context, txContext, statedb, config, vm.Config{NoBaseFee: true}) 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, Data: data,
SkipAccountChecks: true, SkipAccountChecks: true,
} }
context := core.NewEVMBlockContext(header, lc, nil) context := core.NewEVMBlockContext(header, lc, config, nil)
txContext := core.NewEVMTxContext(msg) txContext := core.NewEVMTxContext(msg)
vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true}) vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true})
gp := new(core.GasPool).AddGas(math.MaxUint64) gp := new(core.GasPool).AddGas(math.MaxUint64)

View file

@ -63,7 +63,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types.
// Assemble the transaction call message and return if the requested offset // Assemble the transaction call message and return if the requested offset
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
txContext := core.NewEVMTxContext(msg) 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) statedb.SetTxContext(tx.Hash(), idx)
if idx == txIndex { if idx == txIndex {
return msg, context, statedb, release, nil return msg, context, statedb, release, nil

View file

@ -215,7 +215,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
SkipAccountChecks: true, SkipAccountChecks: true,
} }
txContext := core.NewEVMTxContext(msg) 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}) vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true})
gp := new(core.GasPool).AddGas(math.MaxUint64) gp := new(core.GasPool).AddGas(math.MaxUint64)
signer := types.MakeSigner(config, header.Number, header.Time) signer := types.MakeSigner(config, header.Number, header.Time)

View file

@ -82,12 +82,12 @@ var (
// environment is the worker's current environment and holds all // environment is the worker's current environment and holds all
// information of the sealing block generation. // information of the sealing block generation.
type environment struct { type environment struct {
signer types.Signer signer types.Signer
state *state.StateDB // apply state changes here state *state.StateDB // apply state changes here
tcount int // tx count in cycle tcount int // tx count in cycle
blockSize uint64 // approximate size of tx payload in bytes blockSize uint64 // approximate size of tx payload in bytes
gasPool *core.GasPool // available gas used to pack transactions gasPool *core.GasPool // available gas used to pack transactions
coinbase common.Address coinbase common.Address
header *types.Header header *types.Header
txs []*types.Transaction txs []*types.Transaction
@ -994,7 +994,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
return nil, err return nil, err
} }
if header.ParentBeaconRoot != nil { 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{}) vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, w.chainConfig, vm.Config{})
core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, env.state) core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, env.state)
} }

View file

@ -259,7 +259,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
// Prepare the EVM. // Prepare the EVM.
txContext := core.NewEVMTxContext(msg) 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.GetHash = vmTestBlockHash
context.BaseFee = baseFee context.BaseFee = baseFee
evm := vm.NewEVM(context, txContext, statedb, config, vmconfig) evm := vm.NewEVM(context, txContext, statedb, config, vmconfig)

View file

@ -272,7 +272,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
// Prepare the EVM. // Prepare the EVM.
txContext := core.NewEVMTxContext(msg) 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.GetHash = vmTestBlockHash
context.BaseFee = baseFee context.BaseFee = baseFee
context.Random = nil context.Random = nil