Skip to content

Commit

Permalink
Extract specialised DescriptorPublicKey functionality into Descriptor…
Browse files Browse the repository at this point in the history
…MultiExtendedPublicKey
  • Loading branch information
Scott Robinson committed Jul 23, 2023
1 parent eaba815 commit a1dbaf5
Showing 1 changed file with 49 additions and 24 deletions.
73 changes: 49 additions & 24 deletions src/descriptor/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{hash256, MiniscriptKey, ToPublicKey};

type DescriptorSinglePublicKey = SinglePub;
type DescriptorExtendedPublicKey = DescriptorXKey<bip32::ExtendedPubKey>;
type DescriptorMultiExtendedPublicKey = DescriptorMultiXKey<bip32::ExtendedPubKey>;

/// The descriptor pubkey, either a single pubkey or an xpub.
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)]
Expand All @@ -29,7 +30,7 @@ pub enum DescriptorPublicKey {
/// Extended public key (xpub).
XPub(DescriptorExtendedPublicKey),
/// Multiple extended public keys.
MultiXPub(DescriptorMultiXKey<bip32::ExtendedPubKey>),
MultiXPub(DescriptorMultiExtendedPublicKey),
}

/// The descriptor secret key, either a single private key or an xprv.
Expand Down Expand Up @@ -311,22 +312,26 @@ impl fmt::Display for DescriptorExtendedPublicKey {
}
}

impl fmt::Display for DescriptorMultiExtendedPublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
maybe_fmt_master_id(f, &self.origin)?;
self.xkey.fmt(f)?;
fmt_derivation_paths(f, self.derivation_paths.paths())?;
match self.wildcard {
Wildcard::None => {}
Wildcard::Unhardened => write!(f, "/*")?,
Wildcard::Hardened => write!(f, "/*h")?,
}
Ok(())
}
}

impl fmt::Display for DescriptorPublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
DescriptorPublicKey::Single(ref pk) => pk.fmt(f),
DescriptorPublicKey::XPub(ref xpub) => xpub.fmt(f),
DescriptorPublicKey::MultiXPub(ref xpub) => {
maybe_fmt_master_id(f, &xpub.origin)?;
xpub.xkey.fmt(f)?;
fmt_derivation_paths(f, xpub.derivation_paths.paths())?;
match xpub.wildcard {
Wildcard::None => {}
Wildcard::Unhardened => write!(f, "/*")?,
Wildcard::Hardened => write!(f, "/*h")?,
}
Ok(())
}
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.fmt(f),
}
}
}
Expand Down Expand Up @@ -664,18 +669,38 @@ impl DescriptorInnerKey for DescriptorExtendedPublicKey {
}
}

impl DescriptorInnerKey for DescriptorMultiExtendedPublicKey {
fn master_fingerprint(&self) -> bip32::Fingerprint {
if let Some((fingerprint, _)) = self.origin {
fingerprint
} else {
self.xkey.fingerprint()
}
}

fn full_derivation_path(&self) -> Option<bip32::DerivationPath> {
None
}

fn has_wildcard(&self) -> bool {
self.wildcard != Wildcard::None
}

fn at_derivation_index(self, _index: u32) -> Result<DefiniteDescriptorKey, ConversionError> {
Err(ConversionError::MultiKey)
}

fn is_multipath(&self) -> bool {
true
}
}

impl DescriptorPublicKey {
/// The fingerprint of the master key associated with this key, `0x00000000` if none.
pub fn master_fingerprint(&self) -> bip32::Fingerprint {
match *self {
DescriptorPublicKey::XPub(ref xpub) => xpub.master_fingerprint(),
DescriptorPublicKey::MultiXPub(ref xpub) => {
if let Some((fingerprint, _)) = xpub.origin {
fingerprint
} else {
xpub.xkey.fingerprint()
}
}
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.master_fingerprint(),
DescriptorPublicKey::Single(ref single) => single.master_fingerprint(),
}
}
Expand All @@ -691,7 +716,7 @@ impl DescriptorPublicKey {
match *self {
DescriptorPublicKey::XPub(ref xpub) => xpub.full_derivation_path(),
DescriptorPublicKey::Single(ref single) => single.full_derivation_path(),
DescriptorPublicKey::MultiXPub(_) => None,
DescriptorPublicKey::MultiXPub(_) => self.full_derivation_path(),
}
}

Expand All @@ -706,7 +731,7 @@ impl DescriptorPublicKey {
match *self {
DescriptorPublicKey::Single(ref single) => single.has_wildcard(),
DescriptorPublicKey::XPub(ref xpub) => xpub.has_wildcard(),
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.wildcard != Wildcard::None,
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.has_wildcard(),
}
}

Expand All @@ -732,15 +757,15 @@ impl DescriptorPublicKey {
match self {
DescriptorPublicKey::Single(single) => single.at_derivation_index(index),
DescriptorPublicKey::XPub(xpub) => xpub.at_derivation_index(index),
DescriptorPublicKey::MultiXPub(_) => Err(ConversionError::MultiKey),
DescriptorPublicKey::MultiXPub(xpub) => xpub.at_derivation_index(index),
}
}

/// Whether or not this key has multiple derivation paths.
pub fn is_multipath(&self) -> bool {
match *self {
DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => self.is_multipath(),
DescriptorPublicKey::MultiXPub(_) => true,
DescriptorPublicKey::MultiXPub(_) => self.is_multipath(),
}
}

Expand Down Expand Up @@ -1458,7 +1483,7 @@ mod test {
fn get_multipath_xpub(
key_str: &str,
num_paths: usize,
) -> DescriptorMultiXKey<bip32::ExtendedPubKey> {
) -> DescriptorMultiExtendedPublicKey {
let desc_key = DescriptorPublicKey::from_str(key_str).unwrap();
assert_eq!(desc_key.num_der_paths(), num_paths);
match desc_key {
Expand Down

0 comments on commit a1dbaf5

Please sign in to comment.