From f1cb76d0f2fd17c896c87f08dbed0ea07542cc75 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Tue, 26 Aug 2025 06:30:06 +0800 Subject: [PATCH] triedb: force flush --- core/blockchain.go | 1 + triedb/database.go | 9 +++++++++ triedb/pathdb/database.go | 16 +++++++++++++++- triedb/pathdb/disklayer.go | 2 +- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 83c09336d7..eea945f30c 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -536,6 +536,7 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine, stateSizer, err := state.NewSizeTracker(bc.db, bc.triedb) if err == nil { bc.stateSizer = stateSizer + triedb.EnableForceFlush() } else { log.Info("Failed to setup size tracker", "err", err) } diff --git a/triedb/database.go b/triedb/database.go index d2637bd909..61f612d7cc 100644 --- a/triedb/database.go +++ b/triedb/database.go @@ -384,3 +384,12 @@ func (db *Database) SnapshotCompleted() bool { } return pdb.SnapshotCompleted() } + +// EnableForceFlush enables the pathdb to flush any pending changes to disk immediately, +// regardless of the buffer size threshold. This can be used to accelerate +// state sizer initialization by making buffered state changes visible on disk. +func (db *Database) EnableForceFlush() { + if pdb, ok := db.backend.(*pathdb.Database); ok { + pdb.EnableForceFlush() + } +} diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index 1592f97d01..f708e8ef0a 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -137,7 +137,8 @@ type Database struct { stateFreezer ethdb.ResettableAncientStore // Freezer for storing state histories, nil possible in tests stateIndexer *historyIndexer // History indexer historical state data, nil possible - lock sync.RWMutex // Lock to prevent mutations from happening at the same time + lock sync.RWMutex // Lock to prevent mutations from happening at the same time + forceFlush bool // Flag to force buffer flush regardless of size } // New attempts to load an already existing layer from a persistent key-value @@ -360,6 +361,19 @@ func (db *Database) Commit(root common.Hash, report bool) error { return db.tree.cap(root, 0) } +// EnableForceFlush enables force flushing for the next state update. +// This will cause the next Update() call to flush the disk buffer immediately, +// regardless of the buffer threshold, while preserving the 128 diff layers in memory. +func (db *Database) EnableForceFlush() { + db.lock.Lock() + defer db.lock.Unlock() + + if !db.forceFlush { + log.Info("Enabling force flush for next pathdb update") + db.forceFlush = true + } +} + // Disable deactivates the database and invalidates all available state layers // as stale to prevent access to the persistent state, which is in the syncing // stage. diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index 2042e91611..5a53167203 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -417,7 +417,7 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { // Terminate the background state snapshot generation before mutating the // persistent state. - if combined.full() || force || flush { + if combined.full() || force || flush || dl.db.forceFlush { // Wait until the previous frozen buffer is fully flushed if dl.frozen != nil { if err := dl.frozen.waitFlush(); err != nil {