Skip to content
This repository has been archived by the owner on Mar 14, 2023. It is now read-only.

Iterators over spks should have their own iterator type #190

Open
LLFourn opened this issue Feb 15, 2023 · 0 comments
Open

Iterators over spks should have their own iterator type #190

LLFourn opened this issue Feb 15, 2023 · 0 comments

Comments

@LLFourn
Copy link
Owner

LLFourn commented Feb 15, 2023

Something like this because with the current method using range_descriptor_spks the returned iterator will not be able quickly call skip or nth on the iterator. It will do all the intermediate derivations.

use bitcoin::{
    secp256k1::{Secp256k1, VerifyOnly},
    Script,
};
use miniscript::{Descriptor, DescriptorPublicKey};

/// An iterator over a descriptor's script pubkeys.
///
// TODO: put this into miniscript
#[derive(Clone, Debug)]
pub struct SpkIter {
    descriptor: Descriptor<DescriptorPublicKey>,
    index: usize,
    secp: Secp256k1<VerifyOnly>,
    end: usize,
}

impl SpkIter {
    /// Creates a new script pubkey iterator starting at 0 from a descriptor
    pub fn new(descriptor: Descriptor<DescriptorPublicKey>) -> Self {
        let secp = Secp256k1::verification_only();
        let end = if descriptor.has_wildcard() {
            // Because we only iterate over non-hardened indexes there are 2^31 values
            (1 << 31) - 1
        } else {
            0
        };

        Self {
            descriptor,
            index: 0,
            secp,
            end,
        }
    }
}

impl Iterator for SpkIter {
    type Item = (u32, Script);

    fn nth(&mut self, n: usize) -> Option<Self::Item> {
        self.index = self.index.saturating_add(n);
        self.next()
    }

    fn next(&mut self) -> Option<Self::Item> {
        let index = self.index;
        if index > self.end {
            return None;
        }

        let script = self
            .descriptor
            .at_derivation_index(self.index as u32)
            .derived_descriptor(&self.secp)
            .expect("the descritpor cannot need hardened derivation")
            .script_pubkey();

        self.index += 1;

        Some((index as u32, script))
    }
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant