refactor(core/rawdb): improve db APIs for accessing trie nodes #29362#2313
refactor(core/rawdb): improve db APIs for accessing trie nodes #29362#2313gzliudan wants to merge 2 commits intoXinFinOrg:dev-upgradefrom
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…um#27270 Move the testHasher helper to internal/blocktest/test_hash.go and update all usages to import from there. This reduces code duplication and improves maintainability.
There was a problem hiding this comment.
Pull request overview
Refactors rawdb trie-node access APIs (especially path-scheme) and consolidates test-only hashing helpers into a shared internal package.
Changes:
- Simplify path-scheme trie node accessors to return only node blobs and recompute hashes where needed.
- Centralize the test hasher implementation under
internal/blocktestand reuse it across multiple test packages. - Remove the unused
NodeSet.Hashes()helper.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
trie/trienode/node.go |
Removes unused NodeSet.Hashes() helper. |
core/rawdb/accessors_trie.go |
Refactors trie node read/has APIs and hashing helper usage for path-scheme. |
internal/blocktest/test_hash.go |
Adds shared test hasher implementation (used to avoid import cycles). |
internal/ethapi/api_test.go |
Switches to shared blocktest.NewHasher helper. |
core/types/block_test.go |
Switches benchmark block construction to shared blocktest.NewHasher. |
core/rawdb/accessors_indexes_test.go |
Switches test block construction to shared blocktest.NewHasher. |
core/rawdb/accessors_chain_test.go |
Uses shared newTestHasher() in body/block storage tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var blob []byte | ||
| if owner == (common.Hash{}) { | ||
| return HasAccountTrieNode(db, path, hash) | ||
| blob = ReadAccountTrieNode(db, path) | ||
| } else { | ||
| blob = ReadStorageTrieNode(db, owner, path) | ||
| } | ||
| return HasStorageTrieNode(db, owner, path, hash) | ||
| if len(blob) == 0 { | ||
| return false | ||
| } | ||
| h := newHasher() | ||
| defer h.release() | ||
| return h.hash(blob) == hash // exists but not match |
There was a problem hiding this comment.
In the PathScheme branch, existence is inferred via len(blob)==0 after calling Read*TrieNode (which currently ignores db.Get errors). This makes "missing" depend on the stored value length (and treats a present-but-empty value as absent) and also prevents distinguishing genuine DB read errors from NotFound. Prefer checking the db.Get error (or a boolean ok) to decide existence, then hash the returned bytes (even if empty).
| } | ||
| h := newHasher() | ||
| defer h.release() | ||
| return h.hash(blob) == hash // exists but not match |
There was a problem hiding this comment.
This inline comment is misleading: the function returns whether the computed hash matches the provided hash; it doesn't specifically indicate the "exists but not match" case. Please reword the comment (or remove it) so it describes the boolean result accurately.
| return h.hash(blob) == hash // exists but not match | |
| return h.hash(blob) == hash // whether the stored node matches the provided hash |
| // Package utesting provides a standalone replacement for package testing. | ||
| // | ||
| // This package exists because package testing cannot easily be embedded into a | ||
| // standalone go program. It provides an API that mirrors the standard library | ||
| // testing API. |
There was a problem hiding this comment.
The file-level package comment appears to be copy/pasted and refers to "Package utesting" and a replacement for the standard testing package, but this file declares package blocktest and implements a test hasher. Please update or remove this comment block so that it accurately describes the blocktest package (or move the correct package comment to a dedicated doc.go).
| // Package utesting provides a standalone replacement for package testing. | |
| // | |
| // This package exists because package testing cannot easily be embedded into a | |
| // standalone go program. It provides an API that mirrors the standard library | |
| // testing API. | |
| // Package blocktest provides helpers for block-related tests. | |
| // | |
| // In particular, it contains a lightweight hasher used for transaction and | |
| // receipt list hashing in tests without importing the trie hasher and creating | |
| // an import cycle. |
| // hasher is used to compute the sha256 hash of the provided data. | ||
| type hasher struct{ sha crypto.KeccakState } | ||
|
|
||
| var hasherPool = sync.Pool{ | ||
| New: func() interface{} { return &nodeHasher{sha: keccak.NewLegacyKeccak256().(crypto.KeccakState)} }, | ||
| New: func() interface{} { return &hasher{sha: crypto.NewKeccakState()} }, |
There was a problem hiding this comment.
The comment says this helper computes a sha256 hash, but the implementation uses Keccak (via crypto.NewKeccakState/crypto.HashData). Please update the comment (and any related naming) to avoid misleading future maintainers about the hashing algorithm used here.
|
|
||
| // ReadAccountTrieNode retrieves the account trie node with the specified node path. | ||
| func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) []byte { | ||
| data, _ := db.Get(accountTrieNodeKey(path)) |
There was a problem hiding this comment.
ReadAccountTrieNode discards the db.Get error and returns the raw data unconditionally. Downstream code uses len(data)==0 to infer absence, which changes semantics if the key exists with an empty value and also hides non-NotFound read errors. Consider returning (data, error)/(data, ok) or ensuring callers check the Get error rather than using len(data) as the existence check.
| data, _ := db.Get(accountTrieNodeKey(path)) | |
| key := accountTrieNodeKey(path) | |
| has, err := db.Has(key) | |
| if err != nil { | |
| log.Crit("Failed to check account trie node", "err", err) | |
| } | |
| if !has { | |
| return nil | |
| } | |
| data, err := db.Get(key) | |
| if err != nil { | |
| log.Crit("Failed to read account trie node", "err", err) | |
| } |
| // ReadStorageTrieNode retrieves the storage trie node with the specified node path. | ||
| func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) []byte { | ||
| data, _ := db.Get(storageTrieNodeKey(accountHash, path)) | ||
| return data |
There was a problem hiding this comment.
ReadStorageTrieNode discards the db.Get error and returns the raw data unconditionally. Callers later treat len(data)==0 as "missing", which is not equivalent to "key not found" and can also mask non-NotFound DB read failures. Consider returning (data, error)/(data, ok) or ensure callers check the Get error.
5ef7710 to
01d9676
Compare
Proposed changes
Ref: ethereum#29362
Types of changes
What types of changes does your code introduce to XDC network?
Put an
✅in the boxes that applyImpacted Components
Which parts of the codebase does this PR touch?
Put an
✅in the boxes that applyChecklist
Put an
✅in the boxes once you have confirmed below actions (or provide reasons on not doing so) that