Skip to content

Commit 08e92ea

Browse files
qdm12ARR4N
andcommitted
chore(all): final changes to the libevm branch
Changes applied from comments on the review of ava-labs/coreth#820 See original PR ava-labs/coreth#862 Signed-off-by: Quentin McGaw <[email protected]> Co-authored-by: Arran Schlosberg <[email protected]>
1 parent d6e4708 commit 08e92ea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+281
-417
lines changed

core/blockchain.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func (c *CacheConfig) triedbConfig() *triedb.Config {
216216
config.DBOverride = hashdb.Config{
217217
CleanCacheSize: c.TrieCleanLimit * 1024 * 1024,
218218
StatsPrefix: trieCleanCacheStatsNamespace,
219-
ReferenceRootAtomicallyOnUpdate: true, // Automatically reference root nodes when an update is made
219+
ReferenceRootAtomicallyOnUpdate: true,
220220
}.BackendConstructor
221221
}
222222
if c.StateScheme == rawdb.PathScheme {
@@ -1235,8 +1235,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, parentRoot common.
12351235
}
12361236

12371237
// Commit all cached state changes into underlying memory database.
1238-
var err error
1239-
_, err = bc.commitWithSnap(block, parentRoot, state)
1238+
_, err := bc.commitWithSnap(block, parentRoot, state)
12401239
if err != nil {
12411240
return err
12421241
}
@@ -1758,8 +1757,8 @@ func (bc *BlockChain) reprocessBlock(parent *types.Block, current *types.Block)
17581757
func (bc *BlockChain) commitWithSnap(
17591758
current *types.Block, parentRoot common.Hash, statedb *state.StateDB,
17601759
) (common.Hash, error) {
1761-
// blockHashes must be passed through Commit since snapshots are based on the
1762-
// block hash.
1760+
// blockHashes must be passed through [state.StateDB]'s Commit since snapshots
1761+
// are based on the block hash.
17631762
blockHashes := snapshot.WithBlockHashes(current.Hash(), current.ParentHash())
17641763
root, err := statedb.Commit(current.NumberU64(), bc.chainConfig.IsEIP158(current.Number()), blockHashes)
17651764
if err != nil {

core/evm.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ func init() {
4949

5050
type hooks struct{}
5151

52-
// OverrideNewEVMArgs is a hook that is called back when a new EVM is created.
52+
// OverrideNewEVMArgs is a hook that is called in [vm.NewEVM].
5353
// It allows for the modification of the EVM arguments before the EVM is created.
5454
// Specifically, we set Random to be the same as Difficulty since Shanghai.
5555
// This allows using the same jump table as upstream.
5656
// Then we set Difficulty to 0 as it is post Merge in upstream.
5757
// Additionally we wrap the StateDB with the appropriate StateDB wrapper,
58-
// which is used in coreth to process historical pre-AP1 blocks with the
59-
// GetCommittedState method as it was historically.
58+
// which is used in subnet-evm to process historical pre-AP1 blocks with the
59+
// [StateDbAP1.GetCommittedState] method as it was historically.
6060
func (hooks) OverrideNewEVMArgs(args *vm.NewEVMArgs) *vm.NewEVMArgs {
6161
rules := args.ChainConfig.Rules(args.BlockContext.BlockNumber, params.IsMergeTODO, args.BlockContext.Time)
6262
args.StateDB = wrapStateDB(rules, args.StateDB)
@@ -76,7 +76,7 @@ func (hooks) OverrideEVMResetArgs(rules params.Rules, args *vm.EVMResetArgs) *vm
7676
}
7777

7878
func wrapStateDB(rules params.Rules, db vm.StateDB) vm.StateDB {
79-
return &extstate.StateDB{VmStateDB: db.(extstate.VmStateDB)}
79+
return extstate.New(db.(extstate.VmStateDB))
8080
}
8181

8282
// ChainContext supports retrieving headers and consensus parameters from the

core/extstate/statedb.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,35 @@ import (
1414
type VmStateDB interface {
1515
vm.StateDB
1616
Logs() []*types.Log
17-
1817
GetTxHash() common.Hash
1918
}
2019

20+
type vmStateDB = VmStateDB
21+
2122
type StateDB struct {
22-
VmStateDB
23+
vmStateDB
2324

2425
// Ordered storage slots to be used in predicate verification as set in the tx access list.
25-
// Only set in PrepareAccessList, and un-modified through execution.
26+
// Only set in [StateDB.Prepare], and un-modified through execution.
2627
predicateStorageSlots map[common.Address][][]byte
2728
}
2829

30+
// New creates a new [*StateDB] with the given [VmStateDB], effectively wrapping it
31+
// with additional functionality.
32+
func New(vm VmStateDB) *StateDB {
33+
return &StateDB{
34+
vmStateDB: vm,
35+
predicateStorageSlots: make(map[common.Address][][]byte),
36+
}
37+
}
38+
2939
func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) {
3040
rulesExtra := params.GetRulesExtra(rules)
3141
s.predicateStorageSlots = predicate.PreparePredicateStorageSlots(rulesExtra, list)
32-
s.VmStateDB.Prepare(rules, sender, coinbase, dst, precompiles, list)
42+
s.vmStateDB.Prepare(rules, sender, coinbase, dst, precompiles, list)
3343
}
3444

35-
// GetLogData returns the underlying topics and data from each log included in the StateDB
45+
// GetLogData returns the underlying topics and data from each log included in the [StateDB].
3646
// Test helper function.
3747
func (s *StateDB) GetLogData() (topics [][]common.Hash, data [][]byte) {
3848
for _, log := range s.Logs() {
@@ -54,19 +64,13 @@ func (s *StateDB) GetLogData() (topics [][]common.Hash, data [][]byte) {
5464
// GetPredicateStorageSlots(AddrA, 1) -> Predicate3
5565
func (s *StateDB) GetPredicateStorageSlots(address common.Address, index int) ([]byte, bool) {
5666
predicates, exists := s.predicateStorageSlots[address]
57-
if !exists {
58-
return nil, false
59-
}
60-
if index >= len(predicates) {
67+
if !exists || index >= len(predicates) {
6168
return nil, false
6269
}
6370
return predicates[index], true
6471
}
6572

6673
// SetPredicateStorageSlots sets the predicate storage slots for the given address
6774
func (s *StateDB) SetPredicateStorageSlots(address common.Address, predicates [][]byte) {
68-
if s.predicateStorageSlots == nil {
69-
s.predicateStorageSlots = make(map[common.Address][][]byte)
70-
}
7175
s.predicateStorageSlots[address] = predicates
7276
}

core/extstate/test_statedb.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ func NewTestStateDB(t testing.TB) contract.StateDB {
1616
db := rawdb.NewMemoryDatabase()
1717
statedb, err := state.New(common.Hash{}, state.NewDatabase(db), nil)
1818
require.NoError(t, err)
19-
return &StateDB{VmStateDB: statedb}
19+
return New(statedb)
2020
}

core/genesis.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ import (
5555

5656
var errGenesisNoConfig = errors.New("genesis has no chain configuration")
5757

58-
// Deprecated: use types.GenesisAccount instead.
58+
// Deprecated: use types.Account instead.
5959
type GenesisAccount = types.Account
6060

6161
// Deprecated: use types.GenesisAlloc instead.

core/genesis_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"github.com/ava-labs/libevm/core/types"
3939
"github.com/ava-labs/libevm/core/vm"
4040
"github.com/ava-labs/libevm/ethdb"
41+
ethparams "github.com/ava-labs/libevm/params"
4142
"github.com/ava-labs/libevm/trie"
4243
"github.com/ava-labs/libevm/triedb"
4344
"github.com/ava-labs/subnet-evm/consensus/dummy"
@@ -164,7 +165,7 @@ func testSetupGenesis(t *testing.T, scheme string) {
164165
},
165166
wantHash: customghash,
166167
wantConfig: customg.Config,
167-
wantErr: &params.ConfigCompatError{
168+
wantErr: &ethparams.ConfigCompatError{
168169
What: "SubnetEVM fork block timestamp",
169170
StoredTime: u64(90),
170171
NewTime: u64(100),

core/state/database.go

Lines changed: 10 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// (c) 2019-2020, Ava Labs, Inc.
1+
// (c) 2019-2025, Ava Labs, Inc.
22
//
33
// This file is a derived work, based on the go-ethereum library whose original
44
// notices appear below.
@@ -27,165 +27,24 @@
2727
package state
2828

2929
import (
30-
"errors"
31-
"fmt"
32-
33-
"github.com/ava-labs/libevm/common"
34-
"github.com/ava-labs/libevm/common/lru"
35-
"github.com/ava-labs/libevm/core/rawdb"
3630
ethstate "github.com/ava-labs/libevm/core/state"
37-
"github.com/ava-labs/libevm/crypto"
3831
"github.com/ava-labs/libevm/ethdb"
39-
"github.com/ava-labs/libevm/trie"
40-
"github.com/ava-labs/libevm/trie/utils"
4132
"github.com/ava-labs/libevm/triedb"
42-
"github.com/crate-crypto/go-ipa/banderwagon"
4333
)
4434

45-
const (
46-
// Number of codehash->size associations to keep.
47-
codeSizeCacheSize = 100000
48-
49-
// Cache size granted for caching clean code.
50-
codeCacheSize = 64 * 1024 * 1024
51-
52-
// commitmentSize is the size of commitment stored in cache.
53-
commitmentSize = banderwagon.UncompressedSize
54-
55-
// Cache item granted for caching commitment results.
56-
commitmentCacheItems = 64 * 1024 * 1024 / (commitmentSize + common.AddressLength)
35+
type (
36+
Database = ethstate.Database
37+
Trie = ethstate.Trie
5738
)
5839

59-
// Database wraps access to tries and contract code.
60-
type Database interface {
61-
// OpenTrie opens the main account trie.
62-
OpenTrie(root common.Hash) (Trie, error)
63-
64-
// OpenStorageTrie opens the storage trie of an account.
65-
OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, trie Trie) (Trie, error)
66-
67-
// CopyTrie returns an independent copy of the given trie.
68-
CopyTrie(Trie) Trie
69-
70-
// ContractCode retrieves a particular contract's code.
71-
ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error)
72-
73-
// ContractCodeSize retrieves a particular contracts code's size.
74-
ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error)
75-
76-
// DiskDB returns the underlying key-value disk database.
77-
DiskDB() ethdb.KeyValueStore
78-
79-
// TrieDB returns the underlying trie database for managing trie nodes.
80-
TrieDB() *triedb.Database
81-
}
82-
83-
// Trie is a Ethereum Merkle Patricia trie.
84-
type Trie = ethstate.Trie
85-
86-
// NewDatabase creates a backing store for state. The returned database is safe for
87-
// concurrent use, but does not retain any recent trie nodes in memory. To keep some
88-
// historical state in memory, use the NewDatabaseWithConfig constructor.
89-
func NewDatabase(db ethdb.Database) Database {
90-
return NewDatabaseWithConfig(db, nil)
91-
}
92-
93-
// NewDatabaseWithConfig creates a backing store for state. The returned database
94-
// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
95-
// large memory cache.
96-
func NewDatabaseWithConfig(db ethdb.Database, config *triedb.Config) Database {
97-
return &cachingDB{
98-
disk: db,
99-
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
100-
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
101-
triedb: triedb.NewDatabase(db, config),
102-
}
103-
}
104-
105-
// NewDatabaseWithNodeDB creates a state database with an already initialized node database.
106-
func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) Database {
107-
return &cachingDB{
108-
disk: db,
109-
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
110-
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
111-
triedb: triedb,
112-
}
113-
}
114-
115-
type cachingDB struct {
116-
disk ethdb.KeyValueStore
117-
codeSizeCache *lru.Cache[common.Hash, int]
118-
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]
119-
triedb *triedb.Database
120-
}
121-
122-
// OpenTrie opens the main account trie at a specific root hash.
123-
func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
124-
if db.triedb.IsVerkle() {
125-
return trie.NewVerkleTrie(root, db.triedb, utils.NewPointCache(commitmentCacheItems))
126-
}
127-
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
128-
if err != nil {
129-
return nil, err
130-
}
131-
return tr, nil
132-
}
133-
134-
// OpenStorageTrie opens the storage trie of an account.
135-
func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) {
136-
// In the verkle case, there is only one tree. But the two-tree structure
137-
// is hardcoded in the codebase. So we need to return the same trie in this
138-
// case.
139-
if db.triedb.IsVerkle() {
140-
return self, nil
141-
}
142-
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb)
143-
if err != nil {
144-
return nil, err
145-
}
146-
return tr, nil
147-
}
148-
149-
// CopyTrie returns an independent copy of the given trie.
150-
func (db *cachingDB) CopyTrie(t Trie) Trie {
151-
switch t := t.(type) {
152-
case *trie.StateTrie:
153-
return t.Copy()
154-
default:
155-
panic(fmt.Errorf("unknown trie type %T", t))
156-
}
157-
}
158-
159-
// ContractCode retrieves a particular contract's code.
160-
func (db *cachingDB) ContractCode(address common.Address, codeHash common.Hash) ([]byte, error) {
161-
code, _ := db.codeCache.Get(codeHash)
162-
if len(code) > 0 {
163-
return code, nil
164-
}
165-
code = rawdb.ReadCode(db.disk, codeHash)
166-
if len(code) > 0 {
167-
db.codeCache.Add(codeHash, code)
168-
db.codeSizeCache.Add(codeHash, len(code))
169-
return code, nil
170-
}
171-
return nil, errors.New("not found")
172-
}
173-
174-
// ContractCodeSize retrieves a particular contracts code's size.
175-
func (db *cachingDB) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
176-
if cached, ok := db.codeSizeCache.Get(codeHash); ok {
177-
return cached, nil
178-
}
179-
code, err := db.ContractCode(addr, codeHash)
180-
return len(code), err
40+
func NewDatabase(db ethdb.Database) ethstate.Database {
41+
return ethstate.NewDatabase(db)
18142
}
18243

183-
// DiskDB returns the underlying key-value disk database.
184-
func (db *cachingDB) DiskDB() ethdb.KeyValueStore {
185-
return db.disk
44+
func NewDatabaseWithConfig(db ethdb.Database, config *triedb.Config) ethstate.Database {
45+
return ethstate.NewDatabaseWithConfig(db, config)
18646
}
18747

188-
// TrieDB retrieves any intermediate trie-node caching layer.
189-
func (db *cachingDB) TrieDB() *triedb.Database {
190-
return db.triedb
48+
func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) ethstate.Database {
49+
return ethstate.NewDatabaseWithNodeDB(db, triedb)
19150
}

core/state/snapshot/iterator.go

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,34 +39,11 @@ import (
3939

4040
// Iterator is an iterator to step over all the accounts or the specific
4141
// storage in a snapshot which may or may not be composed of multiple layers.
42-
type Iterator interface {
43-
// Next steps the iterator forward one element, returning false if exhausted,
44-
// or an error if iteration failed for some reason (e.g. root being iterated
45-
// becomes stale and garbage collected).
46-
Next() bool
47-
48-
// Error returns any failure that occurred during iteration, which might have
49-
// caused a premature iteration exit (e.g. snapshot stack becoming stale).
50-
Error() error
51-
52-
// Hash returns the hash of the account or storage slot the iterator is
53-
// currently at.
54-
Hash() common.Hash
55-
56-
// Release releases associated resources. Release should always succeed and
57-
// can be called multiple times without causing error.
58-
Release()
59-
}
42+
type Iterator = ethsnapshot.Iterator
6043

6144
// AccountIterator is an iterator to step over all the accounts in a snapshot,
6245
// which may or may not be composed of multiple layers.
63-
type AccountIterator interface {
64-
Iterator
65-
66-
// Account returns the RLP encoded slim account the iterator is currently at.
67-
// An error will be returned if the iterator becomes invalid
68-
Account() []byte
69-
}
46+
type AccountIterator = ethsnapshot.AccountIterator
7047

7148
// StorageIterator is an iterator to step over the specific storage in a snapshot,
7249
// which may or may not be composed of multiple layers.

core/state/statedb.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,15 @@ func (s *StateDB) Copy() *StateDB {
120120
}
121121

122122
// NormalizeCoinID ORs the 0th bit of the first byte in
123-
// [coinID], which ensures this bit will be 1 and all other
123+
// `coinID`, which ensures this bit will be 1 and all other
124124
// bits are left the same.
125125
// This partitions multicoin storage from normal state storage.
126126
func NormalizeCoinID(coinID *common.Hash) {
127127
coinID[0] |= 0x01
128128
}
129129

130130
// NormalizeStateKey ANDs the 0th bit of the first byte in
131-
// [key], which ensures this bit will be 0 and all other bits
131+
// `key`, which ensures this bit will be 0 and all other bits
132132
// are left the same.
133133
// This partitions normal state storage from multicoin storage.
134134
func NormalizeStateKey(key *common.Hash) {

0 commit comments

Comments
 (0)