From eaba8151488f796f763b76a3941e9418560eb808 Mon Sep 17 00:00:00 2001 From: Scott Robinson Date: Sun, 23 Jul 2023 13:07:23 +1000 Subject: [PATCH] Extract specialised DescriptorPublicKey functionality into DescriptorSinglePublicKey --- src/descriptor/key.rs | 98 ++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index 4120a4ef2..ef9658800 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -18,6 +18,7 @@ use crate::prelude::*; use crate::serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::{hash256, MiniscriptKey, ToPublicKey}; +type DescriptorSinglePublicKey = SinglePub; type DescriptorExtendedPublicKey = DescriptorXKey; /// The descriptor pubkey, either a single pubkey or an xpub. @@ -285,6 +286,17 @@ impl error::Error for DescriptorKeyParseError { } } +impl fmt::Display for DescriptorSinglePublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + maybe_fmt_master_id(f, &self.origin)?; + match self.key { + SinglePubKey::FullKey(full_key) => full_key.fmt(f), + SinglePubKey::XOnly(x_only_key) => x_only_key.fmt(f), + }?; + Ok(()) + } +} + impl fmt::Display for DescriptorExtendedPublicKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { maybe_fmt_master_id(f, &self.origin)?; @@ -302,14 +314,7 @@ impl fmt::Display for DescriptorExtendedPublicKey { impl fmt::Display for DescriptorPublicKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - DescriptorPublicKey::Single(ref pk) => { - maybe_fmt_master_id(f, &pk.origin)?; - match pk.key { - SinglePubKey::FullKey(full_key) => full_key.fmt(f), - SinglePubKey::XOnly(x_only_key) => x_only_key.fmt(f), - }?; - Ok(()) - } + 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)?; @@ -565,6 +570,48 @@ pub trait DescriptorInnerKey { fn is_multipath(&self) -> bool; } +impl DescriptorInnerKey for DescriptorSinglePublicKey { + fn master_fingerprint(&self) -> bip32::Fingerprint { + if let Some((fingerprint, _)) = self.origin { + fingerprint + } else { + let mut engine = XpubIdentifier::engine(); + match self.key { + SinglePubKey::FullKey(pk) => { + pk.write_into(&mut engine).expect("engines don't error") + } + SinglePubKey::XOnly(x_only_pk) => engine.input(&x_only_pk.serialize()), + }; + bip32::Fingerprint::from( + &XpubIdentifier::from_engine(engine)[..4] + .try_into() + .expect("4 byte slice"), + ) + } + } + + fn full_derivation_path(&self) -> Option { + Some(if let Some((_, ref path)) = self.origin { + path.clone() + } else { + bip32::DerivationPath::from(vec![]) + }) + } + + fn has_wildcard(&self) -> bool { + false + } + + fn at_derivation_index(self, _index: u32) -> Result { + Ok(DefiniteDescriptorKey::new(DescriptorPublicKey::Single(self)) + .expect("The key should not contain any wildcards at this point")) + } + + fn is_multipath(&self) -> bool { + false + } +} + impl DescriptorInnerKey for DescriptorExtendedPublicKey { fn master_fingerprint(&self) -> bip32::Fingerprint { if let Some((fingerprint, _)) = self.origin { @@ -629,24 +676,7 @@ impl DescriptorPublicKey { xpub.xkey.fingerprint() } } - DescriptorPublicKey::Single(ref single) => { - if let Some((fingerprint, _)) = single.origin { - fingerprint - } else { - let mut engine = XpubIdentifier::engine(); - match single.key { - SinglePubKey::FullKey(pk) => { - pk.write_into(&mut engine).expect("engines don't error") - } - SinglePubKey::XOnly(x_only_pk) => engine.input(&x_only_pk.serialize()), - }; - bip32::Fingerprint::from( - &XpubIdentifier::from_engine(engine)[..4] - .try_into() - .expect("4 byte slice"), - ) - } - } + DescriptorPublicKey::Single(ref single) => single.master_fingerprint(), } } @@ -660,13 +690,7 @@ impl DescriptorPublicKey { pub fn full_derivation_path(&self) -> Option { match *self { DescriptorPublicKey::XPub(ref xpub) => xpub.full_derivation_path(), - DescriptorPublicKey::Single(ref single) => { - Some(if let Some((_, ref path)) = single.origin { - path.clone() - } else { - bip32::DerivationPath::from(vec![]) - }) - } + DescriptorPublicKey::Single(ref single) => single.full_derivation_path(), DescriptorPublicKey::MultiXPub(_) => None, } } @@ -680,7 +704,7 @@ impl DescriptorPublicKey { /// Whether or not the key has a wildcard pub fn has_wildcard(&self) -> bool { match *self { - DescriptorPublicKey::Single(..) => false, + DescriptorPublicKey::Single(ref single) => single.has_wildcard(), DescriptorPublicKey::XPub(ref xpub) => xpub.has_wildcard(), DescriptorPublicKey::MultiXPub(ref xpub) => xpub.wildcard != Wildcard::None, } @@ -706,8 +730,7 @@ impl DescriptorPublicKey { /// - If `index` is hardened. pub fn at_derivation_index(self, index: u32) -> Result { match self { - DescriptorPublicKey::Single(_) => Ok(DefiniteDescriptorKey::new(self) - .expect("The key should not contain any wildcards at this point")), + DescriptorPublicKey::Single(single) => single.at_derivation_index(index), DescriptorPublicKey::XPub(xpub) => xpub.at_derivation_index(index), DescriptorPublicKey::MultiXPub(_) => Err(ConversionError::MultiKey), } @@ -716,8 +739,7 @@ impl DescriptorPublicKey { /// Whether or not this key has multiple derivation paths. pub fn is_multipath(&self) -> bool { match *self { - DescriptorPublicKey::Single(..) => false, - DescriptorPublicKey::XPub(..) => self.is_multipath(), + DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => self.is_multipath(), DescriptorPublicKey::MultiXPub(_) => true, } }