]> Untitled Git - bdk/commitdiff
refactor: Remove `scan` and `scan_txout` from SpkTxoutIndex and KeychainTxoutIndex
authorVladimir Fomene <vladimirfomene@gmail.com>
Fri, 25 Aug 2023 09:52:09 +0000 (12:52 +0300)
committer志宇 <hello@evanlinjin.me>
Sat, 2 Sep 2023 17:51:21 +0000 (01:51 +0800)
crates/chain/src/indexed_tx_graph.rs
crates/chain/src/keychain/txout_index.rs
crates/chain/src/spk_txout_index.rs
crates/chain/tests/test_keychain_txout_index.rs
crates/chain/tests/test_spk_txout_index.rs

index 6dc2e9943babf2919e9ba3eaa3c1089ff374f627..4643a93ec9856f9effe9ede1ce147d1c6d737d1c 100644 (file)
@@ -233,7 +233,18 @@ pub trait Indexer {
     /// Scan and index the given `outpoint` and `txout`.
     fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::ChangeSet;
 
-    /// Scan and index the given transaction.
+    /// Scans a transaction for relevant outpoints, which are stored and indexed internally.
+    ///
+    /// If the matched script pubkey is part of the lookahead, the last stored index is updated for
+    /// the script pubkey's keychain and the [`ChangeSet`] returned will reflect the
+    /// change.
+    ///
+    /// Typically, this method is used in two situations:
+    ///
+    /// 1. After loading transaction data from the disk, you may scan over all the txouts to restore all
+    /// your txouts.
+    /// 2. When getting new data from the chain, you usually scan it before incorporating it into
+    /// your chain state.
     fn index_tx(&mut self, tx: &Transaction) -> Self::ChangeSet;
 
     /// Apply changeset to itself.
index 0376473ffefacfd8f540832da733c6c5bad4845e..5996d4d46d9b7158aac061b8a30cbfeff4fda01b 100644 (file)
@@ -91,11 +91,19 @@ impl<K: Clone + Ord + Debug> Indexer for KeychainTxOutIndex<K> {
     type ChangeSet = super::ChangeSet<K>;
 
     fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::ChangeSet {
-        self.scan_txout(outpoint, txout)
+        let mut changeset = super::ChangeSet::<K>::default();
+        for (keychain, index) in self.inner.index_txout(outpoint, txout) {
+            changeset.append(self.reveal_to_target(&keychain, index).1);
+        }
+        changeset
     }
 
     fn index_tx(&mut self, tx: &bitcoin::Transaction) -> Self::ChangeSet {
-        self.scan(tx)
+        let mut changeset = super::ChangeSet::<K>::default();
+        for (op, txout) in tx.output.iter().enumerate() {
+            changeset.append(self.index_txout(OutPoint::new(tx.txid(), op as u32), txout));
+        }
+        changeset
     }
 
     fn initial_changeset(&self) -> Self::ChangeSet {
@@ -112,36 +120,6 @@ impl<K: Clone + Ord + Debug> Indexer for KeychainTxOutIndex<K> {
 }
 
 impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
-    /// Scans a transaction for relevant outpoints, which are stored and indexed internally.
-    ///
-    /// If the matched script pubkey is part of the lookahead, the last stored index is updated for
-    /// the script pubkey's keychain and the [`super::ChangeSet`] returned will reflect the
-    /// change.
-    ///
-    /// Typically, this method is used in two situations:
-    ///
-    /// 1. After loading transaction data from the disk, you may scan over all the txouts to restore all
-    /// your txouts.
-    /// 2. When getting new data from the chain, you usually scan it before incorporating it into
-    /// your chain state (i.e., `SparseChain`, `ChainGraph`).
-    pub fn scan(&mut self, tx: &bitcoin::Transaction) -> super::ChangeSet<K> {
-        let mut changeset = super::ChangeSet::<K>::default();
-        for (op, txout) in tx.output.iter().enumerate() {
-            changeset.append(self.scan_txout(OutPoint::new(tx.txid(), op as u32), txout));
-        }
-        changeset
-    }
-
-    /// Scan a single outpoint for a matching script pubkey.
-    ///
-    /// If it matches, this will store and index it.
-    pub fn scan_txout(&mut self, op: OutPoint, txout: &TxOut) -> super::ChangeSet<K> {
-        match self.inner.scan_txout(op, txout).cloned() {
-            Some((keychain, index)) => self.reveal_to_target(&keychain, index).1,
-            None => super::ChangeSet::default(),
-        }
-    }
-
     /// Return a reference to the internal [`SpkTxOutIndex`].
     pub fn inner(&self) -> &SpkTxOutIndex<(K, u32)> {
         &self.inner
@@ -198,14 +176,11 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     /// Set the lookahead count for `keychain`.
     ///
     /// The lookahead is the number of scripts to cache ahead of the last stored script index. This
-    /// is useful during a scan via [`scan`] or [`scan_txout`].
+    /// is useful during a scan via [`Indexer::index_tx`] or [`Indexer::index_txout`].
     ///
     /// # Panics
     ///
     /// This will panic if the `keychain` does not exist.
-    ///
-    /// [`scan`]: Self::scan
-    /// [`scan_txout`]: Self::scan_txout
     pub fn set_lookahead(&mut self, keychain: &K, lookahead: u32) {
         self.lookahead.insert(keychain.clone(), lookahead);
         self.replenish_lookahead(keychain);
index a4d6d7c2b67bb41dfe46a8255c69354cb8fe18d7..8bac74131bc72d89bb6fb0577cee785884bb7535 100644 (file)
@@ -9,8 +9,9 @@ use bitcoin::{self, OutPoint, Script, ScriptBuf, Transaction, TxOut, Txid};
 /// An index storing [`TxOut`]s that have a script pubkey that matches those in a list.
 ///
 /// The basic idea is that you insert script pubkeys you care about into the index with
-/// [`insert_spk`] and then when you call [`scan`], the index will look at any txouts you pass in and
-/// store and index any txouts matching one of its script pubkeys.
+/// [`insert_spk`] and then when you call [`Indexer::index_tx`] or [`Indexer::index_txout`], the
+/// index will look at any txouts you pass in and store and index any txouts matching one of its
+/// script pubkeys.
 ///
 /// Each script pubkey is associated with an application-defined index script index `I`, which must be
 /// [`Ord`]. Usually, this is used to associate the derivation index of the script pubkey or even a
@@ -24,7 +25,6 @@ use bitcoin::{self, OutPoint, Script, ScriptBuf, Transaction, TxOut, Txid};
 /// [`TxOut`]: bitcoin::TxOut
 /// [`insert_spk`]: Self::insert_spk
 /// [`Ord`]: core::cmp::Ord
-/// [`scan`]: Self::scan
 /// [`TxGraph`]: crate::tx_graph::TxGraph
 #[derive(Clone, Debug)]
 pub struct SpkTxOutIndex<I> {
@@ -53,19 +53,35 @@ impl<I> Default for SpkTxOutIndex<I> {
 }
 
 impl<I: Clone + Ord> Indexer for SpkTxOutIndex<I> {
-    type ChangeSet = ();
+    type ChangeSet = BTreeSet<I>;
 
     fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::ChangeSet {
-        self.scan_txout(outpoint, txout);
-        Default::default()
+        let spk_i = self.spk_indices.get(&txout.script_pubkey);
+        let mut scanned_indices = BTreeSet::new();
+        if let Some(spk_i) = spk_i {
+            self.txouts.insert(outpoint, (spk_i.clone(), txout.clone()));
+            self.spk_txouts.insert((spk_i.clone(), outpoint));
+            self.unused.remove(spk_i);
+            scanned_indices.insert(spk_i.clone());
+        }
+        scanned_indices
     }
 
     fn index_tx(&mut self, tx: &Transaction) -> Self::ChangeSet {
-        self.scan(tx);
-        Default::default()
+        let mut scanned_indices = BTreeSet::new();
+
+        for (i, txout) in tx.output.iter().enumerate() {
+            let op = OutPoint::new(tx.txid(), i as u32);
+            let mut txout_indices = self.index_txout(op, txout);
+            scanned_indices.append(&mut txout_indices);
+        }
+
+        scanned_indices
     }
 
-    fn initial_changeset(&self) -> Self::ChangeSet {}
+    fn initial_changeset(&self) -> Self::ChangeSet {
+        self.spks.keys().cloned().collect()
+    }
 
     fn apply_changeset(&mut self, _changeset: Self::ChangeSet) {
         // This applies nothing.
@@ -77,38 +93,6 @@ impl<I: Clone + Ord> Indexer for SpkTxOutIndex<I> {
 }
 
 impl<I: Clone + Ord> SpkTxOutIndex<I> {
-    /// Scans a transaction containing many txouts.
-    ///
-    /// Typically, this is used in two situations:
-    ///
-    /// 1. After loading transaction data from the disk, you may scan over all the txouts to restore all
-    /// your txouts.
-    /// 2. When getting new data from the chain, you usually scan it before incorporating it into your chain state.
-    pub fn scan(&mut self, tx: &bitcoin::Transaction) -> BTreeSet<I> {
-        let mut scanned_indices = BTreeSet::new();
-
-        for (i, txout) in tx.output.iter().enumerate() {
-            let op = OutPoint::new(tx.txid(), i as u32);
-            if let Some(spk_i) = self.scan_txout(op, txout) {
-                scanned_indices.insert(spk_i.clone());
-            }
-        }
-
-        scanned_indices
-    }
-
-    /// Scan a single `TxOut` for a matching script pubkey and returns the index that matches the
-    /// script pubkey (if any).
-    pub fn scan_txout(&mut self, op: OutPoint, txout: &TxOut) -> Option<&I> {
-        let spk_i = self.spk_indices.get(&txout.script_pubkey);
-        if let Some(spk_i) = spk_i {
-            self.txouts.insert(op, (spk_i.clone(), txout.clone()));
-            self.spk_txouts.insert((spk_i.clone(), op));
-            self.unused.remove(spk_i);
-        }
-        spk_i
-    }
-
     /// Get a reference to the set of indexed outpoints.
     pub fn outpoints(&self) -> &BTreeSet<(I, OutPoint)> {
         &self.spk_txouts
index 817b0349969ab81ae569fa87c8546db52536b63c..c4f4347155e57c1e5b9ec418f8d19f9c265c7283 100644 (file)
@@ -4,6 +4,7 @@
 mod common;
 use bdk_chain::{
     collections::BTreeMap,
+    indexed_tx_graph::Indexer,
     keychain::{self, KeychainTxOutIndex},
     Append,
 };
@@ -194,7 +195,7 @@ fn test_lookahead() {
             ],
             ..common::new_tx(external_index)
         };
-        assert_eq!(txout_index.scan(&tx), keychain::ChangeSet::default());
+        assert_eq!(txout_index.index_tx(&tx), keychain::ChangeSet::default());
         assert_eq!(
             txout_index.last_revealed_index(&TestKeychain::External),
             Some(last_external_index)
@@ -248,7 +249,7 @@ fn test_scan_with_lookahead() {
             value: 0,
         };
 
-        let changeset = txout_index.scan_txout(op, &txout);
+        let changeset = txout_index.index_txout(op, &txout);
         assert_eq!(
             changeset.as_inner(),
             &[(TestKeychain::External, spk_i)].into()
@@ -273,7 +274,7 @@ fn test_scan_with_lookahead() {
         script_pubkey: spk_41,
         value: 0,
     };
-    let changeset = txout_index.scan_txout(op, &txout);
+    let changeset = txout_index.index_txout(op, &txout);
     assert!(changeset.is_empty());
 }
 
index 099b4ca884071ac64bec9ad01817a09dd487ba6a..e8b752146cc80ac2eb188d51ff0d8d18a887fb00 100644 (file)
@@ -1,4 +1,4 @@
-use bdk_chain::SpkTxOutIndex;
+use bdk_chain::{indexed_tx_graph::Indexer, SpkTxOutIndex};
 use bitcoin::{absolute, OutPoint, ScriptBuf, Transaction, TxIn, TxOut};
 
 #[test]
@@ -22,7 +22,7 @@ fn spk_txout_sent_and_received() {
 
     assert_eq!(index.sent_and_received(&tx1), (0, 42_000));
     assert_eq!(index.net_value(&tx1), 42_000);
-    index.scan(&tx1);
+    index.index_tx(&tx1);
     assert_eq!(
         index.sent_and_received(&tx1),
         (0, 42_000),
@@ -82,7 +82,7 @@ fn mark_used() {
         }],
     };
 
-    spk_index.scan(&tx1);
+    spk_index.index_tx(&tx1);
     spk_index.unmark_used(&1);
     assert!(
         spk_index.is_used(&1),