Skip to content

Commit b6c62d5

Browse files
authored
core, trie, triedb: minor changes from snapshot integration (ethereum#30599)
This change ports some non-important changes from ethereum#30159, including interface renaming and some trivial refactorings.
1 parent 3ff73d4 commit b6c62d5

40 files changed

+991
-787
lines changed

cmd/geth/snapshot.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ func traverseRawState(ctx *cli.Context) error {
428428
log.Error("Failed to open iterator", "root", root, "err", err)
429429
return err
430430
}
431-
reader, err := triedb.Reader(root)
431+
reader, err := triedb.NodeReader(root)
432432
if err != nil {
433433
log.Error("State is non-existent", "root", root)
434434
return nil

core/blockchain.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ func (c *CacheConfig) triedbConfig(isVerkle bool) *triedb.Config {
160160
}
161161
if c.StateScheme == rawdb.PathScheme {
162162
config.PathDB = &pathdb.Config{
163-
StateHistory: c.StateHistory,
164-
CleanCacheSize: c.TrieCleanLimit * 1024 * 1024,
165-
DirtyCacheSize: c.TrieDirtyLimit * 1024 * 1024,
163+
StateHistory: c.StateHistory,
164+
CleanCacheSize: c.TrieCleanLimit * 1024 * 1024,
165+
WriteBufferSize: c.TrieDirtyLimit * 1024 * 1024,
166166
}
167167
}
168168
return config

core/state/snapshot/generate.go

+5-12
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
"github.com/ethereum/go-ethereum/log"
3232
"github.com/ethereum/go-ethereum/rlp"
3333
"github.com/ethereum/go-ethereum/trie"
34-
"github.com/ethereum/go-ethereum/trie/trienode"
3534
"github.com/ethereum/go-ethereum/triedb"
3635
)
3736

@@ -353,20 +352,14 @@ func (dl *diskLayer) generateRange(ctx *generatorContext, trieId *trie.ID, prefi
353352
// main account trie as a primary lookup when resolving hashes
354353
var resolver trie.NodeResolver
355354
if len(result.keys) > 0 {
356-
mdb := rawdb.NewMemoryDatabase()
357-
tdb := triedb.NewDatabase(mdb, triedb.HashDefaults)
358-
defer tdb.Close()
359-
snapTrie := trie.NewEmpty(tdb)
355+
tr := trie.NewEmpty(nil)
360356
for i, key := range result.keys {
361-
snapTrie.Update(key, result.vals[i])
362-
}
363-
root, nodes := snapTrie.Commit(false)
364-
if nodes != nil {
365-
tdb.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
366-
tdb.Commit(root, false)
357+
tr.Update(key, result.vals[i])
367358
}
359+
_, nodes := tr.Commit(false)
360+
hashSet := nodes.HashSet()
368361
resolver = func(owner common.Hash, path []byte, hash common.Hash) []byte {
369-
return rawdb.ReadTrieNode(mdb, owner, path, hash, tdb.Scheme())
362+
return hashSet[hash]
370363
}
371364
}
372365
// Construct the trie for state iteration, reuse the trie

core/state/snapshot/generate_test.go

+55-39
Large diffs are not rendered by default.

core/state/statedb.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import (
3838
"github.com/ethereum/go-ethereum/params"
3939
"github.com/ethereum/go-ethereum/trie"
4040
"github.com/ethereum/go-ethereum/trie/trienode"
41-
"github.com/ethereum/go-ethereum/trie/triestate"
4241
"github.com/ethereum/go-ethereum/trie/utils"
4342
"github.com/holiman/uint256"
4443
"golang.org/x/sync/errgroup"
@@ -1282,8 +1281,7 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool) (*stateU
12821281
// If trie database is enabled, commit the state update as a new layer
12831282
if db := s.db.TrieDB(); db != nil {
12841283
start := time.Now()
1285-
set := triestate.New(ret.accountsOrigin, ret.storagesOrigin)
1286-
if err := db.Update(ret.root, ret.originRoot, block, ret.nodes, set); err != nil {
1284+
if err := db.Update(ret.root, ret.originRoot, block, ret.nodes, ret.stateSet()); err != nil {
12871285
return nil, err
12881286
}
12891287
s.TrieDBCommits += time.Since(start)

core/state/statedb_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -981,8 +981,8 @@ func testMissingTrieNodes(t *testing.T, scheme string) {
981981
)
982982
if scheme == rawdb.PathScheme {
983983
tdb = triedb.NewDatabase(memDb, &triedb.Config{PathDB: &pathdb.Config{
984-
CleanCacheSize: 0,
985-
DirtyCacheSize: 0,
984+
CleanCacheSize: 0,
985+
WriteBufferSize: 0,
986986
}}) // disable caching
987987
} else {
988988
tdb = triedb.NewDatabase(memDb, &triedb.Config{HashDB: &hashdb.Config{

core/state/stateupdate.go

+15
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/ethereum/go-ethereum/common"
2121
"github.com/ethereum/go-ethereum/core/types"
2222
"github.com/ethereum/go-ethereum/trie/trienode"
23+
"github.com/ethereum/go-ethereum/triedb"
2324
)
2425

2526
// contractCode represents a contract code with associated metadata.
@@ -131,3 +132,17 @@ func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common
131132
nodes: nodes,
132133
}
133134
}
135+
136+
// stateSet converts the current stateUpdate object into a triedb.StateSet
137+
// object. This function extracts the necessary data from the stateUpdate
138+
// struct and formats it into the StateSet structure consumed by the triedb
139+
// package.
140+
func (sc *stateUpdate) stateSet() *triedb.StateSet {
141+
return &triedb.StateSet{
142+
Destructs: sc.destructs,
143+
Accounts: sc.accounts,
144+
AccountsOrigin: sc.accountsOrigin,
145+
Storages: sc.storages,
146+
StoragesOrigin: sc.storagesOrigin,
147+
}
148+
}

core/state/sync_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ func testIterativeStateSync(t *testing.T, count int, commit bool, bypath bool, s
207207
for i := 0; i < len(codes); i++ {
208208
codeElements = append(codeElements, stateElement{code: codes[i]})
209209
}
210-
reader, err := ndb.Reader(srcRoot)
210+
reader, err := ndb.NodeReader(srcRoot)
211211
if err != nil {
212212
t.Fatalf("state is not existent, %#x", srcRoot)
213213
}
@@ -326,7 +326,7 @@ func testIterativeDelayedStateSync(t *testing.T, scheme string) {
326326
for i := 0; i < len(codes); i++ {
327327
codeElements = append(codeElements, stateElement{code: codes[i]})
328328
}
329-
reader, err := ndb.Reader(srcRoot)
329+
reader, err := ndb.NodeReader(srcRoot)
330330
if err != nil {
331331
t.Fatalf("state is not existent, %#x", srcRoot)
332332
}
@@ -430,7 +430,7 @@ func testIterativeRandomStateSync(t *testing.T, count int, scheme string) {
430430
for _, hash := range codes {
431431
codeQueue[hash] = struct{}{}
432432
}
433-
reader, err := ndb.Reader(srcRoot)
433+
reader, err := ndb.NodeReader(srcRoot)
434434
if err != nil {
435435
t.Fatalf("state is not existent, %#x", srcRoot)
436436
}
@@ -523,7 +523,7 @@ func testIterativeRandomDelayedStateSync(t *testing.T, scheme string) {
523523
for _, hash := range codes {
524524
codeQueue[hash] = struct{}{}
525525
}
526-
reader, err := ndb.Reader(srcRoot)
526+
reader, err := ndb.NodeReader(srcRoot)
527527
if err != nil {
528528
t.Fatalf("state is not existent, %#x", srcRoot)
529529
}
@@ -628,7 +628,7 @@ func testIncompleteStateSync(t *testing.T, scheme string) {
628628
addedPaths []string
629629
addedHashes []common.Hash
630630
)
631-
reader, err := ndb.Reader(srcRoot)
631+
reader, err := ndb.NodeReader(srcRoot)
632632
if err != nil {
633633
t.Fatalf("state is not available %x", srcRoot)
634634
}

eth/handler.go

-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
"github.com/ethereum/go-ethereum/common"
2828
"github.com/ethereum/go-ethereum/core"
2929
"github.com/ethereum/go-ethereum/core/forkid"
30-
"github.com/ethereum/go-ethereum/core/rawdb"
3130
"github.com/ethereum/go-ethereum/core/txpool"
3231
"github.com/ethereum/go-ethereum/core/types"
3332
"github.com/ethereum/go-ethereum/crypto"
@@ -41,7 +40,6 @@ import (
4140
"github.com/ethereum/go-ethereum/metrics"
4241
"github.com/ethereum/go-ethereum/p2p"
4342
"github.com/ethereum/go-ethereum/p2p/enode"
44-
"github.com/ethereum/go-ethereum/triedb/pathdb"
4543
)
4644

4745
const (
@@ -558,7 +556,4 @@ func (h *handler) enableSyncedFeatures() {
558556
log.Info("Snap sync complete, auto disabling")
559557
h.snapSync.Store(false)
560558
}
561-
if h.chain.TrieDB().Scheme() == rawdb.PathScheme {
562-
h.chain.TrieDB().SetBufferSize(pathdb.DefaultBufferSize)
563-
}
564559
}

eth/protocols/snap/sync_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,7 @@ func makeAccountTrieNoStorage(n int, scheme string) (string, *trie.Trie, []*kv)
15151515
// Commit the state changes into db and re-create the trie
15161516
// for accessing later.
15171517
root, nodes := accTrie.Commit(false)
1518-
db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
1518+
db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), triedb.NewStateSet())
15191519

15201520
accTrie, _ = trie.New(trie.StateTrieID(root), db)
15211521
return db.Scheme(), accTrie, entries
@@ -1577,7 +1577,7 @@ func makeBoundaryAccountTrie(scheme string, n int) (string, *trie.Trie, []*kv) {
15771577
// Commit the state changes into db and re-create the trie
15781578
// for accessing later.
15791579
root, nodes := accTrie.Commit(false)
1580-
db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
1580+
db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), triedb.NewStateSet())
15811581

15821582
accTrie, _ = trie.New(trie.StateTrieID(root), db)
15831583
return db.Scheme(), accTrie, entries
@@ -1626,7 +1626,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(scheme string, accounts, slots
16261626
nodes.Merge(set)
16271627

16281628
// Commit gathered dirty nodes into database
1629-
db.Update(root, types.EmptyRootHash, 0, nodes, nil)
1629+
db.Update(root, types.EmptyRootHash, 0, nodes, triedb.NewStateSet())
16301630

16311631
// Re-create tries with new root
16321632
accTrie, _ = trie.New(trie.StateTrieID(root), db)
@@ -1693,7 +1693,7 @@ func makeAccountTrieWithStorage(scheme string, accounts, slots int, code, bounda
16931693
nodes.Merge(set)
16941694

16951695
// Commit gathered dirty nodes into database
1696-
db.Update(root, types.EmptyRootHash, 0, nodes, nil)
1696+
db.Update(root, types.EmptyRootHash, 0, nodes, triedb.NewStateSet())
16971697

16981698
// Re-create tries with new root
16991699
accTrie, err := trie.New(trie.StateTrieID(root), db)

trie/database_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func newTestDatabase(diskdb ethdb.Database, scheme string) *testDb {
7373
}
7474
}
7575

76-
func (db *testDb) Reader(stateRoot common.Hash) (database.Reader, error) {
76+
func (db *testDb) NodeReader(stateRoot common.Hash) (database.NodeReader, error) {
7777
nodes, _ := db.dirties(stateRoot, true)
7878
return &testReader{db: db.disk, scheme: db.scheme, nodes: nodes}, nil
7979
}

trie/iterator_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func testNodeIteratorCoverage(t *testing.T, scheme string) {
146146
}
147147
}
148148
// Cross check the hashes and the database itself
149-
reader, err := nodeDb.Reader(trie.Hash())
149+
reader, err := nodeDb.NodeReader(trie.Hash())
150150
if err != nil {
151151
t.Fatalf("state is not available %x", trie.Hash())
152152
}

trie/secure_trie.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ type SecureTrie = StateTrie
4040

4141
// NewSecure creates a new StateTrie.
4242
// Deprecated: use NewStateTrie.
43-
func NewSecure(stateRoot common.Hash, owner common.Hash, root common.Hash, db database.Database) (*SecureTrie, error) {
43+
func NewSecure(stateRoot common.Hash, owner common.Hash, root common.Hash, db database.NodeDatabase) (*SecureTrie, error) {
4444
id := &ID{
4545
StateRoot: stateRoot,
4646
Owner: owner,
@@ -61,7 +61,7 @@ func NewSecure(stateRoot common.Hash, owner common.Hash, root common.Hash, db da
6161
// StateTrie is not safe for concurrent use.
6262
type StateTrie struct {
6363
trie Trie
64-
db database.Database
64+
db database.NodeDatabase
6565
preimages preimageStore
6666
hashKeyBuf [common.HashLength]byte
6767
secKeyCache map[string][]byte
@@ -73,7 +73,7 @@ type StateTrie struct {
7373
// If root is the zero hash or the sha3 hash of an empty string, the
7474
// trie is initially empty. Otherwise, New will panic if db is nil
7575
// and returns MissingNodeError if the root node cannot be found.
76-
func NewStateTrie(id *ID, db database.Database) (*StateTrie, error) {
76+
func NewStateTrie(id *ID, db database.NodeDatabase) (*StateTrie, error) {
7777
if db == nil {
7878
panic("trie.NewStateTrie called without a database")
7979
}

trie/sync_test.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ func testIterativeSync(t *testing.T, count int, bypath bool, scheme string) {
183183
syncPath: NewSyncPath([]byte(paths[i])),
184184
})
185185
}
186-
reader, err := srcDb.Reader(srcTrie.Hash())
186+
reader, err := srcDb.NodeReader(srcTrie.Hash())
187187
if err != nil {
188188
t.Fatalf("State is not available %x", srcTrie.Hash())
189189
}
@@ -258,7 +258,7 @@ func testIterativeDelayedSync(t *testing.T, scheme string) {
258258
syncPath: NewSyncPath([]byte(paths[i])),
259259
})
260260
}
261-
reader, err := srcDb.Reader(srcTrie.Hash())
261+
reader, err := srcDb.NodeReader(srcTrie.Hash())
262262
if err != nil {
263263
t.Fatalf("State is not available %x", srcTrie.Hash())
264264
}
@@ -327,7 +327,7 @@ func testIterativeRandomSync(t *testing.T, count int, scheme string) {
327327
syncPath: NewSyncPath([]byte(paths[i])),
328328
}
329329
}
330-
reader, err := srcDb.Reader(srcTrie.Hash())
330+
reader, err := srcDb.NodeReader(srcTrie.Hash())
331331
if err != nil {
332332
t.Fatalf("State is not available %x", srcTrie.Hash())
333333
}
@@ -394,7 +394,7 @@ func testIterativeRandomDelayedSync(t *testing.T, scheme string) {
394394
syncPath: NewSyncPath([]byte(path)),
395395
}
396396
}
397-
reader, err := srcDb.Reader(srcTrie.Hash())
397+
reader, err := srcDb.NodeReader(srcTrie.Hash())
398398
if err != nil {
399399
t.Fatalf("State is not available %x", srcTrie.Hash())
400400
}
@@ -466,7 +466,7 @@ func testDuplicateAvoidanceSync(t *testing.T, scheme string) {
466466
syncPath: NewSyncPath([]byte(paths[i])),
467467
})
468468
}
469-
reader, err := srcDb.Reader(srcTrie.Hash())
469+
reader, err := srcDb.NodeReader(srcTrie.Hash())
470470
if err != nil {
471471
t.Fatalf("State is not available %x", srcTrie.Hash())
472472
}
@@ -542,7 +542,7 @@ func testIncompleteSync(t *testing.T, scheme string) {
542542
syncPath: NewSyncPath([]byte(paths[i])),
543543
})
544544
}
545-
reader, err := srcDb.Reader(srcTrie.Hash())
545+
reader, err := srcDb.NodeReader(srcTrie.Hash())
546546
if err != nil {
547547
t.Fatalf("State is not available %x", srcTrie.Hash())
548548
}
@@ -634,7 +634,7 @@ func testSyncOrdering(t *testing.T, scheme string) {
634634
})
635635
reqs = append(reqs, NewSyncPath([]byte(paths[i])))
636636
}
637-
reader, err := srcDb.Reader(srcTrie.Hash())
637+
reader, err := srcDb.NodeReader(srcTrie.Hash())
638638
if err != nil {
639639
t.Fatalf("State is not available %x", srcTrie.Hash())
640640
}
@@ -704,7 +704,7 @@ func syncWithHookWriter(t *testing.T, root common.Hash, db ethdb.Database, srcDb
704704
syncPath: NewSyncPath([]byte(paths[i])),
705705
})
706706
}
707-
reader, err := srcDb.Reader(root)
707+
reader, err := srcDb.NodeReader(root)
708708
if err != nil {
709709
t.Fatalf("State is not available %x", root)
710710
}

trie/trie.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func (t *Trie) Copy() *Trie {
8383
// zero hash or the sha3 hash of an empty string, then trie is initially
8484
// empty, otherwise, the root node must be present in database or returns
8585
// a MissingNodeError if not.
86-
func New(id *ID, db database.Database) (*Trie, error) {
86+
func New(id *ID, db database.NodeDatabase) (*Trie, error) {
8787
reader, err := newTrieReader(id.StateRoot, id.Owner, db)
8888
if err != nil {
8989
return nil, err
@@ -104,7 +104,7 @@ func New(id *ID, db database.Database) (*Trie, error) {
104104
}
105105

106106
// NewEmpty is a shortcut to create empty tree. It's mostly used in tests.
107-
func NewEmpty(db database.Database) *Trie {
107+
func NewEmpty(db database.NodeDatabase) *Trie {
108108
tr, _ := New(TrieID(types.EmptyRootHash), db)
109109
return tr
110110
}

trie/trie_reader.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ import (
2727
// for concurrent usage.
2828
type trieReader struct {
2929
owner common.Hash
30-
reader database.Reader
30+
reader database.NodeReader
3131
banned map[string]struct{} // Marker to prevent node from being accessed, for tests
3232
}
3333

3434
// newTrieReader initializes the trie reader with the given node reader.
35-
func newTrieReader(stateRoot, owner common.Hash, db database.Database) (*trieReader, error) {
35+
func newTrieReader(stateRoot, owner common.Hash, db database.NodeDatabase) (*trieReader, error) {
3636
if stateRoot == (common.Hash{}) || stateRoot == types.EmptyRootHash {
3737
if stateRoot == (common.Hash{}) {
3838
log.Error("Zero state root hash!")
3939
}
4040
return &trieReader{owner: owner}, nil
4141
}
42-
reader, err := db.Reader(stateRoot)
42+
reader, err := db.NodeReader(stateRoot)
4343
if err != nil {
4444
return nil, &MissingNodeError{Owner: owner, NodeHash: stateRoot, err: err}
4545
}
@@ -55,6 +55,9 @@ func newEmptyReader() *trieReader {
5555
// node retrieves the rlp-encoded trie node with the provided trie node
5656
// information. An MissingNodeError will be returned in case the node is
5757
// not found or any error is encountered.
58+
//
59+
// Don't modify the returned byte slice since it's not deep-copied and
60+
// still be referenced by database.
5861
func (r *trieReader) node(path []byte, hash common.Hash) ([]byte, error) {
5962
// Perform the logics in tests for preventing trie node access.
6063
if r.banned != nil {

trie/trienode/node.go

+9
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,15 @@ func (set *NodeSet) Size() (int, int) {
153153
return set.updates, set.deletes
154154
}
155155

156+
// HashSet returns a set of trie nodes keyed by node hash.
157+
func (set *NodeSet) HashSet() map[common.Hash][]byte {
158+
ret := make(map[common.Hash][]byte, len(set.Nodes))
159+
for _, n := range set.Nodes {
160+
ret[n.Hash] = n.Blob
161+
}
162+
return ret
163+
}
164+
156165
// Summary returns a string-representation of the NodeSet.
157166
func (set *NodeSet) Summary() string {
158167
var out = new(strings.Builder)

0 commit comments

Comments
 (0)