@@ -73,6 +73,7 @@ type Store struct {
7373 sc * SMT // reference to the state commitment store
7474 * Indexer // reference to the indexer store
7575 metrics * lib.Metrics // telemetry
76+ syncing atomic.Bool // when true, skip compaction to avoid write stalls during sync
7677 log lib.LoggerI // logger
7778 config lib.Config // config
7879 mu * sync.Mutex // mutex for concurrent commits
@@ -472,6 +473,39 @@ func (s *Store) IncreaseVersion() { func() { s.version++; s.sc = nil }() }
472473// number of the state. This is used to track the versioning of the state data.
473474func (s * Store ) Version () uint64 { return s .version }
474475
476+ // SetSyncing tells the store whether the node is currently syncing, allowing it to
477+ // defer expensive maintenance operations (compaction) that cause write stalls at scale.
478+ func (s * Store ) SetSyncing (v bool ) { s .syncing .Store (v ) }
479+
480+ // CompactAll runs compaction across all store prefixes including SMT commitment nodes
481+ // and indexer entries that are not covered by the regular MaybeCompact cycle.
482+ // Should be called after sync completes to consolidate the accumulated versions.
483+ func (s * Store ) CompactAll () {
484+ if s .compaction .Load () {
485+ return
486+ }
487+ s .compaction .Store (true )
488+ defer s .compaction .Store (false )
489+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Minute )
490+ defer cancel ()
491+ version := s .Version ()
492+ s .log .Infof ("full compaction started at height %d (post-sync)" , version )
493+ now := time .Now ()
494+ for _ , prefix := range [][]byte {
495+ latestStatePrefix ,
496+ historicStatePrefix ,
497+ stateCommitmentPrefix ,
498+ stateCommitIDPrefix ,
499+ indexerPrefix ,
500+ } {
501+ if err := s .db .Compact (ctx , prefix , prefixEnd (prefix ), false ); err != nil {
502+ s .log .Errorf ("full compaction failed for prefix: %s" , err )
503+ return
504+ }
505+ }
506+ s .log .Infof ("full compaction finished at height %d in %s" , version , time .Since (now ))
507+ }
508+
475509// NewTxn() creates and returns a new transaction for the Store, allowing atomic operations
476510// on the StateStore, StateCommitStore, Indexer, and CommitIDStore.
477511func (s * Store ) NewTxn () lib.StoreI {
@@ -612,6 +646,11 @@ func getLatestCommitID(db *pebble.DB, log lib.LoggerI) (id *lib.CommitID) {
612646
613647// MaybeCompact() checks if it is time to compact the LSS and HSS respectively
614648func (s * Store ) MaybeCompact () {
649+ // skip compaction during syncing: at scale (~1.5M+ blocks) HSS range compaction causes
650+ // PebbleDB write stalls that throttle the sync loop's db.Apply calls
651+ if s .syncing .Load () {
652+ return
653+ }
615654 // check if the current version is a multiple of the cleanup block interval
616655 compactionInterval := s .config .StoreConfig .LSSCompactionInterval
617656 version := s .Version ()
0 commit comments