Skip to content

Commit bb0888f

Browse files
doc: Improve TxGraph & co docs
1 parent 6ebdd19 commit bb0888f

File tree

6 files changed

+56
-21
lines changed

6 files changed

+56
-21
lines changed

crates/chain/src/chain_data.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ impl From<(&u32, &BlockHash)> for BlockId {
147147

148148
/// An [`Anchor`] implementation that also records the exact confirmation height of the transaction.
149149
///
150+
/// Note that the confirmation block and the anchor block can be different here. If you
151+
/// know they're always going to be the same, you can use the [`BlockId`] anchor instead.
152+
///
150153
/// Refer to [`Anchor`] for more details.
151154
#[derive(Debug, Default, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
152155
#[cfg_attr(
@@ -186,6 +189,9 @@ impl AnchorFromBlockPosition for ConfirmationHeightAnchor {
186189
/// An [`Anchor`] implementation that also records the exact confirmation time and height of the
187190
/// transaction.
188191
///
192+
/// Note that the confirmation block and the anchor block can be different here. If you
193+
/// know they're always going to be the same, you can use the [`BlockId`] anchor instead.
194+
///
189195
/// Refer to [`Anchor`] for more details.
190196
#[derive(Debug, Default, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
191197
#[cfg_attr(

crates/chain/src/chain_oracle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::BlockId;
33
/// Represents a service that tracks the blockchain.
44
///
55
/// The main method is [`is_block_in_chain`] which determines whether a given block of [`BlockId`]
6-
/// is an ancestor of another "static block".
6+
/// is an ancestor of the `chain_tip`.
77
///
88
/// [`is_block_in_chain`]: Self::is_block_in_chain
99
pub trait ChainOracle {

crates/chain/src/indexed_tx_graph.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
//! Contains the [`IndexedTxGraph`] structure and associated types.
1+
//! Contains the [`Indexer`] trait, the [`IndexedTxGraph`] structure,
2+
//! and the associated [`ChangeSet`].
23
//!
3-
//! This is essentially a [`TxGraph`] combined with an indexer.
4+
//! The [`IndexedTxGraph`] is essentially a [`TxGraph`] combined with
5+
//! an implementation of the [`Indexer`] trait.
46
57
use alloc::vec::Vec;
68
use bitcoin::{Block, OutPoint, Transaction, TxOut, Txid};

crates/chain/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212
//! you do it synchronously or asynchronously. If you know a fact about the blockchain, you can just
1313
//! tell `bdk_chain`'s APIs about it, and that information will be integrated, if it can be done
1414
//! consistently.
15-
//! 2. Error-free APIs.
16-
//! 3. Data persistence agnostic -- `bdk_chain` does not care where you cache on-chain data, what you
17-
//! cache or how you fetch it.
15+
//! 2. Data persistence agnostic -- `bdk_chain` does not care where you cache on-chain data, what you
16+
//! cache or how you retrieve it from persistence.
1817
//!
1918
//! [Bitcoin Dev Kit]: https://bitcoindevkit.org/
2019

crates/chain/src/tx_data_traits.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,22 @@ use alloc::vec::Vec;
55

66
/// Trait that "anchors" blockchain data to a specific block of height and hash.
77
///
8-
/// [`Anchor`] implementations must be [`Ord`] by the anchor block's [`BlockId`] first.
9-
///
10-
/// I.e. If transaction A is anchored in block B, then if block B is in the best chain, we can
8+
/// If transaction A is anchored in block B, then if block B is in the best chain, we can
119
/// assume that transaction A is also confirmed in the best chain. This does not necessarily mean
1210
/// that transaction A is confirmed in block B. It could also mean transaction A is confirmed in a
1311
/// parent block of B.
1412
///
13+
/// Every [`Anchor`] implementation must contain a [`BlockId`] parameter, and must implement
14+
/// [`Ord`]. When implementing [`Ord`], the first elements to compare must be the anchors'
15+
/// [`BlockId`]s.
16+
///
1517
/// ```
1618
/// # use bdk_chain::local_chain::LocalChain;
1719
/// # use bdk_chain::tx_graph::TxGraph;
1820
/// # use bdk_chain::BlockId;
1921
/// # use bdk_chain::ConfirmationHeightAnchor;
2022
/// # use bdk_chain::example_utils::*;
2123
/// # use bitcoin::hashes::Hash;
22-
///
2324
/// // Initialize the local chain with two blocks.
2425
/// let chain = LocalChain::from_blocks(
2526
/// [

crates/chain/src/tx_graph.rs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
//! Module for structures that store and traverse transactions.
22
//!
3-
//! [`TxGraph`] is a monotone structure that inserts transactions and indexes the spends. The
4-
//! [`ChangeSet`] structure reports changes of [`TxGraph`] but can also be applied to a
5-
//! [`TxGraph`] as well. Lastly, [`TxDescendants`] is an [`Iterator`] that traverses descendants of
6-
//! a given transaction.
3+
//! [`TxGraph`] is a monotone structure that contains transactions and indexes the spends. It can
4+
//! contain either full transactions, or partial transactions (transactions for which we have only
5+
//! certain outputs, which we usually call "floating outputs").
6+
//!
7+
//! The graph contains transactions in the form of [`TxNode`] structures. Each node contains the
8+
//! txid, the transaction (whole or partial), the blocks it's anchored in (see the [`Anchor`]
9+
//! documentation for more details), and the timestamp of the last time we saw
10+
//! the transaction as unconfirmed.
711
//!
812
//! Conflicting transactions are allowed to coexist within a [`TxGraph`]. This is useful for
9-
//! identifying and traversing conflicts and descendants of a given transaction.
13+
//! identifying and traversing conflicts and descendants of a given transaction. Some [`TxGraph`]
14+
//! methods only consider "canonical" (i.e., in the best chain or in mempool) transactions,
15+
//! we decide which transactions are canonical based on anchors `last_seen_unconfirmed`;
16+
//! see the [`try_get_chain_position`] documentation for more details.
17+
//!
18+
//! The [`ChangeSet`] structure reports changes of [`TxGraph`]; it can be used to either save to persistance,
19+
//! or to be applied to another [`TxGraph`].
20+
//!
21+
//! Lastly, you can use [`TxAncestors`]/[`TxDescendants`] to traverse ancestors and descendants of
22+
//! a given transaction.
1023
//!
1124
//! # Applying changes
1225
//!
@@ -49,6 +62,7 @@
4962
//! let changeset = graph.apply_update(update);
5063
//! assert!(changeset.is_empty());
5164
//! ```
65+
//! [`try_get_chain_position`]: TxGraph::try_get_chain_position
5266
5367
use crate::{
5468
collections::*, keychain::Balance, local_chain::LocalChain, Anchor, Append, BlockId,
@@ -90,7 +104,7 @@ impl<A> Default for TxGraph<A> {
90104
}
91105
}
92106

93-
/// An outward-facing view of a (transaction) node in the [`TxGraph`].
107+
/// A transaction node in the [`TxGraph`].
94108
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
95109
pub struct TxNode<'a, T, A> {
96110
/// Txid of the transaction.
@@ -127,7 +141,7 @@ impl Default for TxNodeInternal {
127141
}
128142
}
129143

130-
/// An outwards-facing view of a transaction that is part of the *best chain*'s history.
144+
/// A transaction that is included in a certain chain.
131145
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
132146
pub struct CanonicalTx<'a, T, A> {
133147
/// How the transaction is observed as (confirmed or unconfirmed).
@@ -687,8 +701,20 @@ impl<A: Anchor> TxGraph<A> {
687701

688702
/// Get the position of the transaction in `chain` with tip `chain_tip`.
689703
///
690-
/// If the given transaction of `txid` does not exist in the chain of `chain_tip`, `None` is
691-
/// returned.
704+
/// If the given `txid` does not exist in the chain of `chain_tip`, and
705+
/// we believe that the transaction is not in mempool anymore, `None` is returned.
706+
///
707+
/// We determine whether the transaction `tx` is in the mempool or not by looking at
708+
/// tx's conflicting transactions, and tx's ancestors' conflicting transactions;
709+
/// if in these transactions we find one which is anchored to a block in the best chain,
710+
/// then `tx` can't be in mempool.
711+
///
712+
/// Otherwise, we decide which transactions are in mempool based on their
713+
/// `last_seen_unconfirmed`. We first of all calculate `tx`'s `max_last_seen_unconfirmed`,
714+
/// which is the max `last_seen_unconfirmed` between `tx` and all its descendants.
715+
/// We then look at all the conflicts of `tx`, and if all of them have
716+
/// `last_seen_unconfirmed` < `max_last_seen_unconfirmed`, then we consider `tx` to be still
717+
/// in mempool.
692718
///
693719
/// # Error
694720
///
@@ -714,7 +740,7 @@ impl<A: Anchor> TxGraph<A> {
714740
}
715741
}
716742

717-
// The tx is not anchored to a block which is in the best chain, which means that it
743+
// The tx is not anchored to a block in the best chain, which means that it
718744
// might be in mempool, or it might have been dropped already.
719745
// Let's check conflicts to find out!
720746
let tx = match tx_node {
@@ -911,7 +937,8 @@ impl<A: Anchor> TxGraph<A> {
911937
/// (`OI`) for convenience. If `OI` is not necessary, the caller can use `()`, or
912938
/// [`Iterator::enumerate`] over a list of [`OutPoint`]s.
913939
///
914-
/// Floating outputs are ignored.
940+
/// Floating outputs (i.e., outputs for which we don't have the full transaction in the graph)
941+
/// are ignored.
915942
///
916943
/// # Error
917944
///

0 commit comments

Comments
 (0)