Skip to content

Commit a4abc14

Browse files
authored
chore(core/rawdb): add ExampleInspectDatabase to check custom behavior (#790)
1 parent bd1aabe commit a4abc14

File tree

4 files changed

+137
-6
lines changed

4 files changed

+137
-6
lines changed

core/rawdb/accessors_state_sync.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func NewSyncSegmentsIterator(db ethdb.Iteratee, root common.Hash) ethdb.Iterator
7777
}
7878

7979
// WriteSyncSegment adds a trie segment for root at the given start position.
80-
func WriteSyncSegment(db ethdb.KeyValueWriter, root common.Hash, start []byte) error {
80+
func WriteSyncSegment(db ethdb.KeyValueWriter, root common.Hash, start common.Hash) error {
8181
return db.Put(packSyncSegmentKey(root, start), []byte{0x01})
8282
}
8383

@@ -104,11 +104,11 @@ func UnpackSyncSegmentKey(keyBytes []byte) (common.Hash, []byte) {
104104
}
105105

106106
// packSyncSegmentKey packs root and account into a key for storage in db.
107-
func packSyncSegmentKey(root common.Hash, start []byte) []byte {
108-
bytes := make([]byte, len(syncSegmentsPrefix)+common.HashLength+len(start))
107+
func packSyncSegmentKey(root common.Hash, start common.Hash) []byte {
108+
bytes := make([]byte, syncSegmentsKeyLength)
109109
copy(bytes, syncSegmentsPrefix)
110110
copy(bytes[len(syncSegmentsPrefix):], root[:])
111-
copy(bytes[len(syncSegmentsPrefix)+common.HashLength:], start)
111+
copy(bytes[len(syncSegmentsPrefix)+common.HashLength:], start.Bytes())
112112
return bytes
113113
}
114114

core/rawdb/accessors_state_sync_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func TestClearPrefix(t *testing.T) {
1414
require := require.New(t)
1515
db := NewMemoryDatabase()
1616
// add a key that should be cleared
17-
require.NoError(WriteSyncSegment(db, common.Hash{1}, common.Hash{}.Bytes()))
17+
require.NoError(WriteSyncSegment(db, common.Hash{1}, common.Hash{}))
1818

1919
// add a key that should not be cleared
2020
key := append(syncSegmentsPrefix, []byte("foo")...)

core/rawdb/database_ext_test.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package rawdb
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/ava-labs/libevm/common"
7+
"github.com/ava-labs/libevm/ethdb"
8+
)
9+
10+
func ExampleInspectDatabase() {
11+
db := &stubDatabase{
12+
iterator: &stubIterator{},
13+
}
14+
15+
// Extra metadata keys: (17 + 32) + (12 + 32) = 93 bytes
16+
WriteSnapshotBlockHash(db, common.Hash{})
17+
WriteSnapshotRoot(db, common.Hash{})
18+
// Trie segments: (77 + 2) + 1 = 80 bytes
19+
_ = WriteSyncSegment(db, common.Hash{}, common.Hash{})
20+
// Storage tries to fetch: 76 + 1 = 77 bytes
21+
_ = WriteSyncStorageTrie(db, common.Hash{}, common.Hash{})
22+
// Code to fetch: 34 + 0 = 34 bytes
23+
AddCodeToFetch(db, common.Hash{})
24+
// Block numbers synced to: 22 + 1 = 23 bytes
25+
_ = WriteSyncPerformed(db, 0)
26+
27+
keyPrefix := []byte(nil)
28+
keyStart := []byte(nil)
29+
30+
err := InspectDatabase(db, keyPrefix, keyStart)
31+
if err != nil {
32+
fmt.Println(err)
33+
}
34+
// Output:
35+
// +-----------------+-------------------------+----------+-------+
36+
// | DATABASE | CATEGORY | SIZE | ITEMS |
37+
// +-----------------+-------------------------+----------+-------+
38+
// | Key-Value store | Headers | 0.00 B | 0 |
39+
// | Key-Value store | Bodies | 0.00 B | 0 |
40+
// | Key-Value store | Receipt lists | 0.00 B | 0 |
41+
// | Key-Value store | Block number->hash | 0.00 B | 0 |
42+
// | Key-Value store | Block hash->number | 0.00 B | 0 |
43+
// | Key-Value store | Transaction index | 0.00 B | 0 |
44+
// | Key-Value store | Bloombit index | 0.00 B | 0 |
45+
// | Key-Value store | Contract codes | 0.00 B | 0 |
46+
// | Key-Value store | Hash trie nodes | 0.00 B | 0 |
47+
// | Key-Value store | Path trie state lookups | 0.00 B | 0 |
48+
// | Key-Value store | Path trie account nodes | 0.00 B | 0 |
49+
// | Key-Value store | Path trie storage nodes | 0.00 B | 0 |
50+
// | Key-Value store | Trie preimages | 0.00 B | 0 |
51+
// | Key-Value store | Account snapshot | 0.00 B | 0 |
52+
// | Key-Value store | Storage snapshot | 0.00 B | 0 |
53+
// | Key-Value store | Clique snapshots | 0.00 B | 0 |
54+
// | Key-Value store | Singleton metadata | 93.00 B | 2 |
55+
// | Light client | CHT trie nodes | 0.00 B | 0 |
56+
// | Light client | Bloom trie nodes | 0.00 B | 0 |
57+
// | State sync | Trie segments | 78.00 B | 1 |
58+
// | State sync | Storage tries to fetch | 77.00 B | 1 |
59+
// | State sync | Code to fetch | 34.00 B | 1 |
60+
// | State sync | Block numbers synced to | 23.00 B | 1 |
61+
// +-----------------+-------------------------+----------+-------+
62+
// | TOTAL | 305.00 B | |
63+
// +-----------------+-------------------------+----------+-------+
64+
}
65+
66+
type stubDatabase struct {
67+
ethdb.Database
68+
iterator *stubIterator
69+
}
70+
71+
func (s *stubDatabase) NewIterator(keyPrefix, keyStart []byte) ethdb.Iterator {
72+
return s.iterator
73+
}
74+
75+
// AncientSize is used in [InspectDatabase] to determine the ancient sizes.
76+
func (s *stubDatabase) AncientSize(kind string) (uint64, error) {
77+
return 0, nil
78+
}
79+
80+
func (s *stubDatabase) Ancients() (uint64, error) {
81+
return 0, nil
82+
}
83+
84+
func (s *stubDatabase) Tail() (uint64, error) {
85+
return 0, nil
86+
}
87+
88+
func (s *stubDatabase) Put(key, value []byte) error {
89+
s.iterator.kvs = append(s.iterator.kvs, keyValue{key: key, value: value})
90+
return nil
91+
}
92+
93+
func (s *stubDatabase) Get(key []byte) ([]byte, error) {
94+
return nil, nil
95+
}
96+
97+
func (s *stubDatabase) ReadAncients(fn func(ethdb.AncientReaderOp) error) error {
98+
return nil
99+
}
100+
101+
type stubIterator struct {
102+
ethdb.Iterator
103+
i int // see [stubIterator.pos]
104+
kvs []keyValue
105+
}
106+
107+
type keyValue struct {
108+
key []byte
109+
value []byte
110+
}
111+
112+
// pos returns the true iterator position, which is otherwise off by one because
113+
// Next() is called _before_ usage.
114+
func (s *stubIterator) pos() int {
115+
return s.i - 1
116+
}
117+
118+
func (s *stubIterator) Next() bool {
119+
s.i++
120+
return s.pos() < len(s.kvs)
121+
}
122+
123+
func (s *stubIterator) Release() {}
124+
125+
func (s *stubIterator) Key() []byte {
126+
return s.kvs[s.pos()].key
127+
}
128+
129+
func (s *stubIterator) Value() []byte {
130+
return s.kvs[s.pos()].value
131+
}

sync/statesync/trie_segments.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func (t *trieToSync) createSegments(numSegments int) error {
301301

302302
// create the segments
303303
segment := t.addSegment(startBytes, endBytes)
304-
if err := rawdb.WriteSyncSegment(t.sync.db, t.root, segment.start); err != nil {
304+
if err := rawdb.WriteSyncSegment(t.sync.db, t.root, common.BytesToHash(segment.start)); err != nil {
305305
return err
306306
}
307307
}

0 commit comments

Comments
 (0)