diff --git a/crates/chain/src/indexed_tx_graph.rs b/crates/chain/src/indexed_tx_graph.rs
index 7ab0ffa8a..f69b227a2 100644
--- a/crates/chain/src/indexed_tx_graph.rs
+++ b/crates/chain/src/indexed_tx_graph.rs
@@ -1,12 +1,9 @@
-use core::convert::Infallible;
-
use alloc::vec::Vec;
-use bitcoin::{OutPoint, Script, Transaction, TxOut};
+use bitcoin::{OutPoint, Transaction, TxOut};
use crate::{
- keychain::Balance,
tx_graph::{Additions, TxGraph},
- Anchor, Append, BlockId, ChainOracle, FullTxOut, ObservedAs,
+ Anchor, Append,
};
/// A struct that combines [`TxGraph`] and an [`Indexer`] implementation.
@@ -29,6 +26,14 @@ impl Default for IndexedTxGraph {
}
impl IndexedTxGraph {
+ /// Construct a new [`IndexedTxGraph`] with a given `index`.
+ pub fn new(index: I) -> Self {
+ Self {
+ index,
+ graph: TxGraph::default(),
+ }
+ }
+
/// Get a reference of the internal transaction graph.
pub fn graph(&self) -> &TxGraph {
&self.graph
@@ -157,115 +162,6 @@ where
}
}
-impl IndexedTxGraph {
- pub fn try_list_owned_txouts<'a, C: ChainOracle + 'a>(
- &'a self,
- chain: &'a C,
- chain_tip: BlockId,
- ) -> impl Iterator- >, C::Error>> + 'a {
- self.graph()
- .try_list_chain_txouts(chain, chain_tip)
- .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: ChainOracle + 'a>(
- &'a self,
- chain: &'a C,
- chain_tip: BlockId,
- ) -> impl Iterator
- >> + 'a {
- self.try_list_owned_txouts(chain, chain_tip)
- .map(|r| r.expect("oracle is infallible"))
- }
-
- pub fn try_list_owned_unspents<'a, C: ChainOracle + 'a>(
- &'a self,
- chain: &'a C,
- chain_tip: BlockId,
- ) -> impl Iterator
- >, C::Error>> + 'a {
- self.graph()
- .try_list_chain_unspents(chain, chain_tip)
- .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_unspents<'a, C: ChainOracle + 'a>(
- &'a self,
- chain: &'a C,
- chain_tip: BlockId,
- ) -> impl Iterator
- >> + 'a {
- self.try_list_owned_unspents(chain, chain_tip)
- .map(|r| r.expect("oracle is infallible"))
- }
-
- pub fn try_balance(
- &self,
- chain: &C,
- chain_tip: BlockId,
- mut should_trust: F,
- ) -> Result
- where
- C: ChainOracle,
- F: FnMut(&Script) -> bool,
- {
- let tip_height = chain_tip.height;
-
- let mut immature = 0;
- let mut trusted_pending = 0;
- let mut untrusted_pending = 0;
- let mut confirmed = 0;
-
- for res in self.try_list_owned_unspents(chain, chain_tip) {
- let txout = res?;
-
- match &txout.chain_position {
- ObservedAs::Confirmed(_) => {
- if txout.is_confirmed_and_spendable(tip_height) {
- confirmed += txout.txout.value;
- } else if !txout.is_mature(tip_height) {
- immature += txout.txout.value;
- }
- }
- ObservedAs::Unconfirmed(_) => {
- if should_trust(&txout.txout.script_pubkey) {
- trusted_pending += txout.txout.value;
- } else {
- untrusted_pending += txout.txout.value;
- }
- }
- }
- }
-
- Ok(Balance {
- immature,
- trusted_pending,
- untrusted_pending,
- confirmed,
- })
- }
-
- pub fn balance(&self, chain: &C, chain_tip: BlockId, should_trust: F) -> Balance
- where
- C: ChainOracle,
- F: FnMut(&Script) -> bool,
- {
- self.try_balance(chain, chain_tip, should_trust)
- .expect("error is infallible")
- }
-}
-
/// A structure that represents changes to an [`IndexedTxGraph`].
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
@@ -324,9 +220,3 @@ pub trait Indexer {
/// Determines whether the transaction should be included in the index.
fn is_tx_relevant(&self, tx: &Transaction) -> bool;
}
-
-/// A trait that extends [`Indexer`] to also index "owned" script pubkeys.
-pub trait OwnedIndexer: Indexer {
- /// Determines whether a given script pubkey (`spk`) is owned.
- fn is_spk_owned(&self, spk: &Script) -> bool;
-}
diff --git a/crates/chain/src/keychain/txout_index.rs b/crates/chain/src/keychain/txout_index.rs
index c7a8dd54b..397c43386 100644
--- a/crates/chain/src/keychain/txout_index.rs
+++ b/crates/chain/src/keychain/txout_index.rs
@@ -1,6 +1,6 @@
use crate::{
collections::*,
- indexed_tx_graph::{Indexer, OwnedIndexer},
+ indexed_tx_graph::Indexer,
miniscript::{Descriptor, DescriptorPublicKey},
spk_iter::BIP32_MAX_INDEX,
ForEachTxOut, SpkIterator, SpkTxOutIndex,
@@ -109,12 +109,6 @@ impl Indexer for KeychainTxOutIndex {
}
}
-impl OwnedIndexer for KeychainTxOutIndex {
- fn is_spk_owned(&self, spk: &Script) -> bool {
- self.index_of_spk(spk).is_some()
- }
-}
-
impl KeychainTxOutIndex {
/// Scans an object for relevant outpoints, which are stored and indexed internally.
///
@@ -153,6 +147,11 @@ impl KeychainTxOutIndex {
&self.inner
}
+ /// Get a reference to the set of indexed outpoints.
+ pub fn outpoints(&self) -> &BTreeSet<((K, u32), OutPoint)> {
+ self.inner.outpoints()
+ }
+
/// Return a reference to the internal map of the keychain to descriptors.
pub fn keychains(&self) -> &BTreeMap> {
&self.keychains
diff --git a/crates/chain/src/persist.rs b/crates/chain/src/persist.rs
index 188f88f26..07ff67957 100644
--- a/crates/chain/src/persist.rs
+++ b/crates/chain/src/persist.rs
@@ -41,11 +41,19 @@ where
/// Commit the staged changes to the underlying persistance backend.
///
+ /// Changes that are committed (if any) are returned.
+ ///
+ /// # Error
+ ///
/// Returns a backend-defined error if this fails.
- pub fn commit(&mut self) -> Result<(), B::WriteError> {
- let mut temp = C::default();
- core::mem::swap(&mut temp, &mut self.stage);
- self.backend.write_changes(&temp)
+ pub fn commit(&mut self) -> Result