Skip to content

refactor(chain)!: drop the bound framing from confirmation APIs - #2299

Open
evanlinjin wants to merge 2 commits into
bitcoindevkit:masterfrom
evanlinjin:refactor/anchor-confirmation-height
Open

refactor(chain)!: drop the bound framing from confirmation APIs#2299
evanlinjin wants to merge 2 commits into
bitcoindevkit:masterfrom
evanlinjin:refactor/anchor-confirmation-height

Conversation

@evanlinjin

@evanlinjin evanlinjin commented Sep 11, 2026

Copy link
Copy Markdown
Member

Description

Fixes #2298.

The Anchor trait previously said an anchor block might be a descendant of the block that actually confirmed a transaction. Nothing in this repo ever produces that kind of anchor:

  • Electrum validates a merkle proof before building one
  • Esplora uses the confirming block from TxStatus
  • TxPosInBlock carries the transaction’s index inside that block

So the height is exact, not an upper bound. This PR removes that framing and renames:

  • confirmation_height_upper_boundconfirmation_height (on both Anchor and ChainPosition)
  • confirmations_lower_boundconfirmations

The second rename follows for the same reason: a higher height produces fewer confirmations, so an upper-bounded height used to yield a lower-bounded count. With an exact height the count is exact.

Notes to reviewers

No behaviour change. Every implementation already returned anchor_block().height. The override on ConfirmationBlockTime is removed because it was identical to the trait default.

Hard renames, no deprecated shims. The next bdk_chain release is already breaking, so a downstream impl that still overrides the old name should fail to compile rather than be silently ignored.

Changelog notice

bdk_chain

  • Renamed Anchor::confirmation_height_upper_bound and ChainPosition::confirmation_height_upper_bound to confirmation_height. An anchor names the confirming block, so the height is exact. No deprecated alias.
  • Renamed ChainPosition::confirmations_lower_bound to ChainPosition::confirmations (the derived count is now exact).
  • Updated Anchor trait docs: they no longer claim an anchor block may be a descendant of the confirming block.

Checklists

All Submissions:

Bugfixes:

  • This pull request breaks the existing API
  • I'm linking the issue being fixed by this PR

The `Anchor` trait doc claimed an anchored transaction "could also mean
transaction A is confirmed in a parent block of B". No chain source in
this repo produces such an anchor: electrum only builds one after
`validate_merkle_proof` succeeds, esplora uses `TxStatus`'s confirming
block, and `TxPosInBlock` carries the transaction's index within that
block. The framing only leaves ambiguity for a case that does not occur.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NND8BhEmYTYdLRv4dbUUro
@codecov

codecov Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.72%. Comparing base (38b52d9) to head (40cb3d1).

Files with missing lines Patch % Lines
crates/chain/src/tx_data_traits.rs 33.33% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2299      +/-   ##
==========================================
- Coverage   78.75%   78.72%   -0.03%     
==========================================
  Files          31       31              
  Lines        5974     5966       -8     
  Branches      284      284              
==========================================
- Hits         4705     4697       -8     
  Misses       1193     1193              
  Partials       76       76              
Flag Coverage Δ
rust 78.72% <85.71%> (-0.03%) ⬇️

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.

@evanlinjin
evanlinjin force-pushed the refactor/anchor-confirmation-height branch from 4ad7715 to 38f2078 Compare September 11, 2026 02:31
@evanlinjin evanlinjin self-assigned this Sep 11, 2026
@evanlinjin evanlinjin added the api A breaking API change label Sep 11, 2026
Comment thread crates/chain/src/chain_data.rs Outdated
An anchor names the block that confirmed the transaction, so its height
is exact, not an upper bound. Rename `confirmation_height_upper_bound`
to `confirmation_height` on both `Anchor` and `ChainPosition`.

`ChainPosition::confirmations_lower_bound` was a lower bound only
because it derives from that height: a higher height yields fewer
confirmations, so an upper-bounded height yields a lower-bounded count.
With the height exact the count is exact too, so it becomes
`confirmations`.

These are hard renames with no deprecated aliases. The next `bdk_chain`
release is already breaking, so a downstream `Anchor` impl overriding an
old name should fail to compile rather than be silently ignored.

`ConfirmationBlockTime`'s override is removed as it was identical to the
default. This drops the false-negative caveats from
`CanonicalTxOut::is_mature` and `is_confirmed_and_spendable`, which only
described the loose bound. No behaviour change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NND8BhEmYTYdLRv4dbUUro
@evanlinjin
evanlinjin force-pushed the refactor/anchor-confirmation-height branch from 38f2078 to 40cb3d1 Compare September 11, 2026 09:44
@evanlinjin evanlinjin changed the title refactor(chain)!: rename confirmation_height_upper_bound to confirmation_height refactor(chain)!: drop the bound framing from confirmation APIs Sep 11, 2026
@evanlinjin
evanlinjin marked this pull request as ready for review September 11, 2026 09:57

@nymius nymius 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.

cACK 40cb3d1

For now, if we have no use for the probabilistic case, I agree with removing it. If we need it in the future (e.g., Utreexo?), I would reintroduce it under a different name to avoid colliding with previous versions.

///
/// [`confirmation_height_upper_bound`]: Anchor::confirmation_height_upper_bound
/// A coinbase output is mature once [`COINBASE_MATURITY`] blocks (including the block that
/// confirmed it) have been mined up to and including `tip`. Non-coinbase outputs are always

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.

I don't know the best way to word this, but a coin is mature if it's eligible to be included in the next block. The minimum such height is COINBASE_MATURITY - 1 , so this should say something like:

/// A coinbase output is mature once it can be included in the next block after
/// [`COINBASE_MATURITY`] blocks have been mined after its confirmation

@evanlinjin

Copy link
Copy Markdown
Member Author

@nymius Thank you for the review. How do you envision UTreexo potentially using this feature?

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

Labels

api A breaking API change

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Drop the "anchor may be a descendant" framing; introduce Anchor::confirmation_height

2 participants