Skip to content

Commit f2e7a78

Browse files
committed
Merge bitcoindevkit#2135: docs: Document TxUpdate temporal context requirements (supports Wizardsardine audit recommendation)
b69d7bf docs: document TxUpdate temporal context requirements (Rafael Turon) Pull request description: Closes bitcoindevkit#2133 This introduces clear temporal context **documentation** to the `TxUpdate` struct, explicitly stating that entries must have either `anchors` or `seen_ats` to be considered canonical and contribute to wallet balances. It also explicitly documents the `seen_ats` HashSet signature to prevent usage errors when writing custom chain sources. This fulfills the recommendation outlined in the Wizardsardine BDK Audit Report (Q4 2024). ### Description This primarily affects developers building **custom chain sources** — anyone constructing `Update` structs outside of `bdk_electrum`/`bdk_esplora`/`bdk_bitcoind_rpc`. As the ecosystem grows (streaming Electrum, Nostr relay sync, compact block filters, custom backends), more developers will encounter this undocumented contract. ### What I Changed *1. Doc comment on `TxUpdate` struct* * **`anchors` or `seen_ats`** are stored in the graph but do not affect the balance. * **`seen_ats` collection type**: `TxUpdate::seen_ats` is a `BTreeSet<(Txid, u64)>`, requiring `.insert((txid, timestamp))`. *2. Doc comment on `Wallet::apply_update()`* * **TxGraph `apply_update`**: transactions without temporal context note. * **IndexedTxGraph `apply_update`**: transactions without temporal context note. ### Impact This is just a documentation fix - no code changes, no breaking changes. ### Checklists #### All Submissions: * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) ACKs for top commit: evanlinjin: ACK b69d7bf Tree-SHA512: 669fbd2c23f7615c697d550ab448b3fd72955223cef4146d6719e2d0c26b959253ce987eebf737366968cb88e5477a897289274ddf78c1ffd338be4e5d795f4b
2 parents fb05873 + b69d7bf commit f2e7a78

3 files changed

Lines changed: 14 additions & 0 deletions

File tree

crates/chain/src/indexed_tx_graph.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ where
178178
///
179179
/// `update` is a [`tx_graph::TxUpdate<A>`] and the resultant changes is returned as
180180
/// [`ChangeSet`].
181+
///
182+
/// **Note**: Transactions in the `update` without temporal context (anchors or seen_ats)
183+
/// will be stored but will not be considered canonical. See [`tx_graph::TxUpdate`] for
184+
/// more details.
181185
pub fn apply_update(&mut self, update: tx_graph::TxUpdate<A>) -> ChangeSet<A, I::ChangeSet> {
182186
let tx_graph = self.graph.apply_update(update);
183187
let indexer = self.index_tx_graph_changeset(&tx_graph);

crates/chain/src/tx_graph.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,9 @@ impl<A: Anchor> TxGraph<A> {
912912
///
913913
/// The returned [`ChangeSet`] is the set difference between `update` and `self` (transactions
914914
/// that exist in `update` but not in `self`).
915+
///
916+
/// **Note**: Transactions in the `update` without temporal context (anchors or seen_ats)
917+
/// will be stored but will not be considered canonical. See [`TxUpdate`] for more details.
915918
pub fn apply_update(&mut self, update: TxUpdate<A>) -> ChangeSet<A> {
916919
let mut changeset = ChangeSet::<A>::default();
917920
for tx in update.txs {

crates/core/src/tx_update.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ use bitcoin::{OutPoint, Transaction, TxOut, Txid};
1818
/// tx_update.txs.push(tx);
1919
/// tx_update.anchors.insert((anchor, txid));
2020
/// ```
21+
/// ## Temporal context
22+
/// To contribute to a wallet's balance, transactions must have an entry in either:
23+
/// - [`Self::anchors`]: for confirmed transactions.
24+
/// - [`Self::seen_ats`]: for unconfirmed transactions.
25+
///
26+
/// The built-in chain-source crates (`bdk_electrum`, `bdk_esplora`, `bdk_bitcoind_rpc`) handle this
27+
/// automatically. Transactions lacking temporal context are stored but ignored by canonicalization.
2128
#[derive(Debug, Clone)]
2229
#[non_exhaustive]
2330
pub struct TxUpdate<A = ()> {

0 commit comments

Comments
 (0)