refactor(chain)!: update KeychainTxOutIndex methods to use owned K

This commit is contained in:
Rob N 2024-07-08 07:44:35 -10:00 committed by Steve Myers
parent 0c8ee1dfe2
commit 7c07b9de02
No known key found for this signature in database
GPG Key ID: 8105A46B22C2D051
6 changed files with 95 additions and 103 deletions

View File

@ -99,7 +99,7 @@ pub const DEFAULT_LOOKAHEAD: u32 = 25;
/// let _ = txout_index.insert_descriptor(MyKeychain::Internal, internal_descriptor)?; /// let _ = txout_index.insert_descriptor(MyKeychain::Internal, internal_descriptor)?;
/// let _ = txout_index.insert_descriptor(MyKeychain::MyAppUser { user_id: 42 }, descriptor_42)?; /// let _ = txout_index.insert_descriptor(MyKeychain::MyAppUser { user_id: 42 }, descriptor_42)?;
/// ///
/// let new_spk_for_user = txout_index.reveal_next_spk(&MyKeychain::MyAppUser{ user_id: 42 }); /// let new_spk_for_user = txout_index.reveal_next_spk(MyKeychain::MyAppUser{ user_id: 42 });
/// # Ok::<_, bdk_chain::indexer::keychain_txout::InsertDescriptorError<_>>(()) /// # Ok::<_, bdk_chain::indexer::keychain_txout::InsertDescriptorError<_>>(())
/// ``` /// ```
/// ///
@ -335,11 +335,11 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// Return all keychains and their corresponding descriptors. /// Return all keychains and their corresponding descriptors.
pub fn keychains( pub fn keychains(
&self, &self,
) -> impl DoubleEndedIterator<Item = (&K, &Descriptor<DescriptorPublicKey>)> + ExactSizeIterator + '_ ) -> impl DoubleEndedIterator<Item = (K, &Descriptor<DescriptorPublicKey>)> + ExactSizeIterator + '_
{ {
self.keychain_to_descriptor_id self.keychain_to_descriptor_id
.iter() .iter()
.map(|(k, did)| (k, self.descriptors.get(did).expect("invariant"))) .map(|(k, did)| (k.clone(), self.descriptors.get(did).expect("invariant")))
} }
/// Insert a descriptor with a keychain associated to it. /// Insert a descriptor with a keychain associated to it.
@ -399,8 +399,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// Gets the descriptor associated with the keychain. Returns `None` if the keychain doesn't /// Gets the descriptor associated with the keychain. Returns `None` if the keychain doesn't
/// have a descriptor associated with it. /// have a descriptor associated with it.
pub fn get_descriptor(&self, keychain: &K) -> Option<&Descriptor<DescriptorPublicKey>> { pub fn get_descriptor(&self, keychain: K) -> Option<&Descriptor<DescriptorPublicKey>> {
let did = self.keychain_to_descriptor_id.get(keychain)?; let did = self.keychain_to_descriptor_id.get(&keychain)?;
self.descriptors.get(did) self.descriptors.get(did)
} }
@ -416,8 +416,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// Store lookahead scripts until `target_index` (inclusive). /// Store lookahead scripts until `target_index` (inclusive).
/// ///
/// This does not change the global `lookahead` setting. /// This does not change the global `lookahead` setting.
pub fn lookahead_to_target(&mut self, keychain: &K, target_index: u32) { pub fn lookahead_to_target(&mut self, keychain: K, target_index: u32) {
if let Some((next_index, _)) = self.next_index(keychain) { if let Some((next_index, _)) = self.next_index(keychain.clone()) {
let temp_lookahead = (target_index + 1) let temp_lookahead = (target_index + 1)
.checked_sub(next_index) .checked_sub(next_index)
.filter(|&index| index > 0); .filter(|&index| index > 0);
@ -434,9 +434,9 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
} }
} }
fn replenish_inner_index_keychain(&mut self, keychain: &K, lookahead: u32) { fn replenish_inner_index_keychain(&mut self, keychain: K, lookahead: u32) {
if let Some(did) = self.keychain_to_descriptor_id.get(keychain) { if let Some(did) = self.keychain_to_descriptor_id.get(&keychain) {
self.replenish_inner_index(*did, keychain, lookahead); self.replenish_inner_index(*did, &keychain, lookahead);
} }
} }
@ -464,7 +464,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// keychain doesn't exist /// keychain doesn't exist
pub fn unbounded_spk_iter( pub fn unbounded_spk_iter(
&self, &self,
keychain: &K, keychain: K,
) -> Option<SpkIterator<Descriptor<DescriptorPublicKey>>> { ) -> Option<SpkIterator<Descriptor<DescriptorPublicKey>>> {
let descriptor = self.get_descriptor(keychain)?.clone(); let descriptor = self.get_descriptor(keychain)?.clone();
Some(SpkIterator::new(descriptor)) Some(SpkIterator::new(descriptor))
@ -525,12 +525,12 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// ///
/// This is a double ended iterator so you can easily reverse it to get an iterator where /// This is a double ended iterator so you can easily reverse it to get an iterator where
/// the script pubkeys that were most recently revealed are first. /// the script pubkeys that were most recently revealed are first.
pub fn revealed_keychain_spks<'a>( pub fn revealed_keychain_spks(
&'a self, &self,
keychain: &'a K, keychain: K,
) -> impl DoubleEndedIterator<Item = Indexed<&Script>> + 'a { ) -> impl DoubleEndedIterator<Item = Indexed<&Script>> {
let end = self let end = self
.last_revealed_index(keychain) .last_revealed_index(keychain.clone())
.map(|v| v + 1) .map(|v| v + 1)
.unwrap_or(0); .unwrap_or(0);
self.inner self.inner
@ -544,7 +544,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
&self, &self,
) -> impl DoubleEndedIterator<Item = KeychainIndexed<K, &Script>> + Clone { ) -> impl DoubleEndedIterator<Item = KeychainIndexed<K, &Script>> + Clone {
self.keychain_to_descriptor_id.keys().flat_map(|keychain| { self.keychain_to_descriptor_id.keys().flat_map(|keychain| {
self.unused_keychain_spks(keychain) self.unused_keychain_spks(keychain.clone())
.map(|(i, spk)| ((keychain.clone(), i), spk)) .map(|(i, spk)| ((keychain.clone(), i), spk))
}) })
} }
@ -553,9 +553,9 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// Returns an empty iterator if the provided keychain doesn't exist. /// Returns an empty iterator if the provided keychain doesn't exist.
pub fn unused_keychain_spks( pub fn unused_keychain_spks(
&self, &self,
keychain: &K, keychain: K,
) -> impl DoubleEndedIterator<Item = Indexed<&Script>> + Clone { ) -> impl DoubleEndedIterator<Item = Indexed<&Script>> + Clone {
let end = match self.keychain_to_descriptor_id.get(keychain) { let end = match self.keychain_to_descriptor_id.get(&keychain) {
Some(did) => self.last_revealed.get(did).map(|v| *v + 1).unwrap_or(0), Some(did) => self.last_revealed.get(did).map(|v| *v + 1).unwrap_or(0),
None => 0, None => 0,
}; };
@ -577,8 +577,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// Not checking the second field of the tuple may result in address reuse. /// Not checking the second field of the tuple may result in address reuse.
/// ///
/// Returns None if the provided `keychain` doesn't exist. /// Returns None if the provided `keychain` doesn't exist.
pub fn next_index(&self, keychain: &K) -> Option<(u32, bool)> { pub fn next_index(&self, keychain: K) -> Option<(u32, bool)> {
let did = self.keychain_to_descriptor_id.get(keychain)?; let did = self.keychain_to_descriptor_id.get(&keychain)?;
let last_index = self.last_revealed.get(did).cloned(); let last_index = self.last_revealed.get(did).cloned();
let descriptor = self.descriptors.get(did).expect("invariant"); let descriptor = self.descriptors.get(did).expect("invariant");
@ -615,8 +615,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// Get the last derivation index revealed for `keychain`. Returns None if the keychain doesn't /// Get the last derivation index revealed for `keychain`. Returns None if the keychain doesn't
/// exist, or if the keychain doesn't have any revealed scripts. /// exist, or if the keychain doesn't have any revealed scripts.
pub fn last_revealed_index(&self, keychain: &K) -> Option<u32> { pub fn last_revealed_index(&self, keychain: K) -> Option<u32> {
let descriptor_id = self.keychain_to_descriptor_id.get(keychain)?; let descriptor_id = self.keychain_to_descriptor_id.get(&keychain)?;
self.last_revealed.get(descriptor_id).cloned() self.last_revealed.get(descriptor_id).cloned()
} }
@ -625,7 +625,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
let mut changeset = ChangeSet::default(); let mut changeset = ChangeSet::default();
for (keychain, &index) in keychains { for (keychain, &index) in keychains {
if let Some((_, new_changeset)) = self.reveal_to_target(keychain, index) { if let Some((_, new_changeset)) = self.reveal_to_target(keychain.clone(), index) {
changeset.merge(new_changeset); changeset.merge(new_changeset);
} }
} }
@ -648,16 +648,16 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
#[must_use] #[must_use]
pub fn reveal_to_target( pub fn reveal_to_target(
&mut self, &mut self,
keychain: &K, keychain: K,
target_index: u32, target_index: u32,
) -> Option<(Vec<Indexed<ScriptBuf>>, ChangeSet)> { ) -> Option<(Vec<Indexed<ScriptBuf>>, ChangeSet)> {
let mut changeset = ChangeSet::default(); let mut changeset = ChangeSet::default();
let mut spks: Vec<Indexed<ScriptBuf>> = vec![]; let mut spks: Vec<Indexed<ScriptBuf>> = vec![];
while let Some((i, new)) = self.next_index(keychain) { while let Some((i, new)) = self.next_index(keychain.clone()) {
if !new || i > target_index { if !new || i > target_index {
break; break;
} }
match self.reveal_next_spk(keychain) { match self.reveal_next_spk(keychain.clone()) {
Some(((i, spk), change)) => { Some(((i, spk), change)) => {
spks.push((i, spk)); spks.push((i, spk));
changeset.merge(change); changeset.merge(change);
@ -686,10 +686,10 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
let mut changeset = ChangeSet::default(); let mut changeset = ChangeSet::default();
if new { if new {
let did = self.keychain_to_descriptor_id.get(keychain)?; let did = self.keychain_to_descriptor_id.get(&keychain)?;
self.last_revealed.insert(*did, next_index); self.last_revealed.insert(*did, next_index);
changeset.last_revealed.insert(*did, next_index); changeset.last_revealed.insert(*did, next_index);
self.replenish_inner_index(*did, keychain, self.lookahead); self.replenish_inner_index(*did, &keychain, self.lookahead);
} }
let script = self let script = self
.inner .inner
@ -711,9 +711,9 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// could be revealed (see [`reveal_next_spk`] for when this happens). /// could be revealed (see [`reveal_next_spk`] for when this happens).
/// ///
/// [`reveal_next_spk`]: Self::reveal_next_spk /// [`reveal_next_spk`]: Self::reveal_next_spk
pub fn next_unused_spk(&mut self, keychain: &K) -> Option<(Indexed<ScriptBuf>, ChangeSet)> { pub fn next_unused_spk(&mut self, keychain: K) -> Option<(Indexed<ScriptBuf>, ChangeSet)> {
let next_unused = self let next_unused = self
.unused_keychain_spks(keychain) .unused_keychain_spks(keychain.clone())
.next() .next()
.map(|(i, spk)| ((i, spk.to_owned()), ChangeSet::default())); .map(|(i, spk)| ((i, spk.to_owned()), ChangeSet::default()));
@ -722,11 +722,11 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// Iterate over all [`OutPoint`]s that have `TxOut`s with script pubkeys derived from /// Iterate over all [`OutPoint`]s that have `TxOut`s with script pubkeys derived from
/// `keychain`. /// `keychain`.
pub fn keychain_outpoints<'a>( pub fn keychain_outpoints(
&'a self, &self,
keychain: &'a K, keychain: K,
) -> impl DoubleEndedIterator<Item = Indexed<OutPoint>> + 'a { ) -> impl DoubleEndedIterator<Item = Indexed<OutPoint>> + '_ {
self.keychain_outpoints_in_range(keychain..=keychain) self.keychain_outpoints_in_range(keychain.clone()..=keychain)
.map(|((_, i), op)| (i, op)) .map(|((_, i), op)| (i, op))
} }
@ -757,7 +757,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// Returns the highest derivation index of the `keychain` where [`KeychainTxOutIndex`] has /// Returns the highest derivation index of the `keychain` where [`KeychainTxOutIndex`] has
/// found a [`TxOut`] with it's script pubkey. /// found a [`TxOut`] with it's script pubkey.
pub fn last_used_index(&self, keychain: &K) -> Option<u32> { pub fn last_used_index(&self, keychain: K) -> Option<u32> {
self.keychain_outpoints(keychain).last().map(|(i, _)| i) self.keychain_outpoints(keychain).last().map(|(i, _)| i)
} }
@ -767,7 +767,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
self.keychain_to_descriptor_id self.keychain_to_descriptor_id
.iter() .iter()
.filter_map(|(keychain, _)| { .filter_map(|(keychain, _)| {
self.last_used_index(keychain) self.last_used_index(keychain.clone())
.map(|index| (keychain.clone(), index)) .map(|index| (keychain.clone(), index))
}) })
.collect() .collect()

View File

@ -161,7 +161,7 @@ fn test_list_owned_txouts() {
for _ in 0..10 { for _ in 0..10 {
let ((_, script), _) = graph let ((_, script), _) = graph
.index .index
.reveal_next_spk(&"keychain_1".to_string()) .reveal_next_spk("keychain_1".to_string())
.unwrap(); .unwrap();
// TODO Assert indexes // TODO Assert indexes
trusted_spks.push(script.to_owned()); trusted_spks.push(script.to_owned());
@ -171,7 +171,7 @@ fn test_list_owned_txouts() {
for _ in 0..10 { for _ in 0..10 {
let ((_, script), _) = graph let ((_, script), _) = graph
.index .index
.reveal_next_spk(&"keychain_2".to_string()) .reveal_next_spk("keychain_2".to_string())
.unwrap(); .unwrap();
untrusted_spks.push(script.to_owned()); untrusted_spks.push(script.to_owned());
} }

View File

@ -142,7 +142,7 @@ fn test_lookahead() {
// - stored scripts of external keychain should be of expected counts // - stored scripts of external keychain should be of expected counts
for index in (0..20).skip_while(|i| i % 2 == 1) { for index in (0..20).skip_while(|i| i % 2 == 1) {
let (revealed_spks, revealed_changeset) = txout_index let (revealed_spks, revealed_changeset) = txout_index
.reveal_to_target(&TestKeychain::External, index) .reveal_to_target(TestKeychain::External, index)
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
revealed_spks, revealed_spks,
@ -161,25 +161,25 @@ fn test_lookahead() {
); );
assert_eq!( assert_eq!(
txout_index txout_index
.revealed_keychain_spks(&TestKeychain::External) .revealed_keychain_spks(TestKeychain::External)
.count(), .count(),
index as usize + 1, index as usize + 1,
); );
assert_eq!( assert_eq!(
txout_index txout_index
.revealed_keychain_spks(&TestKeychain::Internal) .revealed_keychain_spks(TestKeychain::Internal)
.count(), .count(),
0, 0,
); );
assert_eq!( assert_eq!(
txout_index txout_index
.unused_keychain_spks(&TestKeychain::External) .unused_keychain_spks(TestKeychain::External)
.count(), .count(),
index as usize + 1, index as usize + 1,
); );
assert_eq!( assert_eq!(
txout_index txout_index
.unused_keychain_spks(&TestKeychain::Internal) .unused_keychain_spks(TestKeychain::Internal)
.count(), .count(),
0, 0,
); );
@ -193,7 +193,7 @@ fn test_lookahead() {
// expect: // expect:
// - scripts cached in spk_txout_index should increase correctly, a.k.a. no scripts are skipped // - scripts cached in spk_txout_index should increase correctly, a.k.a. no scripts are skipped
let (revealed_spks, revealed_changeset) = txout_index let (revealed_spks, revealed_changeset) = txout_index
.reveal_to_target(&TestKeychain::Internal, 24) .reveal_to_target(TestKeychain::Internal, 24)
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
revealed_spks, revealed_spks,
@ -214,17 +214,17 @@ fn test_lookahead() {
); );
assert_eq!( assert_eq!(
txout_index txout_index
.revealed_keychain_spks(&TestKeychain::Internal) .revealed_keychain_spks(TestKeychain::Internal)
.count(), .count(),
25, 25,
); );
// ensure derivation indices are expected for each keychain // ensure derivation indices are expected for each keychain
let last_external_index = txout_index let last_external_index = txout_index
.last_revealed_index(&TestKeychain::External) .last_revealed_index(TestKeychain::External)
.expect("already derived"); .expect("already derived");
let last_internal_index = txout_index let last_internal_index = txout_index
.last_revealed_index(&TestKeychain::Internal) .last_revealed_index(TestKeychain::Internal)
.expect("already derived"); .expect("already derived");
assert_eq!(last_external_index, 19); assert_eq!(last_external_index, 19);
assert_eq!(last_internal_index, 24); assert_eq!(last_internal_index, 24);
@ -257,22 +257,22 @@ fn test_lookahead() {
}; };
assert_eq!(txout_index.index_tx(&tx), ChangeSet::default()); assert_eq!(txout_index.index_tx(&tx), ChangeSet::default());
assert_eq!( assert_eq!(
txout_index.last_revealed_index(&TestKeychain::External), txout_index.last_revealed_index(TestKeychain::External),
Some(last_external_index) Some(last_external_index)
); );
assert_eq!( assert_eq!(
txout_index.last_revealed_index(&TestKeychain::Internal), txout_index.last_revealed_index(TestKeychain::Internal),
Some(last_internal_index) Some(last_internal_index)
); );
assert_eq!( assert_eq!(
txout_index txout_index
.revealed_keychain_spks(&TestKeychain::External) .revealed_keychain_spks(TestKeychain::External)
.count(), .count(),
last_external_index as usize + 1, last_external_index as usize + 1,
); );
assert_eq!( assert_eq!(
txout_index txout_index
.revealed_keychain_spks(&TestKeychain::Internal) .revealed_keychain_spks(TestKeychain::Internal)
.count(), .count(),
last_internal_index as usize + 1, last_internal_index as usize + 1,
); );
@ -317,11 +317,11 @@ fn test_scan_with_lookahead() {
&[(external_descriptor.descriptor_id(), spk_i)].into() &[(external_descriptor.descriptor_id(), spk_i)].into()
); );
assert_eq!( assert_eq!(
txout_index.last_revealed_index(&TestKeychain::External), txout_index.last_revealed_index(TestKeychain::External),
Some(spk_i) Some(spk_i)
); );
assert_eq!( assert_eq!(
txout_index.last_used_index(&TestKeychain::External), txout_index.last_used_index(TestKeychain::External),
Some(spk_i) Some(spk_i)
); );
} }
@ -357,11 +357,11 @@ fn test_wildcard_derivations() {
// - next_derivation_index() == (0, true) // - next_derivation_index() == (0, true)
// - derive_new() == ((0, <spk>), keychain::ChangeSet) // - derive_new() == ((0, <spk>), keychain::ChangeSet)
// - next_unused() == ((0, <spk>), keychain::ChangeSet:is_empty()) // - next_unused() == ((0, <spk>), keychain::ChangeSet:is_empty())
assert_eq!(txout_index.next_index(&TestKeychain::External).unwrap(), (0, true)); assert_eq!(txout_index.next_index(TestKeychain::External).unwrap(), (0, true));
let (spk, changeset) = txout_index.reveal_next_spk(&TestKeychain::External).unwrap(); let (spk, changeset) = txout_index.reveal_next_spk(TestKeychain::External).unwrap();
assert_eq!(spk, (0_u32, external_spk_0.clone())); assert_eq!(spk, (0_u32, external_spk_0.clone()));
assert_eq!(&changeset.last_revealed, &[(external_descriptor.descriptor_id(), 0)].into()); assert_eq!(&changeset.last_revealed, &[(external_descriptor.descriptor_id(), 0)].into());
let (spk, changeset) = txout_index.next_unused_spk(&TestKeychain::External).unwrap(); let (spk, changeset) = txout_index.next_unused_spk(TestKeychain::External).unwrap();
assert_eq!(spk, (0_u32, external_spk_0.clone())); assert_eq!(spk, (0_u32, external_spk_0.clone()));
assert_eq!(&changeset.last_revealed, &[].into()); assert_eq!(&changeset.last_revealed, &[].into());
@ -373,20 +373,20 @@ fn test_wildcard_derivations() {
// - next_derivation_index() = (26, true) // - next_derivation_index() = (26, true)
// - derive_new() = ((26, <spk>), keychain::ChangeSet) // - derive_new() = ((26, <spk>), keychain::ChangeSet)
// - next_unused() == ((16, <spk>), keychain::ChangeSet::is_empty()) // - next_unused() == ((16, <spk>), keychain::ChangeSet::is_empty())
let _ = txout_index.reveal_to_target(&TestKeychain::External, 25); let _ = txout_index.reveal_to_target(TestKeychain::External, 25);
(0..=15) (0..=15)
.chain([17, 20, 23]) .chain([17, 20, 23])
.for_each(|index| assert!(txout_index.mark_used(TestKeychain::External, index))); .for_each(|index| assert!(txout_index.mark_used(TestKeychain::External, index)));
assert_eq!(txout_index.next_index(&TestKeychain::External).unwrap(), (26, true)); assert_eq!(txout_index.next_index(TestKeychain::External).unwrap(), (26, true));
let (spk, changeset) = txout_index.reveal_next_spk(&TestKeychain::External).unwrap(); let (spk, changeset) = txout_index.reveal_next_spk(TestKeychain::External).unwrap();
assert_eq!(spk, (26, external_spk_26)); assert_eq!(spk, (26, external_spk_26));
assert_eq!(&changeset.last_revealed, &[(external_descriptor.descriptor_id(), 26)].into()); assert_eq!(&changeset.last_revealed, &[(external_descriptor.descriptor_id(), 26)].into());
let (spk, changeset) = txout_index.next_unused_spk(&TestKeychain::External).unwrap(); let (spk, changeset) = txout_index.next_unused_spk(TestKeychain::External).unwrap();
assert_eq!(spk, (16, external_spk_16)); assert_eq!(spk, (16, external_spk_16));
assert_eq!(&changeset.last_revealed, &[].into()); assert_eq!(&changeset.last_revealed, &[].into());
@ -396,7 +396,7 @@ fn test_wildcard_derivations() {
txout_index.mark_used(TestKeychain::External, index); txout_index.mark_used(TestKeychain::External, index);
}); });
let (spk, changeset) = txout_index.next_unused_spk(&TestKeychain::External).unwrap(); let (spk, changeset) = txout_index.next_unused_spk(TestKeychain::External).unwrap();
assert_eq!(spk, (27, external_spk_27)); assert_eq!(spk, (27, external_spk_27));
assert_eq!(&changeset.last_revealed, &[(external_descriptor.descriptor_id(), 27)].into()); assert_eq!(&changeset.last_revealed, &[(external_descriptor.descriptor_id(), 27)].into());
} }
@ -424,21 +424,17 @@ fn test_non_wildcard_derivations() {
// - when we derive a new script, script @ index 0 // - when we derive a new script, script @ index 0
// - when we get the next unused script, script @ index 0 // - when we get the next unused script, script @ index 0
assert_eq!( assert_eq!(
txout_index.next_index(&TestKeychain::External).unwrap(), txout_index.next_index(TestKeychain::External).unwrap(),
(0, true) (0, true)
); );
let (spk, changeset) = txout_index let (spk, changeset) = txout_index.reveal_next_spk(TestKeychain::External).unwrap();
.reveal_next_spk(&TestKeychain::External)
.unwrap();
assert_eq!(spk, (0, external_spk.clone())); assert_eq!(spk, (0, external_spk.clone()));
assert_eq!( assert_eq!(
&changeset.last_revealed, &changeset.last_revealed,
&[(no_wildcard_descriptor.descriptor_id(), 0)].into() &[(no_wildcard_descriptor.descriptor_id(), 0)].into()
); );
let (spk, changeset) = txout_index let (spk, changeset) = txout_index.next_unused_spk(TestKeychain::External).unwrap();
.next_unused_spk(&TestKeychain::External)
.unwrap();
assert_eq!(spk, (0, external_spk.clone())); assert_eq!(spk, (0, external_spk.clone()));
assert_eq!(&changeset.last_revealed, &[].into()); assert_eq!(&changeset.last_revealed, &[].into());
@ -449,24 +445,20 @@ fn test_non_wildcard_derivations() {
// - derive new and next unused should return the old script // - derive new and next unused should return the old script
// - store_up_to should not panic and return empty changeset // - store_up_to should not panic and return empty changeset
assert_eq!( assert_eq!(
txout_index.next_index(&TestKeychain::External).unwrap(), txout_index.next_index(TestKeychain::External).unwrap(),
(0, false) (0, false)
); );
txout_index.mark_used(TestKeychain::External, 0); txout_index.mark_used(TestKeychain::External, 0);
let (spk, changeset) = txout_index let (spk, changeset) = txout_index.reveal_next_spk(TestKeychain::External).unwrap();
.reveal_next_spk(&TestKeychain::External)
.unwrap();
assert_eq!(spk, (0, external_spk.clone())); assert_eq!(spk, (0, external_spk.clone()));
assert_eq!(&changeset.last_revealed, &[].into()); assert_eq!(&changeset.last_revealed, &[].into());
let (spk, changeset) = txout_index let (spk, changeset) = txout_index.next_unused_spk(TestKeychain::External).unwrap();
.next_unused_spk(&TestKeychain::External)
.unwrap();
assert_eq!(spk, (0, external_spk.clone())); assert_eq!(spk, (0, external_spk.clone()));
assert_eq!(&changeset.last_revealed, &[].into()); assert_eq!(&changeset.last_revealed, &[].into());
let (revealed_spks, revealed_changeset) = txout_index let (revealed_spks, revealed_changeset) = txout_index
.reveal_to_target(&TestKeychain::External, 200) .reveal_to_target(TestKeychain::External, 200)
.unwrap(); .unwrap();
assert_eq!(revealed_spks.len(), 0); assert_eq!(revealed_spks.len(), 0);
assert!(revealed_changeset.is_empty()); assert!(revealed_changeset.is_empty());
@ -474,7 +466,7 @@ fn test_non_wildcard_derivations() {
// we check that spks_of_keychain returns a SpkIterator with just one element // we check that spks_of_keychain returns a SpkIterator with just one element
assert_eq!( assert_eq!(
txout_index txout_index
.revealed_keychain_spks(&TestKeychain::External) .revealed_keychain_spks(TestKeychain::External)
.count(), .count(),
1, 1,
); );
@ -540,10 +532,10 @@ fn lookahead_to_target() {
); );
if let Some(last_revealed) = t.external_last_revealed { if let Some(last_revealed) = t.external_last_revealed {
let _ = index.reveal_to_target(&TestKeychain::External, last_revealed); let _ = index.reveal_to_target(TestKeychain::External, last_revealed);
} }
if let Some(last_revealed) = t.internal_last_revealed { if let Some(last_revealed) = t.internal_last_revealed {
let _ = index.reveal_to_target(&TestKeychain::Internal, last_revealed); let _ = index.reveal_to_target(TestKeychain::Internal, last_revealed);
} }
let keychain_test_cases = [ let keychain_test_cases = [
@ -570,7 +562,7 @@ fn lookahead_to_target() {
} }
None => target, None => target,
}; };
index.lookahead_to_target(&keychain, target); index.lookahead_to_target(keychain.clone(), target);
let keys = index let keys = index
.inner() .inner()
.all_spks() .all_spks()
@ -671,7 +663,7 @@ fn when_querying_over_a_range_of_keychains_the_utxos_should_show_up() {
let _ = indexer.insert_descriptor(i, descriptor.clone()).unwrap(); let _ = indexer.insert_descriptor(i, descriptor.clone()).unwrap();
if i != 4 { if i != 4 {
// skip one in the middle to see if uncovers any bugs // skip one in the middle to see if uncovers any bugs
indexer.reveal_next_spk(&i); indexer.reveal_next_spk(i);
} }
tx.output.push(TxOut { tx.output.push(TxOut {
script_pubkey: descriptor.at_derivation_index(0).unwrap().script_pubkey(), script_pubkey: descriptor.at_derivation_index(0).unwrap().script_pubkey(),

View File

@ -542,7 +542,7 @@ impl Wallet {
} }
/// Iterator over all keychains in this wallet /// Iterator over all keychains in this wallet
pub fn keychains(&self) -> impl Iterator<Item = (&KeychainKind, &ExtendedDescriptor)> { pub fn keychains(&self) -> impl Iterator<Item = (KeychainKind, &ExtendedDescriptor)> {
self.indexed_graph.index.keychains() self.indexed_graph.index.keychains()
} }
@ -558,7 +558,7 @@ impl Wallet {
let mut spk_iter = self let mut spk_iter = self
.indexed_graph .indexed_graph
.index .index
.unbounded_spk_iter(&keychain) .unbounded_spk_iter(keychain)
.expect("keychain must exist"); .expect("keychain must exist");
if !spk_iter.descriptor().has_wildcard() { if !spk_iter.descriptor().has_wildcard() {
index = 0; index = 0;
@ -604,7 +604,7 @@ impl Wallet {
let stage = &mut self.stage; let stage = &mut self.stage;
let ((index, spk), index_changeset) = index let ((index, spk), index_changeset) = index
.reveal_next_spk(&keychain) .reveal_next_spk(keychain)
.expect("keychain must exist"); .expect("keychain must exist");
stage.merge(index_changeset.into()); stage.merge(index_changeset.into());
@ -634,7 +634,7 @@ impl Wallet {
let (spks, index_changeset) = self let (spks, index_changeset) = self
.indexed_graph .indexed_graph
.index .index
.reveal_to_target(&keychain, index) .reveal_to_target(keychain, index)
.expect("keychain must exist"); .expect("keychain must exist");
self.stage.merge(index_changeset.into()); self.stage.merge(index_changeset.into());
@ -658,7 +658,7 @@ impl Wallet {
let index = &mut self.indexed_graph.index; let index = &mut self.indexed_graph.index;
let ((index, spk), index_changeset) = index let ((index, spk), index_changeset) = index
.next_unused_spk(&keychain) .next_unused_spk(keychain)
.expect("keychain must exist"); .expect("keychain must exist");
self.stage self.stage
@ -702,7 +702,7 @@ impl Wallet {
) -> impl DoubleEndedIterator<Item = AddressInfo> + '_ { ) -> impl DoubleEndedIterator<Item = AddressInfo> + '_ {
self.indexed_graph self.indexed_graph
.index .index
.unused_keychain_spks(&keychain) .unused_keychain_spks(keychain)
.map(move |(index, spk)| AddressInfo { .map(move |(index, spk)| AddressInfo {
index, index,
address: Address::from_script(spk, self.network).expect("must have address form"), address: Address::from_script(spk, self.network).expect("must have address form"),
@ -783,7 +783,7 @@ impl Wallet {
) -> impl Iterator<Item = Indexed<ScriptBuf>> + Clone { ) -> impl Iterator<Item = Indexed<ScriptBuf>> + Clone {
self.indexed_graph self.indexed_graph
.index .index
.unbounded_spk_iter(&keychain) .unbounded_spk_iter(keychain)
.expect("keychain must exist") .expect("keychain must exist")
} }
@ -1354,7 +1354,7 @@ impl Wallet {
let ((index, spk), index_changeset) = self let ((index, spk), index_changeset) = self
.indexed_graph .indexed_graph
.index .index
.next_unused_spk(&change_keychain) .next_unused_spk(change_keychain)
.expect("keychain must exist"); .expect("keychain must exist");
self.indexed_graph.index.mark_used(change_keychain, index); self.indexed_graph.index.mark_used(change_keychain, index);
self.stage.merge(index_changeset.into()); self.stage.merge(index_changeset.into());
@ -1734,7 +1734,7 @@ impl Wallet {
pub fn public_descriptor(&self, keychain: KeychainKind) -> &ExtendedDescriptor { pub fn public_descriptor(&self, keychain: KeychainKind) -> &ExtendedDescriptor {
self.indexed_graph self.indexed_graph
.index .index
.get_descriptor(&keychain) .get_descriptor(keychain)
.expect("keychain must exist") .expect("keychain must exist")
} }
@ -1843,14 +1843,14 @@ impl Wallet {
/// The derivation index of this wallet. It will return `None` if it has not derived any addresses. /// The derivation index of this wallet. It will return `None` if it has not derived any addresses.
/// Otherwise, it will return the index of the highest address it has derived. /// Otherwise, it will return the index of the highest address it has derived.
pub fn derivation_index(&self, keychain: KeychainKind) -> Option<u32> { pub fn derivation_index(&self, keychain: KeychainKind) -> Option<u32> {
self.indexed_graph.index.last_revealed_index(&keychain) self.indexed_graph.index.last_revealed_index(keychain)
} }
/// The index of the next address that you would get if you were to ask the wallet for a new address /// The index of the next address that you would get if you were to ask the wallet for a new address
pub fn next_derivation_index(&self, keychain: KeychainKind) -> u32 { pub fn next_derivation_index(&self, keychain: KeychainKind) -> u32 {
self.indexed_graph self.indexed_graph
.index .index
.next_index(&keychain) .next_index(keychain)
.expect("keychain must exist") .expect("keychain must exist")
.0 .0
} }

View File

@ -252,7 +252,7 @@ where
let internal_keychain = if graph let internal_keychain = if graph
.index .index
.keychains() .keychains()
.any(|(k, _)| *k == Keychain::Internal) .any(|(k, _)| k == Keychain::Internal)
{ {
Keychain::Internal Keychain::Internal
} else { } else {
@ -261,7 +261,7 @@ where
let ((change_index, change_script), change_changeset) = graph let ((change_index, change_script), change_changeset) = graph
.index .index
.next_unused_spk(&internal_keychain) .next_unused_spk(internal_keychain)
.expect("Must exist"); .expect("Must exist");
changeset.merge(change_changeset); changeset.merge(change_changeset);
@ -269,7 +269,7 @@ where
&graph &graph
.index .index
.keychains() .keychains()
.find(|(k, _)| *k == &internal_keychain) .find(|(k, _)| *k == internal_keychain)
.expect("must exist") .expect("must exist")
.1 .1
.at_derivation_index(change_index) .at_derivation_index(change_index)
@ -288,7 +288,7 @@ where
min_drain_value: graph min_drain_value: graph
.index .index
.keychains() .keychains()
.find(|(k, _)| *k == &internal_keychain) .find(|(k, _)| *k == internal_keychain)
.expect("must exist") .expect("must exist")
.1 .1
.dust_value(), .dust_value(),
@ -433,7 +433,7 @@ pub fn planned_utxos<A: Anchor, O: ChainOracle, K: Clone + bdk_tmp_plan::CanDeri
let desc = graph let desc = graph
.index .index
.keychains() .keychains()
.find(|(keychain, _)| *keychain == &k) .find(|(keychain, _)| *keychain == k)
.expect("keychain must exist") .expect("keychain must exist")
.1 .1
.at_derivation_index(i) .at_derivation_index(i)
@ -479,7 +479,7 @@ where
}; };
let ((spk_i, spk), index_changeset) = let ((spk_i, spk), index_changeset) =
spk_chooser(index, &Keychain::External).expect("Must exist"); spk_chooser(index, Keychain::External).expect("Must exist");
let db = &mut *db.lock().unwrap(); let db = &mut *db.lock().unwrap();
db.append_changeset(&C::from(( db.append_changeset(&C::from((
local_chain::ChangeSet::default(), local_chain::ChangeSet::default(),
@ -501,7 +501,7 @@ where
true => Keychain::Internal, true => Keychain::Internal,
false => Keychain::External, false => Keychain::External,
}; };
for (spk_i, spk) in index.revealed_keychain_spks(&target_keychain) { for (spk_i, spk) in index.revealed_keychain_spks(target_keychain) {
let address = Address::from_script(spk, network) let address = Address::from_script(spk, network)
.expect("should always be able to derive address"); .expect("should always be able to derive address");
println!( println!(

View File

@ -166,7 +166,7 @@ fn main() -> anyhow::Result<()> {
Keychain::External, Keychain::External,
graph graph
.index .index
.unbounded_spk_iter(&Keychain::External) .unbounded_spk_iter(Keychain::External)
.into_iter() .into_iter()
.flatten(), .flatten(),
) )
@ -174,7 +174,7 @@ fn main() -> anyhow::Result<()> {
Keychain::Internal, Keychain::Internal,
graph graph
.index .index
.unbounded_spk_iter(&Keychain::Internal) .unbounded_spk_iter(Keychain::Internal)
.into_iter() .into_iter()
.flatten(), .flatten(),
) )