]> Untitled Git - bdk/commitdiff
Merge bitcoindevkit/bdk#2372: fix(chain): skip coinbase txs with a `last_seen` in... master github/master
authormerge-script <hello@evanlinjin.me>
Fri, 16 Oct 2026 03:57:26 +0000 (03:57 +0000)
committermerge-script <hello@evanlinjin.me>
Fri, 16 Oct 2026 03:57:26 +0000 (03:57 +0000)
a921c78d7aaad2c231dc5c9919e8b9b04b105954 fix(chain): skip coinbase txs with a `last_seen` in canonicalization (志宇)

Pull request description:

  ### Description

  Alternative to #2322, taking the approach outlined in https://github.com/bitcoindevkit/bdk/pull/2322#issuecomment-6136246396. Addresses part of #2269.

  - **`SeenTxs` now skips coinbase txs.** A coinbase cannot be in the mempool, so a `last_seen` value on one is bad data and must not make it canonical. This was only a `debug_assert!`, so release builds canonicalized it at `ChainPosition::Unconfirmed`. The check now mirrors the one in `LeftOverTxs`.
  - **`CanonicalTxOut::is_mature` no longer asserts on a coinbase without a confirmation height.** It returns `false` (maturity cannot be proven), which is what release builds already did.

  Unlike #2322, a coinbase that is an ancestor of a canonical tx, or is in `assume_canonical`, stays canonical even when no anchor is held for it. A canonical spend of a coinbase implies the coinbase is in the chain, and excluding it leaves the view with a canonical tx whose parent is missing.

  ### Notes to the reviewers

  This does not change what `ChainPosition` such a coinbase resolves to: it is still `Unconfirmed`. How (or whether) to represent "canonical coinbase, no anchor held" is a breaking design question and is left for a separate issue.

  The `is_mature` assert was reachable through `balance()` on master: an unanchored coinbase with an unspent output, pulled in by an unconfirmed spend of another of its outputs. The second new test scenario covers this.

  ### Changelog notice

  - Fixed: a coinbase tx with a `last_seen` value is no longer canonicalized in release builds.
  - Fixed: `CanonicalTxOut::is_mature` no longer panics in debug builds for a canonical coinbase with no known anchor; it returns `false`.

  ### Checklists

  #### All Submissions:

  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)

  #### Bugfixes:

  * [ ] This pull request breaks the existing API
  * [x] I've added tests to reproduce the issue which are now passing
  * [x] I'm linking the issue being fixed by this PR

  🤖 Generated with [Claude Code](https://claude.com/claude-code)

ACKs for top commit:
  noahjoeris:
    ACK a921c78d7aaad2c231dc5c9919e8b9b04b105954

Tree-SHA512: 495acb3f5c4c1c04db7d2162853cb926705b31a2b88cd4be6c68d558465869354d579bbb6826ef0e2bd904696ce4bed67875bddb488f0f41bef6f3bc2fc6f0bc

1  2 
crates/chain/src/canonical.rs
crates/chain/src/canonical_task.rs
crates/chain/tests/test_tx_graph_conflicts.rs

Simple merge
Simple merge