pub struct TxGraph<A = ()> { /* private fields */ }
Expand description
A graph of transactions and spends.
See the module-level documentation for more.
Implementations§
source§impl<A> TxGraph<A>
impl<A> TxGraph<A>
sourcepub fn all_txouts(&self) -> impl Iterator<Item = (OutPoint, &TxOut)>
pub fn all_txouts(&self) -> impl Iterator<Item = (OutPoint, &TxOut)>
Iterate over all tx outputs known by TxGraph
.
This includes txouts of both full transactions as well as floating transactions.
sourcepub fn floating_txouts(&self) -> impl Iterator<Item = (OutPoint, &TxOut)>
pub fn floating_txouts(&self) -> impl Iterator<Item = (OutPoint, &TxOut)>
Iterate over floating txouts known by TxGraph
.
Floating txouts are txouts that do not have the residing full transaction contained in the graph.
sourcepub fn full_txs(&self) -> impl Iterator<Item = TxNode<'_, Arc<Transaction>, A>>
pub fn full_txs(&self) -> impl Iterator<Item = TxNode<'_, Arc<Transaction>, A>>
Iterate over all full transactions in the graph.
sourcepub fn get_tx(&self, txid: Txid) -> Option<Arc<Transaction>>
pub fn get_tx(&self, txid: Txid) -> Option<Arc<Transaction>>
Get a transaction by txid. This only returns Some
for full transactions.
Refer to get_txout
for getting a specific [TxOut
].
sourcepub fn get_tx_node(&self, txid: Txid) -> Option<TxNode<'_, Arc<Transaction>, A>>
pub fn get_tx_node(&self, txid: Txid) -> Option<TxNode<'_, Arc<Transaction>, A>>
Get a transaction node by txid. This only returns Some
for full transactions.
sourcepub fn get_txout(&self, outpoint: OutPoint) -> Option<&TxOut>
pub fn get_txout(&self, outpoint: OutPoint) -> Option<&TxOut>
Obtains a single tx output (if any) at the specified outpoint.
sourcepub fn tx_outputs(&self, txid: Txid) -> Option<BTreeMap<u32, &TxOut>>
pub fn tx_outputs(&self, txid: Txid) -> Option<BTreeMap<u32, &TxOut>>
Returns known outputs of a given txid
.
Returns a BTreeMap
of vout to output of the provided txid
.
sourcepub fn calculate_fee(&self, tx: &Transaction) -> Result<u64, CalculateFeeError>
pub fn calculate_fee(&self, tx: &Transaction) -> Result<u64, CalculateFeeError>
Calculates the fee of a given transaction. Returns 0 if tx
is a coinbase transaction.
Returns OK(_)
if we have all the [TxOut
]s being spent by tx
in the graph (either as
the full transactions or individual txouts).
To calculate the fee for a [Transaction
] that depends on foreign [TxOut
] values you must
first manually insert the foreign TxOuts into the tx graph using the insert_txout
function.
Only insert TxOuts you trust the values for!
Note tx
does not have to be in the graph for this to work.
sourcepub fn outspends(&self, outpoint: OutPoint) -> &HashSet<Txid>
pub fn outspends(&self, outpoint: OutPoint) -> &HashSet<Txid>
The transactions spending from this output.
TxGraph
allows conflicting transactions within the graph. Obviously the transactions in
the returned set will never be in the same active-chain.
sourcepub fn tx_spends(
&self,
txid: Txid
) -> impl DoubleEndedIterator<Item = (u32, &HashSet<Txid>)> + '_
pub fn tx_spends(
&self,
txid: Txid
) -> impl DoubleEndedIterator<Item = (u32, &HashSet<Txid>)> + '_
Iterates over the transactions spending from txid
.
The iterator item is a union of (vout, txid-set)
where:
vout
is the providedtxid
’s outpoint that is being spenttxid-set
is the set of txids spending thevout
.
source§impl<A: Clone + Ord> TxGraph<A>
impl<A: Clone + Ord> TxGraph<A>
sourcepub fn walk_ancestors<'g, T, F, O>(
&'g self,
tx: T,
walk_map: F
) -> TxAncestors<'g, A, F> ⓘwhere
T: Into<Arc<Transaction>>,
F: FnMut(usize, Arc<Transaction>) -> Option<O> + 'g,
pub fn walk_ancestors<'g, T, F, O>(
&'g self,
tx: T,
walk_map: F
) -> TxAncestors<'g, A, F> ⓘwhere
T: Into<Arc<Transaction>>,
F: FnMut(usize, Arc<Transaction>) -> Option<O> + 'g,
Creates an iterator that filters and maps ancestor transactions.
The iterator starts with the ancestors of the supplied tx
(ancestor transactions of tx
are transactions spent by tx
). The supplied transaction is excluded from the iterator.
The supplied closure takes in two inputs (depth, ancestor_tx)
:
depth
is the distance between the startingTransaction
and theancestor_tx
. I.e., if theTransaction
is spending an output of theancestor_tx
thendepth
will be 1.ancestor_tx
is theTransaction
’s ancestor which we are considering to walk.
The supplied closure returns an Option<T>
, allowing the caller to map each Transaction
it visits and decide whether to visit ancestors.
sourcepub fn walk_descendants<'g, F, O>(
&'g self,
txid: Txid,
walk_map: F
) -> TxDescendants<'_, A, F> ⓘwhere
F: FnMut(usize, Txid) -> Option<O> + 'g,
pub fn walk_descendants<'g, F, O>(
&'g self,
txid: Txid,
walk_map: F
) -> TxDescendants<'_, A, F> ⓘwhere
F: FnMut(usize, Txid) -> Option<O> + 'g,
Creates an iterator that filters and maps descendants from the starting txid
.
The supplied closure takes in two inputs (depth, descendant_txid)
:
depth
is the distance between the startingtxid
and thedescendant_txid
. I.e., if the descendant is spending an output of the startingtxid
thendepth
will be 1.descendant_txid
is the descendant’s txid which we are considering to walk.
The supplied closure returns an Option<T>
, allowing the caller to map each node it visits
and decide whether to visit descendants.
source§impl<A> TxGraph<A>
impl<A> TxGraph<A>
sourcepub fn walk_conflicts<'g, F, O>(
&'g self,
tx: &'g Transaction,
walk_map: F
) -> TxDescendants<'_, A, F> ⓘwhere
F: FnMut(usize, Txid) -> Option<O> + 'g,
pub fn walk_conflicts<'g, F, O>(
&'g self,
tx: &'g Transaction,
walk_map: F
) -> TxDescendants<'_, A, F> ⓘwhere
F: FnMut(usize, Txid) -> Option<O> + 'g,
Creates an iterator that both filters and maps conflicting transactions (this includes descendants of directly-conflicting transactions, which are also considered conflicts).
Refer to Self::walk_descendants
for walk_map
usage.
sourcepub fn direct_conflicts<'g>(
&'g self,
tx: &'g Transaction
) -> impl Iterator<Item = (usize, Txid)> + '_
pub fn direct_conflicts<'g>(
&'g self,
tx: &'g Transaction
) -> impl Iterator<Item = (usize, Txid)> + '_
Given a transaction, return an iterator of txids that directly conflict with the given transaction’s inputs (spends). The conflicting txids are returned with the given transaction’s vin (in which it conflicts).
Note that this only returns directly conflicting txids and won’t include:
- descendants of conflicting transactions (which are technically also conflicting)
- transactions conflicting with the given transaction’s ancestors
sourcepub fn all_anchors(&self) -> &BTreeSet<(A, Txid)>
pub fn all_anchors(&self) -> &BTreeSet<(A, Txid)>
Get all transaction anchors known by TxGraph
.
source§impl<A: Clone + Ord> TxGraph<A>
impl<A: Clone + Ord> TxGraph<A>
sourcepub fn new(txs: impl IntoIterator<Item = Transaction>) -> Self
pub fn new(txs: impl IntoIterator<Item = Transaction>) -> Self
Construct a new TxGraph
from a list of transactions.
sourcepub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) -> ChangeSet<A>
pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) -> ChangeSet<A>
Inserts the given [TxOut
] at [OutPoint
].
Inserting floating txouts are useful for determining fee/feerate of transactions we care about.
The ChangeSet
result will be empty if the outpoint
(or a full transaction containing
the outpoint
) already existed in self
.
sourcepub fn batch_insert_unconfirmed(
&mut self,
txs: impl IntoIterator<Item = (Transaction, u64)>
) -> ChangeSet<A>
pub fn batch_insert_unconfirmed(
&mut self,
txs: impl IntoIterator<Item = (Transaction, u64)>
) -> ChangeSet<A>
Batch insert unconfirmed transactions.
Items of txs
are tuples containing the transaction and a last seen timestamp. The
last seen communicates when the transaction is last seen in mempool which is used for
conflict-resolution (refer to TxGraph::insert_seen_at
for details).
sourcepub fn insert_anchor(&mut self, txid: Txid, anchor: A) -> ChangeSet<A>
pub fn insert_anchor(&mut self, txid: Txid, anchor: A) -> ChangeSet<A>
sourcepub fn insert_seen_at(&mut self, txid: Txid, seen_at: u64) -> ChangeSet<A>
pub fn insert_seen_at(&mut self, txid: Txid, seen_at: u64) -> ChangeSet<A>
Inserts the given seen_at
for txid
into TxGraph
.
Note that TxGraph
only keeps track of the latest seen_at
. To batch
update all unconfirmed transactions with the latest seen_at
, see
update_last_seen_unconfirmed
.
sourcepub fn update_last_seen_unconfirmed(&mut self, seen_at: u64) -> ChangeSet<A>
pub fn update_last_seen_unconfirmed(&mut self, seen_at: u64) -> ChangeSet<A>
Update the last seen time for all unconfirmed transactions.
This method updates the last seen unconfirmed time for this TxGraph
by inserting
the given seen_at
for every transaction not yet anchored to a confirmed block,
and returns the ChangeSet
after applying all updates to self
.
This is useful for keeping track of the latest time a transaction was seen
unconfirmed, which is important for evaluating transaction conflicts in the same
TxGraph
. For details of how TxGraph
resolves conflicts, see the docs for
try_get_chain_position
.
A normal use of this method is to call it with the current system time. Although block headers contain a timestamp, using the header time would be less effective at tracking mempool transactions, because it can drift from actual clock time, plus we may want to update a transaction’s last seen time repeatedly between blocks.
Example
let now = std::time::SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("valid duration")
.as_secs();
let changeset = tx_graph.update_last_seen_unconfirmed(now);
assert!(!changeset.last_seen.is_empty());
Note that TxGraph
only keeps track of the latest seen_at
, so the given time must
by strictly greater than what is currently stored for a transaction to have an effect.
To insert a last seen time for a single txid, see insert_seen_at
.
sourcepub fn apply_update(&mut self, update: TxGraph<A>) -> ChangeSet<A>
pub fn apply_update(&mut self, update: TxGraph<A>) -> ChangeSet<A>
Extends this graph with another so that self
becomes the union of the two sets of
transactions.
The returned ChangeSet
is the set difference between update
and self
(transactions that
exist in update
but not in self
).
sourcepub fn initial_changeset(&self) -> ChangeSet<A>
pub fn initial_changeset(&self) -> ChangeSet<A>
sourcepub fn apply_changeset(&mut self, changeset: ChangeSet<A>)
pub fn apply_changeset(&mut self, changeset: ChangeSet<A>)
source§impl<A: Anchor> TxGraph<A>
impl<A: Anchor> TxGraph<A>
sourcepub fn try_get_chain_position<C: ChainOracle>(
&self,
chain: &C,
chain_tip: BlockId,
txid: Txid
) -> Result<Option<ChainPosition<&A>>, C::Error>
pub fn try_get_chain_position<C: ChainOracle>(
&self,
chain: &C,
chain_tip: BlockId,
txid: Txid
) -> Result<Option<ChainPosition<&A>>, C::Error>
Get the position of the transaction in chain
with tip chain_tip
.
Chain data is fetched from chain
, a ChainOracle
implementation.
This method returns Ok(None)
if the transaction is not found in the chain, and no longer
belongs in the mempool. The following factors are used to approximate whether an
unconfirmed transaction exists in the mempool (not evicted):
- Unconfirmed transactions that conflict with confirmed transactions are evicted.
- Unconfirmed transactions that spend from transactions that are evicted, are also evicted.
- Given two conflicting unconfirmed transactions, the transaction with the lower
last_seen_unconfirmed
parameter is evicted. A transaction’slast_seen_unconfirmed
parameter is the max of all it’s descendants’last_seen_unconfirmed
parameters. If the finallast_seen_unconfirmed
s are the same, the transaction with the lowertxid
(by lexicographical order) is evicted.
Error
An error will occur if the ChainOracle
implementation (chain
) fails. If the
ChainOracle
is infallible, get_chain_position
can be used instead.
sourcepub fn get_chain_position<C: ChainOracle<Error = Infallible>>(
&self,
chain: &C,
chain_tip: BlockId,
txid: Txid
) -> Option<ChainPosition<&A>>
pub fn get_chain_position<C: ChainOracle<Error = Infallible>>(
&self,
chain: &C,
chain_tip: BlockId,
txid: Txid
) -> Option<ChainPosition<&A>>
Get the position of the transaction in chain
with tip chain_tip
.
This is the infallible version of try_get_chain_position
.
sourcepub fn try_get_chain_spend<C: ChainOracle>(
&self,
chain: &C,
chain_tip: BlockId,
outpoint: OutPoint
) -> Result<Option<(ChainPosition<&A>, Txid)>, C::Error>
pub fn try_get_chain_spend<C: ChainOracle>(
&self,
chain: &C,
chain_tip: BlockId,
outpoint: OutPoint
) -> Result<Option<(ChainPosition<&A>, Txid)>, C::Error>
Get the txid of the spending transaction and where the spending transaction is observed in
the chain
of chain_tip
.
If no in-chain transaction spends outpoint
, None
will be returned.
Error
An error will occur only if the ChainOracle
implementation (chain
) fails.
If the ChainOracle
is infallible, get_chain_spend
can be used instead.
sourcepub fn get_chain_spend<C: ChainOracle<Error = Infallible>>(
&self,
chain: &C,
static_block: BlockId,
outpoint: OutPoint
) -> Option<(ChainPosition<&A>, Txid)>
pub fn get_chain_spend<C: ChainOracle<Error = Infallible>>(
&self,
chain: &C,
static_block: BlockId,
outpoint: OutPoint
) -> Option<(ChainPosition<&A>, Txid)>
Get the txid of the spending transaction and where the spending transaction is observed in
the chain
of chain_tip
.
This is the infallible version of try_get_chain_spend
sourcepub fn try_list_chain_txs<'a, C: ChainOracle + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId
) -> impl Iterator<Item = Result<CanonicalTx<'a, Arc<Transaction>, A>, C::Error>>
pub fn try_list_chain_txs<'a, C: ChainOracle + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId
) -> impl Iterator<Item = Result<CanonicalTx<'a, Arc<Transaction>, A>, C::Error>>
List graph transactions that are in chain
with chain_tip
.
Each transaction is represented as a CanonicalTx
that contains where the transaction is
observed in-chain, and the TxNode
.
Error
If the ChainOracle
implementation (chain
) fails, an error will be returned with the
returned item.
If the ChainOracle
is infallible, list_chain_txs
can be used instead.
sourcepub fn list_chain_txs<'a, C: ChainOracle + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId
) -> impl Iterator<Item = CanonicalTx<'a, Arc<Transaction>, A>>
pub fn list_chain_txs<'a, C: ChainOracle + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId
) -> impl Iterator<Item = CanonicalTx<'a, Arc<Transaction>, A>>
List graph transactions that are in chain
with chain_tip
.
This is the infallible version of try_list_chain_txs
.
sourcepub fn try_filter_chain_txouts<'a, C: ChainOracle + 'a, OI: Clone + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)> + 'a
) -> impl Iterator<Item = Result<(OI, FullTxOut<A>), C::Error>> + 'a
pub fn try_filter_chain_txouts<'a, C: ChainOracle + 'a, OI: Clone + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)> + 'a
) -> impl Iterator<Item = Result<(OI, FullTxOut<A>), C::Error>> + 'a
Get a filtered list of outputs from the given outpoints
that are in chain
with
chain_tip
.
outpoints
is a list of outpoints we are interested in, coupled with an outpoint identifier
(OI
) for convenience. If OI
is not necessary, the caller can use ()
, or
Iterator::enumerate
over a list of [OutPoint
]s.
Floating outputs (i.e., outputs for which we don’t have the full transaction in the graph) are ignored.
Error
An Iterator::Item
can be an Err
if the ChainOracle
implementation (chain
)
fails.
If the ChainOracle
implementation is infallible, filter_chain_txouts
can be used
instead.
sourcepub fn filter_chain_txouts<'a, C: ChainOracle<Error = Infallible> + 'a, OI: Clone + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)> + 'a
) -> impl Iterator<Item = (OI, FullTxOut<A>)> + 'a
pub fn filter_chain_txouts<'a, C: ChainOracle<Error = Infallible> + 'a, OI: Clone + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)> + 'a
) -> impl Iterator<Item = (OI, FullTxOut<A>)> + 'a
Get a filtered list of outputs from the given outpoints
that are in chain
with
chain_tip
.
This is the infallible version of try_filter_chain_txouts
.
sourcepub fn try_filter_chain_unspents<'a, C: ChainOracle + 'a, OI: Clone + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)> + 'a
) -> impl Iterator<Item = Result<(OI, FullTxOut<A>), C::Error>> + 'a
pub fn try_filter_chain_unspents<'a, C: ChainOracle + 'a, OI: Clone + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)> + 'a
) -> impl Iterator<Item = Result<(OI, FullTxOut<A>), C::Error>> + 'a
Get a filtered list of unspent outputs (UTXOs) from the given outpoints
that are in
chain
with chain_tip
.
outpoints
is a list of outpoints we are interested in, coupled with an outpoint identifier
(OI
) for convenience. If OI
is not necessary, the caller can use ()
, or
Iterator::enumerate
over a list of [OutPoint
]s.
Floating outputs are ignored.
Error
An Iterator::Item
can be an Err
if the ChainOracle
implementation (chain
)
fails.
If the ChainOracle
implementation is infallible, filter_chain_unspents
can be used
instead.
sourcepub fn filter_chain_unspents<'a, C: ChainOracle<Error = Infallible> + 'a, OI: Clone + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
txouts: impl IntoIterator<Item = (OI, OutPoint)> + 'a
) -> impl Iterator<Item = (OI, FullTxOut<A>)> + 'a
pub fn filter_chain_unspents<'a, C: ChainOracle<Error = Infallible> + 'a, OI: Clone + 'a>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
txouts: impl IntoIterator<Item = (OI, OutPoint)> + 'a
) -> impl Iterator<Item = (OI, FullTxOut<A>)> + 'a
Get a filtered list of unspent outputs (UTXOs) from the given outpoints
that are in
chain
with chain_tip
.
This is the infallible version of try_filter_chain_unspents
.
sourcepub fn try_balance<C: ChainOracle, OI: Clone>(
&self,
chain: &C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)>,
trust_predicate: impl FnMut(&OI, &Script) -> bool
) -> Result<Balance, C::Error>
pub fn try_balance<C: ChainOracle, OI: Clone>(
&self,
chain: &C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)>,
trust_predicate: impl FnMut(&OI, &Script) -> bool
) -> Result<Balance, C::Error>
Get the total balance of outpoints
that are in chain
of chain_tip
.
The output of trust_predicate
should return true
for scripts that we trust.
outpoints
is a list of outpoints we are interested in, coupled with an outpoint identifier
(OI
) for convenience. If OI
is not necessary, the caller can use ()
, or
Iterator::enumerate
over a list of [OutPoint
]s.
If the provided ChainOracle
implementation (chain
) is infallible, balance
can be
used instead.
sourcepub fn balance<C: ChainOracle<Error = Infallible>, OI: Clone>(
&self,
chain: &C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)>,
trust_predicate: impl FnMut(&OI, &Script) -> bool
) -> Balance
pub fn balance<C: ChainOracle<Error = Infallible>, OI: Clone>(
&self,
chain: &C,
chain_tip: BlockId,
outpoints: impl IntoIterator<Item = (OI, OutPoint)>,
trust_predicate: impl FnMut(&OI, &Script) -> bool
) -> Balance
Get the total balance of outpoints
that are in chain
of chain_tip
.
This is the infallible version of try_balance
.