Skip to content

Commit 100b7d6

Browse files
author
Scott Robinson
committed
Extract specialised DescriptorPublicKey functionality into DescriptorMultiExtendedPublicKey
1 parent fa4dabb commit 100b7d6

File tree

1 file changed

+56
-26
lines changed

1 file changed

+56
-26
lines changed

src/descriptor/key.rs

+56-26
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::{hash256, MiniscriptKey, ToPublicKey};
2020

2121
type DescriptorSinglePublicKey = SinglePub;
2222
type DescriptorExtendedPublicKey = DescriptorXKey<bip32::ExtendedPubKey>;
23+
type DescriptorMultiExtendedPublicKey = DescriptorMultiXKey<bip32::ExtendedPubKey>;
2324

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

3536
/// The descriptor secret key, either a single private key or an xprv.
@@ -310,22 +311,26 @@ impl fmt::Display for DescriptorExtendedPublicKey {
310311
}
311312
}
312313

314+
impl fmt::Display for DescriptorMultiExtendedPublicKey {
315+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316+
maybe_fmt_master_id(f, &self.origin)?;
317+
self.xkey.fmt(f)?;
318+
fmt_derivation_paths(f, self.derivation_paths.paths())?;
319+
match self.wildcard {
320+
Wildcard::None => {}
321+
Wildcard::Unhardened => write!(f, "/*")?,
322+
Wildcard::Hardened => write!(f, "/*h")?,
323+
}
324+
Ok(())
325+
}
326+
}
327+
313328
impl fmt::Display for DescriptorPublicKey {
314329
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
315330
match *self {
316331
DescriptorPublicKey::Single(ref pk) => pk.fmt(f),
317332
DescriptorPublicKey::XPub(ref xpub) => xpub.fmt(f),
318-
DescriptorPublicKey::MultiXPub(ref xpub) => {
319-
maybe_fmt_master_id(f, &xpub.origin)?;
320-
xpub.xkey.fmt(f)?;
321-
fmt_derivation_paths(f, xpub.derivation_paths.paths())?;
322-
match xpub.wildcard {
323-
Wildcard::None => {}
324-
Wildcard::Unhardened => write!(f, "/*")?,
325-
Wildcard::Hardened => write!(f, "/*h")?,
326-
}
327-
Ok(())
328-
}
333+
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.fmt(f),
329334
}
330335
}
331336
}
@@ -730,18 +735,45 @@ impl DescriptorInnerKey for DescriptorExtendedPublicKey {
730735
}
731736
}
732737

738+
impl DescriptorInnerKey for DescriptorMultiExtendedPublicKey {
739+
fn master_fingerprint(&self) -> bip32::Fingerprint {
740+
if let Some((fingerprint, _)) = self.origin {
741+
fingerprint
742+
} else {
743+
self.xkey.fingerprint()
744+
}
745+
}
746+
747+
fn full_derivation_path(&self) -> Option<bip32::DerivationPath> {
748+
None
749+
}
750+
751+
fn has_wildcard(&self) -> bool {
752+
self.wildcard != Wildcard::None
753+
}
754+
755+
fn at_derivation_index(self, _index: u32) -> Result<DefiniteDescriptorKey, ConversionError> {
756+
Err(ConversionError::MultiKey)
757+
}
758+
759+
fn is_multipath(&self) -> bool {
760+
true
761+
}
762+
763+
fn derive_public_key<C: Verification>(
764+
&self,
765+
_secp: &Secp256k1<C>,
766+
) -> Result<bitcoin::PublicKey, ConversionError> {
767+
Err(ConversionError::MultiKey)
768+
}
769+
}
770+
733771
impl DescriptorPublicKey {
734772
/// The fingerprint of the master key associated with this key, `0x00000000` if none.
735773
pub fn master_fingerprint(&self) -> bip32::Fingerprint {
736774
match *self {
737775
DescriptorPublicKey::XPub(ref xpub) => xpub.master_fingerprint(),
738-
DescriptorPublicKey::MultiXPub(ref xpub) => {
739-
if let Some((fingerprint, _)) = xpub.origin {
740-
fingerprint
741-
} else {
742-
xpub.xkey.fingerprint()
743-
}
744-
}
776+
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.master_fingerprint(),
745777
DescriptorPublicKey::Single(ref single) => single.master_fingerprint(),
746778
}
747779
}
@@ -757,7 +789,7 @@ impl DescriptorPublicKey {
757789
match *self {
758790
DescriptorPublicKey::XPub(ref xpub) => xpub.full_derivation_path(),
759791
DescriptorPublicKey::Single(ref single) => single.full_derivation_path(),
760-
DescriptorPublicKey::MultiXPub(_) => None,
792+
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.full_derivation_path(),
761793
}
762794
}
763795

@@ -772,7 +804,7 @@ impl DescriptorPublicKey {
772804
match *self {
773805
DescriptorPublicKey::Single(ref single) => single.has_wildcard(),
774806
DescriptorPublicKey::XPub(ref xpub) => xpub.has_wildcard(),
775-
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.wildcard != Wildcard::None,
807+
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.has_wildcard(),
776808
}
777809
}
778810

@@ -798,7 +830,7 @@ impl DescriptorPublicKey {
798830
match self {
799831
DescriptorPublicKey::Single(single) => single.at_derivation_index(index),
800832
DescriptorPublicKey::XPub(xpub) => xpub.at_derivation_index(index),
801-
DescriptorPublicKey::MultiXPub(_) => Err(ConversionError::MultiKey),
833+
DescriptorPublicKey::MultiXPub(xpub) => xpub.at_derivation_index(index),
802834
}
803835
}
804836

@@ -807,7 +839,7 @@ impl DescriptorPublicKey {
807839
match self {
808840
DescriptorPublicKey::Single(single) => single.is_multipath(),
809841
DescriptorPublicKey::XPub(xpub) => xpub.is_multipath(),
810-
DescriptorPublicKey::MultiXPub(_) => true,
842+
DescriptorPublicKey::MultiXPub(xpub) => xpub.is_multipath(),
811843
}
812844
}
813845

@@ -1181,9 +1213,7 @@ impl DefiniteDescriptorKey {
11811213
match self.0 {
11821214
DescriptorPublicKey::Single(ref pk) => pk.derive_public_key(secp),
11831215
DescriptorPublicKey::XPub(ref xpk) => xpk.derive_public_key(secp),
1184-
DescriptorPublicKey::MultiXPub(_) => {
1185-
unreachable!("A definite key cannot contain a multipath key.")
1186-
}
1216+
DescriptorPublicKey::MultiXPub(ref xpk) => xpk.derive_public_key(secp),
11871217
}
11881218
}
11891219

0 commit comments

Comments
 (0)