diff --git a/crates/chain/src/indexed_tx_graph.rs b/crates/chain/src/indexed_tx_graph.rs index 6dc2e9943b..4643a93ec9 100644 --- a/crates/chain/src/indexed_tx_graph.rs +++ b/crates/chain/src/indexed_tx_graph.rs @@ -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. diff --git a/crates/chain/src/keychain/txout_index.rs b/crates/chain/src/keychain/txout_index.rs index 0376473ffe..17d89e3d4b 100644 --- a/crates/chain/src/keychain/txout_index.rs +++ b/crates/chain/src/keychain/txout_index.rs @@ -91,11 +91,19 @@ impl Indexer for KeychainTxOutIndex { type ChangeSet = super::ChangeSet; fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::ChangeSet { - self.scan_txout(outpoint, txout) + let mut changeset = super::ChangeSet::::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::::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 Indexer for KeychainTxOutIndex { } impl KeychainTxOutIndex { - /// 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 { - let mut changeset = super::ChangeSet::::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 { - 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 diff --git a/crates/chain/src/spk_txout_index.rs b/crates/chain/src/spk_txout_index.rs index 6a8ae27cc8..6208cbf135 100644 --- a/crates/chain/src/spk_txout_index.rs +++ b/crates/chain/src/spk_txout_index.rs @@ -53,19 +53,35 @@ impl Default for SpkTxOutIndex { } impl Indexer for SpkTxOutIndex { - type ChangeSet = (); + type ChangeSet = BTreeSet; 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 Indexer for SpkTxOutIndex { } impl SpkTxOutIndex { - /// 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 { - 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