From: Rafael Turon <3598269+rafaelturon@users.noreply.github.com> Date: Thu, 5 Mar 2026 21:02:06 +0000 (-0300) Subject: docs: document TxUpdate temporal context requirements X-Git-Url: http://internal-gitweb-vhost/parse/src/example_cli/%22https:/encode/struct.EncoderStringWriter.html?a=commitdiff_plain;h=b69d7bfce32d20a5849052a2e61bf8d8bff813a6;p=bdk docs: document TxUpdate temporal context requirements 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. This fulfills the recommendation outlined in the Wizardsardine BDK Audit Report (Q4 2024). Signed-off-by: Rafael Turon <3598269+rafaelturon@users.noreply.github.com> --- diff --git a/crates/chain/src/indexed_tx_graph.rs b/crates/chain/src/indexed_tx_graph.rs index 9adf7ed9..69337840 100644 --- a/crates/chain/src/indexed_tx_graph.rs +++ b/crates/chain/src/indexed_tx_graph.rs @@ -178,6 +178,10 @@ where /// /// `update` is a [`tx_graph::TxUpdate`] and the resultant changes is returned as /// [`ChangeSet`]. + /// + /// **Note**: Transactions in the `update` without temporal context (anchors or seen_ats) + /// will be stored but will not be considered canonical. See [`tx_graph::TxUpdate`] for + /// more details. pub fn apply_update(&mut self, update: tx_graph::TxUpdate) -> ChangeSet { let tx_graph = self.graph.apply_update(update); let indexer = self.index_tx_graph_changeset(&tx_graph); diff --git a/crates/chain/src/tx_graph.rs b/crates/chain/src/tx_graph.rs index 701de335..c2e77d34 100644 --- a/crates/chain/src/tx_graph.rs +++ b/crates/chain/src/tx_graph.rs @@ -913,6 +913,9 @@ impl TxGraph { /// /// The returned [`ChangeSet`] is the set difference between `update` and `self` (transactions /// that exist in `update` but not in `self`). + /// + /// **Note**: Transactions in the `update` without temporal context (anchors or seen_ats) + /// will be stored but will not be considered canonical. See [`TxUpdate`] for more details. pub fn apply_update(&mut self, update: TxUpdate) -> ChangeSet { let mut changeset = ChangeSet::::default(); for tx in update.txs { diff --git a/crates/core/src/tx_update.rs b/crates/core/src/tx_update.rs index 47489070..f92cf3e9 100644 --- a/crates/core/src/tx_update.rs +++ b/crates/core/src/tx_update.rs @@ -18,6 +18,13 @@ use bitcoin::{OutPoint, Transaction, TxOut, Txid}; /// tx_update.txs.push(tx); /// tx_update.anchors.insert((anchor, txid)); /// ``` +/// ## Temporal context +/// To contribute to a wallet's balance, transactions must have an entry in either: +/// - [`Self::anchors`]: for confirmed transactions. +/// - [`Self::seen_ats`]: for unconfirmed transactions. +/// +/// The built-in chain-source crates (`bdk_electrum`, `bdk_esplora`, `bdk_bitcoind_rpc`) handle this +/// automatically. Transactions lacking temporal context are stored but ignored by canonicalization. #[derive(Debug, Clone)] #[non_exhaustive] pub struct TxUpdate {