From 36d6e742cb84c6efade621ce34288f1cc7e4bdcd Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Mon, 4 Mar 2024 12:04:55 +0800 Subject: [PATCH] triedb/pathdb: limit the meta batch size for single retrieval --- triedb/pathdb/database.go | 34 +++++++++++++++++++++++++++------- triedb/pathdb/history.go | 30 +++++++++++------------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index b1e01abac4..a4350dcbd7 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -398,14 +398,34 @@ func (db *Database) Recoverable(root common.Hash) bool { return false } // Ensure the requested state is a canonical state and all state - // histories in range [id+1, disklayer.ID] are present and complete. - return checkHistories(db.freezer, *id+1, dl.stateID()-*id, func(m *meta) error { - if m.parent != root { - return errors.New("unexpected state history") + // histories in range [id+1, diskLayer.ID] are present and linked. + var ( + start = *id + 1 + limit = dl.stateID() + ) + for { + // Short circuit if nothing more to check + if start > limit { + break } - root = m.root - return nil - }) == nil + // Cap the meta items for single retrieval + count := limit - start + 1 + if count > 1024 { + count = 1024 + } + err := checkHistories(db.freezer, start, count, func(m *meta) error { + if m.parent != root { + return errors.New("unexpected state history") + } + root = m.root + return nil + }) + if err != nil { + return false + } + start += count + } + return true } // Close closes the trie database and the held freezer. diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index 68fb4809f0..ee19102696 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -519,29 +519,21 @@ func writeHistory(freezer *rawdb.ResettableFreezer, dl *diffLayer) error { return nil } -// checkHistories retrieves a batch of meta objects with the specified range -// and performs the callback on each item. +// checkHistories retrieves a batch of meta objects within the specified range +// and performs the callback on top. func checkHistories(freezer *rawdb.ResettableFreezer, start, count uint64, check func(*meta) error) error { - for count > 0 { - number := count - if number > 10000 { - number = 10000 // split the big read into small chunks - } - blobs, err := rawdb.ReadStateHistoryMetaList(freezer, start, number) - if err != nil { + blobs, err := rawdb.ReadStateHistoryMetaList(freezer, start, count) + if err != nil { + return err + } + for _, blob := range blobs { + var dec meta + if err := dec.decode(blob); err != nil { return err } - for _, blob := range blobs { - var dec meta - if err := dec.decode(blob); err != nil { - return err - } - if err := check(&dec); err != nil { - return err - } + if err := check(&dec); err != nil { + return err } - count -= uint64(len(blobs)) - start += uint64(len(blobs)) } return nil }