@@ -22,6 +22,7 @@ import (
22
22
"encoding/binary"
23
23
24
24
"github.com/ethereum/go-ethereum/common"
25
+ "github.com/ethereum/go-ethereum/crypto"
25
26
"github.com/ethereum/go-ethereum/metrics"
26
27
)
27
28
@@ -248,3 +249,52 @@ func accountTrieNodeKey(path []byte) []byte {
248
249
func storageTrieNodeKey (accountHash common.Hash , path []byte ) []byte {
249
250
return append (append (trieNodeStoragePrefix , accountHash .Bytes ()... ), path ... )
250
251
}
252
+
253
+ // IsLegacyTrieNode reports whether a provided database entry is a legacy trie
254
+ // node. The characteristics of legacy trie node are:
255
+ // - the key length is 32 bytes
256
+ // - the key is the hash of val
257
+ func IsLegacyTrieNode (key []byte , val []byte ) bool {
258
+ if len (key ) != common .HashLength {
259
+ return false
260
+ }
261
+ return bytes .Equal (key , crypto .Keccak256 (val ))
262
+ }
263
+
264
+ // IsAccountTrieNode reports whether a provided database entry is an account
265
+ // trie node in path-based state scheme.
266
+ func IsAccountTrieNode (key []byte ) (bool , []byte ) {
267
+ if ! bytes .HasPrefix (key , trieNodeAccountPrefix ) {
268
+ return false , nil
269
+ }
270
+ // The remaining key should only consist a hex node path
271
+ // whose length is in the range 0 to 64 (64 is excluded
272
+ // since leaves are always embedded in parent).
273
+ remain := key [len (trieNodeAccountPrefix ):]
274
+ if len (remain ) >= common .HashLength * 2 {
275
+ return false , nil
276
+ }
277
+ return true , remain
278
+ }
279
+
280
+ // IsStorageTrieNode reports whether a provided database entry is a storage
281
+ // trie node in path-based state scheme.
282
+ func IsStorageTrieNode (key []byte ) (bool , common.Hash , []byte ) {
283
+ if ! bytes .HasPrefix (key , trieNodeStoragePrefix ) {
284
+ return false , common.Hash {}, nil
285
+ }
286
+ // The remaining key consists of 2 parts:
287
+ // - 32 bytes account hash
288
+ // - hex node path whose length is in the range 0 to 64
289
+ remain := key [len (trieNodeStoragePrefix ):]
290
+ if len (remain ) < common .HashLength {
291
+ return false , common.Hash {}, nil
292
+ }
293
+ accountHash := common .BytesToHash (remain [:common .HashLength ])
294
+ remain = remain [common .HashLength :]
295
+
296
+ if len (remain ) >= common .HashLength * 2 {
297
+ return false , common.Hash {}, nil
298
+ }
299
+ return true , accountHash , remain
300
+ }
0 commit comments