diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 4e3fbeb09a..7d5007f241 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -360,6 +360,12 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types. amount := new(uint256.Int).SetUint64(w.Amount) amount = amount.Mul(amount, uint256.NewInt(params.GWei)) state.AddBalance(w.Address, amount, tracing.BalanceIncreaseWithdrawal) + + // Add the balance of each withdrawal to the witness, no gas will + // be charged. + if chain.Config().IsEIP4762(header.Number, header.Time) { + state.AccessEvents().BalanceGas(w.Address[:], true) + } } // No block reward which is issued by consensus layer instead. } diff --git a/core/state/access_events.go b/core/state/access_events.go index 3ad5ef28d2..bc6064e96d 100644 --- a/core/state/access_events.go +++ b/core/state/access_events.go @@ -66,7 +66,7 @@ func (aw *AccessEvents) Merge(other *AccessEvents) { } } -// Keys returns, predictably, the list of keys that were touched during the +// Key returns, predictably, the list of keys that were touched during the // buildup of the access witness. func (aw *AccessEvents) Keys() [][]byte { // TODO: consider if parallelizing this is worth it, probably depending on len(aw.chunks). @@ -173,6 +173,7 @@ func (aw *AccessEvents) touchAddressAndChargeGas(addr []byte, treeIndex uint256. if selectorFill { gas += params.WitnessChunkFillCost } + return gas } @@ -205,8 +206,10 @@ func (aw *AccessEvents) touchAddress(addr []byte, treeIndex uint256.Int, subInde chunkWrite = true aw.chunks[chunkKey] |= AccessWitnessWriteFlag } + // TODO: charge chunk filling costs if the leaf was previously empty in the state } + return branchRead, chunkRead, branchWrite, chunkWrite, chunkFill } @@ -265,6 +268,7 @@ func (aw *AccessEvents) CodeChunksRangeGas(contractAddr []byte, startPC, size ui panic("overflow when adding gas") } } + return statelessGasCharged } diff --git a/core/state/database.go b/core/state/database.go index 15479de985..8ae2c52546 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -38,9 +38,6 @@ const ( // Cache size granted for caching clean code. codeCacheSize = 64 * 1024 * 1024 - - // Number of address->curve point associations to keep. - pointCacheSize = 4096 ) // Database wraps access to tries and contract code. @@ -65,9 +62,6 @@ type Database interface { // TrieDB returns the underlying trie database for managing trie nodes. TrieDB() *triedb.Database - - // PointCache returns the cache of evaluated curve points. - PointCache() *utils.PointCache } // Trie is a Ethereum Merkle Patricia trie. @@ -159,7 +153,6 @@ func NewDatabaseWithConfig(db ethdb.Database, config *triedb.Config) Database { codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), triedb: triedb.NewDatabase(db, config), - pointCache: utils.NewPointCache(pointCacheSize), } } @@ -170,7 +163,6 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) Database codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), triedb: triedb, - pointCache: utils.NewPointCache(pointCacheSize), } } @@ -179,13 +171,12 @@ type cachingDB struct { codeSizeCache *lru.Cache[common.Hash, int] codeCache *lru.SizeConstrainedCache[common.Hash, []byte] triedb *triedb.Database - pointCache *utils.PointCache } // OpenTrie opens the main account trie at a specific root hash. func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { if db.triedb.IsVerkle() { - return trie.NewVerkleTrie(root, db.triedb, db.pointCache) + return trie.NewVerkleTrie(root, db.triedb, utils.NewPointCache(100)) } tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb) if err != nil { @@ -271,8 +262,3 @@ func (db *cachingDB) DiskDB() ethdb.KeyValueStore { func (db *cachingDB) TrieDB() *triedb.Database { return db.triedb } - -// PointCache returns the cache of evaluated curve points. -func (db *cachingDB) PointCache() *utils.PointCache { - return db.pointCache -} diff --git a/core/state/statedb.go b/core/state/statedb.go index 6cdef8f2a6..008de7994e 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/triestate" + "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" ) @@ -139,8 +140,8 @@ type StateDB struct { // Transient storage transientStorage transientStorage - // State access events, used for EIP4762 - accessEvents *AccessEvents // reset for each transaction + // State access events, used for Verkle tries/EIP4762 + accessEvents *AccessEvents // Journal of state modifications. This is the backbone of // Snapshot and RevertToSnapshot. @@ -196,16 +197,30 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) transientStorage: newTransientStorage(), hasher: crypto.NewKeccakState(), } + if tr.IsVerkle() { + sdb.accessEvents = sdb.NewAccessEvents() + } if sdb.snaps != nil { sdb.snap = sdb.snaps.Snapshot(root) } return sdb, nil } +func (s *StateDB) NewAccessEvents() *AccessEvents { + return NewAccessEvents(utils.NewPointCache(100)) +} + func (s *StateDB) AccessEvents() *AccessEvents { + if s.accessEvents == nil { + s.accessEvents = s.NewAccessEvents() + } return s.accessEvents } +func (s *StateDB) SetAccessEvents(ae *AccessEvents) { + s.accessEvents = ae +} + // SetLogger sets the logger for account update hooks. func (s *StateDB) SetLogger(l *tracing.Hooks) { s.logger = l @@ -752,9 +767,6 @@ func (s *StateDB) Copy() *StateDB { if s.prefetcher != nil { state.prefetcher = s.prefetcher.copy() } - if s.accessEvents != nil { - state.accessEvents = s.accessEvents.Copy() - } return state } @@ -1285,9 +1297,6 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er // - Add coinbase to access list (EIP-3651) // - Reset transient storage (EIP-1153) func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) { - if rules.IsEIP2929 && rules.IsEIP4762 { - panic("eip2929 and eip4762 are both activated") - } if rules.IsEIP2929 { // Clear out any leftover from previous executions al := newAccessList() @@ -1311,9 +1320,6 @@ func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, d al.AddAddress(coinbase) } } - if rules.IsEIP4762 { - s.accessEvents = NewAccessEvents(s.db.PointCache()) - } // Reset transient storage at the beginning of transaction execution s.transientStorage = newTransientStorage() } diff --git a/core/state_processor.go b/core/state_processor.go index b891db249b..66de959543 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -120,6 +120,7 @@ func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPo } // Create a new context to be used in the EVM environment. txContext := NewEVMTxContext(msg) + txContext.AccessEvents = statedb.NewAccessEvents() evm.Reset(txContext, statedb) // Apply the transaction to the current state (included in the env). @@ -157,6 +158,11 @@ func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPo if msg.To == nil { receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce()) } + + if statedb.AccessEvents() != nil { + statedb.AccessEvents().Merge(txContext.AccessEvents) + } + // Set the receipt logs and create the bloom filter. receipt.Logs = statedb.GetLogs(tx.Hash(), blockNumber.Uint64(), blockHash) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) @@ -202,5 +208,8 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *stat statedb.AddAddressToAccessList(params.BeaconRootsAddress) } _, _, _ = vmenv.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) + if vmenv.ChainConfig().Rules(vmenv.Context.BlockNumber, true, vmenv.Context.Time).IsEIP4762 { + statedb.AccessEvents().Merge(txctx.AccessEvents) + } statedb.Finalise(true) } diff --git a/core/state_transition.go b/core/state_transition.go index 5fb5639212..fba41762ad 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -406,10 +406,10 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { st.gasRemaining -= gas if rules.IsEIP4762 { - st.evm.StateDB.AccessEvents().AddTxOrigin(msg.From.Bytes()) + st.evm.AccessEvents.AddTxOrigin(msg.From.Bytes()) if targetAddr := msg.To; targetAddr != nil { - st.evm.StateDB.AccessEvents().AddTxDestination(targetAddr.Bytes(), msg.Value.Sign() != 0) + st.evm.AccessEvents.AddTxDestination(targetAddr.Bytes(), msg.Value.Sign() != 0) // ensure the code size ends up in the access witness st.evm.StateDB.GetCodeSize(*targetAddr) @@ -472,7 +472,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { // add the coinbase to the witness iff the fee is greater than 0 if rules.IsEIP4762 && fee.Sign() != 0 { - st.evm.StateDB.AccessEvents().BalanceGas(st.evm.Context.Coinbase[:], true) + st.evm.AccessEvents.BalanceGas(st.evm.Context.Coinbase[:], true) } } diff --git a/core/vm/eips.go b/core/vm/eips.go index 947539f58f..2af1b17672 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -331,7 +331,7 @@ func opCreateEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContex var endowment = scope.Stack.peek() contractAddress := crypto.CreateAddress(scope.Contract.Address(), interpreter.evm.StateDB.GetNonce(scope.Contract.Address())) - statelessGas := interpreter.evm.StateDB.AccessEvents().ContractCreateInitGas(contractAddress.Bytes()[:], endowment.Sign() != 0) + statelessGas := interpreter.evm.AccessEvents.ContractCreateInitGas(contractAddress.Bytes()[:], endowment.Sign() != 0) if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { return nil, ErrExecutionReverted } @@ -352,7 +352,7 @@ func opCreate2EIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte codeAndHash := &codeAndHash{code: input} contractAddress := crypto.CreateAddress2(scope.Contract.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) - statelessGas := interpreter.evm.StateDB.AccessEvents().ContractCreateInitGas(contractAddress.Bytes()[:], endowment.Sign() != 0) + statelessGas := interpreter.evm.AccessEvents.ContractCreateInitGas(contractAddress.Bytes()[:], endowment.Sign() != 0) if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { return nil, ErrExecutionReverted } @@ -379,7 +379,7 @@ func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC self: AccountRef(addr), } paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(code, uint64CodeOffset, length.Uint64()) - statelessGas := interpreter.evm.StateDB.AccessEvents().CodeChunksRangeGas(addr[:], copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) + statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr[:], copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { scope.Contract.Gas = 0 return nil, ErrOutOfGas @@ -405,7 +405,7 @@ func opPush1EIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext // touch next chunk if PUSH1 is at the boundary. if so, *pc has // advanced past this boundary. contractAddr := scope.Contract.Address() - statelessGas := interpreter.evm.StateDB.AccessEvents().CodeChunksRangeGas(contractAddr[:], *pc+1, uint64(1), uint64(len(scope.Contract.Code)), false) + statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr[:], *pc+1, uint64(1), uint64(len(scope.Contract.Code)), false) if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { scope.Contract.Gas = 0 return nil, ErrOutOfGas @@ -433,7 +433,7 @@ func makePushEIP4762(size uint64, pushByteSize int) executionFunc { if !scope.Contract.IsDeployment { contractAddr := scope.Contract.Address() - statelessGas := interpreter.evm.StateDB.AccessEvents().CodeChunksRangeGas(contractAddr[:], uint64(start), uint64(pushByteSize), uint64(len(scope.Contract.Code)), false) + statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr[:], uint64(start), uint64(pushByteSize), uint64(len(scope.Contract.Code)), false) if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) { scope.Contract.Gas = 0 return nil, ErrOutOfGas diff --git a/core/vm/evm.go b/core/vm/evm.go index 541c49ce45..9393c732b2 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -22,6 +22,7 @@ import ( "sync/atomic" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -87,10 +88,11 @@ type BlockContext struct { // All fields can change between transactions. type TxContext struct { // Message information - Origin common.Address // Provides information for ORIGIN - GasPrice *big.Int // Provides information for GASPRICE (and is used to zero the basefee if NoBaseFee is set) - BlobHashes []common.Hash // Provides information for BLOBHASH - BlobFeeCap *big.Int // Is used to zero the blobbasefee if NoBaseFee is set + Origin common.Address // Provides information for ORIGIN + GasPrice *big.Int // Provides information for GASPRICE (and is used to zero the basefee if NoBaseFee is set) + BlobHashes []common.Hash // Provides information for BLOBHASH + BlobFeeCap *big.Int // Is used to zero the blobbasefee if NoBaseFee is set + AccessEvents *state.AccessEvents // Capture all state accesses for this tx } // EVM is the Ethereum Virtual Machine base object and provides @@ -151,6 +153,9 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig chainConfig: chainConfig, chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time), } + if txCtx.AccessEvents == nil && chainConfig.IsPrague(blockCtx.BlockNumber, blockCtx.Time) { + evm.AccessEvents = evm.StateDB.(*state.StateDB).NewAccessEvents() + } evm.interpreter = NewEVMInterpreter(evm) return evm } @@ -158,6 +163,9 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig // Reset resets the EVM with a new transaction context.Reset // This is not threadsafe and should only be done very cautiously. func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) { + if txCtx.AccessEvents == nil && evm.chainRules.IsPrague { + txCtx.AccessEvents = evm.StateDB.(*state.StateDB).NewAccessEvents() + } evm.TxContext = txCtx evm.StateDB = statedb } @@ -204,7 +212,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas if !evm.StateDB.Exist(addr) { if !isPrecompile && evm.chainRules.IsEIP4762 { // add proof of absence to witness - wgas := evm.StateDB.AccessEvents().AddAccount(addr.Bytes(), false) + wgas := evm.AccessEvents.AddAccount(addr.Bytes(), false) if gas < wgas { evm.StateDB.RevertToSnapshot(snapshot) return nil, 0, ErrOutOfGas @@ -495,7 +503,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // Charge the contract creation init gas in verkle mode if evm.chainRules.IsEIP4762 { - if !contract.UseGas(evm.StateDB.AccessEvents().ContractCreateInitGas(address.Bytes(), value.Sign() != 0), evm.Config.Tracer, tracing.GasChangeWitnessContractInit) { + if !contract.UseGas(evm.AccessEvents.ContractCreateInitGas(address.Bytes(), value.Sign() != 0), evm.Config.Tracer, tracing.GasChangeWitnessContractInit) { err = ErrOutOfGas } } @@ -526,11 +534,11 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, } } else { // Contract creation completed, touch the missing fields in the contract - if !contract.UseGas(evm.StateDB.AccessEvents().AddAccount(address.Bytes()[:], true), evm.Config.Tracer, tracing.GasChangeWitnessContractCreation) { + if !contract.UseGas(evm.AccessEvents.AddAccount(address.Bytes()[:], true), evm.Config.Tracer, tracing.GasChangeWitnessContractCreation) { err = ErrCodeStoreOutOfGas } - if err == nil && len(ret) > 0 && !contract.UseGas(evm.StateDB.AccessEvents().CodeChunksRangeGas(address.Bytes(), 0, uint64(len(ret)), uint64(len(ret)), true), evm.Config.Tracer, tracing.GasChangeWitnessCodeChunk) { + if err == nil && len(ret) > 0 && !contract.UseGas(evm.AccessEvents.CodeChunksRangeGas(address.Bytes(), 0, uint64(len(ret)), uint64(len(ret)), true), evm.Config.Tracer, tracing.GasChangeWitnessCodeChunk) { err = ErrCodeStoreOutOfGas } } diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 8f74287718..b3cedfd09e 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -404,7 +404,7 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize } if evm.chainRules.IsEIP4762 { if transfersValue { - gas, overflow = math.SafeAdd(gas, evm.StateDB.AccessEvents().ValueTransferGas(contract.Address().Bytes()[:], address.Bytes()[:])) + gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address().Bytes()[:], address.Bytes()[:])) if overflow { return 0, ErrGasUintOverflow } @@ -440,7 +440,7 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory address := common.Address(stack.Back(1).Bytes20()) transfersValue := !stack.Back(2).IsZero() if transfersValue { - gas, overflow = math.SafeAdd(gas, evm.StateDB.AccessEvents().ValueTransferGas(contract.Address().Bytes()[:], address.Bytes()[:])) + gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address().Bytes()[:], address.Bytes()[:])) if overflow { return 0, ErrGasUintOverflow } diff --git a/core/vm/interface.go b/core/vm/interface.go index a54375572b..774360a08e 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -20,7 +20,6 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" @@ -76,9 +75,6 @@ type StateDB interface { // AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform // even if the feature/fork is not active yet AddSlotToAccessList(addr common.Address, slot common.Hash) - - AccessEvents() *state.AccessEvents - Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) RevertToSnapshot(int) diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 196eb840d9..7761790f43 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -227,7 +227,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // if the PC ends up in a new "chunk" of verkleized code, charge the // associated costs. contractAddr := contract.Address() - contract.Gas -= in.evm.StateDB.AccessEvents().CodeChunksRangeGas(contractAddr[:], pc, 1, uint64(len(contract.Code)), false) + contract.Gas -= in.evm.TxContext.AccessEvents.CodeChunksRangeGas(contractAddr[:], pc, 1, uint64(len(contract.Code)), false) } // Get the operation from the jump table and validate the stack to ensure there are diff --git a/core/vm/operations_verkle.go b/core/vm/operations_verkle.go index 5167e744e7..2ded65950b 100644 --- a/core/vm/operations_verkle.go +++ b/core/vm/operations_verkle.go @@ -23,7 +23,7 @@ import ( ) func gasSStore4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas := evm.StateDB.AccessEvents().SlotGas(contract.Address().Bytes(), common.Hash(stack.peek().Bytes32()), true) + gas := evm.AccessEvents.SlotGas(contract.Address().Bytes(), common.Hash(stack.peek().Bytes32()), true) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 } @@ -31,7 +31,7 @@ func gasSStore4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo } func gasSLoad4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas := evm.StateDB.AccessEvents().SlotGas(contract.Address().Bytes(), common.Hash(stack.peek().Bytes32()), false) + gas := evm.AccessEvents.SlotGas(contract.Address().Bytes(), common.Hash(stack.peek().Bytes32()), false) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 } @@ -40,7 +40,7 @@ func gasSLoad4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memor func gasBalance4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { address := stack.peek().Bytes20() - gas := evm.StateDB.AccessEvents().BalanceGas(address[:], false) + gas := evm.AccessEvents.BalanceGas(address[:], false) if gas == 0 { gas = params.WarmStorageReadCostEIP2929 } @@ -52,8 +52,8 @@ func gasExtCodeSize4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, if _, isPrecompile := evm.precompile(address); isPrecompile { return 0, nil } - wgas := evm.StateDB.AccessEvents().VersionGas(address[:], false) - wgas += evm.StateDB.AccessEvents().CodeSizeGas(address[:], false) + wgas := evm.AccessEvents.VersionGas(address[:], false) + wgas += evm.AccessEvents.CodeSizeGas(address[:], false) if wgas == 0 { wgas = params.WarmStorageReadCostEIP2929 } @@ -65,7 +65,7 @@ func gasExtCodeHash4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, if _, isPrecompile := evm.precompile(address); isPrecompile { return 0, nil } - codehashgas := evm.StateDB.AccessEvents().CodeHashGas(address[:], false) + codehashgas := evm.AccessEvents.CodeHashGas(address[:], false) if codehashgas == 0 { codehashgas = params.WarmStorageReadCostEIP2929 } @@ -81,7 +81,7 @@ func makeCallVariantGasEIP4762(oldCalculator gasFunc) gasFunc { if _, isPrecompile := evm.precompile(contract.Address()); isPrecompile { return gas, nil } - wgas := evm.StateDB.AccessEvents().MessageCallGas(contract.Address().Bytes()) + wgas := evm.AccessEvents.MessageCallGas(contract.Address().Bytes()) if wgas == 0 { wgas = params.WarmStorageReadCostEIP2929 } @@ -102,17 +102,17 @@ func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Mem return 0, nil } contractAddr := contract.Address() - statelessGas := evm.StateDB.AccessEvents().VersionGas(contractAddr[:], false) - statelessGas += evm.StateDB.AccessEvents().CodeSizeGas(contractAddr[:], false) - statelessGas += evm.StateDB.AccessEvents().BalanceGas(contractAddr[:], false) + statelessGas := evm.AccessEvents.VersionGas(contractAddr[:], false) + statelessGas += evm.AccessEvents.CodeSizeGas(contractAddr[:], false) + statelessGas += evm.AccessEvents.BalanceGas(contractAddr[:], false) if contractAddr != beneficiaryAddr { - statelessGas += evm.StateDB.AccessEvents().BalanceGas(beneficiaryAddr[:], false) + statelessGas += evm.AccessEvents.BalanceGas(beneficiaryAddr[:], false) } // Charge write costs if it transfers value if evm.StateDB.GetBalance(contractAddr).Sign() != 0 { - statelessGas += evm.StateDB.AccessEvents().BalanceGas(contractAddr[:], true) + statelessGas += evm.AccessEvents.BalanceGas(contractAddr[:], true) if contractAddr != beneficiaryAddr { - statelessGas += evm.StateDB.AccessEvents().BalanceGas(beneficiaryAddr[:], true) + statelessGas += evm.AccessEvents.BalanceGas(beneficiaryAddr[:], true) } } return statelessGas, nil @@ -133,7 +133,7 @@ func gasCodeCopyEip4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, } _, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(contract.Code, uint64CodeOffset, length.Uint64()) if !contract.IsDeployment { - gas += evm.StateDB.AccessEvents().CodeChunksRangeGas(contract.Address().Bytes(), copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) + gas += evm.AccessEvents.CodeChunksRangeGas(contract.Address().Bytes(), copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false) } return gas, nil } @@ -145,8 +145,8 @@ func gasExtCodeCopyEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memo return 0, err } addr := common.Address(stack.peek().Bytes20()) - wgas := evm.StateDB.AccessEvents().VersionGas(addr[:], false) - wgas += evm.StateDB.AccessEvents().CodeSizeGas(addr[:], false) + wgas := evm.AccessEvents.VersionGas(addr[:], false) + wgas += evm.AccessEvents.CodeSizeGas(addr[:], false) if wgas == 0 { wgas = params.WarmStorageReadCostEIP2929 } diff --git a/params/config.go b/params/config.go index 5fedfd3519..176738b868 100644 --- a/params/config.go +++ b/params/config.go @@ -921,7 +921,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules } // disallow setting Merge out of order isMerge = isMerge && c.IsLondon(num) - isVerkle := isMerge && c.IsVerkle(num, timestamp) return Rules{ ChainID: new(big.Int).Set(chainID), IsHomestead: c.IsHomestead(num), @@ -933,13 +932,13 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsPetersburg: c.IsPetersburg(num), IsIstanbul: c.IsIstanbul(num), IsBerlin: c.IsBerlin(num), - IsEIP2929: c.IsBerlin(num) && !isVerkle, + IsEIP2929: c.IsBerlin(num) && !c.IsVerkle(num, timestamp), + IsEIP4762: c.IsVerkle(num, timestamp), IsLondon: c.IsLondon(num), IsMerge: isMerge, IsShanghai: isMerge && c.IsShanghai(num, timestamp), IsCancun: isMerge && c.IsCancun(num, timestamp), IsPrague: isMerge && c.IsPrague(num, timestamp), - IsVerkle: isVerkle, - IsEIP4762: isVerkle, + IsVerkle: isMerge && c.IsVerkle(num, timestamp), } }