Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions crates/chain/src/canonical_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,14 @@ impl<'g, A: Anchor, C: ChainOracle> CanonicalIter<'g, A, C> {
}

/// Mark transaction as canonical if it is anchored in the best chain.
fn scan_anchors(
&mut self,
txid: Txid,
tx: Arc<Transaction>,
anchors: &BTreeSet<A>,
) -> Result<(), C::Error> {
fn scan_anchors(&mut self, txid: Txid, tx: Arc<Transaction>, anchors: &BTreeSet<A>) {
for anchor in anchors {
let in_chain_opt = self
.chain
.is_block_in_chain(anchor.anchor_block(), self.chain_tip)?;
.is_block_in_chain(anchor.anchor_block(), self.chain_tip);
if in_chain_opt == Some(true) {
self.mark_canonical(txid, tx, CanonicalReason::from_anchor(anchor.clone()));
return Ok(());
return;
}
}
// cannot determine
Expand All @@ -112,7 +107,6 @@ impl<'g, A: Anchor, C: ChainOracle> CanonicalIter<'g, A, C> {
)
.confirmation_height_upper_bound(),
));
Ok(())
}

/// Marks `tx` and it's ancestors as canonical and mark all conflicts of these as
Expand Down Expand Up @@ -201,7 +195,7 @@ impl<'g, A: Anchor, C: ChainOracle> CanonicalIter<'g, A, C> {
}

impl<A: Anchor, C: ChainOracle> Iterator for CanonicalIter<'_, A, C> {
type Item = Result<(Txid, Arc<Transaction>, CanonicalReason<A>), C::Error>;
type Item = (Txid, Arc<Transaction>, CanonicalReason<A>);

fn next(&mut self) -> Option<Self::Item> {
loop {
Expand All @@ -211,7 +205,7 @@ impl<A: Anchor, C: ChainOracle> Iterator for CanonicalIter<'_, A, C> {
.get(&txid)
.cloned()
.expect("reason must exist");
return Some(Ok((txid, tx, reason)));
return Some((txid, tx, reason));
}

if let Some((txid, tx)) = self.unprocessed_assumed_txs.next() {
Expand All @@ -222,9 +216,7 @@ impl<A: Anchor, C: ChainOracle> Iterator for CanonicalIter<'_, A, C> {

if let Some((txid, tx, anchors)) = self.unprocessed_anchored_txs.next() {
if !self.is_canonicalized(txid) {
if let Err(err) = self.scan_anchors(txid, tx, anchors) {
return Some(Err(err));
}
self.scan_anchors(txid, tx, anchors);
}
continue;
}
Expand Down
11 changes: 2 additions & 9 deletions crates/chain/src/chain_oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,12 @@ use crate::BlockId;
///
/// [`is_block_in_chain`]: Self::is_block_in_chain
pub trait ChainOracle {
/// Error type.
type Error: core::fmt::Debug;

/// Determines whether `block` of [`BlockId`] exists as an ancestor of `chain_tip`.
///
/// If `None` is returned, it means the implementation cannot determine whether `block` exists
/// under `chain_tip`.
fn is_block_in_chain(
&self,
block: BlockId,
chain_tip: BlockId,
) -> Result<Option<bool>, Self::Error>;
fn is_block_in_chain(&self, block: BlockId, chain_tip: BlockId) -> Option<bool>;

/// Get the best chain's chain tip.
fn get_chain_tip(&self) -> Result<BlockId, Self::Error>;
fn get_chain_tip(&self) -> BlockId;
}
34 changes: 3 additions & 31 deletions crates/chain/src/indexed_tx_graph.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Contains the [`IndexedTxGraph`] and associated types. Refer to the
//! [`IndexedTxGraph`] documentation for more.
use core::{
convert::Infallible,
fmt::{self, Debug},
ops::RangeBounds,
};
Expand Down Expand Up @@ -438,46 +437,19 @@ where
///
///
/// The spk index range can be contrained with `range`.
///
/// # Error
///
/// If the [`ChainOracle`] implementation (`chain`) fails, an error will be returned with the
/// returned item.
///
/// If the [`ChainOracle`] is infallible,
/// [`list_expected_spk_txids`](Self::list_expected_spk_txids) can be used instead.
pub fn try_list_expected_spk_txids<'a, C, I>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
spk_index_range: impl RangeBounds<I> + 'a,
) -> impl Iterator<Item = Result<(ScriptBuf, Txid), C::Error>> + 'a
where
C: ChainOracle,
X: AsRef<SpkTxOutIndex<I>> + 'a,
I: fmt::Debug + Clone + Ord + 'a,
{
self.graph
.try_list_expected_spk_txids(chain, chain_tip, &self.index, spk_index_range)
}

/// List txids that are expected to exist under the given spks.
///
/// This is the infallible version of
/// [`try_list_expected_spk_txids`](Self::try_list_expected_spk_txids).
pub fn list_expected_spk_txids<'a, C, I>(
&'a self,
chain: &'a C,
chain_tip: BlockId,
spk_index_range: impl RangeBounds<I> + 'a,
) -> impl Iterator<Item = (ScriptBuf, Txid)> + 'a
where
C: ChainOracle<Error = Infallible>,
C: ChainOracle,
X: AsRef<SpkTxOutIndex<I>> + 'a,
I: fmt::Debug + Clone + Ord + 'a,
{
self.try_list_expected_spk_txids(chain, chain_tip, spk_index_range)
.map(|r| r.expect("infallible"))
self.graph
.list_expected_spk_txids(chain, chain_tip, &self.index, spk_index_range)
}
}

Expand Down
22 changes: 7 additions & 15 deletions crates/chain/src/local_chain.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! The [`LocalChain`] is a local implementation of [`ChainOracle`].

use core::convert::Infallible;
use core::fmt;
use core::ops::RangeBounds;

Expand Down Expand Up @@ -70,27 +69,20 @@ impl<D> PartialEq for LocalChain<D> {
}

impl<D> ChainOracle for LocalChain<D> {
type Error = Infallible;

fn is_block_in_chain(
&self,
block: BlockId,
chain_tip: BlockId,
) -> Result<Option<bool>, Self::Error> {
fn is_block_in_chain(&self, block: BlockId, chain_tip: BlockId) -> Option<bool> {
let chain_tip_cp = match self.tip.get(chain_tip.height) {
// we can only determine whether `block` is in chain of `chain_tip` if `chain_tip` can
// be identified in chain
Some(cp) if cp.hash() == chain_tip.hash => cp,
_ => return Ok(None),
_ => return None,
};
match chain_tip_cp.get(block.height) {
Some(cp) => Ok(Some(cp.hash() == block.hash)),
None => Ok(None),
}
chain_tip_cp
.get(block.height)
.map(|cp| cp.hash() == block.hash)
}

fn get_chain_tip(&self) -> Result<BlockId, Self::Error> {
Ok(self.tip.block_id())
fn get_chain_tip(&self) -> BlockId {
self.tip.block_id()
}
}

Expand Down
Loading
Loading