Skip to content

Commit 5478bb1

Browse files
committed
Merge #1506: Standardize API ownership in KeychainTxOutIndex
7926218 refactor(chain)!: update KeychainTxOutIndex methods to use owned ScriptBuf (Steve Myers) 7c07b9d refactor(chain)!: update KeychainTxOutIndex methods to use owned K (Rob N) Pull request description: ### Description Make all method signatures of `KeychainTxOutIndex` take owned `K` and use `ScriptBuf` instead of its borrowed counterpart `&Script`. Fixes #1482 ### Notes to the reviewers Steve also added a CI fix as well ### Changelog notice - Make all method signatures of `KeychainTxOutIndex` take owned `K` - Update `KeychainTxOutIndex` methods to use `ScriptBuf` ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### New Features: * [ ] I've added tests for the new feature * [ ] I've added docs for the new feature #### Bugfixes: * [x] This pull request breaks the existing API * [ ] I've added tests to reproduce the issue which are now passing * [x] I'm linking the issue being fixed by this PR Top commit has no ACKs. Tree-SHA512: 3cb7d627ef6f38e1eaf6b88174f143c42dfc4d34e3d3d56cc843c256b2f32360fd00fa9ee328d0a41dac1f46771ccae797a96d9e3cee6f5ac4ef63e27cf6b7b7
2 parents 0c8ee1d + 7926218 commit 5478bb1

File tree

11 files changed

+149
-155
lines changed

11 files changed

+149
-155
lines changed

crates/chain/src/indexer/keychain_txout.rs

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{
99
DescriptorExt, DescriptorId, Indexed, Indexer, KeychainIndexed, SpkIterator,
1010
};
1111
use alloc::{borrow::ToOwned, vec::Vec};
12-
use bitcoin::{Amount, OutPoint, Script, ScriptBuf, SignedAmount, Transaction, TxOut, Txid};
12+
use bitcoin::{Amount, OutPoint, ScriptBuf, SignedAmount, Transaction, TxOut, Txid};
1313
use core::{
1414
fmt::Debug,
1515
ops::{Bound, RangeBounds},
@@ -99,7 +99,7 @@ pub const DEFAULT_LOOKAHEAD: u32 = 25;
9999
/// let _ = txout_index.insert_descriptor(MyKeychain::Internal, internal_descriptor)?;
100100
/// let _ = txout_index.insert_descriptor(MyKeychain::MyAppUser { user_id: 42 }, descriptor_42)?;
101101
///
102-
/// let new_spk_for_user = txout_index.reveal_next_spk(&MyKeychain::MyAppUser{ user_id: 42 });
102+
/// let new_spk_for_user = txout_index.reveal_next_spk(MyKeychain::MyAppUser{ user_id: 42 });
103103
/// # Ok::<_, bdk_chain::indexer::keychain_txout::InsertDescriptorError<_>>(())
104104
/// ```
105105
///
@@ -251,14 +251,14 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
251251
/// Return the script that exists under the given `keychain`'s `index`.
252252
///
253253
/// This calls [`SpkTxOutIndex::spk_at_index`] internally.
254-
pub fn spk_at_index(&self, keychain: K, index: u32) -> Option<&Script> {
254+
pub fn spk_at_index(&self, keychain: K, index: u32) -> Option<ScriptBuf> {
255255
self.inner.spk_at_index(&(keychain.clone(), index))
256256
}
257257

258258
/// Returns the keychain and keychain index associated with the spk.
259259
///
260260
/// This calls [`SpkTxOutIndex::index_of_spk`] internally.
261-
pub fn index_of_spk(&self, script: &Script) -> Option<&(K, u32)> {
261+
pub fn index_of_spk(&self, script: ScriptBuf) -> Option<&(K, u32)> {
262262
self.inner.index_of_spk(script)
263263
}
264264

@@ -335,11 +335,11 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
335335
/// Return all keychains and their corresponding descriptors.
336336
pub fn keychains(
337337
&self,
338-
) -> impl DoubleEndedIterator<Item = (&K, &Descriptor<DescriptorPublicKey>)> + ExactSizeIterator + '_
338+
) -> impl DoubleEndedIterator<Item = (K, &Descriptor<DescriptorPublicKey>)> + ExactSizeIterator + '_
339339
{
340340
self.keychain_to_descriptor_id
341341
.iter()
342-
.map(|(k, did)| (k, self.descriptors.get(did).expect("invariant")))
342+
.map(|(k, did)| (k.clone(), self.descriptors.get(did).expect("invariant")))
343343
}
344344

345345
/// Insert a descriptor with a keychain associated to it.
@@ -399,8 +399,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
399399

400400
/// Gets the descriptor associated with the keychain. Returns `None` if the keychain doesn't
401401
/// have a descriptor associated with it.
402-
pub fn get_descriptor(&self, keychain: &K) -> Option<&Descriptor<DescriptorPublicKey>> {
403-
let did = self.keychain_to_descriptor_id.get(keychain)?;
402+
pub fn get_descriptor(&self, keychain: K) -> Option<&Descriptor<DescriptorPublicKey>> {
403+
let did = self.keychain_to_descriptor_id.get(&keychain)?;
404404
self.descriptors.get(did)
405405
}
406406

@@ -416,8 +416,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
416416
/// Store lookahead scripts until `target_index` (inclusive).
417417
///
418418
/// This does not change the global `lookahead` setting.
419-
pub fn lookahead_to_target(&mut self, keychain: &K, target_index: u32) {
420-
if let Some((next_index, _)) = self.next_index(keychain) {
419+
pub fn lookahead_to_target(&mut self, keychain: K, target_index: u32) {
420+
if let Some((next_index, _)) = self.next_index(keychain.clone()) {
421421
let temp_lookahead = (target_index + 1)
422422
.checked_sub(next_index)
423423
.filter(|&index| index > 0);
@@ -434,9 +434,9 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
434434
}
435435
}
436436

437-
fn replenish_inner_index_keychain(&mut self, keychain: &K, lookahead: u32) {
438-
if let Some(did) = self.keychain_to_descriptor_id.get(keychain) {
439-
self.replenish_inner_index(*did, keychain, lookahead);
437+
fn replenish_inner_index_keychain(&mut self, keychain: K, lookahead: u32) {
438+
if let Some(did) = self.keychain_to_descriptor_id.get(&keychain) {
439+
self.replenish_inner_index(*did, &keychain, lookahead);
440440
}
441441
}
442442

@@ -464,7 +464,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
464464
/// keychain doesn't exist
465465
pub fn unbounded_spk_iter(
466466
&self,
467-
keychain: &K,
467+
keychain: K,
468468
) -> Option<SpkIterator<Descriptor<DescriptorPublicKey>>> {
469469
let descriptor = self.get_descriptor(keychain)?.clone();
470470
Some(SpkIterator::new(descriptor))
@@ -489,7 +489,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
489489
pub fn revealed_spks(
490490
&self,
491491
range: impl RangeBounds<K>,
492-
) -> impl Iterator<Item = KeychainIndexed<K, &Script>> {
492+
) -> impl Iterator<Item = KeychainIndexed<K, ScriptBuf>> + '_ {
493493
let start = range.start_bound();
494494
let end = range.end_bound();
495495
let mut iter_last_revealed = self
@@ -516,7 +516,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
516516
let (current_keychain, last_revealed) = current_keychain?;
517517

518518
if current_keychain == keychain && Some(*index) <= last_revealed {
519-
break Some(((keychain.clone(), *index), spk.as_script()));
519+
break Some(((keychain.clone(), *index), spk.clone()));
520520
}
521521
})
522522
}
@@ -525,37 +525,37 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
525525
///
526526
/// This is a double ended iterator so you can easily reverse it to get an iterator where
527527
/// the script pubkeys that were most recently revealed are first.
528-
pub fn revealed_keychain_spks<'a>(
529-
&'a self,
530-
keychain: &'a K,
531-
) -> impl DoubleEndedIterator<Item = Indexed<&Script>> + 'a {
528+
pub fn revealed_keychain_spks(
529+
&self,
530+
keychain: K,
531+
) -> impl DoubleEndedIterator<Item = Indexed<ScriptBuf>> + '_ {
532532
let end = self
533-
.last_revealed_index(keychain)
533+
.last_revealed_index(keychain.clone())
534534
.map(|v| v + 1)
535535
.unwrap_or(0);
536536
self.inner
537537
.all_spks()
538538
.range((keychain.clone(), 0)..(keychain.clone(), end))
539-
.map(|((_, index), spk)| (*index, spk.as_script()))
539+
.map(|((_, index), spk)| (*index, spk.clone()))
540540
}
541541

542542
/// Iterate over revealed, but unused, spks of all keychains.
543543
pub fn unused_spks(
544544
&self,
545-
) -> impl DoubleEndedIterator<Item = KeychainIndexed<K, &Script>> + Clone {
545+
) -> impl DoubleEndedIterator<Item = KeychainIndexed<K, ScriptBuf>> + Clone + '_ {
546546
self.keychain_to_descriptor_id.keys().flat_map(|keychain| {
547-
self.unused_keychain_spks(keychain)
548-
.map(|(i, spk)| ((keychain.clone(), i), spk))
547+
self.unused_keychain_spks(keychain.clone())
548+
.map(|(i, spk)| ((keychain.clone(), i), spk.clone()))
549549
})
550550
}
551551

552552
/// Iterate over revealed, but unused, spks of the given `keychain`.
553553
/// Returns an empty iterator if the provided keychain doesn't exist.
554554
pub fn unused_keychain_spks(
555555
&self,
556-
keychain: &K,
557-
) -> impl DoubleEndedIterator<Item = Indexed<&Script>> + Clone {
558-
let end = match self.keychain_to_descriptor_id.get(keychain) {
556+
keychain: K,
557+
) -> impl DoubleEndedIterator<Item = Indexed<ScriptBuf>> + Clone + '_ {
558+
let end = match self.keychain_to_descriptor_id.get(&keychain) {
559559
Some(did) => self.last_revealed.get(did).map(|v| *v + 1).unwrap_or(0),
560560
None => 0,
561561
};
@@ -577,8 +577,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
577577
/// Not checking the second field of the tuple may result in address reuse.
578578
///
579579
/// Returns None if the provided `keychain` doesn't exist.
580-
pub fn next_index(&self, keychain: &K) -> Option<(u32, bool)> {
581-
let did = self.keychain_to_descriptor_id.get(keychain)?;
580+
pub fn next_index(&self, keychain: K) -> Option<(u32, bool)> {
581+
let did = self.keychain_to_descriptor_id.get(&keychain)?;
582582
let last_index = self.last_revealed.get(did).cloned();
583583
let descriptor = self.descriptors.get(did).expect("invariant");
584584

@@ -615,8 +615,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
615615

616616
/// Get the last derivation index revealed for `keychain`. Returns None if the keychain doesn't
617617
/// exist, or if the keychain doesn't have any revealed scripts.
618-
pub fn last_revealed_index(&self, keychain: &K) -> Option<u32> {
619-
let descriptor_id = self.keychain_to_descriptor_id.get(keychain)?;
618+
pub fn last_revealed_index(&self, keychain: K) -> Option<u32> {
619+
let descriptor_id = self.keychain_to_descriptor_id.get(&keychain)?;
620620
self.last_revealed.get(descriptor_id).cloned()
621621
}
622622

@@ -625,7 +625,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
625625
let mut changeset = ChangeSet::default();
626626

627627
for (keychain, &index) in keychains {
628-
if let Some((_, new_changeset)) = self.reveal_to_target(keychain, index) {
628+
if let Some((_, new_changeset)) = self.reveal_to_target(keychain.clone(), index) {
629629
changeset.merge(new_changeset);
630630
}
631631
}
@@ -648,16 +648,16 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
648648
#[must_use]
649649
pub fn reveal_to_target(
650650
&mut self,
651-
keychain: &K,
651+
keychain: K,
652652
target_index: u32,
653653
) -> Option<(Vec<Indexed<ScriptBuf>>, ChangeSet)> {
654654
let mut changeset = ChangeSet::default();
655655
let mut spks: Vec<Indexed<ScriptBuf>> = vec![];
656-
while let Some((i, new)) = self.next_index(keychain) {
656+
while let Some((i, new)) = self.next_index(keychain.clone()) {
657657
if !new || i > target_index {
658658
break;
659659
}
660-
match self.reveal_next_spk(keychain) {
660+
match self.reveal_next_spk(keychain.clone()) {
661661
Some(((i, spk), change)) => {
662662
spks.push((i, spk));
663663
changeset.merge(change);
@@ -681,21 +681,21 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
681681
/// 1. The descriptor has no wildcard and already has one script revealed.
682682
/// 2. The descriptor has already revealed scripts up to the numeric bound.
683683
/// 3. There is no descriptor associated with the given keychain.
684-
pub fn reveal_next_spk(&mut self, keychain: &K) -> Option<(Indexed<ScriptBuf>, ChangeSet)> {
685-
let (next_index, new) = self.next_index(keychain)?;
684+
pub fn reveal_next_spk(&mut self, keychain: K) -> Option<(Indexed<ScriptBuf>, ChangeSet)> {
685+
let (next_index, new) = self.next_index(keychain.clone())?;
686686
let mut changeset = ChangeSet::default();
687687

688688
if new {
689-
let did = self.keychain_to_descriptor_id.get(keychain)?;
689+
let did = self.keychain_to_descriptor_id.get(&keychain)?;
690690
self.last_revealed.insert(*did, next_index);
691691
changeset.last_revealed.insert(*did, next_index);
692-
self.replenish_inner_index(*did, keychain, self.lookahead);
692+
self.replenish_inner_index(*did, &keychain, self.lookahead);
693693
}
694694
let script = self
695695
.inner
696696
.spk_at_index(&(keychain.clone(), next_index))
697697
.expect("we just inserted it");
698-
Some(((next_index, script.into()), changeset))
698+
Some(((next_index, script), changeset))
699699
}
700700

701701
/// Gets the next unused script pubkey in the keychain. I.e., the script pubkey with the lowest
@@ -711,9 +711,9 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
711711
/// could be revealed (see [`reveal_next_spk`] for when this happens).
712712
///
713713
/// [`reveal_next_spk`]: Self::reveal_next_spk
714-
pub fn next_unused_spk(&mut self, keychain: &K) -> Option<(Indexed<ScriptBuf>, ChangeSet)> {
714+
pub fn next_unused_spk(&mut self, keychain: K) -> Option<(Indexed<ScriptBuf>, ChangeSet)> {
715715
let next_unused = self
716-
.unused_keychain_spks(keychain)
716+
.unused_keychain_spks(keychain.clone())
717717
.next()
718718
.map(|(i, spk)| ((i, spk.to_owned()), ChangeSet::default()));
719719

@@ -722,11 +722,11 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
722722

723723
/// Iterate over all [`OutPoint`]s that have `TxOut`s with script pubkeys derived from
724724
/// `keychain`.
725-
pub fn keychain_outpoints<'a>(
726-
&'a self,
727-
keychain: &'a K,
728-
) -> impl DoubleEndedIterator<Item = Indexed<OutPoint>> + 'a {
729-
self.keychain_outpoints_in_range(keychain..=keychain)
725+
pub fn keychain_outpoints(
726+
&self,
727+
keychain: K,
728+
) -> impl DoubleEndedIterator<Item = Indexed<OutPoint>> + '_ {
729+
self.keychain_outpoints_in_range(keychain.clone()..=keychain)
730730
.map(|((_, i), op)| (i, op))
731731
}
732732

@@ -757,7 +757,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
757757

758758
/// Returns the highest derivation index of the `keychain` where [`KeychainTxOutIndex`] has
759759
/// found a [`TxOut`] with it's script pubkey.
760-
pub fn last_used_index(&self, keychain: &K) -> Option<u32> {
760+
pub fn last_used_index(&self, keychain: K) -> Option<u32> {
761761
self.keychain_outpoints(keychain).last().map(|(i, _)| i)
762762
}
763763

@@ -767,7 +767,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
767767
self.keychain_to_descriptor_id
768768
.iter()
769769
.filter_map(|(keychain, _)| {
770-
self.last_used_index(keychain)
770+
self.last_used_index(keychain.clone())
771771
.map(|index| (keychain.clone(), index))
772772
})
773773
.collect()

crates/chain/src/indexer/spk_txout.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap},
77
Indexer,
88
};
9-
use bitcoin::{Amount, OutPoint, Script, ScriptBuf, SignedAmount, Transaction, TxOut, Txid};
9+
use bitcoin::{Amount, OutPoint, ScriptBuf, SignedAmount, Transaction, TxOut, Txid};
1010

1111
/// An index storing [`TxOut`]s that have a script pubkey that matches those in a list.
1212
///
@@ -176,8 +176,8 @@ impl<I: Clone + Ord + core::fmt::Debug> SpkTxOutIndex<I> {
176176
/// Returns the script that has been inserted at the `index`.
177177
///
178178
/// If that index hasn't been inserted yet, it will return `None`.
179-
pub fn spk_at_index(&self, index: &I) -> Option<&Script> {
180-
self.spks.get(index).map(|s| s.as_script())
179+
pub fn spk_at_index(&self, index: &I) -> Option<ScriptBuf> {
180+
self.spks.get(index).cloned()
181181
}
182182

183183
/// The script pubkeys that are being tracked by the index.
@@ -217,7 +217,10 @@ impl<I: Clone + Ord + core::fmt::Debug> SpkTxOutIndex<I> {
217217
/// let unused_change_spks =
218218
/// txout_index.unused_spks((change_index, u32::MIN)..(change_index, u32::MAX));
219219
/// ```
220-
pub fn unused_spks<R>(&self, range: R) -> impl DoubleEndedIterator<Item = (&I, &Script)> + Clone
220+
pub fn unused_spks<R>(
221+
&self,
222+
range: R,
223+
) -> impl DoubleEndedIterator<Item = (&I, ScriptBuf)> + Clone + '_
221224
where
222225
R: RangeBounds<I>,
223226
{
@@ -268,8 +271,8 @@ impl<I: Clone + Ord + core::fmt::Debug> SpkTxOutIndex<I> {
268271
}
269272

270273
/// Returns the index associated with the script pubkey.
271-
pub fn index_of_spk(&self, script: &Script) -> Option<&I> {
272-
self.spk_indices.get(script)
274+
pub fn index_of_spk(&self, script: ScriptBuf) -> Option<&I> {
275+
self.spk_indices.get(script.as_script())
273276
}
274277

275278
/// Computes the total value transfer effect `tx` has on the script pubkeys in `range`. Value is
@@ -293,7 +296,7 @@ impl<I: Clone + Ord + core::fmt::Debug> SpkTxOutIndex<I> {
293296
}
294297
}
295298
for txout in &tx.output {
296-
if let Some(index) = self.index_of_spk(&txout.script_pubkey) {
299+
if let Some(index) = self.index_of_spk(txout.script_pubkey.clone()) {
297300
if range.contains(index) {
298301
received += txout.value;
299302
}

crates/chain/src/tx_graph.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ use crate::{
9494
use alloc::collections::vec_deque::VecDeque;
9595
use alloc::sync::Arc;
9696
use alloc::vec::Vec;
97-
use bitcoin::{Amount, OutPoint, Script, SignedAmount, Transaction, TxOut, Txid};
97+
use bitcoin::{Amount, OutPoint, ScriptBuf, SignedAmount, Transaction, TxOut, Txid};
9898
use core::fmt::{self, Formatter};
9999
use core::{
100100
convert::Infallible,
@@ -1163,7 +1163,7 @@ impl<A: Anchor> TxGraph<A> {
11631163
chain: &C,
11641164
chain_tip: BlockId,
11651165
outpoints: impl IntoIterator<Item = (OI, OutPoint)>,
1166-
mut trust_predicate: impl FnMut(&OI, &Script) -> bool,
1166+
mut trust_predicate: impl FnMut(&OI, ScriptBuf) -> bool,
11671167
) -> Result<Balance, C::Error> {
11681168
let mut immature = Amount::ZERO;
11691169
let mut trusted_pending = Amount::ZERO;
@@ -1182,7 +1182,7 @@ impl<A: Anchor> TxGraph<A> {
11821182
}
11831183
}
11841184
ChainPosition::Unconfirmed(_) => {
1185-
if trust_predicate(&spk_i, &txout.txout.script_pubkey) {
1185+
if trust_predicate(&spk_i, txout.txout.script_pubkey) {
11861186
trusted_pending += txout.txout.value;
11871187
} else {
11881188
untrusted_pending += txout.txout.value;
@@ -1209,7 +1209,7 @@ impl<A: Anchor> TxGraph<A> {
12091209
chain: &C,
12101210
chain_tip: BlockId,
12111211
outpoints: impl IntoIterator<Item = (OI, OutPoint)>,
1212-
trust_predicate: impl FnMut(&OI, &Script) -> bool,
1212+
trust_predicate: impl FnMut(&OI, ScriptBuf) -> bool,
12131213
) -> Balance {
12141214
self.try_balance(chain, chain_tip, outpoints, trust_predicate)
12151215
.expect("oracle is infallible")

crates/chain/tests/common/tx_template.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pub fn init_graph<'a, A: Anchor + Clone + 'a>(
119119
},
120120
Some(index) => TxOut {
121121
value: Amount::from_sat(output.value),
122-
script_pubkey: spk_index.spk_at_index(index).unwrap().to_owned(),
122+
script_pubkey: spk_index.spk_at_index(index).unwrap(),
123123
},
124124
})
125125
.collect(),

0 commit comments

Comments
 (0)