Skip to content

Backport release/v6.3: fix: pruning goroutine lifecycle and prune failure snapshot#2947

Merged
blindchaser merged 5 commits intorelease/v6.3from
backport-2800-to-release/v6.3
Feb 22, 2026
Merged

Backport release/v6.3: fix: pruning goroutine lifecycle and prune failure snapshot#2947
blindchaser merged 5 commits intorelease/v6.3from
backport-2800-to-release/v6.3

Conversation

@seidroid
Copy link

@seidroid seidroid bot commented Feb 21, 2026

Backport of #2800 to release/v6.3.

@seidroid
Copy link
Author

seidroid bot commented Feb 21, 2026

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin backport-2800-to-release/v6.3
git worktree add --checkout .worktree/backport-2800-to-release/v6.3 backport-2800-to-release/v6.3
cd .worktree/backport-2800-to-release/v6.3
git reset --hard HEAD^
git cherry-pick -x c6621a327deee051f79f44fbce328c624ea80ccf
git push --force-with-lease

@github-actions
Copy link

github-actions bot commented Feb 21, 2026

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

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedFeb 22, 2026, 12:29 AM

@github-actions
Copy link

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

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedFeb 21, 2026, 10:47 PM

@codecov
Copy link

codecov bot commented Feb 21, 2026

Codecov Report

❌ Patch coverage is 71.64179% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.46%. Comparing base (119b700) to head (6d753ea).
⚠️ Report is 1 commits behind head on release/v6.3.

Files with missing lines Patch % Lines
sei-db/sc/memiavl/db.go 52.94% 5 Missing and 3 partials ⚠️
sei-db/ss/pruning/manager.go 80.00% 5 Missing and 2 partials ⚠️
sei-db/ss/pebbledb/db.go 33.33% 1 Missing and 1 partial ⚠️
sei-db/ss/rocksdb/db.go 33.33% 1 Missing and 1 partial ⚠️

❌ Your project status has failed because the head coverage (38.45%) is below the target coverage (40.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##           release/v6.3    #2947   +/-   ##
=============================================
  Coverage         43.46%   43.46%           
=============================================
  Files              1866     1866           
  Lines            155380   155420   +40     
=============================================
+ Hits              67537    67560   +23     
- Misses            81801    81808    +7     
- Partials           6042     6052   +10     
Flag Coverage Δ
sei-chain 42.53% <ø> (-0.02%) ⬇️
sei-cosmos 38.21% <ø> (+<0.01%) ⬆️
sei-db 45.67% <71.64%> (+0.43%) ⬆️
sei-ibc-go 55.96% <ø> (ø)
sei-tendermint 47.56% <ø> (-0.06%) ⬇️
sei-wasmd 41.56% <ø> (ø)
sei-wasmvm 39.88% <ø> (ø)

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

Files with missing lines Coverage Δ
app/app.go 75.50% <ø> (+0.27%) ⬆️
sei-db/ss/store.go 50.84% <100.00%> (+5.56%) ⬆️
sei-db/ss/pebbledb/db.go 64.02% <33.33%> (-0.14%) ⬇️
sei-db/ss/rocksdb/db.go 58.49% <33.33%> (-0.31%) ⬇️
sei-db/ss/pruning/manager.go 83.72% <80.00%> (+83.72%) ⬆️
sei-db/sc/memiavl/db.go 62.33% <52.94%> (-0.97%) ⬇️

... and 16 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.

- Wrap StateStore with PrunableStateStore that stops the pruning
goroutine before closing the underlying database
- Remove redundant stateStore.Close() from HandleClose() since
cms.Close() already handles it
- Add nil checks in Prune() methods for pebbledb/rocksdb as an
additional safety layer
- Use sync.Once to ensure Start/Stop/Close operations are safe to call
multiple times
- Prune old memiavl snapshots even when snapshot rewrite fails

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit c6621a3)
@blindchaser blindchaser force-pushed the backport-2800-to-release/v6.3 branch from 7d6e36c to 2efb7e4 Compare February 21, 2026 22:59
@blindchaser blindchaser marked this pull request as ready for review February 21, 2026 23:07
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.logger.Info(fmt.Sprintf("Pruned state store till version %d took %s", pruneVersion, time.Since(pruneStartTime)))
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

// Stop gracefully stops the pruning goroutine and waits for it to exit.
// Safe to call multiple times (idempotent).
func (m *Manager) Stop() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not calling this at all in non-test codepath execution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stop now wired into non-test close path,second comment addressed by lifecycle guarantee

// and trim history when possible.
func (db *Database) Prune(version int64) error {
// Defensive check: ensure database is not closed
if db.storage == nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be guarded; concurrent goroutines can still hit nil pointer dereference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is managed by the upper lifecycle, but yeah I added an atomic check defensively.

Wrap the state store with a prunable wrapper so Close() always stops the pruning goroutine before closing the underlying DB, preventing prune/close races during shutdown.

Co-authored-by: Cursor <cursoragent@cursor.com>
@blindchaser blindchaser merged commit ac53eb9 into release/v6.3 Feb 22, 2026
44 of 45 checks passed
@blindchaser blindchaser deleted the backport-2800-to-release/v6.3 branch February 22, 2026 02:47
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.

3 participants