Skip to content

test(chain): add missing prev_blockhash cases to merge_chains_with_prev_blockhash - #2412

Closed
ravindra-RKB wants to merge 1 commit into
bitcoindevkit:masterfrom
ravindra-RKB:test/chain-merge-prev-blockhash
Closed

ravindra-RKB wants to merge 1 commit into
bitcoindevkit:masterfrom
ravindra-RKB:test/chain-merge-prev-blockhash

Conversation

@ravindra-RKB

@ravindra-RKB ravindra-RKB commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Description

Following up on the suggestion in #2410 regarding test coverage for merge_chains correctness, this PR adds a test case to merge_chains_with_prev_blockhash in crates/chain/tests/test_local_chain.rs:

  • Update connection without explicit genesis:
    Verifies that an update starting at height > 1 with a valid prev_blockhash connects via an inferred placeholder checkpoint without requiring an explicit genesis checkpoint in the update.

Notes to the reviewers

The test case is written using the existing TestLocalChain table-driven runner in crates/chain/tests/test_local_chain.rs and passes against the current implementation.

Changelog notice

none

Checklists

All Submissions:

@ravindra-RKB
ravindra-RKB requested a review from a team as a code owner October 19, 2026 17:54
@github-project-automation github-project-automation Bot moved this to Triage in BDK Chain Oct 19, 2026
@codecov

codecov Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.66%. Comparing base (5e7dd4a) to head (086a748).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2412   +/-   ##
=======================================
  Coverage   80.66%   80.66%           
=======================================
  Files          31       31           
  Lines        6236     6236           
  Branches      293      293           
=======================================
  Hits         5030     5030           
  Misses       1136     1136           
  Partials       70       70           
Flag Coverage Δ
rust 80.66% <ø> (ø)

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

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ravindra-RKB
ravindra-RKB force-pushed the test/chain-merge-prev-blockhash branch from 50f0627 to e0b475f Compare October 19, 2026 18:21

@evanlinjin evanlinjin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only one case covers something new. The other five either repeat existing cases with one more block, or the update holds every height involved, so prev_blockhash is never consulted and a BlockHash chain gives the same result (all the evictions come from the ordinary invalidation rule). The PR body says they test prev_blockhash behaviour, but they don't. Per-case comments below.

Other:

  • The style(core) commit duplicates the user's #2405 (still open). It should be dropped and the branch rebased once #2405 merges.
  • Changelog notice: test-only changes don't go in CHANGELOG.md; it should say "none". "I've added tests for the new feature" doesn't apply either (no feature).

Comment thread crates/chain/tests/test_local_chain.rs Outdated
// The update contains contiguous blocks B (height 2) and C (height 3) without genesis.
// B's `prev_blockhash` connects to chain's A at height 1.
TestLocalChain {
name: "prev_blockhash extends chain with multiple blocks without explicit genesis",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

design: This is the previous case with one more block. C.prev_blockhash = B points inside the update, so the only placeholder that matters is still A from B, which the case above already covers. Drop it?

Comment thread crates/core/src/lib.rs Outdated
//!
//! - `std` (default): use the standard library, including its `HashMap`/`HashSet`. Without it,
//! this crate is `no_std` and uses `alloc`'s `BTreeMap`/`BTreeSet` instead.
//! - `std` (default): use the standard library, including its `HashMap`/`HashSet`. Without it, this

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: Unrelated to the PR, and #2405 already does this reformat. Please drop this commit and rebase once #2405 is merged (fmt is red on master until then, and that isn't this PR's fault).

Comment thread crates/chain/tests/test_local_chain.rs Outdated
// Chain has a gap at height 1. The update provides block A (filling the gap and satisfying
// B's `prev_blockhash`) and extends the tip to height 3 with C.
TestLocalChain {
name: "update fills gap and extends tip with matching prev_blockhashes",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

design: This is update fills gap with matching prev_blockhash (:1279) plus C on top. Extending the tip isn't a prev_blockhash path, and the update holds every height, so a BlockHash chain gives the same changeset. Drop it?

Comment thread crates/chain/tests/test_local_chain.rs Outdated
// Update reorganizes heights 2 and 3 simultaneously. Both B' and D' have updated
// `prev_blockhash` references that chain together (`D' -> B' -> A`).
TestLocalChain {
name: "multi-block reorg with matching heights and updated prev_blockhashes",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

design: The update has every height from 0 to 3, so no placeholder is created and prev_blockhash is never checked against the original chain. It's a plain reorg, and the BlockHash cases already cover that (transitive invalidation applies to checkpoints higher than invalidation). Drop it?

Comment thread crates/chain/tests/test_local_chain.rs Outdated
// Update forks at height 1 and extends to height 2 on the alternate chain. Height 3 of
// the original chain is evicted, and heights 1 and 2 are updated.
TestLocalChain {
name: "reorg at height 1 replaces chain with alternate fork",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

design: Height 3 isn't evicted through prev_blockhash: the update conflicts at height 1, below its tip, so merge_chains drops every original block above that anyway (same as the BlockHash transitive invalidation cases). cascading eviction through multiple blocks (:1304) already covers eviction via prev_blockhash. The PR body's "evicts higher chain blocks that depend on the original chain via prev_blockhash" doesn't describe what this tests. Drop it?

Comment thread crates/chain/tests/test_local_chain.rs Outdated
// (at height 1) and the update (at height 2) have blocks above genesis that do not
// overlap or resolve, connection fails at height 1.
TestLocalChain {
name: "prev_blockhash cannot connect when update references unknown block across gap",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

design: This fails for the BlockHash reason, not because of X: the chain's A sits between the point of agreement (genesis) and the update's next block, and the update doesn't include height 1. With BlockHash data (_, then C at 3) you get the same try_include_height: 1, the rule update and chain does not connect (:212) tests. It's also unverifiable connection despite shared genesis (:1223) with chain and update swapped. Drop it?

@evanlinjin evanlinjin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Additionally, commits need to be signed otherwise merging won't be possible.

…v_blockhash

Extend merge_chains_with_prev_blockhash in 	est_local_chain.rs to verify that an update connecting via an inferred prev_blockhash placeholder merges correctly without requiring an explicit genesis checkpoint in the update.
@ravindra-RKB
ravindra-RKB force-pushed the test/chain-merge-prev-blockhash branch from e0b475f to 086a748 Compare October 20, 2026 06:53
@ravindra-RKB

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review @evanlinjin!

I have addressed all the feedback:

  • Dropped the 5 redundant test cases, keeping only the update connection without explicit genesis case.
  • Removed the unused test block definitions.
  • Dropped the style(core) commit and rebased onto latest master (leaving crates/core/src/lib.rs for chore: cargo fmt crates/core/src/lib.rs #2405 as noted).
  • Signed the commit with SSH.
  • Updated the PR description, checklists, and changelog notice to none.

@evanlinjin

Copy link
Copy Markdown
Contributor

Thanks @ravindra-RKB, and I'm sorry: I got this one wrong.

In my review I asked you to keep the "update connection without explicit genesis" case because I thought nothing covered it. On a second look, test_apply_update_single_header already does. It applies single-header updates with no genesis that connect only through the prev_blockhash placeholder, and its height-2 step is this exact case. So the PR doesn't add new coverage, and I'm closing it.

Apologies for the extra round of trimming, rebasing and signing I asked of you. You handled the feedback quickly and cleanly. If you'd like to keep working on merge_chains, cases that only Header data can hit and that no existing test reaches would be the place to look. Thanks again!

@evanlinjin evanlinjin closed this Oct 20, 2026
@github-project-automation github-project-automation Bot moved this from Triage to Done in BDK Chain Oct 20, 2026
@ravindra-RKB

Copy link
Copy Markdown
Contributor Author

No worries at all @evanlinjin, appreciate the clarification and the thorough review! I'll take a look at the Header-specific paths in merge_chains. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants