1
1
//! Module for structures that store and traverse transactions.
2
2
//!
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.
7
+ //! Furthermore, there is currently no way to delete a transaction.
8
+ //!
9
+ //! Transactions can be either whole or partial (i.e., transactions for which we only
10
+ //! know some outputs, which we usually call "floating outputs").
11
+ //!
12
+ //! The graph contains transactions in the form of [`TxNode`]s. Each node contains the
13
+ //! txid, the transaction (whole or partial), the blocks it's anchored in (see the [`Anchor`]
14
+ //! documentation for more details), and the timestamp of the last time we saw
15
+ //! the transaction as unconfirmed.
7
16
//!
8
17
//! Conflicting transactions are allowed to coexist within a [`TxGraph`]. This is useful for
9
- //! identifying and traversing conflicts and descendants of a given transaction.
18
+ //! identifying and traversing conflicts and descendants of a given transaction. Some [`TxGraph`]
19
+ //! methods only consider "canonical" (i.e., in the best chain or in mempool) transactions,
20
+ //! we decide which transactions are canonical based on anchors `last_seen_unconfirmed`;
21
+ //! see the [`try_get_chain_position`] documentation for more details.
22
+ //!
23
+ //! The [`ChangeSet`] reports changes made to a [`TxGraph`]; it can be used to either save to
24
+ //! persistent storage, or to be applied to another [`TxGraph`].
25
+ //!
26
+ //! Lastly, you can use [`TxAncestors`]/[`TxDescendants`] to traverse ancestors and descendants of
27
+ //! a given transaction, respectively.
10
28
//!
11
29
//! # Applying changes
12
30
//!
49
67
//! let changeset = graph.apply_update(update);
50
68
//! assert!(changeset.is_empty());
51
69
//! ```
70
+ //! [`try_get_chain_position`]: TxGraph::try_get_chain_position
52
71
53
72
use crate :: {
54
73
collections:: * , keychain:: Balance , local_chain:: LocalChain , Anchor , Append , BlockId ,
@@ -90,7 +109,7 @@ impl<A> Default for TxGraph<A> {
90
109
}
91
110
}
92
111
93
- /// An outward-facing view of a ( transaction) node in the [`TxGraph`].
112
+ /// A transaction node in the [`TxGraph`].
94
113
#[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
95
114
pub struct TxNode < ' a , T , A > {
96
115
/// Txid of the transaction.
@@ -127,7 +146,7 @@ impl Default for TxNodeInternal {
127
146
}
128
147
}
129
148
130
- /// An outwards-facing view of a transaction that is part of the *best chain*'s history .
149
+ /// A transaction that is included in a certain chain.
131
150
#[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
132
151
pub struct CanonicalTx < ' a , T , A > {
133
152
/// How the transaction is observed as (confirmed or unconfirmed).
@@ -454,7 +473,7 @@ impl<A: Clone + Ord> TxGraph<A> {
454
473
/// Batch insert unconfirmed transactions.
455
474
///
456
475
/// 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
476
+ /// *last seen* communicates when the transaction is last seen in mempool which is used for
458
477
/// conflict-resolution (refer to [`TxGraph::insert_seen_at`] for details).
459
478
pub fn batch_insert_unconfirmed (
460
479
& mut self ,
@@ -687,8 +706,21 @@ impl<A: Anchor> TxGraph<A> {
687
706
688
707
/// Get the position of the transaction in `chain` with tip `chain_tip`.
689
708
///
690
- /// If the given transaction of `txid` does not exist in the chain of `chain_tip`, `None` is
691
- /// returned.
709
+ /// If the given `txid` does not exist in the chain of `chain_tip`, and
710
+ /// we believe that the transaction is not in mempool anymore, `None` is returned.
711
+ ///
712
+ /// There are two factors that we use to approximate whether an unconfirmed
713
+ /// transaction currently exists in mempool:
714
+ /// 1. Conflicts with confirmed txs. If the transaction `tx` or any of its unconfirmed
715
+ /// ancestors conflict with a confirmed transaction, then `tx` can't be in mempool.
716
+ /// 2. The `last_seen_unconfirmed` parameter. Given two conflicting transactions, we say
717
+ /// that the one with a higher `last_seen_unconfirmed` (i.e., we saw it later) has a higher
718
+ /// chance of still being in mempool. When trying to figure out if `tx`
719
+ /// is still in mempool, we first of all calculate `tx`'s `max_last_seen_unconfirmed`,
720
+ /// which is the max `last_seen_unconfirmed` between `tx` and all its descendants.
721
+ /// We then look at all the conflicts of `tx`, and if for all of them
722
+ /// `last_seen_unconfirmed` < `max_last_seen_unconfirmed` holds,
723
+ /// then we consider `tx` to be still in mempool.
692
724
///
693
725
/// # Error
694
726
///
@@ -714,7 +746,7 @@ impl<A: Anchor> TxGraph<A> {
714
746
}
715
747
}
716
748
717
- // The tx is not anchored to a block which is in the best chain, which means that it
749
+ // The tx is not anchored to a block in the best chain, which means that it
718
750
// might be in mempool, or it might have been dropped already.
719
751
// Let's check conflicts to find out!
720
752
let tx = match tx_node {
@@ -911,7 +943,8 @@ impl<A: Anchor> TxGraph<A> {
911
943
/// (`OI`) for convenience. If `OI` is not necessary, the caller can use `()`, or
912
944
/// [`Iterator::enumerate`] over a list of [`OutPoint`]s.
913
945
///
914
- /// Floating outputs are ignored.
946
+ /// Floating outputs (i.e., outputs for which we don't have the full transaction in the graph)
947
+ /// are ignored.
915
948
///
916
949
/// # Error
917
950
///
0 commit comments