triedb/pathdb: update

This commit is contained in:
Gary Rong 2025-05-27 11:45:49 +08:00
parent 602890ba43
commit 8f9c277fe9
2 changed files with 21 additions and 3 deletions

View file

@ -202,6 +202,10 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
for i := 0; i < len(list); i++ { for i := 0; i < len(list); i++ {
if list[i] == state { if list[i] == state {
if i == 0 { if i == 0 {
// Remove the first element by shifting the slice forward.
// Pros: zero-copy.
// Cons: may retain large backing array, causing memory leaks.
// Mitigation: release the array if capacity exceeds threshold.
list = list[1:] list = list[1:]
if cap(list) > 1024 { if cap(list) > 1024 {
list = append(make([]common.Hash, 0, len(list)), list...) list = append(make([]common.Hash, 0, len(list)), list...)
@ -241,6 +245,10 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
for i := 0; i < len(list); i++ { for i := 0; i < len(list); i++ {
if list[i] == state { if list[i] == state {
if i == 0 { if i == 0 {
// Remove the first element by shifting the slice forward.
// Pros: zero-copy.
// Cons: may retain large backing array, causing memory leaks.
// Mitigation: release the array if capacity exceeds threshold.
list = list[1:] list = list[1:]
if cap(list) > 1024 { if cap(list) > 1024 {
list = append(make([]common.Hash, 0, len(list)), list...) list = append(make([]common.Hash, 0, len(list)), list...)

View file

@ -103,7 +103,12 @@ func (r *reader) AccountRLP(hash common.Hash) ([]byte, error) {
} }
// If the located layer is stale, fall back to the slow path to retrieve // If the located layer is stale, fall back to the slow path to retrieve
// the account data. This is an edge case where the located layer is the // the account data. This is an edge case where the located layer is the
// disk layer, and it becomes stale within a very short time window. // disk layer (e.g., the requested account was not changed in all the diff
// layers), and it becomes stale within a very short time window.
//
// This fallback mechanism is essential, because the traversal starts from
// the entry point layer and goes down, the staleness of the disk layer does
// not affect the result unless the entry point layer is also stale.
blob, err := l.account(hash, 0) blob, err := l.account(hash, 0)
if errors.Is(err, errSnapshotStale) { if errors.Is(err, errSnapshotStale) {
return r.layer.account(hash, 0) return r.layer.account(hash, 0)
@ -146,8 +151,13 @@ func (r *reader) Storage(accountHash, storageHash common.Hash) ([]byte, error) {
return nil, err return nil, err
} }
// If the located layer is stale, fall back to the slow path to retrieve // If the located layer is stale, fall back to the slow path to retrieve
// the account data. This is an edge case where the located layer is the // the storage data. This is an edge case where the located layer is the
// disk layer, and it becomes stale within a very short time window. // disk layer (e.g., the requested account was not changed in all the diff
// layers), and it becomes stale within a very short time window.
//
// This fallback mechanism is essential, because the traversal starts from
// the entry point layer and goes down, the staleness of the disk layer does
// not affect the result unless the entry point layer is also stale.
blob, err := l.storage(accountHash, storageHash, 0) blob, err := l.storage(accountHash, storageHash, 0)
if errors.Is(err, errSnapshotStale) { if errors.Is(err, errSnapshotStale) {
return r.layer.storage(accountHash, storageHash, 0) return r.layer.storage(accountHash, storageHash, 0)