Commit 023fdf0
committed
Merge bitcoindevkit#2038: refactor(chain,core)!: replace
555f774 fix(chain): position resolution for assumed txs (Leonardo Lima)
4f10cde chore(chain,example)!: remove `ChainOracle`, update docs (志宇)
a3c73e4 refactor(chain)!: split `canonical_view` into `canonical`,`canonical_view_task` (志宇)
22b04c3 refactor(chain)!: split canonicalization into two tasks with generic `Canonical<A, P>` (志宇)
a9f5ca4 refactor(chain)!: remove `CanonicalIter` APIs (Leonardo Lima)
bb83da8 chore(workspace): use new `LocalChain::canonical_view` API (Leonardo Lima)
987da73 feat(core,chain): introduce `CanonicalizationTask` and `ChainQuery` (Leonardo Lima)
Pull request description:
fixes bitcoindevkit#1816
### Description
Replaces the iterator-based `CanonicalIter` with a two-phase sans-IO canonicalization pipeline, and introduces a generic `ChainQuery` trait in `bdk_core` to decouple canonicalization from chain sources.
**Old API:**
```rust
// Direct coupling between canonicalization logic and ChainOracle
let view = tx_graph.canonical_view(&chain, chain_tip, params)?;
```
**New API:**
```rust
// Option A: Two-phase (full control)
let canonical_txs = chain.canonicalize(tx_graph.canonical_task(tip, params));
let view = chain.canonicalize(canonical_txs.view_task(&tx_graph));
// Option B: Convenience method
let view = chain.canonical_view(&tx_graph, tip, params);
```
#### Phase 1: `CanonicalTask`
Determines which transactions are canonical by processing them in stages:
1. **Assumed txs** — transactions assumed canonical via `CanonicalParams`
2. **Anchored txs** — transactions anchored in the best chain (descending height)
3. **Seen txs** — unconfirmed transactions by descending last-seen time
4. **Remaining txs** — leftover anchored transactions not in the best chain
Produces a `CanonicalTxs<A>` containing each canonical transaction with its `CanonicalReason`.
#### Phase 2: `CanonicalViewTask`
Resolves `CanonicalReason`s into concrete `ChainPosition`s (confirmed height or unconfirmed with last-seen), producing the final `CanonicalView<A>`.
Both phases implement the `ChainQuery` trait, so any chain source can drive them via the same `next_query`/`resolve_query` loop.
#### Key structural changes
- **`ChainQuery` trait** added to `bdk_core` — a generic sans-IO interface (`next_query` → `resolve_query` → `finish`) for any algorithm that needs to verify blocks against a chain source.
- **`ChainOracle` trait removed** — replaced by `ChainQuery`. `LocalChain::canonicalize()` now drives any `ChainQuery` implementor.
- **`Canonical<A, P>` generic container** — `CanonicalTxs<A>` (phase 1 output) and `CanonicalView<A>` (phase 2 output) are type aliases over `Canonical<A, P>`.
- **Module split** — `canonical_view.rs` split into `canonical.rs` (types: `Canonical`, `CanonicalTx`, `CanonicalTxOut`) and `canonical_view_task.rs` (phase 2 task). `canonical_iter.rs` replaced by `canonical_task.rs`.
### Notes to the reviewers
The changes are split into multiple commits for easier review. Also depends on bitcoindevkit#2029.
### Changelog notice
```
### Added
- `bdk_core::ChainQuery` trait — generic sans-IO interface for chain verification queries
- `bdk_core::ChainRequest` / `ChainResponse` type aliases
- `CanonicalTask` — phase 1 sans-IO canonicalization (determines canonical txs)
- `CanonicalViewTask` — phase 2 sans-IO canonicalization (resolves chain positions)
- `Canonical<A, P>` generic container with `CanonicalTxs<A>` and `CanonicalView<A>` aliases
- `LocalChain::canonicalize()` — drives any `ChainQuery` implementor
- `LocalChain::canonical_view()` — convenience method for full two-phase canonicalization
### Changed
- **Breaking:** Replace `TxGraph::canonical_iter()` / `TxGraph::canonical_view()` with `TxGraph::canonical_task()`
- **Breaking:** Canonicalization now uses a two-phase sans-IO process via `ChainQuery`
- **Breaking:** `ChainQuery`, `ChainRequest`, `ChainResponse` have no generics (use `BlockId` directly)
- **Breaking:** Chain tip moved from `ChainRequest` to `ChainQuery::tip()`
### Removed
- **Breaking:** `ChainOracle` trait and all implementations
- **Breaking:** `CanonicalIter` type and `canonical_iter` module
- **Breaking:** `TxGraph::try_canonical_view()` and `TxGraph::canonical_view()` methods
- **Breaking:** `CanonicalView::new()` public constructor
```
### 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
ACKs for top commit:
evanlinjin:
ACK 555f774
Tree-SHA512: ce466a623a1f8df20dedd3e4e68460892bd369567db44e6ba391c3d9ae1d10bca6204ebdcdb7b1376a9c97f3155b89e991846af4122e200d1fa15d998deb7830CanonicalIter with sans-IO CanonicalTask + ChainQuery trait25 files changed
Lines changed: 1432 additions & 885 deletions
File tree
- crates
- bitcoind_rpc
- examples
- tests
- chain
- benches
- src
- tests
- common
- core/src
- electrum/tests
- esplora/tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
72 | | - | |
| 72 | + | |
| 73 | + | |
73 | 74 | | |
74 | 75 | | |
75 | 76 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
318 | 318 | | |
319 | 319 | | |
320 | 320 | | |
321 | | - | |
322 | 321 | | |
323 | | - | |
324 | | - | |
325 | | - | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
326 | 329 | | |
327 | 330 | | |
328 | 331 | | |
| |||
631 | 634 | | |
632 | 635 | | |
633 | 636 | | |
634 | | - | |
635 | | - | |
| 637 | + | |
| 638 | + | |
636 | 639 | | |
637 | 640 | | |
638 | 641 | | |
| |||
647 | 650 | | |
648 | 651 | | |
649 | 652 | | |
650 | | - | |
651 | | - | |
| 653 | + | |
| 654 | + | |
652 | 655 | | |
653 | 656 | | |
654 | 657 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
2 | 1 | | |
3 | 2 | | |
4 | 3 | | |
| |||
95 | 94 | | |
96 | 95 | | |
97 | 96 | | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
| 97 | + | |
103 | 98 | | |
104 | 99 | | |
105 | 100 | | |
106 | 101 | | |
107 | 102 | | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
| 103 | + | |
113 | 104 | | |
114 | 105 | | |
115 | 106 | | |
116 | 107 | | |
117 | 108 | | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
| 109 | + | |
123 | 110 | | |
124 | 111 | | |
125 | 112 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
85 | | - | |
86 | 85 | | |
87 | | - | |
88 | | - | |
| 86 | + | |
| 87 | + | |
89 | 88 | | |
90 | 89 | | |
91 | 90 | | |
| |||
0 commit comments