Skip to content

Commit 9f96e07

Browse files
authored
core/rawdb, trie: improve db APIs for accessing trie nodes (#29362)
* core/rawdb, trie: improve db APIs for accessing trie nodes * triedb/pathdb: fix
1 parent f8820f1 commit 9f96e07

File tree

24 files changed

+141
-180
lines changed

24 files changed

+141
-180
lines changed

cmd/devp2p/internal/ethtest/snap.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import (
3232
"github.com/ethereum/go-ethereum/internal/utesting"
3333
"github.com/ethereum/go-ethereum/trie"
3434
"github.com/ethereum/go-ethereum/trie/trienode"
35-
"golang.org/x/crypto/sha3"
3635
)
3736

3837
func (c *Conn) snapRequest(code uint64, msg any) (any, error) {
@@ -905,7 +904,7 @@ func (s *Suite) snapGetByteCodes(t *utesting.T, tc *byteCodesTest) error {
905904
// that the serving node is missing
906905
var (
907906
bytecodes = res.Codes
908-
hasher = sha3.NewLegacyKeccak256().(crypto.KeccakState)
907+
hasher = crypto.NewKeccakState()
909908
hash = make([]byte, 32)
910909
codes = make([][]byte, len(req.Hashes))
911910
)
@@ -964,7 +963,7 @@ func (s *Suite) snapGetTrieNodes(t *utesting.T, tc *trieNodesTest) error {
964963

965964
// Cross reference the requested trienodes with the response to find gaps
966965
// that the serving node is missing
967-
hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
966+
hasher := crypto.NewKeccakState()
968967
hash := make([]byte, 32)
969968
trienodes := res.Nodes
970969
if got, want := len(trienodes), len(tc.expHashes); got != want {

cmd/geth/dbcmd.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,17 @@ func removeDB(ctx *cli.Context) error {
246246
ancientDir = config.Node.ResolvePath(ancientDir)
247247
}
248248
// Delete state data
249-
statePaths := []string{rootDir, filepath.Join(ancientDir, rawdb.StateFreezerName)}
249+
statePaths := []string{
250+
rootDir,
251+
filepath.Join(ancientDir, rawdb.StateFreezerName),
252+
}
250253
confirmAndRemoveDB(statePaths, "state data", ctx, removeStateDataFlag.Name)
251254

252255
// Delete ancient chain
253-
chainPaths := []string{filepath.Join(ancientDir, rawdb.ChainFreezerName)}
256+
chainPaths := []string{filepath.Join(
257+
ancientDir,
258+
rawdb.ChainFreezerName,
259+
)}
254260
confirmAndRemoveDB(chainPaths, "ancient chain", ctx, removeChainDataFlag.Name)
255261
return nil
256262
}

core/genesis_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ func TestVerkleGenesisCommit(t *testing.T) {
322322
t.Fatalf("expected trie to be verkle")
323323
}
324324

325-
if !rawdb.ExistsAccountTrieNode(db, nil) {
325+
if !rawdb.HasAccountTrieNode(db, nil) {
326326
t.Fatal("could not find node")
327327
}
328328
}

core/rawdb/accessors_trie.go

Lines changed: 41 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"github.com/ethereum/go-ethereum/crypto"
2525
"github.com/ethereum/go-ethereum/ethdb"
2626
"github.com/ethereum/go-ethereum/log"
27-
"golang.org/x/crypto/sha3"
2827
)
2928

3029
// HashScheme is the legacy hash-based state scheme with which trie nodes are
@@ -50,7 +49,7 @@ const PathScheme = "path"
5049
type hasher struct{ sha crypto.KeccakState }
5150

5251
var hasherPool = sync.Pool{
53-
New: func() interface{} { return &hasher{sha: sha3.NewLegacyKeccak256().(crypto.KeccakState)} },
52+
New: func() interface{} { return &hasher{sha: crypto.NewKeccakState()} },
5453
}
5554

5655
func newHasher() *hasher {
@@ -65,33 +64,15 @@ func (h *hasher) release() {
6564
hasherPool.Put(h)
6665
}
6766

68-
// ReadAccountTrieNode retrieves the account trie node and the associated node
69-
// hash with the specified node path.
70-
func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) ([]byte, common.Hash) {
71-
data, err := db.Get(accountTrieNodeKey(path))
72-
if err != nil {
73-
return nil, common.Hash{}
74-
}
75-
h := newHasher()
76-
defer h.release()
77-
return data, h.hash(data)
78-
}
79-
80-
// HasAccountTrieNode checks the account trie node presence with the specified
81-
// node path and the associated node hash.
82-
func HasAccountTrieNode(db ethdb.KeyValueReader, path []byte, hash common.Hash) bool {
83-
data, err := db.Get(accountTrieNodeKey(path))
84-
if err != nil {
85-
return false
86-
}
87-
h := newHasher()
88-
defer h.release()
89-
return h.hash(data) == hash
67+
// ReadAccountTrieNode retrieves the account trie node with the specified node path.
68+
func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) []byte {
69+
data, _ := db.Get(accountTrieNodeKey(path))
70+
return data
9071
}
9172

92-
// ExistsAccountTrieNode checks the presence of the account trie node with the
73+
// HasAccountTrieNode checks the presence of the account trie node with the
9374
// specified node path, regardless of the node hash.
94-
func ExistsAccountTrieNode(db ethdb.KeyValueReader, path []byte) bool {
75+
func HasAccountTrieNode(db ethdb.KeyValueReader, path []byte) bool {
9576
has, err := db.Has(accountTrieNodeKey(path))
9677
if err != nil {
9778
return false
@@ -113,33 +94,15 @@ func DeleteAccountTrieNode(db ethdb.KeyValueWriter, path []byte) {
11394
}
11495
}
11596

116-
// ReadStorageTrieNode retrieves the storage trie node and the associated node
117-
// hash with the specified node path.
118-
func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) ([]byte, common.Hash) {
119-
data, err := db.Get(storageTrieNodeKey(accountHash, path))
120-
if err != nil {
121-
return nil, common.Hash{}
122-
}
123-
h := newHasher()
124-
defer h.release()
125-
return data, h.hash(data)
126-
}
127-
128-
// HasStorageTrieNode checks the storage trie node presence with the provided
129-
// node path and the associated node hash.
130-
func HasStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte, hash common.Hash) bool {
131-
data, err := db.Get(storageTrieNodeKey(accountHash, path))
132-
if err != nil {
133-
return false
134-
}
135-
h := newHasher()
136-
defer h.release()
137-
return h.hash(data) == hash
97+
// ReadStorageTrieNode retrieves the storage trie node with the specified node path.
98+
func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) []byte {
99+
data, _ := db.Get(storageTrieNodeKey(accountHash, path))
100+
return data
138101
}
139102

140-
// ExistsStorageTrieNode checks the presence of the storage trie node with the
103+
// HasStorageTrieNode checks the presence of the storage trie node with the
141104
// specified account hash and node path, regardless of the node hash.
142-
func ExistsStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) bool {
105+
func HasStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) bool {
143106
has, err := db.Has(storageTrieNodeKey(accountHash, path))
144107
if err != nil {
145108
return false
@@ -198,54 +161,54 @@ func HasTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash c
198161
case HashScheme:
199162
return HasLegacyTrieNode(db, hash)
200163
case PathScheme:
164+
var blob []byte
201165
if owner == (common.Hash{}) {
202-
return HasAccountTrieNode(db, path, hash)
166+
blob = ReadAccountTrieNode(db, path)
167+
} else {
168+
blob = ReadStorageTrieNode(db, owner, path)
203169
}
204-
return HasStorageTrieNode(db, owner, path, hash)
170+
if len(blob) == 0 {
171+
return false
172+
}
173+
h := newHasher()
174+
defer h.release()
175+
return h.hash(blob) == hash // exists but not match
205176
default:
206177
panic(fmt.Sprintf("Unknown scheme %v", scheme))
207178
}
208179
}
209180

210181
// ReadTrieNode retrieves the trie node from database with the provided node info
211182
// and associated node hash.
212-
// hashScheme-based lookup requires the following:
213-
// - hash
214-
//
215-
// pathScheme-based lookup requires the following:
216-
// - owner
217-
// - path
218183
func ReadTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash common.Hash, scheme string) []byte {
219184
switch scheme {
220185
case HashScheme:
221186
return ReadLegacyTrieNode(db, hash)
222187
case PathScheme:
223-
var (
224-
blob []byte
225-
nHash common.Hash
226-
)
188+
var blob []byte
227189
if owner == (common.Hash{}) {
228-
blob, nHash = ReadAccountTrieNode(db, path)
190+
blob = ReadAccountTrieNode(db, path)
229191
} else {
230-
blob, nHash = ReadStorageTrieNode(db, owner, path)
192+
blob = ReadStorageTrieNode(db, owner, path)
231193
}
232-
if nHash != hash {
194+
if len(blob) == 0 {
233195
return nil
234196
}
197+
h := newHasher()
198+
defer h.release()
199+
if h.hash(blob) != hash {
200+
return nil // exists but not match
201+
}
235202
return blob
236203
default:
237204
panic(fmt.Sprintf("Unknown scheme %v", scheme))
238205
}
239206
}
240207

241-
// WriteTrieNode writes the trie node into database with the provided node info
242-
// and associated node hash.
243-
// hashScheme-based lookup requires the following:
244-
// - hash
208+
// WriteTrieNode writes the trie node into database with the provided node info.
245209
//
246-
// pathScheme-based lookup requires the following:
247-
// - owner
248-
// - path
210+
// hash-scheme requires the node hash as the identifier.
211+
// path-scheme requires the node owner and path as the identifier.
249212
func WriteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, hash common.Hash, node []byte, scheme string) {
250213
switch scheme {
251214
case HashScheme:
@@ -261,14 +224,10 @@ func WriteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, hash
261224
}
262225
}
263226

264-
// DeleteTrieNode deletes the trie node from database with the provided node info
265-
// and associated node hash.
266-
// hashScheme-based lookup requires the following:
267-
// - hash
227+
// DeleteTrieNode deletes the trie node from database with the provided node info.
268228
//
269-
// pathScheme-based lookup requires the following:
270-
// - owner
271-
// - path
229+
// hash-scheme requires the node hash as the identifier.
230+
// path-scheme requires the node owner and path as the identifier.
272231
func DeleteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, hash common.Hash, scheme string) {
273232
switch scheme {
274233
case HashScheme:
@@ -287,9 +246,8 @@ func DeleteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, has
287246
// ReadStateScheme reads the state scheme of persistent state, or none
288247
// if the state is not present in database.
289248
func ReadStateScheme(db ethdb.Reader) string {
290-
// Check if state in path-based scheme is present
291-
blob, _ := ReadAccountTrieNode(db, nil)
292-
if len(blob) != 0 {
249+
// Check if state in path-based scheme is present.
250+
if HasAccountTrieNode(db, nil) {
293251
return PathScheme
294252
}
295253
// The root node might be deleted during the initial snap sync, check
@@ -304,8 +262,7 @@ func ReadStateScheme(db ethdb.Reader) string {
304262
if header == nil {
305263
return "" // empty datadir
306264
}
307-
blob = ReadLegacyTrieNode(db, header.Root)
308-
if len(blob) == 0 {
265+
if !HasLegacyTrieNode(db, header.Root) {
309266
return "" // no state in disk
310267
}
311268
return HashScheme

core/rawdb/ancient_utils.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,17 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) {
8989
infos = append(infos, info)
9090

9191
case StateFreezerName:
92-
if ReadStateScheme(db) != PathScheme {
93-
continue
94-
}
9592
datadir, err := db.AncientDatadir()
9693
if err != nil {
9794
return nil, err
9895
}
9996
f, err := NewStateFreezer(datadir, true)
10097
if err != nil {
101-
return nil, err
98+
continue // might be possible the state freezer is not existent
10299
}
103100
defer f.Close()
104101

105-
info, err := inspect(StateFreezerName, stateFreezerNoSnappy, f)
102+
info, err := inspect(freezer, stateFreezerNoSnappy, f)
106103
if err != nil {
107104
return nil, err
108105
}

eth/handler.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import (
4242
"github.com/ethereum/go-ethereum/p2p"
4343
"github.com/ethereum/go-ethereum/p2p/enode"
4444
"github.com/ethereum/go-ethereum/triedb/pathdb"
45-
"golang.org/x/crypto/sha3"
4645
)
4746

4847
const (
@@ -480,7 +479,7 @@ func (h *handler) BroadcastTransactions(txs types.Transactions) {
480479

481480
var (
482481
signer = types.LatestSignerForChainID(h.chain.Config().ChainID) // Don't care about chain status, we just need *a* sender
483-
hasher = sha3.NewLegacyKeccak256().(crypto.KeccakState)
482+
hasher = crypto.NewKeccakState()
484483
hash = make([]byte, 32)
485484
)
486485
for _, tx := range txs {

eth/protocols/snap/gentrie.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ func (t *pathTrie) deleteAccountNode(path []byte, inner bool) {
164164
} else {
165165
accountOuterLookupGauge.Inc(1)
166166
}
167-
if !rawdb.ExistsAccountTrieNode(t.db, path) {
167+
if !rawdb.HasAccountTrieNode(t.db, path) {
168168
return
169169
}
170170
if inner {
@@ -181,7 +181,7 @@ func (t *pathTrie) deleteStorageNode(path []byte, inner bool) {
181181
} else {
182182
storageOuterLookupGauge.Inc(1)
183183
}
184-
if !rawdb.ExistsStorageTrieNode(t.db, t.owner, path) {
184+
if !rawdb.HasStorageTrieNode(t.db, t.owner, path) {
185185
return
186186
}
187187
if inner {

eth/protocols/snap/sync.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import (
4242
"github.com/ethereum/go-ethereum/rlp"
4343
"github.com/ethereum/go-ethereum/trie"
4444
"github.com/ethereum/go-ethereum/trie/trienode"
45-
"golang.org/x/crypto/sha3"
4645
)
4746

4847
const (
@@ -2653,7 +2652,7 @@ func (s *Syncer) onByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) error
26532652

26542653
// Cross reference the requested bytecodes with the response to find gaps
26552654
// that the serving node is missing
2656-
hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
2655+
hasher := crypto.NewKeccakState()
26572656
hash := make([]byte, 32)
26582657

26592658
codes := make([][]byte, len(req.hashes))
@@ -2901,7 +2900,7 @@ func (s *Syncer) OnTrieNodes(peer SyncPeer, id uint64, trienodes [][]byte) error
29012900
// Cross reference the requested trienodes with the response to find gaps
29022901
// that the serving node is missing
29032902
var (
2904-
hasher = sha3.NewLegacyKeccak256().(crypto.KeccakState)
2903+
hasher = crypto.NewKeccakState()
29052904
hash = make([]byte, 32)
29062905
nodes = make([][]byte, len(req.hashes))
29072906
fills uint64
@@ -3007,7 +3006,7 @@ func (s *Syncer) onHealByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) e
30073006

30083007
// Cross reference the requested bytecodes with the response to find gaps
30093008
// that the serving node is missing
3010-
hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
3009+
hasher := crypto.NewKeccakState()
30113010
hash := make([]byte, 32)
30123011

30133012
codes := make([][]byte, len(req.hashes))

eth/protocols/snap/sync_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func TestHashing(t *testing.T) {
6464
}
6565
}
6666
var new = func() {
67-
hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
67+
hasher := crypto.NewKeccakState()
6868
var hash = make([]byte, 32)
6969
for i := 0; i < len(bytecodes); i++ {
7070
hasher.Reset()
@@ -96,7 +96,7 @@ func BenchmarkHashing(b *testing.B) {
9696
}
9797
}
9898
var new = func() {
99-
hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
99+
hasher := crypto.NewKeccakState()
100100
var hash = make([]byte, 32)
101101
for i := 0; i < len(bytecodes); i++ {
102102
hasher.Reset()

trie/hasher.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121

2222
"github.com/ethereum/go-ethereum/crypto"
2323
"github.com/ethereum/go-ethereum/rlp"
24-
"golang.org/x/crypto/sha3"
2524
)
2625

2726
// hasher is a type used for the trie Hash operation. A hasher has some
@@ -38,7 +37,7 @@ var hasherPool = sync.Pool{
3837
New: func() interface{} {
3938
return &hasher{
4039
tmp: make([]byte, 0, 550), // cap is as large as a full fullNode.
41-
sha: sha3.NewLegacyKeccak256().(crypto.KeccakState),
40+
sha: crypto.NewKeccakState(),
4241
encbuf: rlp.NewEncoderBuffer(nil),
4342
}
4443
},

0 commit comments

Comments
 (0)