[bdk_chain_redesign] Rm unnecessary code and premature optimisation
* Remove `chain_oracle::CacheBackend` for now as it is not used. * `SparseChain` does not need to implement `ChainOracle`. * Remove filter predicate for `list..` methods of `TxGraph` and `IndexedTxGraph` as this is premature optimisation. * `Append` can be implemented for all `BTreeMap`s and `BTreeSet`s, instead of only `local_chain::ChangeSet`.
This commit is contained in:
parent
6c49570742
commit
34a7bf5afe
@ -1,9 +1,3 @@
|
|||||||
use crate::collections::HashSet;
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use alloc::{collections::VecDeque, vec::Vec};
|
|
||||||
use bitcoin::BlockHash;
|
|
||||||
|
|
||||||
use crate::BlockId;
|
use crate::BlockId;
|
||||||
|
|
||||||
/// Represents a service that tracks the blockchain.
|
/// Represents a service that tracks the blockchain.
|
||||||
@ -25,53 +19,3 @@ pub trait ChainOracle {
|
|||||||
static_block: BlockId,
|
static_block: BlockId,
|
||||||
) -> Result<Option<bool>, Self::Error>;
|
) -> Result<Option<bool>, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A cache structure increases the performance of getting chain data.
|
|
||||||
///
|
|
||||||
/// A simple FIFO cache replacement policy is used. Something more efficient and advanced can be
|
|
||||||
/// implemented later.
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct CacheBackend<C> {
|
|
||||||
cache: HashSet<(BlockHash, BlockHash)>,
|
|
||||||
fifo: VecDeque<(BlockHash, BlockHash)>,
|
|
||||||
marker: PhantomData<C>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C> CacheBackend<C> {
|
|
||||||
/// Get the number of elements in the cache.
|
|
||||||
pub fn cache_size(&self) -> usize {
|
|
||||||
self.cache.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prunes the cache to reach the `max_size` target.
|
|
||||||
///
|
|
||||||
/// Returns pruned elements.
|
|
||||||
pub fn prune(&mut self, max_size: usize) -> Vec<(BlockHash, BlockHash)> {
|
|
||||||
let prune_count = self.cache.len().saturating_sub(max_size);
|
|
||||||
(0..prune_count)
|
|
||||||
.filter_map(|_| self.fifo.pop_front())
|
|
||||||
.filter(|k| self.cache.remove(k))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn contains(&self, static_block: BlockId, block: BlockId) -> bool {
|
|
||||||
if static_block.height < block.height
|
|
||||||
|| static_block.height == block.height && static_block.hash != block.hash
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cache.contains(&(static_block.hash, block.hash))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert(&mut self, static_block: BlockId, block: BlockId) -> bool {
|
|
||||||
let cache_key = (static_block.hash, block.hash);
|
|
||||||
|
|
||||||
if self.cache.insert(cache_key) {
|
|
||||||
self.fifo.push_back(cache_key);
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -120,15 +120,12 @@ where
|
|||||||
///
|
///
|
||||||
/// `anchors` can be provided to anchor the transactions to blocks. `seen_at` is a unix
|
/// `anchors` can be provided to anchor the transactions to blocks. `seen_at` is a unix
|
||||||
/// timestamp of when the transactions are last seen.
|
/// timestamp of when the transactions are last seen.
|
||||||
pub fn insert_relevant_txs<'t, T>(
|
pub fn insert_relevant_txs<'t, T: Iterator<Item = &'t Transaction>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
txs: T,
|
txs: T,
|
||||||
anchors: impl IntoIterator<Item = A> + Clone,
|
anchors: impl IntoIterator<Item = A> + Clone,
|
||||||
seen_at: Option<u64>,
|
seen_at: Option<u64>,
|
||||||
) -> IndexedAdditions<A, I::Additions>
|
) -> IndexedAdditions<A, I::Additions> {
|
||||||
where
|
|
||||||
T: Iterator<Item = &'t Transaction>,
|
|
||||||
{
|
|
||||||
txs.filter_map(|tx| match self.index.is_tx_relevant(tx) {
|
txs.filter_map(|tx| match self.index.is_tx_relevant(tx) {
|
||||||
true => Some(self.insert_tx(tx, anchors.clone(), seen_at)),
|
true => Some(self.insert_tx(tx, anchors.clone(), seen_at)),
|
||||||
false => None,
|
false => None,
|
||||||
@ -141,14 +138,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<A: Anchor, I: OwnedIndexer> IndexedTxGraph<A, I> {
|
impl<A: Anchor, I: OwnedIndexer> IndexedTxGraph<A, I> {
|
||||||
pub fn try_list_owned_txs<'a, C>(
|
pub fn try_list_owned_txs<'a, C: ChainOracle + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
) -> impl Iterator<Item = Result<CanonicalTx<'a, Transaction, A>, C::Error>>
|
) -> impl Iterator<Item = Result<CanonicalTx<'a, Transaction, A>, C::Error>> {
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
{
|
|
||||||
self.graph
|
self.graph
|
||||||
.full_txs()
|
.full_txs()
|
||||||
.filter(|node| tx_alters_owned_utxo_set(&self.graph, &self.index, node.txid, node.tx))
|
.filter(|node| tx_alters_owned_utxo_set(&self.graph, &self.index, node.txid, node.tx))
|
||||||
@ -165,55 +159,55 @@ impl<A: Anchor, I: OwnedIndexer> IndexedTxGraph<A, I> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_owned_txs<'a, C>(
|
pub fn list_owned_txs<'a, C: ChainOracle<Error = Infallible> + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
) -> impl Iterator<Item = CanonicalTx<'a, Transaction, A>>
|
) -> impl Iterator<Item = CanonicalTx<'a, Transaction, A>> {
|
||||||
where
|
|
||||||
C: ChainOracle<Error = Infallible> + 'a,
|
|
||||||
{
|
|
||||||
self.try_list_owned_txs(chain, chain_tip)
|
self.try_list_owned_txs(chain, chain_tip)
|
||||||
.map(|r| r.expect("chain oracle is infallible"))
|
.map(|r| r.expect("chain oracle is infallible"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_list_owned_txouts<'a, C>(
|
pub fn try_list_owned_txouts<'a, C: ChainOracle + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
) -> impl Iterator<Item = Result<FullTxOut<ObservedAs<A>>, C::Error>> + 'a
|
) -> impl Iterator<Item = Result<FullTxOut<ObservedAs<A>>, C::Error>> + 'a {
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
{
|
|
||||||
self.graph()
|
self.graph()
|
||||||
.try_list_chain_txouts(chain, chain_tip, |_, txout| {
|
.try_list_chain_txouts(chain, chain_tip)
|
||||||
self.index.is_spk_owned(&txout.script_pubkey)
|
.filter(|r| {
|
||||||
|
if let Ok(full_txout) = r {
|
||||||
|
if !self.index.is_spk_owned(&full_txout.txout.script_pubkey) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_owned_txouts<'a, C>(
|
pub fn list_owned_txouts<'a, C: ChainOracle + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
) -> impl Iterator<Item = FullTxOut<ObservedAs<A>>> + 'a
|
) -> impl Iterator<Item = FullTxOut<ObservedAs<A>>> + 'a {
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
{
|
|
||||||
self.try_list_owned_txouts(chain, chain_tip)
|
self.try_list_owned_txouts(chain, chain_tip)
|
||||||
.map(|r| r.expect("oracle is infallible"))
|
.map(|r| r.expect("oracle is infallible"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_list_owned_unspents<'a, C>(
|
pub fn try_list_owned_unspents<'a, C: ChainOracle + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
) -> impl Iterator<Item = Result<FullTxOut<ObservedAs<A>>, C::Error>> + 'a
|
) -> impl Iterator<Item = Result<FullTxOut<ObservedAs<A>>, C::Error>> + 'a {
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
{
|
|
||||||
self.graph()
|
self.graph()
|
||||||
.try_list_chain_unspents(chain, chain_tip, |_, txout| {
|
.try_list_chain_unspents(chain, chain_tip)
|
||||||
self.index.is_spk_owned(&txout.script_pubkey)
|
.filter(|r| {
|
||||||
|
if let Ok(full_txout) = r {
|
||||||
|
if !self.index.is_spk_owned(&full_txout.txout.script_pubkey) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,35 +272,26 @@ impl<A: Anchor + ConfirmationHeight, I: OwnedIndexer> IndexedTxGraph<A, I> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn balance<C, F>(
|
pub fn balance<C, F>(&self, chain: &C, chain_tip: BlockId, tip: u32, should_trust: F) -> Balance
|
||||||
&self,
|
|
||||||
chain: &C,
|
|
||||||
static_block: BlockId,
|
|
||||||
tip: u32,
|
|
||||||
should_trust: F,
|
|
||||||
) -> Balance
|
|
||||||
where
|
where
|
||||||
C: ChainOracle<Error = Infallible>,
|
C: ChainOracle<Error = Infallible>,
|
||||||
F: FnMut(&Script) -> bool,
|
F: FnMut(&Script) -> bool,
|
||||||
{
|
{
|
||||||
self.try_balance(chain, static_block, tip, should_trust)
|
self.try_balance(chain, chain_tip, tip, should_trust)
|
||||||
.expect("error is infallible")
|
.expect("error is infallible")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_balance_at<C>(
|
pub fn try_balance_at<C>(
|
||||||
&self,
|
&self,
|
||||||
chain: &C,
|
chain: &C,
|
||||||
static_block: BlockId,
|
chain_tip: BlockId,
|
||||||
height: u32,
|
height: u32,
|
||||||
) -> Result<u64, C::Error>
|
) -> Result<u64, C::Error>
|
||||||
where
|
where
|
||||||
C: ChainOracle,
|
C: ChainOracle,
|
||||||
{
|
{
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
for txo_res in self
|
for txo_res in self.try_list_owned_unspents(chain, chain_tip) {
|
||||||
.graph()
|
|
||||||
.try_list_chain_txouts(chain, static_block, |_, _| true)
|
|
||||||
{
|
|
||||||
let txo = txo_res?;
|
let txo = txo_res?;
|
||||||
if txo.is_observed_as_confirmed_and_spendable(height) {
|
if txo.is_observed_as_confirmed_and_spendable(height) {
|
||||||
sum += txo.txout.value;
|
sum += txo.txout.value;
|
||||||
@ -315,11 +300,11 @@ impl<A: Anchor + ConfirmationHeight, I: OwnedIndexer> IndexedTxGraph<A, I> {
|
|||||||
Ok(sum)
|
Ok(sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn balance_at<C>(&self, chain: &C, static_block: BlockId, height: u32) -> u64
|
pub fn balance_at<C>(&self, chain: &C, chain_tip: BlockId, height: u32) -> u64
|
||||||
where
|
where
|
||||||
C: ChainOracle<Error = Infallible>,
|
C: ChainOracle<Error = Infallible>,
|
||||||
{
|
{
|
||||||
self.try_balance_at(chain, static_block, height)
|
self.try_balance_at(chain, chain_tip, height)
|
||||||
.expect("error is infallible")
|
.expect("error is infallible")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use core::convert::Infallible;
|
|||||||
use alloc::collections::{BTreeMap, BTreeSet};
|
use alloc::collections::{BTreeMap, BTreeSet};
|
||||||
use bitcoin::BlockHash;
|
use bitcoin::BlockHash;
|
||||||
|
|
||||||
use crate::{Append, BlockId, ChainOracle};
|
use crate::{BlockId, ChainOracle};
|
||||||
|
|
||||||
/// This is a local implementation of [`ChainOracle`].
|
/// This is a local implementation of [`ChainOracle`].
|
||||||
///
|
///
|
||||||
@ -180,12 +180,6 @@ impl LocalChain {
|
|||||||
/// [`determine_changeset`]: LocalChain::determine_changeset
|
/// [`determine_changeset`]: LocalChain::determine_changeset
|
||||||
pub type ChangeSet = BTreeMap<u32, Option<BlockHash>>;
|
pub type ChangeSet = BTreeMap<u32, Option<BlockHash>>;
|
||||||
|
|
||||||
impl Append for ChangeSet {
|
|
||||||
fn append(&mut self, mut other: Self) {
|
|
||||||
BTreeMap::append(self, &mut other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents an update failure of [`LocalChain`] due to the update not connecting to the original
|
/// Represents an update failure of [`LocalChain`] due to the update not connecting to the original
|
||||||
/// chain.
|
/// chain.
|
||||||
///
|
///
|
||||||
|
@ -307,12 +307,11 @@
|
|||||||
//! );
|
//! );
|
||||||
//! ```
|
//! ```
|
||||||
use core::{
|
use core::{
|
||||||
convert::Infallible,
|
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
ops::{Bound, RangeBounds},
|
ops::{Bound, RangeBounds},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{collections::*, tx_graph::TxGraph, BlockId, ChainOracle, FullTxOut, TxHeight};
|
use crate::{collections::*, tx_graph::TxGraph, BlockId, FullTxOut, TxHeight};
|
||||||
use bitcoin::{hashes::Hash, BlockHash, OutPoint, Txid};
|
use bitcoin::{hashes::Hash, BlockHash, OutPoint, Txid};
|
||||||
|
|
||||||
/// This is a non-monotone structure that tracks relevant [`Txid`]s that are ordered by chain
|
/// This is a non-monotone structure that tracks relevant [`Txid`]s that are ordered by chain
|
||||||
@ -457,26 +456,6 @@ impl<P: core::fmt::Debug> core::fmt::Display for UpdateError<P> {
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<P: core::fmt::Debug> std::error::Error for UpdateError<P> {}
|
impl<P: core::fmt::Debug> std::error::Error for UpdateError<P> {}
|
||||||
|
|
||||||
impl<P> ChainOracle for SparseChain<P> {
|
|
||||||
type Error = Infallible;
|
|
||||||
|
|
||||||
fn is_block_in_chain(
|
|
||||||
&self,
|
|
||||||
block: BlockId,
|
|
||||||
static_block: BlockId,
|
|
||||||
) -> Result<Option<bool>, Self::Error> {
|
|
||||||
Ok(
|
|
||||||
match (
|
|
||||||
self.checkpoint_at(block.height),
|
|
||||||
self.checkpoint_at(static_block.height),
|
|
||||||
) {
|
|
||||||
(Some(b), Some(static_b)) => Some(b == block && static_b == static_block),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> SparseChain<P> {
|
impl<P> SparseChain<P> {
|
||||||
/// Creates a new chain from a list of block hashes and heights. The caller must guarantee they
|
/// Creates a new chain from a list of block hashes and heights. The caller must guarantee they
|
||||||
/// are in the same chain.
|
/// are in the same chain.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use bitcoin::{Block, BlockHash, OutPoint, Transaction, TxOut};
|
use crate::collections::BTreeMap;
|
||||||
|
use crate::collections::BTreeSet;
|
||||||
use crate::BlockId;
|
use crate::BlockId;
|
||||||
|
use bitcoin::{Block, BlockHash, OutPoint, Transaction, TxOut};
|
||||||
|
|
||||||
/// Trait to do something with every txout contained in a structure.
|
/// Trait to do something with every txout contained in a structure.
|
||||||
///
|
///
|
||||||
@ -77,3 +78,15 @@ pub trait Append {
|
|||||||
impl Append for () {
|
impl Append for () {
|
||||||
fn append(&mut self, _other: Self) {}
|
fn append(&mut self, _other: Self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<K: Ord, V> Append for BTreeMap<K, V> {
|
||||||
|
fn append(&mut self, mut other: Self) {
|
||||||
|
BTreeMap::append(self, &mut other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Ord> Append for BTreeSet<T> {
|
||||||
|
fn append(&mut self, mut other: Self) {
|
||||||
|
BTreeSet::append(self, &mut other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -627,15 +627,12 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// [`ChainOracle`] is infallible, [`get_chain_position`] can be used instead.
|
/// [`ChainOracle`] is infallible, [`get_chain_position`] can be used instead.
|
||||||
///
|
///
|
||||||
/// [`get_chain_position`]: Self::get_chain_position
|
/// [`get_chain_position`]: Self::get_chain_position
|
||||||
pub fn try_get_chain_position<C>(
|
pub fn try_get_chain_position<C: ChainOracle>(
|
||||||
&self,
|
&self,
|
||||||
chain: &C,
|
chain: &C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
txid: Txid,
|
txid: Txid,
|
||||||
) -> Result<Option<ObservedAs<&A>>, C::Error>
|
) -> Result<Option<ObservedAs<&A>>, C::Error> {
|
||||||
where
|
|
||||||
C: ChainOracle,
|
|
||||||
{
|
|
||||||
let (tx_node, anchors, &last_seen) = match self.txs.get(&txid) {
|
let (tx_node, anchors, &last_seen) = match self.txs.get(&txid) {
|
||||||
Some((tx, anchors, last_seen)) if !(anchors.is_empty() && *last_seen == 0) => {
|
Some((tx, anchors, last_seen)) if !(anchors.is_empty() && *last_seen == 0) => {
|
||||||
(tx, anchors, last_seen)
|
(tx, anchors, last_seen)
|
||||||
@ -682,15 +679,12 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// This is the infallible version of [`try_get_chain_position`].
|
/// This is the infallible version of [`try_get_chain_position`].
|
||||||
///
|
///
|
||||||
/// [`try_get_chain_position`]: Self::try_get_chain_position
|
/// [`try_get_chain_position`]: Self::try_get_chain_position
|
||||||
pub fn get_chain_position<C>(
|
pub fn get_chain_position<C: ChainOracle<Error = Infallible>>(
|
||||||
&self,
|
&self,
|
||||||
chain: &C,
|
chain: &C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
txid: Txid,
|
txid: Txid,
|
||||||
) -> Option<ObservedAs<&A>>
|
) -> Option<ObservedAs<&A>> {
|
||||||
where
|
|
||||||
C: ChainOracle<Error = Infallible>,
|
|
||||||
{
|
|
||||||
self.try_get_chain_position(chain, chain_tip, txid)
|
self.try_get_chain_position(chain, chain_tip, txid)
|
||||||
.expect("error is infallible")
|
.expect("error is infallible")
|
||||||
}
|
}
|
||||||
@ -707,15 +701,12 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// If the [`ChainOracle`] is infallible, [`get_chain_spend`] can be used instead.
|
/// If the [`ChainOracle`] is infallible, [`get_chain_spend`] can be used instead.
|
||||||
///
|
///
|
||||||
/// [`get_chain_spend`]: Self::get_chain_spend
|
/// [`get_chain_spend`]: Self::get_chain_spend
|
||||||
pub fn try_get_chain_spend<C>(
|
pub fn try_get_chain_spend<C: ChainOracle>(
|
||||||
&self,
|
&self,
|
||||||
chain: &C,
|
chain: &C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
outpoint: OutPoint,
|
outpoint: OutPoint,
|
||||||
) -> Result<Option<(ObservedAs<&A>, Txid)>, C::Error>
|
) -> Result<Option<(ObservedAs<&A>, Txid)>, C::Error> {
|
||||||
where
|
|
||||||
C: ChainOracle,
|
|
||||||
{
|
|
||||||
if self
|
if self
|
||||||
.try_get_chain_position(chain, chain_tip, outpoint.txid)?
|
.try_get_chain_position(chain, chain_tip, outpoint.txid)?
|
||||||
.is_none()
|
.is_none()
|
||||||
@ -738,15 +729,12 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// This is the infallible version of [`try_get_chain_spend`]
|
/// This is the infallible version of [`try_get_chain_spend`]
|
||||||
///
|
///
|
||||||
/// [`try_get_chain_spend`]: Self::try_get_chain_spend
|
/// [`try_get_chain_spend`]: Self::try_get_chain_spend
|
||||||
pub fn get_chain_spend<C>(
|
pub fn get_chain_spend<C: ChainOracle<Error = Infallible>>(
|
||||||
&self,
|
&self,
|
||||||
chain: &C,
|
chain: &C,
|
||||||
static_block: BlockId,
|
static_block: BlockId,
|
||||||
outpoint: OutPoint,
|
outpoint: OutPoint,
|
||||||
) -> Option<(ObservedAs<&A>, Txid)>
|
) -> Option<(ObservedAs<&A>, Txid)> {
|
||||||
where
|
|
||||||
C: ChainOracle<Error = Infallible>,
|
|
||||||
{
|
|
||||||
self.try_get_chain_spend(chain, static_block, outpoint)
|
self.try_get_chain_spend(chain, static_block, outpoint)
|
||||||
.expect("error is infallible")
|
.expect("error is infallible")
|
||||||
}
|
}
|
||||||
@ -764,14 +752,11 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// If the [`ChainOracle`] is infallible, [`list_chain_txs`] can be used instead.
|
/// If the [`ChainOracle`] is infallible, [`list_chain_txs`] can be used instead.
|
||||||
///
|
///
|
||||||
/// [`list_chain_txs`]: Self::list_chain_txs
|
/// [`list_chain_txs`]: Self::list_chain_txs
|
||||||
pub fn try_list_chain_txs<'a, C>(
|
pub fn try_list_chain_txs<'a, C: ChainOracle + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
) -> impl Iterator<Item = Result<CanonicalTx<'a, Transaction, A>, C::Error>>
|
) -> impl Iterator<Item = Result<CanonicalTx<'a, Transaction, A>, C::Error>> {
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
{
|
|
||||||
self.full_txs().filter_map(move |tx| {
|
self.full_txs().filter_map(move |tx| {
|
||||||
self.try_get_chain_position(chain, chain_tip, tx.txid)
|
self.try_get_chain_position(chain, chain_tip, tx.txid)
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
@ -789,14 +774,11 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// This is the infallible version of [`try_list_chain_txs`].
|
/// This is the infallible version of [`try_list_chain_txs`].
|
||||||
///
|
///
|
||||||
/// [`try_list_chain_txs`]: Self::try_list_chain_txs
|
/// [`try_list_chain_txs`]: Self::try_list_chain_txs
|
||||||
pub fn list_chain_txs<'a, C>(
|
pub fn list_chain_txs<'a, C: ChainOracle + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
) -> impl Iterator<Item = CanonicalTx<'a, Transaction, A>>
|
) -> impl Iterator<Item = CanonicalTx<'a, Transaction, A>> {
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
{
|
|
||||||
self.try_list_chain_txs(chain, chain_tip)
|
self.try_list_chain_txs(chain, chain_tip)
|
||||||
.map(|r| r.expect("oracle is infallible"))
|
.map(|r| r.expect("oracle is infallible"))
|
||||||
}
|
}
|
||||||
@ -814,16 +796,11 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// If the [`ChainOracle`] is infallible, [`list_chain_txouts`] can be used instead.
|
/// If the [`ChainOracle`] is infallible, [`list_chain_txouts`] can be used instead.
|
||||||
///
|
///
|
||||||
/// [`list_chain_txouts`]: Self::list_chain_txouts
|
/// [`list_chain_txouts`]: Self::list_chain_txouts
|
||||||
pub fn try_list_chain_txouts<'a, C, P>(
|
pub fn try_list_chain_txouts<'a, C: ChainOracle + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
mut filter_predicate: P,
|
) -> impl Iterator<Item = Result<FullTxOut<ObservedAs<A>>, C::Error>> + 'a {
|
||||||
) -> impl Iterator<Item = Result<FullTxOut<ObservedAs<A>>, C::Error>> + 'a
|
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
P: FnMut(OutPoint, &TxOut) -> bool + 'a,
|
|
||||||
{
|
|
||||||
self.try_list_chain_txs(chain, chain_tip)
|
self.try_list_chain_txs(chain, chain_tip)
|
||||||
.flat_map(move |tx_res| match tx_res {
|
.flat_map(move |tx_res| match tx_res {
|
||||||
Ok(canonical_tx) => canonical_tx
|
Ok(canonical_tx) => canonical_tx
|
||||||
@ -831,13 +808,9 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
.output
|
.output
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(vout, txout)| {
|
.map(|(vout, txout)| {
|
||||||
let outpoint = OutPoint::new(canonical_tx.node.txid, vout as _);
|
let outpoint = OutPoint::new(canonical_tx.node.txid, vout as _);
|
||||||
if filter_predicate(outpoint, txout) {
|
Ok((outpoint, txout.clone(), canonical_tx.clone()))
|
||||||
Some(Ok((outpoint, txout.clone(), canonical_tx.clone())))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
Err(err) => vec![Err(err)],
|
Err(err) => vec![Err(err)],
|
||||||
@ -871,17 +844,12 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// This is the infallible version of [`try_list_chain_txouts`].
|
/// This is the infallible version of [`try_list_chain_txouts`].
|
||||||
///
|
///
|
||||||
/// [`try_list_chain_txouts`]: Self::try_list_chain_txouts
|
/// [`try_list_chain_txouts`]: Self::try_list_chain_txouts
|
||||||
pub fn list_chain_txouts<'a, C, P>(
|
pub fn list_chain_txouts<'a, C: ChainOracle<Error = Infallible> + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
filter_predicate: P,
|
) -> impl Iterator<Item = FullTxOut<ObservedAs<A>>> + 'a {
|
||||||
) -> impl Iterator<Item = FullTxOut<ObservedAs<A>>> + 'a
|
self.try_list_chain_txouts(chain, chain_tip)
|
||||||
where
|
|
||||||
C: ChainOracle<Error = Infallible> + 'a,
|
|
||||||
P: FnMut(OutPoint, &TxOut) -> bool + 'a,
|
|
||||||
{
|
|
||||||
self.try_list_chain_txouts(chain, chain_tip, filter_predicate)
|
|
||||||
.map(|r| r.expect("error in infallible"))
|
.map(|r| r.expect("error in infallible"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,17 +863,12 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// infallible, [`list_chain_unspents`] can be used instead.
|
/// infallible, [`list_chain_unspents`] can be used instead.
|
||||||
///
|
///
|
||||||
/// [`list_chain_unspents`]: Self::list_chain_unspents
|
/// [`list_chain_unspents`]: Self::list_chain_unspents
|
||||||
pub fn try_list_chain_unspents<'a, C, P>(
|
pub fn try_list_chain_unspents<'a, C: ChainOracle + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
chain_tip: BlockId,
|
chain_tip: BlockId,
|
||||||
filter_txout: P,
|
) -> impl Iterator<Item = Result<FullTxOut<ObservedAs<A>>, C::Error>> + 'a {
|
||||||
) -> impl Iterator<Item = Result<FullTxOut<ObservedAs<A>>, C::Error>> + 'a
|
self.try_list_chain_txouts(chain, chain_tip)
|
||||||
where
|
|
||||||
C: ChainOracle + 'a,
|
|
||||||
P: FnMut(OutPoint, &TxOut) -> bool + 'a,
|
|
||||||
{
|
|
||||||
self.try_list_chain_txouts(chain, chain_tip, filter_txout)
|
|
||||||
.filter(|r| !matches!(r, Ok(txo) if txo.spent_by.is_none()))
|
.filter(|r| !matches!(r, Ok(txo) if txo.spent_by.is_none()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,17 +877,12 @@ impl<A: Anchor> TxGraph<A> {
|
|||||||
/// This is the infallible version of [`try_list_chain_unspents`].
|
/// This is the infallible version of [`try_list_chain_unspents`].
|
||||||
///
|
///
|
||||||
/// [`try_list_chain_unspents`]: Self::try_list_chain_unspents
|
/// [`try_list_chain_unspents`]: Self::try_list_chain_unspents
|
||||||
pub fn list_chain_unspents<'a, C, P>(
|
pub fn list_chain_unspents<'a, C: ChainOracle<Error = Infallible> + 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
chain: &'a C,
|
chain: &'a C,
|
||||||
static_block: BlockId,
|
static_block: BlockId,
|
||||||
filter_txout: P,
|
) -> impl Iterator<Item = FullTxOut<ObservedAs<A>>> + 'a {
|
||||||
) -> impl Iterator<Item = FullTxOut<ObservedAs<A>>> + 'a
|
self.try_list_chain_unspents(chain, static_block)
|
||||||
where
|
|
||||||
C: ChainOracle<Error = Infallible> + 'a,
|
|
||||||
P: FnMut(OutPoint, &TxOut) -> bool + 'a,
|
|
||||||
{
|
|
||||||
self.try_list_chain_unspents(chain, static_block, filter_txout)
|
|
||||||
.map(|r| r.expect("error is infallible"))
|
.map(|r| r.expect("error is infallible"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user