refactor(chain)!: update KeychainTxOutIndex methods to use owned K
This commit is contained in:
		
							parent
							
								
									0c8ee1dfe2
								
							
						
					
					
						commit
						7c07b9de02
					
				@ -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::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<_>>(())
 | 
			
		||||
/// ```
 | 
			
		||||
///
 | 
			
		||||
@ -335,11 +335,11 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
    /// Return all keychains and their corresponding descriptors.
 | 
			
		||||
    pub fn keychains(
 | 
			
		||||
        &self,
 | 
			
		||||
    ) -> impl DoubleEndedIterator<Item = (&K, &Descriptor<DescriptorPublicKey>)> + ExactSizeIterator + '_
 | 
			
		||||
    ) -> impl DoubleEndedIterator<Item = (K, &Descriptor<DescriptorPublicKey>)> + ExactSizeIterator + '_
 | 
			
		||||
    {
 | 
			
		||||
        self.keychain_to_descriptor_id
 | 
			
		||||
            .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.
 | 
			
		||||
@ -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
 | 
			
		||||
    /// have a descriptor associated with it.
 | 
			
		||||
    pub fn get_descriptor(&self, keychain: &K) -> Option<&Descriptor<DescriptorPublicKey>> {
 | 
			
		||||
        let did = self.keychain_to_descriptor_id.get(keychain)?;
 | 
			
		||||
    pub fn get_descriptor(&self, keychain: K) -> Option<&Descriptor<DescriptorPublicKey>> {
 | 
			
		||||
        let did = self.keychain_to_descriptor_id.get(&keychain)?;
 | 
			
		||||
        self.descriptors.get(did)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -416,8 +416,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
    /// Store lookahead scripts until `target_index` (inclusive).
 | 
			
		||||
    ///
 | 
			
		||||
    /// This does not change the global `lookahead` setting.
 | 
			
		||||
    pub fn lookahead_to_target(&mut self, keychain: &K, target_index: u32) {
 | 
			
		||||
        if let Some((next_index, _)) = self.next_index(keychain) {
 | 
			
		||||
    pub fn lookahead_to_target(&mut self, keychain: K, target_index: u32) {
 | 
			
		||||
        if let Some((next_index, _)) = self.next_index(keychain.clone()) {
 | 
			
		||||
            let temp_lookahead = (target_index + 1)
 | 
			
		||||
                .checked_sub(next_index)
 | 
			
		||||
                .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) {
 | 
			
		||||
        if let Some(did) = self.keychain_to_descriptor_id.get(keychain) {
 | 
			
		||||
            self.replenish_inner_index(*did, keychain, lookahead);
 | 
			
		||||
    fn replenish_inner_index_keychain(&mut self, keychain: K, lookahead: u32) {
 | 
			
		||||
        if let Some(did) = self.keychain_to_descriptor_id.get(&keychain) {
 | 
			
		||||
            self.replenish_inner_index(*did, &keychain, lookahead);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -464,7 +464,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
    /// keychain doesn't exist
 | 
			
		||||
    pub fn unbounded_spk_iter(
 | 
			
		||||
        &self,
 | 
			
		||||
        keychain: &K,
 | 
			
		||||
        keychain: K,
 | 
			
		||||
    ) -> Option<SpkIterator<Descriptor<DescriptorPublicKey>>> {
 | 
			
		||||
        let descriptor = self.get_descriptor(keychain)?.clone();
 | 
			
		||||
        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
 | 
			
		||||
    /// the script pubkeys that were most recently revealed are first.
 | 
			
		||||
    pub fn revealed_keychain_spks<'a>(
 | 
			
		||||
        &'a self,
 | 
			
		||||
        keychain: &'a K,
 | 
			
		||||
    ) -> impl DoubleEndedIterator<Item = Indexed<&Script>> + 'a {
 | 
			
		||||
    pub fn revealed_keychain_spks(
 | 
			
		||||
        &self,
 | 
			
		||||
        keychain: K,
 | 
			
		||||
    ) -> impl DoubleEndedIterator<Item = Indexed<&Script>> {
 | 
			
		||||
        let end = self
 | 
			
		||||
            .last_revealed_index(keychain)
 | 
			
		||||
            .last_revealed_index(keychain.clone())
 | 
			
		||||
            .map(|v| v + 1)
 | 
			
		||||
            .unwrap_or(0);
 | 
			
		||||
        self.inner
 | 
			
		||||
@ -544,7 +544,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
        &self,
 | 
			
		||||
    ) -> impl DoubleEndedIterator<Item = KeychainIndexed<K, &Script>> + Clone {
 | 
			
		||||
        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))
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
@ -553,9 +553,9 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
    /// Returns an empty iterator if the provided keychain doesn't exist.
 | 
			
		||||
    pub fn unused_keychain_spks(
 | 
			
		||||
        &self,
 | 
			
		||||
        keychain: &K,
 | 
			
		||||
        keychain: K,
 | 
			
		||||
    ) -> 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),
 | 
			
		||||
            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.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Returns None if the provided `keychain` doesn't exist.
 | 
			
		||||
    pub fn next_index(&self, keychain: &K) -> Option<(u32, bool)> {
 | 
			
		||||
        let did = self.keychain_to_descriptor_id.get(keychain)?;
 | 
			
		||||
    pub fn next_index(&self, keychain: K) -> Option<(u32, bool)> {
 | 
			
		||||
        let did = self.keychain_to_descriptor_id.get(&keychain)?;
 | 
			
		||||
        let last_index = self.last_revealed.get(did).cloned();
 | 
			
		||||
        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
 | 
			
		||||
    /// exist, or if the keychain doesn't have any revealed scripts.
 | 
			
		||||
    pub fn last_revealed_index(&self, keychain: &K) -> Option<u32> {
 | 
			
		||||
        let descriptor_id = self.keychain_to_descriptor_id.get(keychain)?;
 | 
			
		||||
    pub fn last_revealed_index(&self, keychain: K) -> Option<u32> {
 | 
			
		||||
        let descriptor_id = self.keychain_to_descriptor_id.get(&keychain)?;
 | 
			
		||||
        self.last_revealed.get(descriptor_id).cloned()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -625,7 +625,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
        let mut changeset = ChangeSet::default();
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@ -648,16 +648,16 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
    #[must_use]
 | 
			
		||||
    pub fn reveal_to_target(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        keychain: &K,
 | 
			
		||||
        keychain: K,
 | 
			
		||||
        target_index: u32,
 | 
			
		||||
    ) -> Option<(Vec<Indexed<ScriptBuf>>, ChangeSet)> {
 | 
			
		||||
        let mut changeset = ChangeSet::default();
 | 
			
		||||
        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 {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            match self.reveal_next_spk(keychain) {
 | 
			
		||||
            match self.reveal_next_spk(keychain.clone()) {
 | 
			
		||||
                Some(((i, spk), change)) => {
 | 
			
		||||
                    spks.push((i, spk));
 | 
			
		||||
                    changeset.merge(change);
 | 
			
		||||
@ -686,10 +686,10 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
        let mut changeset = ChangeSet::default();
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
            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
 | 
			
		||||
            .inner
 | 
			
		||||
@ -711,9 +711,9 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
    /// could be revealed (see [`reveal_next_spk`] for when this happens).
 | 
			
		||||
    ///
 | 
			
		||||
    /// [`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
 | 
			
		||||
            .unused_keychain_spks(keychain)
 | 
			
		||||
            .unused_keychain_spks(keychain.clone())
 | 
			
		||||
            .next()
 | 
			
		||||
            .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
 | 
			
		||||
    /// `keychain`.
 | 
			
		||||
    pub fn keychain_outpoints<'a>(
 | 
			
		||||
        &'a self,
 | 
			
		||||
        keychain: &'a K,
 | 
			
		||||
    ) -> impl DoubleEndedIterator<Item = Indexed<OutPoint>> + 'a {
 | 
			
		||||
        self.keychain_outpoints_in_range(keychain..=keychain)
 | 
			
		||||
    pub fn keychain_outpoints(
 | 
			
		||||
        &self,
 | 
			
		||||
        keychain: K,
 | 
			
		||||
    ) -> impl DoubleEndedIterator<Item = Indexed<OutPoint>> + '_ {
 | 
			
		||||
        self.keychain_outpoints_in_range(keychain.clone()..=keychain)
 | 
			
		||||
            .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
 | 
			
		||||
    /// 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)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -767,7 +767,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 | 
			
		||||
        self.keychain_to_descriptor_id
 | 
			
		||||
            .iter()
 | 
			
		||||
            .filter_map(|(keychain, _)| {
 | 
			
		||||
                self.last_used_index(keychain)
 | 
			
		||||
                self.last_used_index(keychain.clone())
 | 
			
		||||
                    .map(|index| (keychain.clone(), index))
 | 
			
		||||
            })
 | 
			
		||||
            .collect()
 | 
			
		||||
 | 
			
		||||
@ -161,7 +161,7 @@ fn test_list_owned_txouts() {
 | 
			
		||||
        for _ in 0..10 {
 | 
			
		||||
            let ((_, script), _) = graph
 | 
			
		||||
                .index
 | 
			
		||||
                .reveal_next_spk(&"keychain_1".to_string())
 | 
			
		||||
                .reveal_next_spk("keychain_1".to_string())
 | 
			
		||||
                .unwrap();
 | 
			
		||||
            // TODO Assert indexes
 | 
			
		||||
            trusted_spks.push(script.to_owned());
 | 
			
		||||
@ -171,7 +171,7 @@ fn test_list_owned_txouts() {
 | 
			
		||||
        for _ in 0..10 {
 | 
			
		||||
            let ((_, script), _) = graph
 | 
			
		||||
                .index
 | 
			
		||||
                .reveal_next_spk(&"keychain_2".to_string())
 | 
			
		||||
                .reveal_next_spk("keychain_2".to_string())
 | 
			
		||||
                .unwrap();
 | 
			
		||||
            untrusted_spks.push(script.to_owned());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -142,7 +142,7 @@ fn test_lookahead() {
 | 
			
		||||
    // - stored scripts of external keychain should be of expected counts
 | 
			
		||||
    for index in (0..20).skip_while(|i| i % 2 == 1) {
 | 
			
		||||
        let (revealed_spks, revealed_changeset) = txout_index
 | 
			
		||||
            .reveal_to_target(&TestKeychain::External, index)
 | 
			
		||||
            .reveal_to_target(TestKeychain::External, index)
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            revealed_spks,
 | 
			
		||||
@ -161,25 +161,25 @@ fn test_lookahead() {
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            txout_index
 | 
			
		||||
                .revealed_keychain_spks(&TestKeychain::External)
 | 
			
		||||
                .revealed_keychain_spks(TestKeychain::External)
 | 
			
		||||
                .count(),
 | 
			
		||||
            index as usize + 1,
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            txout_index
 | 
			
		||||
                .revealed_keychain_spks(&TestKeychain::Internal)
 | 
			
		||||
                .revealed_keychain_spks(TestKeychain::Internal)
 | 
			
		||||
                .count(),
 | 
			
		||||
            0,
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            txout_index
 | 
			
		||||
                .unused_keychain_spks(&TestKeychain::External)
 | 
			
		||||
                .unused_keychain_spks(TestKeychain::External)
 | 
			
		||||
                .count(),
 | 
			
		||||
            index as usize + 1,
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            txout_index
 | 
			
		||||
                .unused_keychain_spks(&TestKeychain::Internal)
 | 
			
		||||
                .unused_keychain_spks(TestKeychain::Internal)
 | 
			
		||||
                .count(),
 | 
			
		||||
            0,
 | 
			
		||||
        );
 | 
			
		||||
@ -193,7 +193,7 @@ fn test_lookahead() {
 | 
			
		||||
    // expect:
 | 
			
		||||
    // - scripts cached in spk_txout_index should increase correctly, a.k.a. no scripts are skipped
 | 
			
		||||
    let (revealed_spks, revealed_changeset) = txout_index
 | 
			
		||||
        .reveal_to_target(&TestKeychain::Internal, 24)
 | 
			
		||||
        .reveal_to_target(TestKeychain::Internal, 24)
 | 
			
		||||
        .unwrap();
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        revealed_spks,
 | 
			
		||||
@ -214,17 +214,17 @@ fn test_lookahead() {
 | 
			
		||||
    );
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        txout_index
 | 
			
		||||
            .revealed_keychain_spks(&TestKeychain::Internal)
 | 
			
		||||
            .revealed_keychain_spks(TestKeychain::Internal)
 | 
			
		||||
            .count(),
 | 
			
		||||
        25,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // ensure derivation indices are expected for each keychain
 | 
			
		||||
    let last_external_index = txout_index
 | 
			
		||||
        .last_revealed_index(&TestKeychain::External)
 | 
			
		||||
        .last_revealed_index(TestKeychain::External)
 | 
			
		||||
        .expect("already derived");
 | 
			
		||||
    let last_internal_index = txout_index
 | 
			
		||||
        .last_revealed_index(&TestKeychain::Internal)
 | 
			
		||||
        .last_revealed_index(TestKeychain::Internal)
 | 
			
		||||
        .expect("already derived");
 | 
			
		||||
    assert_eq!(last_external_index, 19);
 | 
			
		||||
    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.last_revealed_index(&TestKeychain::External),
 | 
			
		||||
            txout_index.last_revealed_index(TestKeychain::External),
 | 
			
		||||
            Some(last_external_index)
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            txout_index.last_revealed_index(&TestKeychain::Internal),
 | 
			
		||||
            txout_index.last_revealed_index(TestKeychain::Internal),
 | 
			
		||||
            Some(last_internal_index)
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            txout_index
 | 
			
		||||
                .revealed_keychain_spks(&TestKeychain::External)
 | 
			
		||||
                .revealed_keychain_spks(TestKeychain::External)
 | 
			
		||||
                .count(),
 | 
			
		||||
            last_external_index as usize + 1,
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            txout_index
 | 
			
		||||
                .revealed_keychain_spks(&TestKeychain::Internal)
 | 
			
		||||
                .revealed_keychain_spks(TestKeychain::Internal)
 | 
			
		||||
                .count(),
 | 
			
		||||
            last_internal_index as usize + 1,
 | 
			
		||||
        );
 | 
			
		||||
@ -317,11 +317,11 @@ fn test_scan_with_lookahead() {
 | 
			
		||||
            &[(external_descriptor.descriptor_id(), spk_i)].into()
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            txout_index.last_revealed_index(&TestKeychain::External),
 | 
			
		||||
            txout_index.last_revealed_index(TestKeychain::External),
 | 
			
		||||
            Some(spk_i)
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            txout_index.last_used_index(&TestKeychain::External),
 | 
			
		||||
            txout_index.last_used_index(TestKeychain::External),
 | 
			
		||||
            Some(spk_i)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
@ -357,11 +357,11 @@ fn test_wildcard_derivations() {
 | 
			
		||||
    // - next_derivation_index() == (0, true)
 | 
			
		||||
    // - derive_new() == ((0, <spk>), keychain::ChangeSet)
 | 
			
		||||
    // - next_unused() == ((0, <spk>), keychain::ChangeSet:is_empty())
 | 
			
		||||
    assert_eq!(txout_index.next_index(&TestKeychain::External).unwrap(), (0, true));
 | 
			
		||||
    let (spk, changeset) = txout_index.reveal_next_spk(&TestKeychain::External).unwrap();
 | 
			
		||||
    assert_eq!(txout_index.next_index(TestKeychain::External).unwrap(), (0, true));
 | 
			
		||||
    let (spk, changeset) = txout_index.reveal_next_spk(TestKeychain::External).unwrap();
 | 
			
		||||
    assert_eq!(spk, (0_u32, external_spk_0.clone()));
 | 
			
		||||
    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!(&changeset.last_revealed, &[].into());
 | 
			
		||||
 | 
			
		||||
@ -373,20 +373,20 @@ fn test_wildcard_derivations() {
 | 
			
		||||
    // - next_derivation_index() = (26, true)
 | 
			
		||||
    // - derive_new() = ((26, <spk>), keychain::ChangeSet)
 | 
			
		||||
    // - 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)
 | 
			
		||||
        .chain([17, 20, 23])
 | 
			
		||||
        .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!(&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!(&changeset.last_revealed, &[].into());
 | 
			
		||||
 | 
			
		||||
@ -396,7 +396,7 @@ fn test_wildcard_derivations() {
 | 
			
		||||
        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!(&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 get the next unused script, script @ index 0
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        txout_index.next_index(&TestKeychain::External).unwrap(),
 | 
			
		||||
        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, external_spk.clone()));
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        &changeset.last_revealed,
 | 
			
		||||
        &[(no_wildcard_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, external_spk.clone()));
 | 
			
		||||
    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
 | 
			
		||||
    // - store_up_to should not panic and return empty changeset
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        txout_index.next_index(&TestKeychain::External).unwrap(),
 | 
			
		||||
        txout_index.next_index(TestKeychain::External).unwrap(),
 | 
			
		||||
        (0, false)
 | 
			
		||||
    );
 | 
			
		||||
    txout_index.mark_used(TestKeychain::External, 0);
 | 
			
		||||
 | 
			
		||||
    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, external_spk.clone()));
 | 
			
		||||
    assert_eq!(&changeset.last_revealed, &[].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, external_spk.clone()));
 | 
			
		||||
    assert_eq!(&changeset.last_revealed, &[].into());
 | 
			
		||||
    let (revealed_spks, revealed_changeset) = txout_index
 | 
			
		||||
        .reveal_to_target(&TestKeychain::External, 200)
 | 
			
		||||
        .reveal_to_target(TestKeychain::External, 200)
 | 
			
		||||
        .unwrap();
 | 
			
		||||
    assert_eq!(revealed_spks.len(), 0);
 | 
			
		||||
    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
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        txout_index
 | 
			
		||||
            .revealed_keychain_spks(&TestKeychain::External)
 | 
			
		||||
            .revealed_keychain_spks(TestKeychain::External)
 | 
			
		||||
            .count(),
 | 
			
		||||
        1,
 | 
			
		||||
    );
 | 
			
		||||
@ -540,10 +532,10 @@ fn lookahead_to_target() {
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        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 {
 | 
			
		||||
            let _ = index.reveal_to_target(&TestKeychain::Internal, last_revealed);
 | 
			
		||||
            let _ = index.reveal_to_target(TestKeychain::Internal, last_revealed);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let keychain_test_cases = [
 | 
			
		||||
@ -570,7 +562,7 @@ fn lookahead_to_target() {
 | 
			
		||||
                    }
 | 
			
		||||
                    None => target,
 | 
			
		||||
                };
 | 
			
		||||
                index.lookahead_to_target(&keychain, target);
 | 
			
		||||
                index.lookahead_to_target(keychain.clone(), target);
 | 
			
		||||
                let keys = index
 | 
			
		||||
                    .inner()
 | 
			
		||||
                    .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();
 | 
			
		||||
        if i != 4 {
 | 
			
		||||
            // 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 {
 | 
			
		||||
            script_pubkey: descriptor.at_derivation_index(0).unwrap().script_pubkey(),
 | 
			
		||||
 | 
			
		||||
@ -542,7 +542,7 @@ impl 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()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -558,7 +558,7 @@ impl Wallet {
 | 
			
		||||
        let mut spk_iter = self
 | 
			
		||||
            .indexed_graph
 | 
			
		||||
            .index
 | 
			
		||||
            .unbounded_spk_iter(&keychain)
 | 
			
		||||
            .unbounded_spk_iter(keychain)
 | 
			
		||||
            .expect("keychain must exist");
 | 
			
		||||
        if !spk_iter.descriptor().has_wildcard() {
 | 
			
		||||
            index = 0;
 | 
			
		||||
@ -604,7 +604,7 @@ impl Wallet {
 | 
			
		||||
        let stage = &mut self.stage;
 | 
			
		||||
 | 
			
		||||
        let ((index, spk), index_changeset) = index
 | 
			
		||||
            .reveal_next_spk(&keychain)
 | 
			
		||||
            .reveal_next_spk(keychain)
 | 
			
		||||
            .expect("keychain must exist");
 | 
			
		||||
 | 
			
		||||
        stage.merge(index_changeset.into());
 | 
			
		||||
@ -634,7 +634,7 @@ impl Wallet {
 | 
			
		||||
        let (spks, index_changeset) = self
 | 
			
		||||
            .indexed_graph
 | 
			
		||||
            .index
 | 
			
		||||
            .reveal_to_target(&keychain, index)
 | 
			
		||||
            .reveal_to_target(keychain, index)
 | 
			
		||||
            .expect("keychain must exist");
 | 
			
		||||
 | 
			
		||||
        self.stage.merge(index_changeset.into());
 | 
			
		||||
@ -658,7 +658,7 @@ impl Wallet {
 | 
			
		||||
        let index = &mut self.indexed_graph.index;
 | 
			
		||||
 | 
			
		||||
        let ((index, spk), index_changeset) = index
 | 
			
		||||
            .next_unused_spk(&keychain)
 | 
			
		||||
            .next_unused_spk(keychain)
 | 
			
		||||
            .expect("keychain must exist");
 | 
			
		||||
 | 
			
		||||
        self.stage
 | 
			
		||||
@ -702,7 +702,7 @@ impl Wallet {
 | 
			
		||||
    ) -> impl DoubleEndedIterator<Item = AddressInfo> + '_ {
 | 
			
		||||
        self.indexed_graph
 | 
			
		||||
            .index
 | 
			
		||||
            .unused_keychain_spks(&keychain)
 | 
			
		||||
            .unused_keychain_spks(keychain)
 | 
			
		||||
            .map(move |(index, spk)| AddressInfo {
 | 
			
		||||
                index,
 | 
			
		||||
                address: Address::from_script(spk, self.network).expect("must have address form"),
 | 
			
		||||
@ -783,7 +783,7 @@ impl Wallet {
 | 
			
		||||
    ) -> impl Iterator<Item = Indexed<ScriptBuf>> + Clone {
 | 
			
		||||
        self.indexed_graph
 | 
			
		||||
            .index
 | 
			
		||||
            .unbounded_spk_iter(&keychain)
 | 
			
		||||
            .unbounded_spk_iter(keychain)
 | 
			
		||||
            .expect("keychain must exist")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1354,7 +1354,7 @@ impl Wallet {
 | 
			
		||||
                let ((index, spk), index_changeset) = self
 | 
			
		||||
                    .indexed_graph
 | 
			
		||||
                    .index
 | 
			
		||||
                    .next_unused_spk(&change_keychain)
 | 
			
		||||
                    .next_unused_spk(change_keychain)
 | 
			
		||||
                    .expect("keychain must exist");
 | 
			
		||||
                self.indexed_graph.index.mark_used(change_keychain, index);
 | 
			
		||||
                self.stage.merge(index_changeset.into());
 | 
			
		||||
@ -1734,7 +1734,7 @@ impl Wallet {
 | 
			
		||||
    pub fn public_descriptor(&self, keychain: KeychainKind) -> &ExtendedDescriptor {
 | 
			
		||||
        self.indexed_graph
 | 
			
		||||
            .index
 | 
			
		||||
            .get_descriptor(&keychain)
 | 
			
		||||
            .get_descriptor(keychain)
 | 
			
		||||
            .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.
 | 
			
		||||
    /// Otherwise, it will return the index of the highest address it has derived.
 | 
			
		||||
    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
 | 
			
		||||
    pub fn next_derivation_index(&self, keychain: KeychainKind) -> u32 {
 | 
			
		||||
        self.indexed_graph
 | 
			
		||||
            .index
 | 
			
		||||
            .next_index(&keychain)
 | 
			
		||||
            .next_index(keychain)
 | 
			
		||||
            .expect("keychain must exist")
 | 
			
		||||
            .0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -252,7 +252,7 @@ where
 | 
			
		||||
    let internal_keychain = if graph
 | 
			
		||||
        .index
 | 
			
		||||
        .keychains()
 | 
			
		||||
        .any(|(k, _)| *k == Keychain::Internal)
 | 
			
		||||
        .any(|(k, _)| k == Keychain::Internal)
 | 
			
		||||
    {
 | 
			
		||||
        Keychain::Internal
 | 
			
		||||
    } else {
 | 
			
		||||
@ -261,7 +261,7 @@ where
 | 
			
		||||
 | 
			
		||||
    let ((change_index, change_script), change_changeset) = graph
 | 
			
		||||
        .index
 | 
			
		||||
        .next_unused_spk(&internal_keychain)
 | 
			
		||||
        .next_unused_spk(internal_keychain)
 | 
			
		||||
        .expect("Must exist");
 | 
			
		||||
    changeset.merge(change_changeset);
 | 
			
		||||
 | 
			
		||||
@ -269,7 +269,7 @@ where
 | 
			
		||||
        &graph
 | 
			
		||||
            .index
 | 
			
		||||
            .keychains()
 | 
			
		||||
            .find(|(k, _)| *k == &internal_keychain)
 | 
			
		||||
            .find(|(k, _)| *k == internal_keychain)
 | 
			
		||||
            .expect("must exist")
 | 
			
		||||
            .1
 | 
			
		||||
            .at_derivation_index(change_index)
 | 
			
		||||
@ -288,7 +288,7 @@ where
 | 
			
		||||
        min_drain_value: graph
 | 
			
		||||
            .index
 | 
			
		||||
            .keychains()
 | 
			
		||||
            .find(|(k, _)| *k == &internal_keychain)
 | 
			
		||||
            .find(|(k, _)| *k == internal_keychain)
 | 
			
		||||
            .expect("must exist")
 | 
			
		||||
            .1
 | 
			
		||||
            .dust_value(),
 | 
			
		||||
@ -433,7 +433,7 @@ pub fn planned_utxos<A: Anchor, O: ChainOracle, K: Clone + bdk_tmp_plan::CanDeri
 | 
			
		||||
            let desc = graph
 | 
			
		||||
                .index
 | 
			
		||||
                .keychains()
 | 
			
		||||
                .find(|(keychain, _)| *keychain == &k)
 | 
			
		||||
                .find(|(keychain, _)| *keychain == k)
 | 
			
		||||
                .expect("keychain must exist")
 | 
			
		||||
                .1
 | 
			
		||||
                .at_derivation_index(i)
 | 
			
		||||
@ -479,7 +479,7 @@ where
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    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();
 | 
			
		||||
                    db.append_changeset(&C::from((
 | 
			
		||||
                        local_chain::ChangeSet::default(),
 | 
			
		||||
@ -501,7 +501,7 @@ where
 | 
			
		||||
                        true => Keychain::Internal,
 | 
			
		||||
                        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)
 | 
			
		||||
                            .expect("should always be able to derive address");
 | 
			
		||||
                        println!(
 | 
			
		||||
 | 
			
		||||
@ -166,7 +166,7 @@ fn main() -> anyhow::Result<()> {
 | 
			
		||||
                        Keychain::External,
 | 
			
		||||
                        graph
 | 
			
		||||
                            .index
 | 
			
		||||
                            .unbounded_spk_iter(&Keychain::External)
 | 
			
		||||
                            .unbounded_spk_iter(Keychain::External)
 | 
			
		||||
                            .into_iter()
 | 
			
		||||
                            .flatten(),
 | 
			
		||||
                    )
 | 
			
		||||
@ -174,7 +174,7 @@ fn main() -> anyhow::Result<()> {
 | 
			
		||||
                        Keychain::Internal,
 | 
			
		||||
                        graph
 | 
			
		||||
                            .index
 | 
			
		||||
                            .unbounded_spk_iter(&Keychain::Internal)
 | 
			
		||||
                            .unbounded_spk_iter(Keychain::Internal)
 | 
			
		||||
                            .into_iter()
 | 
			
		||||
                            .flatten(),
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user