Skip to content

Conversation

@pauldelucia
Copy link
Member

@pauldelucia pauldelucia commented Nov 27, 2025

If you sync from checkpoint, disconnect, and reconnect, filter headers were being loaded from storage at 0 instead of checkpoint.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed blockchain sync height calculation during checkpoint-based synchronization so the next sync height never regresses when the node's tip is behind the configured sync base, improving synchronization correctness and stability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 27, 2025

Walkthrough

The store_filter_headers function's next-blockchain-height calculation was adjusted: when a checkpoint sync base exists and the current tip is below that checkpoint, the next height is set to the checkpoint; otherwise the prior tip+1 behavior remains. The None-tip path is unchanged.

Changes

Cohort / File(s) Change Summary
Height calculation refinement
dash-spv/src/storage/disk/filters.rs
Modified next_blockchain_height calculation in store_filter_headers: for Some(tip) if sync_base_height > 0 and tip < sync_base_height then set next_blockchain_height = sync_base_height, otherwise set next_blockchain_height = tip + 1. The None case is unchanged.

Sequence Diagram(s)

sequenceDiagram
  participant Caller as store_filter_headers
  participant Storage as FiltersStorage

  Caller->>Storage: request store headers (has sync_base_height)
  alt tip is Some
    Storage->>Storage: if sync_base_height > 0 and tip < sync_base_height
    alt tip < sync_base_height
      Storage-->>Caller: next_blockchain_height = sync_base_height
    else tip >= sync_base_height
      Storage-->>Caller: next_blockchain_height = tip + 1
    end
  else tip is None
    Storage-->>Caller: next_blockchain_height = (unchanged) sync_base_height/path
  end
  Note right of Storage `#D3E4CD`: Decision focused on tip vs checkpoint\n(unchanged None-case)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify the conditional correctly handles tip < sync_base_height.
  • Confirm the None-case remains correct in surrounding logic.
  • Check for off-by-one or integer underflow/overflow edge cases.

Poem

🐰 I nibble code where checkpoints lay,
If tips fall short, I hop and stay—
Keep heights firm until the climb,
No eager leap ahead of time.
A tiny tweak, a steadier pace, hooray!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main fix: filter headers not resuming from checkpoint on reconnect, which matches the primary change in the PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/filters-resync

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
dash-spv/src/storage/disk/filters.rs (1)

22-30: Checkpoint-aware next_blockchain_height logic correctly fixes the reconnect behavior

Anchoring next_blockchain_height to sync_base_height when sync_base_height > 0 and cached_filter_tip_height is still below the checkpoint ensures that new filter headers are written starting at the checkpoint, not into pre-checkpoint indices. That keeps the checkpoint-relative storage mapping consistent on reconnect and avoids mixing “genesis-style” indices with checkpoint-based ones, which aligns with the PR objective.

Given this guard, the next_blockchain_height < sync_base_height branch in the storage index computation (Lines 48–56) should now be unreachable in normal operation. You might consider tightening that path to make the invariant explicit, e.g. via a debug_assert!(next_blockchain_height >= sync_base_height) and keeping the tracing::warn! as a defensive fallback, so any future regressions are easier to spot during development.

Also applies to: 44-56

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e9ef04 and 0b163c5.

📒 Files selected for processing (1)
  • dash-spv/src/storage/disk/filters.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: DCG-Claude
Repo: dashpay/rust-dashcore PR: 0
File: :0-0
Timestamp: 2025-06-26T16:01:37.609Z
Learning: The mempool tracking infrastructure (UnconfirmedTransaction, MempoolState, configuration, and mempool_filter.rs) is fully implemented and integrated in the Dash SPV client as of this PR, including client logic, FFI APIs, and tests.
📚 Learning: 2025-06-26T16:01:37.609Z
Learnt from: DCG-Claude
Repo: dashpay/rust-dashcore PR: 0
File: :0-0
Timestamp: 2025-06-26T16:01:37.609Z
Learning: The mempool tracking infrastructure (UnconfirmedTransaction, MempoolState, configuration, and mempool_filter.rs) is fully implemented and integrated in the Dash SPV client as of this PR, including client logic, FFI APIs, and tests.

Applied to files:

  • dash-spv/src/storage/disk/filters.rs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
dash-spv/src/storage/disk/filters.rs (1)

22-28: Checkpoint resume behavior looks correct; consider logging the unexpected tip < sync_base_height case.

The new conditional cleanly fixes the reconnect-from-checkpoint issue: when a cached tip is behind the checkpoint, you now restart from sync_base_height instead of tip + 1, while leaving genesis-sync and normal continuation (tip ≥ checkpoint) semantics unchanged. That’s consistent with how storage indices are derived later in the loop and avoids writing headers at pre‑checkpoint indices.

Since tip < sync_base_height should generally not happen in a healthy checkpointed flow (other than the specific reconnect scenario you’re targeting), you might optionally emit a tracing::warn! in that branch to surface any future unexpected state transitions:

Some(tip) => {
    if sync_base_height > 0 && tip < sync_base_height {
        tracing::warn!(
            "cached_filter_tip_height ({}) is below sync_base_height ({}); \
             resetting next_blockchain_height to checkpoint",
            tip,
            sync_base_height
        );
        sync_base_height
    } else {
        tip + 1
    }
}

This keeps the fix while making it easier to spot misconfigurations or future regressions around checkpoint handling.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0b163c5 and 050a5cd.

📒 Files selected for processing (1)
  • dash-spv/src/storage/disk/filters.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: DCG-Claude
Repo: dashpay/rust-dashcore PR: 0
File: :0-0
Timestamp: 2025-06-26T16:01:37.609Z
Learning: The mempool tracking infrastructure (UnconfirmedTransaction, MempoolState, configuration, and mempool_filter.rs) is fully implemented and integrated in the Dash SPV client as of this PR, including client logic, FFI APIs, and tests.

@github-actions github-actions bot added the merge-conflict The PR conflicts with the target branch. label Dec 12, 2025
@github-actions
Copy link

This PR has merge conflicts with the base branch. Please rebase or merge the base branch into your branch to resolve them.

@xdustinface xdustinface changed the base branch from v0.41-dev to v0.42-dev December 30, 2025 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-conflict The PR conflicts with the target branch.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants