Skip to content

Commit ef5f25f

Browse files
committed
wqrefactor(chain)!: update ChainOracle and TxGraph methods to being infallible
1 parent faf520d commit ef5f25f

File tree

7 files changed

+99
-293
lines changed

7 files changed

+99
-293
lines changed

crates/chain/src/canonical_iter.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,14 @@ impl<'g, A: Anchor, C: ChainOracle> CanonicalIter<'g, A, C> {
8585
}
8686

8787
/// Mark transaction as canonical if it is anchored in the best chain.
88-
fn scan_anchors(
89-
&mut self,
90-
txid: Txid,
91-
tx: Arc<Transaction>,
92-
anchors: &BTreeSet<A>,
93-
) -> Result<(), C::Error> {
88+
fn scan_anchors(&mut self, txid: Txid, tx: Arc<Transaction>, anchors: &BTreeSet<A>) {
9489
for anchor in anchors {
9590
let in_chain_opt = self
9691
.chain
97-
.is_block_in_chain(anchor.anchor_block(), self.chain_tip)?;
92+
.is_block_in_chain(anchor.anchor_block(), self.chain_tip);
9893
if in_chain_opt == Some(true) {
9994
self.mark_canonical(txid, tx, CanonicalReason::from_anchor(anchor.clone()));
100-
return Ok(());
95+
return;
10196
}
10297
}
10398
// cannot determine
@@ -112,7 +107,6 @@ impl<'g, A: Anchor, C: ChainOracle> CanonicalIter<'g, A, C> {
112107
)
113108
.confirmation_height_upper_bound(),
114109
));
115-
Ok(())
116110
}
117111

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

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

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

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

223217
if let Some((txid, tx, anchors)) = self.unprocessed_anchored_txs.next() {
224218
if !self.is_canonicalized(txid) {
225-
if let Err(err) = self.scan_anchors(txid, tx, anchors) {
226-
return Some(Err(err));
227-
}
219+
self.scan_anchors(txid, tx, anchors);
228220
}
229221
continue;
230222
}

crates/chain/src/chain_oracle.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,12 @@ use crate::BlockId;
77
///
88
/// [`is_block_in_chain`]: Self::is_block_in_chain
99
pub trait ChainOracle {
10-
/// Error type.
11-
type Error: core::fmt::Debug;
12-
1310
/// Determines whether `block` of [`BlockId`] exists as an ancestor of `chain_tip`.
1411
///
1512
/// If `None` is returned, it means the implementation cannot determine whether `block` exists
1613
/// under `chain_tip`.
17-
fn is_block_in_chain(
18-
&self,
19-
block: BlockId,
20-
chain_tip: BlockId,
21-
) -> Result<Option<bool>, Self::Error>;
14+
fn is_block_in_chain(&self, block: BlockId, chain_tip: BlockId) -> Option<bool>;
2215

2316
/// Get the best chain's chain tip.
24-
fn get_chain_tip(&self) -> Result<BlockId, Self::Error>;
17+
fn get_chain_tip(&self) -> BlockId;
2518
}

crates/chain/src/indexed_tx_graph.rs

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Contains the [`IndexedTxGraph`] and associated types. Refer to the
22
//! [`IndexedTxGraph`] documentation for more.
33
use core::{
4-
convert::Infallible,
54
fmt::{self, Debug},
65
ops::RangeBounds,
76
};
@@ -438,46 +437,19 @@ where
438437
///
439438
///
440439
/// The spk index range can be contrained with `range`.
441-
///
442-
/// # Error
443-
///
444-
/// If the [`ChainOracle`] implementation (`chain`) fails, an error will be returned with the
445-
/// returned item.
446-
///
447-
/// If the [`ChainOracle`] is infallible,
448-
/// [`list_expected_spk_txids`](Self::list_expected_spk_txids) can be used instead.
449-
pub fn try_list_expected_spk_txids<'a, C, I>(
450-
&'a self,
451-
chain: &'a C,
452-
chain_tip: BlockId,
453-
spk_index_range: impl RangeBounds<I> + 'a,
454-
) -> impl Iterator<Item = Result<(ScriptBuf, Txid), C::Error>> + 'a
455-
where
456-
C: ChainOracle,
457-
X: AsRef<SpkTxOutIndex<I>> + 'a,
458-
I: fmt::Debug + Clone + Ord + 'a,
459-
{
460-
self.graph
461-
.try_list_expected_spk_txids(chain, chain_tip, &self.index, spk_index_range)
462-
}
463-
464-
/// List txids that are expected to exist under the given spks.
465-
///
466-
/// This is the infallible version of
467-
/// [`try_list_expected_spk_txids`](Self::try_list_expected_spk_txids).
468440
pub fn list_expected_spk_txids<'a, C, I>(
469441
&'a self,
470442
chain: &'a C,
471443
chain_tip: BlockId,
472444
spk_index_range: impl RangeBounds<I> + 'a,
473445
) -> impl Iterator<Item = (ScriptBuf, Txid)> + 'a
474446
where
475-
C: ChainOracle<Error = Infallible>,
447+
C: ChainOracle,
476448
X: AsRef<SpkTxOutIndex<I>> + 'a,
477449
I: fmt::Debug + Clone + Ord + 'a,
478450
{
479-
self.try_list_expected_spk_txids(chain, chain_tip, spk_index_range)
480-
.map(|r| r.expect("infallible"))
451+
self.graph
452+
.list_expected_spk_txids(chain, chain_tip, &self.index, spk_index_range)
481453
}
482454
}
483455

crates/chain/src/local_chain.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! The [`LocalChain`] is a local implementation of [`ChainOracle`].
22
3-
use core::convert::Infallible;
43
use core::fmt;
54
use core::ops::RangeBounds;
65

@@ -70,27 +69,20 @@ impl<D> PartialEq for LocalChain<D> {
7069
}
7170

7271
impl<D> ChainOracle for LocalChain<D> {
73-
type Error = Infallible;
74-
75-
fn is_block_in_chain(
76-
&self,
77-
block: BlockId,
78-
chain_tip: BlockId,
79-
) -> Result<Option<bool>, Self::Error> {
72+
fn is_block_in_chain(&self, block: BlockId, chain_tip: BlockId) -> Option<bool> {
8073
let chain_tip_cp = match self.tip.get(chain_tip.height) {
8174
// we can only determine whether `block` is in chain of `chain_tip` if `chain_tip` can
8275
// be identified in chain
8376
Some(cp) if cp.hash() == chain_tip.hash => cp,
84-
_ => return Ok(None),
77+
_ => return None,
8578
};
86-
match chain_tip_cp.get(block.height) {
87-
Some(cp) => Ok(Some(cp.hash() == block.hash)),
88-
None => Ok(None),
89-
}
79+
chain_tip_cp
80+
.get(block.height)
81+
.map(|cp| cp.hash() == block.hash)
9082
}
9183

92-
fn get_chain_tip(&self) -> Result<BlockId, Self::Error> {
93-
Ok(self.tip.block_id())
84+
fn get_chain_tip(&self) -> BlockId {
85+
self.tip.block_id()
9486
}
9587
}
9688

0 commit comments

Comments
 (0)