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`] contains transactions and indexes them so you can easily traverse the graph of those transactions. 
4+ //! `TxGraph` is *monotone* in that you can always insert a transaction -- it doesn't care whether that 
5+ //! transaction is in the current best chain or whether it conflicts with any of the 
6+ //! existing transactions or what order you insert the transactions. This means that you can always 
7+ //! combine two [`TxGraph`]s together, without resulting in inconsistencies. 
8+ //! Furthermore, there is currently no way to delete a transaction. 
9+ //! 
10+ //! Transactions can be either whole or partial (i.e., transactions for which we only 
11+ //! know some outputs, which we usually call "floating outputs"; these are usually inserted 
12+ //! using the [`insert_txout`] method.). 
13+ //! 
14+ //! The graph contains transactions in the form of [`TxNode`]s. Each node contains the 
15+ //! txid, the transaction (whole or partial), the blocks it's anchored in (see the [`Anchor`] 
16+ //! documentation for more details), and the timestamp of the last time we saw 
17+ //! the transaction as unconfirmed. 
718//! 
819//! Conflicting transactions are allowed to coexist within a [`TxGraph`]. This is useful for 
9- //! identifying and traversing conflicts and descendants of a given transaction. 
20+ //! identifying and traversing conflicts and descendants of a given transaction. Some [`TxGraph`] 
21+ //! methods only consider "canonical" (i.e., in the best chain or in mempool) transactions, 
22+ //! we decide which transactions are canonical based on anchors `last_seen_unconfirmed`; 
23+ //! see the [`try_get_chain_position`] documentation for more details. 
24+ //! 
25+ //! The [`ChangeSet`] reports changes made to a [`TxGraph`]; it can be used to either save to 
26+ //! persistent storage, or to be applied to another [`TxGraph`]. 
27+ //! 
28+ //! Lastly, you can use [`TxAncestors`]/[`TxDescendants`] to traverse ancestors and descendants of 
29+ //! a given transaction, respectively. 
1030//! 
1131//! # Applying changes 
1232//! 
4969//! let changeset = graph.apply_update(update); 
5070//! assert!(changeset.is_empty()); 
5171//! ``` 
72+ //! [`try_get_chain_position`]: TxGraph::try_get_chain_position 
73+ //! [`insert_txout`]: TxGraph::insert_txout 
5274
5375use  crate :: { 
5476    collections:: * ,  keychain:: Balance ,  local_chain:: LocalChain ,  Anchor ,  Append ,  BlockId , 
@@ -90,7 +112,7 @@ impl<A> Default for TxGraph<A> {
90112    } 
91113} 
92114
93- /// An outward-facing view of a ( transaction)  node in the [`TxGraph`]. 
115+ /// A  transaction node in the [`TxGraph`]. 
94116#[ derive( Clone ,  Debug ,  PartialEq ,  Eq ,  PartialOrd ,  Ord ) ]  
95117pub  struct  TxNode < ' a ,  T ,  A >  { 
96118    /// Txid of the transaction. 
@@ -127,7 +149,7 @@ impl Default for TxNodeInternal {
127149    } 
128150} 
129151
130- /// An outwards-facing view of a  transaction that is part of  the *best  chain*'s history . 
152+ /// A  transaction that is included in  the chain, or is still in mempool . 
131153#[ derive( Clone ,  Debug ,  PartialEq ,  Eq ,  PartialOrd ,  Ord ) ]  
132154pub  struct  CanonicalTx < ' a ,  T ,  A >  { 
133155    /// How the transaction is observed as (confirmed or unconfirmed). 
@@ -454,7 +476,7 @@ impl<A: Clone + Ord> TxGraph<A> {
454476    /// Batch insert unconfirmed transactions. 
455477     /// 
456478     /// Items of `txs` are tuples containing the transaction and a *last seen* timestamp. The 
457-      /// *last seen* communicates when the transaction is last seen in the  mempool which is used for 
479+      /// *last seen* communicates when the transaction is last seen in mempool which is used for 
458480     /// conflict-resolution (refer to [`TxGraph::insert_seen_at`] for details). 
459481     pub  fn  batch_insert_unconfirmed ( 
460482        & mut  self , 
@@ -480,7 +502,7 @@ impl<A: Clone + Ord> TxGraph<A> {
480502
481503    /// Inserts the given `seen_at` for `txid` into [`TxGraph`]. 
482504     /// 
483-      /// Note that [`TxGraph`] only keeps track of the lastest  `seen_at`. 
505+      /// Note that [`TxGraph`] only keeps track of the latest  `seen_at`. 
484506     pub  fn  insert_seen_at ( & mut  self ,  txid :  Txid ,  seen_at :  u64 )  -> ChangeSet < A >  { 
485507        let  mut  update = Self :: default ( ) ; 
486508        let  ( _,  _,  update_last_seen)  = update. txs . entry ( txid) . or_default ( ) ; 
@@ -687,8 +709,21 @@ impl<A: Anchor> TxGraph<A> {
687709
688710    /// Get the position of the transaction in `chain` with tip `chain_tip`. 
689711     /// 
690-      /// If the given transaction of `txid` does not exist in the chain of `chain_tip`, `None` is 
691-      /// returned. 
712+      /// If the given `txid` does not exist in the chain of `chain_tip`, and 
713+      /// we believe that the transaction is not in mempool anymore, `None` is returned. 
714+      /// 
715+      /// There are two factors that we use to approximate whether an unconfirmed 
716+      /// transaction currently exists in mempool: 
717+      /// 1. Conflicts with confirmed txs. If the transaction `tx` or any of its unconfirmed 
718+      /// ancestors conflict with a confirmed transaction, then `tx` can't be in mempool. 
719+      /// 2. The `last_seen_unconfirmed` parameter. Given two conflicting transactions, we say 
720+      /// that the one with a higher `last_seen_unconfirmed` (i.e., we saw it later) has a higher 
721+      /// chance of still being in mempool. When trying to figure out if `tx` 
722+      /// is still in mempool, we first of all calculate `tx`'s `max_last_seen_unconfirmed`, 
723+      /// which is the max `last_seen_unconfirmed` between `tx` and all its descendants. 
724+      /// We then look at all the conflicts of `tx`, and if for all of them 
725+      /// `last_seen_unconfirmed` < `max_last_seen_unconfirmed` holds, 
726+      /// then we consider `tx` to be still in mempool. 
692727     /// 
693728     /// # Error 
694729     /// 
@@ -714,7 +749,7 @@ impl<A: Anchor> TxGraph<A> {
714749            } 
715750        } 
716751
717-         // The tx is not anchored to a block which is  in the best chain, which means that it 
752+         // The tx is not anchored to a block in the best chain, which means that it 
718753        // might be in mempool, or it might have been dropped already. 
719754        // Let's check conflicts to find out! 
720755        let  tx = match  tx_node { 
@@ -911,7 +946,8 @@ impl<A: Anchor> TxGraph<A> {
911946     /// (`OI`) for convenience. If `OI` is not necessary, the caller can use `()`, or 
912947     /// [`Iterator::enumerate`] over a list of [`OutPoint`]s. 
913948     /// 
914-      /// Floating outputs are ignored. 
949+      /// Floating outputs (i.e., outputs for which we don't have the full transaction in the graph) 
950+      /// are ignored. 
915951     /// 
916952     /// # Error 
917953     /// 
@@ -1238,7 +1274,7 @@ impl<A> AsRef<TxGraph<A>> for TxGraph<A> {
12381274/// 
12391275/// The iterator excludes partial transactions. 
12401276/// 
1241- /// This ` struct`  is created by the [`walk_ancestors`] method of [`TxGraph`]. 
1277+ /// This struct is created by the [`walk_ancestors`] method of [`TxGraph`]. 
12421278/// 
12431279/// [`walk_ancestors`]: TxGraph::walk_ancestors 
12441280pub  struct  TxAncestors < ' g ,  A ,  F >  { 
0 commit comments