[bdk_chain_redesign] MOVE: IndexedTxGraph
into submodule
This commit is contained in:
parent
784cd34e3d
commit
6cbb18d409
248
crates/chain/src/indexed_tx_graph.rs
Normal file
248
crates/chain/src/indexed_tx_graph.rs
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
use core::convert::Infallible;
|
||||||
|
|
||||||
|
use alloc::collections::BTreeSet;
|
||||||
|
use bitcoin::{OutPoint, Transaction, TxOut};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
sparse_chain::ChainPosition,
|
||||||
|
tx_graph::{Additions, TxGraph, TxInGraph},
|
||||||
|
BlockAnchor, ChainOracle, FullTxOut, ObservedIn, TxIndex, TxIndexAdditions,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct TxInChain<'a, T, A> {
|
||||||
|
pub observed_in: ObservedIn<&'a A>,
|
||||||
|
pub tx: TxInGraph<'a, T, A>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct TxOutInChain<'a, I, A> {
|
||||||
|
pub spk_index: &'a I,
|
||||||
|
pub txout: FullTxOut<ObservedIn<&'a A>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IndexedAdditions<A, D> {
|
||||||
|
pub graph_additions: Additions<A>,
|
||||||
|
pub index_delta: D,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, D: Default> Default for IndexedAdditions<A, D> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
graph_additions: Default::default(),
|
||||||
|
index_delta: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: BlockAnchor, D: TxIndexAdditions> TxIndexAdditions for IndexedAdditions<A, D> {
|
||||||
|
fn append_additions(&mut self, other: Self) {
|
||||||
|
let Self {
|
||||||
|
graph_additions,
|
||||||
|
index_delta,
|
||||||
|
} = other;
|
||||||
|
self.graph_additions.append(graph_additions);
|
||||||
|
self.index_delta.append_additions(index_delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IndexedTxGraph<A, I> {
|
||||||
|
graph: TxGraph<A>,
|
||||||
|
index: I,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, I: Default> Default for IndexedTxGraph<A, I> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
graph: Default::default(),
|
||||||
|
index: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: BlockAnchor, I: TxIndex> IndexedTxGraph<A, I> {
|
||||||
|
/// Get a reference of the internal transaction graph.
|
||||||
|
pub fn graph(&self) -> &TxGraph<A> {
|
||||||
|
&self.graph
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a reference of the internal transaction index.
|
||||||
|
pub fn index(&self) -> &I {
|
||||||
|
&self.index
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Insert a `txout` that exists in `outpoint` with the given `observation`.
|
||||||
|
pub fn insert_txout(
|
||||||
|
&mut self,
|
||||||
|
outpoint: OutPoint,
|
||||||
|
txout: &TxOut,
|
||||||
|
observation: ObservedIn<A>,
|
||||||
|
) -> IndexedAdditions<A, I::Additions> {
|
||||||
|
IndexedAdditions {
|
||||||
|
graph_additions: {
|
||||||
|
let mut graph_additions = self.graph.insert_txout(outpoint, txout.clone());
|
||||||
|
graph_additions.append(match observation {
|
||||||
|
ObservedIn::Block(anchor) => self.graph.insert_anchor(outpoint.txid, anchor),
|
||||||
|
ObservedIn::Mempool(seen_at) => {
|
||||||
|
self.graph.insert_seen_at(outpoint.txid, seen_at)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
graph_additions
|
||||||
|
},
|
||||||
|
index_delta: <I as TxIndex>::index_txout(&mut self.index, outpoint, txout),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_tx(
|
||||||
|
&mut self,
|
||||||
|
tx: &Transaction,
|
||||||
|
observation: ObservedIn<A>,
|
||||||
|
) -> IndexedAdditions<A, I::Additions> {
|
||||||
|
let txid = tx.txid();
|
||||||
|
IndexedAdditions {
|
||||||
|
graph_additions: {
|
||||||
|
let mut graph_additions = self.graph.insert_tx(tx.clone());
|
||||||
|
graph_additions.append(match observation {
|
||||||
|
ObservedIn::Block(anchor) => self.graph.insert_anchor(txid, anchor),
|
||||||
|
ObservedIn::Mempool(seen_at) => self.graph.insert_seen_at(txid, seen_at),
|
||||||
|
});
|
||||||
|
graph_additions
|
||||||
|
},
|
||||||
|
index_delta: <I as TxIndex>::index_tx(&mut self.index, tx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn filter_and_insert_txs<'t, T>(
|
||||||
|
&mut self,
|
||||||
|
txs: T,
|
||||||
|
observation: ObservedIn<A>,
|
||||||
|
) -> IndexedAdditions<A, I::Additions>
|
||||||
|
where
|
||||||
|
T: Iterator<Item = &'t Transaction>,
|
||||||
|
{
|
||||||
|
txs.filter_map(|tx| {
|
||||||
|
if self.index.is_tx_relevant(tx) {
|
||||||
|
Some(self.insert_tx(tx, observation.clone()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.fold(IndexedAdditions::default(), |mut acc, other| {
|
||||||
|
acc.append_additions(other);
|
||||||
|
acc
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn relevant_heights(&self) -> BTreeSet<u32> {
|
||||||
|
self.graph.relevant_heights()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_list_chain_txs<'a, C>(
|
||||||
|
&'a self,
|
||||||
|
chain: C,
|
||||||
|
) -> impl Iterator<Item = Result<TxInChain<'a, Transaction, A>, C::Error>>
|
||||||
|
where
|
||||||
|
C: ChainOracle + 'a,
|
||||||
|
{
|
||||||
|
self.graph
|
||||||
|
.full_transactions()
|
||||||
|
.filter(|tx| self.index.is_tx_relevant(tx))
|
||||||
|
.filter_map(move |tx| {
|
||||||
|
self.graph
|
||||||
|
.try_get_chain_position(&chain, tx.txid)
|
||||||
|
.map(|v| v.map(|observed_in| TxInChain { observed_in, tx }))
|
||||||
|
.transpose()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_chain_txs<'a, C>(
|
||||||
|
&'a self,
|
||||||
|
chain: C,
|
||||||
|
) -> impl Iterator<Item = TxInChain<'a, Transaction, A>>
|
||||||
|
where
|
||||||
|
C: ChainOracle<Error = Infallible> + 'a,
|
||||||
|
{
|
||||||
|
self.try_list_chain_txs(chain)
|
||||||
|
.map(|r| r.expect("error is infallible"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_list_chain_txouts<'a, C>(
|
||||||
|
&'a self,
|
||||||
|
chain: C,
|
||||||
|
) -> impl Iterator<Item = Result<TxOutInChain<'a, I::SpkIndex, A>, C::Error>>
|
||||||
|
where
|
||||||
|
C: ChainOracle + 'a,
|
||||||
|
ObservedIn<A>: ChainPosition,
|
||||||
|
{
|
||||||
|
self.index.relevant_txouts().iter().filter_map(
|
||||||
|
move |(op, (spk_i, txout))| -> Option<Result<_, C::Error>> {
|
||||||
|
let graph_tx = self.graph.get_tx(op.txid)?;
|
||||||
|
|
||||||
|
let is_on_coinbase = graph_tx.is_coin_base();
|
||||||
|
|
||||||
|
let chain_position = match self.graph.try_get_chain_position(&chain, op.txid) {
|
||||||
|
Ok(Some(observed_at)) => observed_at,
|
||||||
|
Ok(None) => return None,
|
||||||
|
Err(err) => return Some(Err(err)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let spent_by = match self.graph.try_get_spend_in_chain(&chain, *op) {
|
||||||
|
Ok(spent_by) => spent_by,
|
||||||
|
Err(err) => return Some(Err(err)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let full_txout = FullTxOut {
|
||||||
|
outpoint: *op,
|
||||||
|
txout: txout.clone(),
|
||||||
|
chain_position,
|
||||||
|
spent_by,
|
||||||
|
is_on_coinbase,
|
||||||
|
};
|
||||||
|
|
||||||
|
let txout_in_chain = TxOutInChain {
|
||||||
|
spk_index: spk_i,
|
||||||
|
txout: full_txout,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(Ok(txout_in_chain))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_chain_txouts<'a, C>(
|
||||||
|
&'a self,
|
||||||
|
chain: C,
|
||||||
|
) -> impl Iterator<Item = TxOutInChain<'a, I::SpkIndex, A>>
|
||||||
|
where
|
||||||
|
C: ChainOracle<Error = Infallible> + 'a,
|
||||||
|
ObservedIn<A>: ChainPosition,
|
||||||
|
{
|
||||||
|
self.try_list_chain_txouts(chain)
|
||||||
|
.map(|r| r.expect("error in infallible"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return relevant unspents.
|
||||||
|
pub fn try_list_chain_utxos<'a, C>(
|
||||||
|
&'a self,
|
||||||
|
chain: C,
|
||||||
|
) -> impl Iterator<Item = Result<TxOutInChain<'a, I::SpkIndex, A>, C::Error>>
|
||||||
|
where
|
||||||
|
C: ChainOracle + 'a,
|
||||||
|
ObservedIn<A>: ChainPosition,
|
||||||
|
{
|
||||||
|
self.try_list_chain_txouts(chain)
|
||||||
|
.filter(|r| !matches!(r, Ok(txo) if txo.txout.spent_by.is_none()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_chain_utxos<'a, C>(
|
||||||
|
&'a self,
|
||||||
|
chain: C,
|
||||||
|
) -> impl Iterator<Item = TxOutInChain<'a, I::SpkIndex, A>>
|
||||||
|
where
|
||||||
|
C: ChainOracle<Error = Infallible> + 'a,
|
||||||
|
ObservedIn<A>: ChainPosition,
|
||||||
|
{
|
||||||
|
self.try_list_chain_utxos(chain)
|
||||||
|
.map(|r| r.expect("error is infallible"))
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,7 @@ mod spk_txout_index;
|
|||||||
pub use spk_txout_index::*;
|
pub use spk_txout_index::*;
|
||||||
mod chain_data;
|
mod chain_data;
|
||||||
pub use chain_data::*;
|
pub use chain_data::*;
|
||||||
|
pub mod indexed_tx_graph;
|
||||||
pub mod keychain;
|
pub mod keychain;
|
||||||
pub mod sparse_chain;
|
pub mod sparse_chain;
|
||||||
mod tx_data_traits;
|
mod tx_data_traits;
|
||||||
|
@ -55,10 +55,7 @@
|
|||||||
//! assert!(additions.is_empty());
|
//! assert!(additions.is_empty());
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::{
|
use crate::{collections::*, BlockAnchor, BlockId, ChainOracle, ForEachTxOut, ObservedIn};
|
||||||
collections::*, sparse_chain::ChainPosition, BlockAnchor, BlockId, ChainOracle, ForEachTxOut,
|
|
||||||
FullTxOut, ObservedIn, TxIndex, TxIndexAdditions,
|
|
||||||
};
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use bitcoin::{OutPoint, Transaction, TxOut, Txid};
|
use bitcoin::{OutPoint, Transaction, TxOut, Txid};
|
||||||
use core::{
|
use core::{
|
||||||
@ -129,18 +126,6 @@ impl<'a, A> TxInGraph<'a, Transaction, A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
pub struct TxInChain<'a, T, A> {
|
|
||||||
pub observed_in: ObservedIn<&'a A>,
|
|
||||||
pub tx: TxInGraph<'a, T, A>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
pub struct TxOutInChain<'a, I, A> {
|
|
||||||
pub spk_index: &'a I,
|
|
||||||
pub txout: FullTxOut<ObservedIn<&'a A>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Internal representation of a transaction node of a [`TxGraph`].
|
/// Internal representation of a transaction node of a [`TxGraph`].
|
||||||
///
|
///
|
||||||
/// This can either be a whole transaction, or a partial transaction (where we only have select
|
/// This can either be a whole transaction, or a partial transaction (where we only have select
|
||||||
@ -692,232 +677,6 @@ impl<A> TxGraph<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IndexedAdditions<A, D> {
|
|
||||||
pub graph_additions: Additions<A>,
|
|
||||||
pub index_delta: D,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, D: Default> Default for IndexedAdditions<A, D> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
graph_additions: Default::default(),
|
|
||||||
index_delta: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A: BlockAnchor, D: TxIndexAdditions> TxIndexAdditions for IndexedAdditions<A, D> {
|
|
||||||
fn append_additions(&mut self, other: Self) {
|
|
||||||
let Self {
|
|
||||||
graph_additions,
|
|
||||||
index_delta,
|
|
||||||
} = other;
|
|
||||||
self.graph_additions.append(graph_additions);
|
|
||||||
self.index_delta.append_additions(index_delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct IndexedTxGraph<A, I> {
|
|
||||||
graph: TxGraph<A>,
|
|
||||||
index: I,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, I: Default> Default for IndexedTxGraph<A, I> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
graph: Default::default(),
|
|
||||||
index: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A: BlockAnchor, I: TxIndex> IndexedTxGraph<A, I> {
|
|
||||||
/// Get a reference of the internal transaction graph.
|
|
||||||
pub fn graph(&self) -> &TxGraph<A> {
|
|
||||||
&self.graph
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a reference of the internal transaction index.
|
|
||||||
pub fn index(&self) -> &I {
|
|
||||||
&self.index
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Insert a `txout` that exists in `outpoint` with the given `observation`.
|
|
||||||
pub fn insert_txout(
|
|
||||||
&mut self,
|
|
||||||
outpoint: OutPoint,
|
|
||||||
txout: &TxOut,
|
|
||||||
observation: ObservedIn<A>,
|
|
||||||
) -> IndexedAdditions<A, I::Additions> {
|
|
||||||
IndexedAdditions {
|
|
||||||
graph_additions: {
|
|
||||||
let mut graph_additions = self.graph.insert_txout(outpoint, txout.clone());
|
|
||||||
graph_additions.append(match observation {
|
|
||||||
ObservedIn::Block(anchor) => self.graph.insert_anchor(outpoint.txid, anchor),
|
|
||||||
ObservedIn::Mempool(seen_at) => {
|
|
||||||
self.graph.insert_seen_at(outpoint.txid, seen_at)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
graph_additions
|
|
||||||
},
|
|
||||||
index_delta: <I as TxIndex>::index_txout(&mut self.index, outpoint, txout),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_tx(
|
|
||||||
&mut self,
|
|
||||||
tx: &Transaction,
|
|
||||||
observation: ObservedIn<A>,
|
|
||||||
) -> IndexedAdditions<A, I::Additions> {
|
|
||||||
let txid = tx.txid();
|
|
||||||
IndexedAdditions {
|
|
||||||
graph_additions: {
|
|
||||||
let mut graph_additions = self.graph.insert_tx(tx.clone());
|
|
||||||
graph_additions.append(match observation {
|
|
||||||
ObservedIn::Block(anchor) => self.graph.insert_anchor(txid, anchor),
|
|
||||||
ObservedIn::Mempool(seen_at) => self.graph.insert_seen_at(txid, seen_at),
|
|
||||||
});
|
|
||||||
graph_additions
|
|
||||||
},
|
|
||||||
index_delta: <I as TxIndex>::index_tx(&mut self.index, tx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn filter_and_insert_txs<'t, T>(
|
|
||||||
&mut self,
|
|
||||||
txs: T,
|
|
||||||
observation: ObservedIn<A>,
|
|
||||||
) -> IndexedAdditions<A, I::Additions>
|
|
||||||
where
|
|
||||||
T: Iterator<Item = &'t Transaction>,
|
|
||||||
{
|
|
||||||
txs.filter_map(|tx| {
|
|
||||||
if self.index.is_tx_relevant(tx) {
|
|
||||||
Some(self.insert_tx(tx, observation.clone()))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.fold(IndexedAdditions::default(), |mut acc, other| {
|
|
||||||
acc.append_additions(other);
|
|
||||||
acc
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn relevant_heights(&self) -> BTreeSet<u32> {
|
|
||||||
self.graph.relevant_heights()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn try_list_chain_txs<'a, C>(
|
|
||||||
&'a self,
|
|
||||||
chain: C,
|
|
||||||
) -> impl Iterator<Item = Result<TxInChain<'a, Transaction, A>, C::Error>>
|
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
{
|
|
||||||
self.graph
|
|
||||||
.full_transactions()
|
|
||||||
.filter(|tx| self.index.is_tx_relevant(tx))
|
|
||||||
.filter_map(move |tx| {
|
|
||||||
self.graph
|
|
||||||
.try_get_chain_position(&chain, tx.txid)
|
|
||||||
.map(|v| v.map(|observed_in| TxInChain { observed_in, tx }))
|
|
||||||
.transpose()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list_chain_txs<'a, C>(
|
|
||||||
&'a self,
|
|
||||||
chain: C,
|
|
||||||
) -> impl Iterator<Item = TxInChain<'a, Transaction, A>>
|
|
||||||
where
|
|
||||||
C: ChainOracle<Error = Infallible> + 'a,
|
|
||||||
{
|
|
||||||
self.try_list_chain_txs(chain)
|
|
||||||
.map(|r| r.expect("error is infallible"))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn try_list_chain_txouts<'a, C>(
|
|
||||||
&'a self,
|
|
||||||
chain: C,
|
|
||||||
) -> impl Iterator<Item = Result<TxOutInChain<'a, I::SpkIndex, A>, C::Error>>
|
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
ObservedIn<A>: ChainPosition,
|
|
||||||
{
|
|
||||||
self.index.relevant_txouts().iter().filter_map(
|
|
||||||
move |(op, (spk_i, txout))| -> Option<Result<_, C::Error>> {
|
|
||||||
let graph_tx = self.graph.get_tx(op.txid)?;
|
|
||||||
|
|
||||||
let is_on_coinbase = graph_tx.is_coin_base();
|
|
||||||
|
|
||||||
let chain_position = match self.graph.try_get_chain_position(&chain, op.txid) {
|
|
||||||
Ok(Some(observed_at)) => observed_at,
|
|
||||||
Ok(None) => return None,
|
|
||||||
Err(err) => return Some(Err(err)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let spent_by = match self.graph.try_get_spend_in_chain(&chain, *op) {
|
|
||||||
Ok(spent_by) => spent_by,
|
|
||||||
Err(err) => return Some(Err(err)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let full_txout = FullTxOut {
|
|
||||||
outpoint: *op,
|
|
||||||
txout: txout.clone(),
|
|
||||||
chain_position,
|
|
||||||
spent_by,
|
|
||||||
is_on_coinbase,
|
|
||||||
};
|
|
||||||
|
|
||||||
let txout_in_chain = TxOutInChain {
|
|
||||||
spk_index: spk_i,
|
|
||||||
txout: full_txout,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(Ok(txout_in_chain))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list_chain_txouts<'a, C>(
|
|
||||||
&'a self,
|
|
||||||
chain: C,
|
|
||||||
) -> impl Iterator<Item = TxOutInChain<'a, I::SpkIndex, A>>
|
|
||||||
where
|
|
||||||
C: ChainOracle<Error = Infallible> + 'a,
|
|
||||||
ObservedIn<A>: ChainPosition,
|
|
||||||
{
|
|
||||||
self.try_list_chain_txouts(chain)
|
|
||||||
.map(|r| r.expect("error in infallible"))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return relevant unspents.
|
|
||||||
pub fn try_list_chain_utxos<'a, C>(
|
|
||||||
&'a self,
|
|
||||||
chain: C,
|
|
||||||
) -> impl Iterator<Item = Result<TxOutInChain<'a, I::SpkIndex, A>, C::Error>>
|
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
ObservedIn<A>: ChainPosition,
|
|
||||||
{
|
|
||||||
self.try_list_chain_txouts(chain)
|
|
||||||
.filter(|r| !matches!(r, Ok(txo) if txo.txout.spent_by.is_none()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list_chain_utxos<'a, C>(
|
|
||||||
&'a self,
|
|
||||||
chain: C,
|
|
||||||
) -> impl Iterator<Item = TxOutInChain<'a, I::SpkIndex, A>>
|
|
||||||
where
|
|
||||||
C: ChainOracle<Error = Infallible> + 'a,
|
|
||||||
ObservedIn<A>: ChainPosition,
|
|
||||||
{
|
|
||||||
self.try_list_chain_utxos(chain)
|
|
||||||
.map(|r| r.expect("error is infallible"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A structure that represents changes to a [`TxGraph`].
|
/// A structure that represents changes to a [`TxGraph`].
|
||||||
///
|
///
|
||||||
/// It is named "additions" because [`TxGraph`] is monotone, so transactions can only be added and
|
/// It is named "additions" because [`TxGraph`] is monotone, so transactions can only be added and
|
||||||
|
Loading…
x
Reference in New Issue
Block a user