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//!
4962//! let changeset = graph.apply_update(update);
5063//! assert!(changeset.is_empty());
5164//! ```
65+ //! [`try_get_chain_position`]: TxGraph::try_get_chain_position
5266
5367use 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 ) ]
95109pub 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 ) ]
132146pub 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