`code_coverage.yml` started failing as can be seen in a [recent CI run](https://github.com/bitcoindevkit/bdk/actions/runs/19946035484/job/57195537541). As a workaround I set the toolchain in the coverage workflow to `nightly-2025-11-27` which is the version of the compiler in use the last time there was a successful coverage run.
The cause is unknown (to me) and likely doesn't originate from a crate in `bdk`. Assuming that a fix can be found, we can eventually revert this or otherwise keep the toolchain in `code_coverage.yml` up to date as needed.
### Changelog notice
```md
ci: Set code coverage toolchain to `nightly-2025-11-27`
```
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
valued mammal [Thu, 4 Dec 2025 22:41:41 +0000 (17:41 -0500)]
ci(coverage): Pin toolchain to `nightly-2025-11-27`
This fixes a CI failure resulting from use of rustc nightly
with `llvm-cov`.
refer to:
https://github.com/bitcoindevkit/bdk/actions/runs/19946035484.
As a workaround we change `code_coverage.yml` to set the toolchain
to `nightly-2025-11-27` which is a version of the compiler that
is known to work with `cargo-llvm-cov` at generating coverage
reports.
Automated update to Github CI workflow `cont_integration.yml` by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action
Several of the steps in the README for example_bitcoind_rpc_polling don't work as written. The most important was at the start, there is a missing "init" command that otherwise gives a file error. Also the specification of regtest network needed is a bit different than what is written.
Apologies, didn't bother with template, this is just a testing writeup fix (whether correct or not).
Adam Gibson [Tue, 21 Oct 2025 16:46:08 +0000 (13:46 -0300)]
Correct rpc example command syntax
Several of the steps in the README for example_bitcoind_rpc_polling
don't work as written. The most important was at the start, there is
a missing "init" command that otherwise gives a file error. Also the
specification of regtest network needed is a bit different than what
is written.
Fix memory leak bug in CheckPoint::drop by using Arc::into_inner.
Add tests (from the old PR) for memory leak + stack overflow when dropping CheckPoint.
### Notes to the reviewers
It should be merged after #2055.
### Changelog notice
```
### Fix:
- Fix memory leak bug in CheckPoint::drop by using `Arc::into_inner`.
```
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
#### Bugfixes:
* [x] 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
It bumps the project MSRV to 1.85.0, as the latest Debian trixie release establishes that as stable, see: https://tracker.debian.org/pkg/rustc.
This PR does:
- update all references to the previous 1.63.0 MSRV.
- update the rust-version to 1.85.0.
- update the CI to not exclude `bdk_electrum` anymore.
- update the ci/pin-msrv.sh to 1.85.0.
### Notes to the reviewers
Should we update something in the GitHub repository configuration to get rid of old mandatory CI jobs ?
### Changelog notice
```
### Changed
- Update all references to the previous 1.63.0 MSRV.
- Update the rust-version to 1.85.0.
- Update the CI to not exclude `bdk_electrum` anymore.
- Update the ci/pin-msrv.sh to 1.85.0.
```
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
Leonardo Lima [Thu, 2 Oct 2025 04:42:28 +0000 (14:42 +1000)]
chore(msrv): bump MSRV to `1.85.0`
- update all references to previous 1.63.0 MSRV.
- update the rust-version to 1.85.0.
- update the CI to not exclude bdk_electrum anymore.
- update the ci/pin-msrv.sh to 1.85.0.
<!-- You can erase any parts of this template not applicable to your Pull Request. -->
### Description
<!-- Describe the purpose of this PR, what's being adding and/or fixed -->
### Notes to the reviewers
<!-- In this section you can include notes directed to the reviewers, like explaining why some parts
of the PR were done in a specific way -->
### Changelog notice
<!-- Notice the release manager should include in the release tag message changelog -->
<!-- See https://keepachangelog.com/en/1.0.0/ for examples -->
### Checklists
#### All Submissions:
* [ ] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
#### New Features:
* [ ] I've added tests for the new feature
* [ ] I've added docs for the new feature
#### Bugfixes:
* [ ] This pull request breaks the existing API
* [ ] I've added tests to reproduce the issue which are now passing
* [ ] I'm linking the issue being fixed by this PR
Replace `ScriptBuf` with `&Script` in `SpkTxOutIndex::index_of_spk` and `KeychainTxOutIndex::index_of_spk` methods, to avoid the need of cloning the `ScriptBuf` for a SPK index lookup.
### Changelog notice
Breaking changes:
- Change `SpkTxOutIndex::index_of_spk` and `KeychainTxOutIndex::index_of_spk` args from `ScriptBuf` to `&Script`.
### Checklists
#### All Submissions:
* [X] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
#### New Features:
* [ ] I've added tests for the new feature
* [ ] I've added docs for the new feature
#### Bugfixes:
* [X] This pull request breaks the existing API
* [ ] I've added tests to reproduce the issue which are now passing
* [ ] I'm linking the issue being fixed by this PR
It's an initial attempt to solve the timeout failures we have been facing on CI when running electrum tests. It it's not solved at all, at least it now adds the total time elapsed so we can know how long it's taking in CI.
The PR updates the `chained_mempool_txs` test to use 6 seconds as timeout, instead of 5, it was the only spot using 5 instead of 6. Also updates the error message to show the total time elapsed, can help debug the CI if the timeout error persists.
### Notes to the reviewers
### Changelog notice
```
### Changed
- Update the `chained_mempool_txs` to use 6 seconds as timeout.
- Update the error message to show the time elapsed.
```
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
Leonardo Lima [Thu, 2 Oct 2025 04:18:47 +0000 (14:18 +1000)]
fix(ci,test): update `chained_mempool_txs` to use 6 secs timeout
- update the chained_mempool_txs test to use 6 seconds as timeout,
instead of 5, it was the only spot using 5 instead of 6.
- update the error message to show the total time elapsed, can help
debug the CI if the timeout error persists.
refactor(chain): replace `ScriptBuf` with `AsRef<Script>` in SPK index methods
Replace `ScriptBuf` with `AsRef<Script>` in `SpkTxOutIndex::index_of_spk` and `KeychainTxOutIndex::index_of_spk` methods, to avoid the need of cloning the `ScriptBuf` for a SPK index lookup.
`CanonicalView` allows us to canonicalize upfront, reducing our API surface and improving performance by reducing canonicalizations we need to do.
This is also the first step to achieving many of our goals.
* Event notifications.
* Intent tracker.
* Getting rid of `CanonicalUnspents` structure in `bdk_tx`.
### Changelog notice
```md
Added
- Introduce `CanonicalView` which allows us to canonicalize once upfront.
- Added `TxGraph::canonical_view` which constructs a `CanonicalView`.
Changed
- `TxGraph` methods which require canonicalization now have `CanonicalView` equivalents.
Removed
- `TxGraph` methods which take in a fallible `ChainOracle` implementations are now removed.
```
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
#### New Features:
* [x] I've added tests for the new feature
* [x] I've added docs for the new feature
It looks like that the retry approach introduced on #2032 does not really work, as the github workflow syntax does not have those fields.
I've opened this PR to revert the changes, and make sure that CI is working again. Though I still think we can implement a manual retry logic on our side, probably using gh cli inside of the CI job.
### Notes to the reviewers
It needs to be merged in order to coverage CI to work properly again.
### Changelog notice
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
test(chain): Add comprehensive tests for min_confirmations parameter
Add test file `tests/test_canonical_view.rs` with three comprehensive test cases:
1. `test_min_confirmations_parameter`: Tests basic min_confirmations functionality
- Verifies min_confirmations = 0 and 1 behave identically
- Tests edge case where transaction has exactly required confirmations
- Tests case where transaction has insufficient confirmations
2. `test_min_confirmations_with_untrusted_tx`: Tests trust predicate interaction
- Verifies insufficient confirmations + untrusted predicate = untrusted_pending
- Ensures trust predicate is respected when confirmations are insufficient
3. `test_min_confirmations_multiple_transactions`: Tests complex scenarios
- Multiple transactions with different confirmation counts
- Verifies correct categorization based on min_confirmations threshold
- Tests both min_confirmations = 5 and min_confirmations = 10 scenarios
These tests validate that the min_confirmations parameter correctly controls
when transactions are treated as confirmed vs trusted/untrusted pending.
🤖 Generated with [Claude Code](https://claude.ai/code)
feat(chain): Add min_confirmations parameter to CanonicalView::balance
Add min_confirmations parameter to control confirmation depth requirements:
- min_confirmations = 0: Include all confirmed transactions (same as 1)
- min_confirmations = 1: Standard behavior - require at least 1 confirmation
- min_confirmations = 6: High security - require at least 6 confirmations
Transactions with fewer than min_confirmations are treated as trusted/untrusted
pending based on the trust_predicate. This restores the minimum confirmation
functionality that was available in the old TxGraph::balance doctest but with
a more intuitive API since CanonicalView has the tip internally.
🤖 Generated with [Claude Code](https://claude.ai/code)
feat(chain)!: Introduce `CanonicalView` and migrate API
- Add `CanonicalView` structure with canonical transaction methods
- Move methods from `TxGraph` to `CanonicalView` (txs, filter_outpoints, balance, etc.)
- Add canonical view methods to `IndexedTxGraph`
- Update all tests and examples to use new API
- Optimize examples to reuse canonical view instances
🤖 Generated with [Claude Code](https://claude.ai/code)
All `last_evicted` field to `TxNode` and remove `TxGraph::get_last_evicted` method.
### Notes to the reviewers
`get_last_evicted` was added as adding fields to `TxNode` is a breaking change. However, we are going to break `bdk_chain` in the next release so a breaking change now is okay.
### Changelog notice
```md
Added:
- `last_evicted` field is added to `TxNode`.
Removed:
- `TxGraph::get_last_evicted` method is removed.
```
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
#### New Features:
~* [ ] I've added tests for the new feature~
* [x] I've added docs for the new feature
This PR is a step towards header checkpointing for `bdk_electrum`. The goal is to be able to store whole headers in `CheckPoint` so they do not have to be re-downloaded. Storing headers this way would be a prerequisite for caching of merkle proofs and for median time passed.
### Notes to the reviewers
### Changelog notice
* `CheckPoint` takes in a generic.
* `LocalChain` and `ChangeSet` take in generics.
* `spk_client` types can take in generics.
### Checklists
#### All Submissions:
* [x] I've signed all my commits
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
* [x] I ran `cargo fmt` and `cargo clippy` before committing
Leonardo Lima [Wed, 10 Sep 2025 01:23:32 +0000 (11:23 +1000)]
chore(release): bump `bdk-chain` to `0.23.2`
- bump `bdk_core` to `0.6.2`
- bump `bitcoind_rpc` to `0.22.0`
- bump `file_store` to `0.22.0`.
- bump `bdk_electrum` to `0.23.2`
- update all the required `CHANGELOG.md`
Previously `FilterIter` did not detect or handle reorgs between `next` calls, meaning that if a reorg occurred, we might process blocks from a stale fork potentially resulting in an invalid wallet state. This PR aims to fix that by adding logic to explicitly check for and respond to a reorg on every call to `next`.
### Notes to the reviewers
The old implementation required storing block IDs of scanned blocks before creating a checkpoint update, but because the interface was split across different methods, it introduced a timing risk between method calls which, when we consider the possibility of reorgs, made the implementation somewhat brittle.
To address this, we make sure that 1) Finding the start block and 2) Updating the internal checkpoint are directly tied to the logic of `next`. Since the checkpoint in practice is derived from a clone of the local chain, this ensures that the checkpoint returned by `next` can always find a connection point with the receiver. Additionally we now emit a checkpoint at every height to ensure that any "must-include" heights are not missing.
For example usage see `examples/filter_iter.rs`
fixes #1848
### Changelog notice
Fixed
- `FilterIter` now handles reorgs to ensure consistency of the header chain.
Changed
- `Event` is now a struct instead of enum
Added
- `FilterIter::new` constructor that takes as input a reference to the RPC client, checkpoint, and a list of SPKs.
- `Error::ReorgDepthExceeded` variant
- `Error::TryFromInt` variant
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
#### New Features:
* [x] I've added tests for the new feature
* [x] I've added docs for the new feature
#### Bugfixes:
* [x] 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
This PR adds a new doctest demonstrating how to simulate a minimum confirmation threshold for confirmed balance calculations by adjusting the `chain_tip` height passed to `TxGraph::balance`.
### Changelog notice
- Added a doctest illustrating how to filter confirmed balance results by simulating a minimum confirmation threshold via `chain_tip` height.
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
#### New Features:
* [x] I've added tests for the new feature
* [x] I've added docs for the new feature
#### Bugfixes:
* [ ] This pull request breaks the existing API
* [ ] I've added tests to reproduce the issue which are now passing
* [x] I'm linking the issue being fixed by this PR
The API now consists of the methods `new` and `next`.
The local checkpoint and SPK inventory are provided to
the constructor. `next` is now responsible for locating
the point of agreement.
The next filter to fetch is determined by the `next_block_hash`
field of `GetBlockHeaderResult`. If the next header has negative
confirmations due to a reorg, we rewind the internal state until
we find a header still in the best chain.
`Event` is changed to a simple struct containing `cp` and optional
`block`. The checkpoint is updated on each iteration whether
or not it corresponds to a matching block. We use
`CheckPoint::insert` which will also purge evicted blocks
if needed.
Change implementation of `find_base` to use `get_block_header_info`
which helps to reduce the number of RPC calls.
Removed `EventInner`.
Add test `event_checkpoint_connects_to_local_chain` to check
the expected events after a reorg, and check that intermediate
updates can be applied to the local chain.
Fixes an issue in `batch_fetch_anchors()` in `bdk_electrum` where, if a stale block header was detected and a fresh header was fetched, the confirmation anchor inserted into `anchor_cache` still used the hash from the original stale header instead of the new one.
### Changelog notice
- `batch_fetch_anchors()` no longer uses a potentially stale hash as the anchor.
### 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
* [ ] I've added tests to reproduce the issue which are now passing
* [ ] I'm linking the issue being fixed by this PR
This PR addresses #1982
It introduces functionality to populate the anchor cache, improving how BDK handles stateful or performance-critical anchor data.
### Changes
- Add `populate_anchor_cache` method to `BdkElectrumClient `in `bdk-core`
- Improves sync speed by caching anchor transactions in advance
- Enables pre-caching of anchor transactions to reduce redundant network calls
Follow-up work will extend this functionality to `bdk-wallet`.
This PR updates the GitHub issue templates `bug_report.md` and `enhancement_request.md` to improve triage and prioritization. Specifically, it adds structured fields for:
* Production impact (e.g., blocking usage vs. nice-to-have)
* Backend in use (Electrum, Esplora, RPC, etc.)
* Project or organization (optional, helps identify high-priority users)
The goal is to make it easier for maintainers to gauge the urgency and relevance of issues, especially for production users or high-impact integrations.
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
* Why something is no longer part of the best history.
* Whether it is possible that something can reappear in the best history.
In order to do this, we need to track conflicts of spk-relevant transactions.
For example, an incoming transaction may be evicted from the mempool due to insufficient fees or cancelled (a conflicting transaction is confirmed). The caller may want to handle these two possibilities differently:
* **Transaction has insufficient fees** - the caller may want to CPFP the transaction.
* **Transaction is cancelled/replaced** - The user may want to forget about this transaction once the conflict reaches x confirmations.
The `IntentTracker` will make use of these relevant-conflicts to help determine the course of action.
#### Side note about chain sources
For some chain sources, obtaining relevant-conflicts is extremely costly or downright impossible (i.e. Electrum, BIP-158 filters).
`bdk_bitcoind_rpc::Emitter` is still the most robust chain source to use.
### Changelog notice
```md
Changed:
- Behavior of `IndexedTxGraph` methods (`apply_block_relevant`, `batch_insert_relevant` and `batch_insert_relevant_unconfirmed`) to also consider conflicts of spk-relevant transactions as relevant.
```
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
#### New Features:
* [x] I've added tests for the new feature
* [x] I've added docs for the new feature
<!-- You can erase any parts of this template not applicable to your Pull Request. -->
### Description
Fixes #1991. As the linked issue mentions `Box`ing helps reduce memory overhead and [limits the size of enums with `StoreErrorWithDump` as variant](https://github.com/bitcoindevkit/bdk_wallet/pull/277#discussion_r2196831262).
Breaking: The enum `StoreErrorWithDump` and the functions `load`,`dump` and `load_or_create` have been changed.
### Changelog Notice
```
Changed
- `changeset` field of `StoreErrorWithDump` is now of type `Option<Box<C>>`
```
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
refactor!: `Box` changeset in `StoreErrorWithDump`
As mentioned in the corresponding issue, `Box`ing helps reduce memory
overhead while passing the enum around and also to limit the size of
enums with `StoreErrorWithDump` as a variant.
Breaking: The enum `StoreErrorWithDump` has been changed.
fixes #1987
depends on https://github.com/bitcoindevkit/rust-electrum-client/pull/170
### Description
- update `batch_fetch_anchors` to use `batch_transaction_get_merkle` method instead of manually creating the batch call.
### Changelog notice
```md
### Changes
- Use new `batch_transaction_get_merkle` method instead of batch raw calls
```
### Checklists
#### All Submissions:
* [x] I've signed all my commits
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
* [x] I ran `cargo +nightly fmt` and `cargo clippy` before committing
Leonardo Lima [Fri, 4 Jul 2025 18:46:03 +0000 (15:46 -0300)]
chore(bdk-electrum): use new `batch_transaction_get_merkle` API
- removes the now unused `serde_json` dependency from `bdk_electrum`.
- update `batch_fetch_anchors` to use `batch_transaction_get_merkle`
method instead of manually creating the batch call.
feat(chain): Txs that conflict with relevant txs are also relevant
Change behavior of {insert|apply}-if-relevant methods of `IndexedTxGraph`
to also consider txs that conflict with relevant txs as relevant.
Rationale:
It is useful to determine why something is evicted from the mempool.
For example, an incoming transaction may be evicted from the mempool due
to insufficient fees or a conflicting transaction is confirmed.
* Insufficient fees - the user may want to CPFP the tx.
* Conflicting tx is confirmed - the sender probably purposefully
cancelled the tx. The user may want to forget about this tx once it
reaches x confirmations.
The `IntentTracker` will make use of these relevant-conflicts.
A note about chain sources:
For some chain sources, obtaining relevant-conflicts is extremely
costly or downright impossible (i.e. Electrum, BIP-158 filters).
`bdk_bitcoind_rpc::Emitter` is still the most robust chain source to use.
Automated update to Github CI workflow `cont_integration.yml` by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action
As explained in #1984 , I discovered some misreportings in the coverage information given by grcov.
Fixes #1984
### Notes to the reviewers
The discussion about the tool to use is open, but I'm adding this PR to showcase how a change from `grcov` to `cargo-llvm-cov` would look like and the improvements in reporting this change will bring. [Look the report in `coveralls`](https://coveralls.io/github/nymius/bdk?branch=ci/replace-grcov-by-cargo-llvm-cov) to get a better perspective of them.
### Checklists
#### All Submissions:
* [x] I've signed all my commits
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
* [x] I ran `cargo +nightly fmt` and `cargo clippy` before committing
There is a bug in `bdk_bitcoind_rpc` where some new mempool transactions will not be emitted at all.
This problem exists because the avoid-re-emission logic depends on rounded-to-nearest-second timestamps.
The fix is to just emit all mempool transactions but wrap them in `Arc`s so that emission becomes cheap.
**Background:** I tried using `bdk_bitcoind_rpc` as the chain-source to write an example to showcase the [`IntentTracker`](https://github.com/bitcoindevkit/bdk_wallet/pull/257). However, `bdk_bitcoind_rpc` failed to emit some mempool transactions.
### Notes to the reviewers
The test added in c22c68f fails without these fixes.
Some tests are removed as they are no longer relevant.
### Changelog notice
```md
Fixed:
- Some mempool transactions not being emitted at all. The fix is to replace the avoid-re-emission-logic with one which emits all mempool transactions.
```
### Checklists
#### All Submissions:
* [x] I've signed all my commits
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
* [x] I ran `cargo +nightly fmt` and `cargo clippy` before committing
#### Bugfixes:
* [x] This pull request breaks the existing API
* [x] I've added tests to reproduce the issue which are now passing
~* [ ] I'm linking the issue being fixed by this PR~
Ideally, this would be included as a field in `TxNode`, however that would be a breaking change.
### Changelog notice
```md
Added
- `TxGraph::get_last_evicted`
```
### Checklists
#### All Submissions:
* [x] I've signed all my commits
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
* [x] I ran `cargo +nightly fmt` and `cargo clippy` before committing
#### New Features:
~* [ ] I've added tests for the new feature~
* [x] I've added docs for the new feature
This PR eliminates all `unwrap()` and `expect()` calls from `bdk_electrum_client`, replacing them with proper error handling. Given that all public methods already return `Result`, we now propagate error messages instead of panicking.
### Changelog notice
* Removed all `unwrap()`s and `expect()`s from `bdk_electrum_client.rs`.
### Checklists
#### All Submissions:
* [x] I've signed all my commits
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
* [x] I ran `cargo +nightly fmt` and `cargo clippy` before committing
This patch improves readability and maintains logical consistency with the use of `spk_cache` throughout the `keychain_txout` module.
While it might offer a performance benefit, the results are mostly comparable with the current benchmarks as far as I can tell. At least there's no indication that it would negatively impact performance.
fixes #1975
### Changelog notice
### Checklists
#### All Submissions:
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
The logic in `CanonicalIter` includes transactions anchored to blocks outside the best chain, since they may still appear in the mempool.
However, coinbase transactions can never be unconfirmed—a case the previous logic failed to exclude.
### Notes to the reviewers
Sorry for my previous oversight on this.
### Changelog notice
```md
Fixed:
- During canonicalization, exclude coinbase transactions when considering txs that are anchored in stale blocks.
```
### Checklists
#### All Submissions:
* [x] I've signed all my commits
* [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
* [x] I ran `cargo +nightly fmt` and `cargo clippy` before committing
#### Bugfixes:
~* [ ] This pull request breaks the existing API~
* [x] I've added tests to reproduce the issue which are now passing
* [ ] I'm linking the issue being fixed by this PR