Skip to content

fix: pruning goroutine lifecycle management to prevent nil pointer on Close#2800

Open
blindchaser wants to merge 3 commits intomainfrom
yiren/fix-prune
Open

fix: pruning goroutine lifecycle management to prevent nil pointer on Close#2800
blindchaser wants to merge 3 commits intomainfrom
yiren/fix-prune

Conversation

@blindchaser
Copy link
Contributor

Describe your changes and provide context

  • Lifecycle management: Wrap StateStore with PrunableStateStore that stops the pruning goroutine before closing the underlying database
  • Remove duplicate Close: Remove redundant stateStore.Close() from HandleClose() since cms.Close() already handles it
  • Defensive checks: Add nil checks in Prune() methods for pebbledb/rocksdb as an additional safety layer
  • Idempotency: Use sync.Once to ensure Start/Stop/Close operations are safe to call multiple times

Testing performed to validate your change

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedFeb 18, 2026, 12:04 AM

@codecov
Copy link

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 71.42857% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.25%. Comparing base (ca2a7c8) to head (231d6ad).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
sei-db/state_db/ss/composite/store.go 60.00% 4 Missing and 2 partials ⚠️
sei-db/state_db/ss/pruning/manager.go 88.57% 2 Missing and 2 partials ⚠️
sei-db/db_engine/pebbledb/mvcc/db.go 0.00% 1 Missing and 1 partial ⚠️
sei-db/db_engine/rocksdb/mvcc/db.go 0.00% 1 Missing and 1 partial ⚠️
sei-db/state_db/sc/memiavl/db.go 0.00% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #2800       +/-   ##
===========================================
+ Coverage   48.37%   57.25%    +8.87%     
===========================================
  Files         671     2099     +1428     
  Lines       50621   172437   +121816     
===========================================
+ Hits        24486    98721    +74235     
- Misses      23987    64865    +40878     
- Partials     2148     8851     +6703     
Flag Coverage Δ
sei-chain 52.73% <74.07%> (?)
sei-cosmos 48.19% <ø> (+<0.01%) ⬆️
sei-db 68.42% <0.00%> (-0.31%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
app/app.go 72.97% <ø> (ø)
sei-db/db_engine/pebbledb/mvcc/db.go 63.92% <0.00%> (ø)
sei-db/db_engine/rocksdb/mvcc/db.go 57.31% <0.00%> (-0.47%) ⬇️
sei-db/state_db/sc/memiavl/db.go 65.63% <0.00%> (ø)
sei-db/state_db/ss/pruning/manager.go 90.69% <88.57%> (ø)
sei-db/state_db/ss/composite/store.go 49.69% <60.00%> (ø)

... and 1546 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

default:
}

pruneStartTime := time.Now()

Check warning

Code scanning / CodeQL

Calling the system time Warning

Calling the system time may be a possible source of non-determinism
}
m.startOnce.Do(func() {
m.wg.Add(1)
go m.pruneLoop()

Check notice

Code scanning / CodeQL

Spawning a Go routine Note

Spawning a Go routine may be a possible source of non-determinism
time.Sleep(time.Duration(m.pruneInterval+randomDelay) * time.Second)
// Generate a random percentage (between 0% and 100%) of the fixed interval as a delay
randomPercentage := rand.Float64()
randomDelay := int64(float64(m.pruneInterval) * randomPercentage)

Check notice

Code scanning / CodeQL

Floating point arithmetic Note

Floating point arithmetic operations are not associative and a possible source of non-determinism
@blindchaser blindchaser force-pushed the yiren/fix-prune branch 3 times, most recently from b1ef012 to 9dba675 Compare February 17, 2026 15:49
… Close

- Add proper Stop() with stopCh/WaitGroup to pruning Manager for graceful shutdown
- Save pruning manager in CompositeStateStore and stop it on Close (idempotent)
- Add defensive nil checks in pebbledb/rocksdb Prune() for closed databases
- Remove duplicate stateStore.Close() in app HandleClose (already closed by BaseApp)

Co-authored-by: Cursor <cursoragent@cursor.com>
blindchaser and others added 2 commits February 17, 2026 11:06
Previously, pruneSnapshots() was only called after a successful snapshot
rewrite. If snapshot creation kept failing, old snapshots would accumulate
indefinitely. Now we prune old snapshots regardless of rewrite outcome.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant