diff --git a/core/state/database.go b/core/state/database.go index 8ae2c52546..04d7c06687 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -38,6 +38,9 @@ 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. @@ -60,6 +63,9 @@ type Database interface { // DiskDB returns the underlying key-value disk database. DiskDB() ethdb.KeyValueStore + // PointCache returns the cache holding points used in verkle tree key computation + PointCache() *utils.PointCache + // TrieDB returns the underlying trie database for managing trie nodes. TrieDB() *triedb.Database } @@ -153,6 +159,7 @@ 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), } } @@ -163,6 +170,7 @@ 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), } } @@ -171,12 +179,13 @@ 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, utils.NewPointCache(100)) + return trie.NewVerkleTrie(root, db.triedb, db.pointCache) } tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb) if err != nil { @@ -262,3 +271,8 @@ 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 7345b1348b..2d94bf34d7 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -140,9 +140,6 @@ type StateDB struct { // Transient storage transientStorage transientStorage - // State access events, used for Verkle tries/EIP4762 - accessEvents *AccessEvents - // Journal of state modifications. This is the backbone of // Snapshot and RevertToSnapshot. journal *journal @@ -197,30 +194,12 @@ 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 @@ -1412,3 +1391,7 @@ func (s *StateDB) markUpdate(addr common.Address) { s.mutations[addr].applied = false s.mutations[addr].typ = update } + +func (s *StateDB) PointCache() *utils.PointCache { + return s.db.PointCache() +} diff --git a/core/state_processor.go b/core/state_processor.go index f73a908ad2..19389f0797 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -120,7 +120,6 @@ 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). @@ -159,10 +158,6 @@ func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPo 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}) diff --git a/core/vm/evm.go b/core/vm/evm.go index 9393c732b2..a360baff9c 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -153,9 +153,6 @@ 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 } @@ -163,8 +160,8 @@ 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() + if evm.chainRules.IsEIP4762 { + txCtx.AccessEvents = state.NewAccessEvents(statedb.PointCache()) } evm.TxContext = txCtx evm.StateDB = statedb diff --git a/core/vm/interface.go b/core/vm/interface.go index 774360a08e..8b2c58898e 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -23,6 +23,7 @@ import ( "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" ) @@ -75,6 +76,10 @@ 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) + + // PointCache returns the point cache used in computations + PointCache() *utils.PointCache + Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) RevertToSnapshot(int)