Skip to content

Commit fa4dabb

Browse files
author
Scott Robinson
committed
Extract specialised DescriptorPublicKey functionality into DescriptorSinglePublicKey
1 parent 151543c commit fa4dabb

File tree

1 file changed

+72
-41
lines changed

1 file changed

+72
-41
lines changed

src/descriptor/key.rs

+72-41
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::prelude::*;
1818
use crate::serde::{Deserialize, Deserializer, Serialize, Serializer};
1919
use crate::{hash256, MiniscriptKey, ToPublicKey};
2020

21+
type DescriptorSinglePublicKey = SinglePub;
2122
type DescriptorExtendedPublicKey = DescriptorXKey<bip32::ExtendedPubKey>;
2223

2324
/// The descriptor pubkey, either a single pubkey or an xpub.
@@ -285,6 +286,16 @@ impl error::Error for DescriptorKeyParseError {
285286
}
286287
}
287288

289+
impl fmt::Display for DescriptorSinglePublicKey {
290+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
291+
maybe_fmt_master_id(f, &self.origin)?;
292+
match self.key {
293+
SinglePubKey::FullKey(full_key) => full_key.fmt(f),
294+
SinglePubKey::XOnly(x_only_key) => x_only_key.fmt(f),
295+
}
296+
}
297+
}
298+
288299
impl fmt::Display for DescriptorExtendedPublicKey {
289300
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
290301
maybe_fmt_master_id(f, &self.origin)?;
@@ -302,14 +313,7 @@ impl fmt::Display for DescriptorExtendedPublicKey {
302313
impl fmt::Display for DescriptorPublicKey {
303314
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
304315
match *self {
305-
DescriptorPublicKey::Single(ref pk) => {
306-
maybe_fmt_master_id(f, &pk.origin)?;
307-
match pk.key {
308-
SinglePubKey::FullKey(full_key) => full_key.fmt(f),
309-
SinglePubKey::XOnly(x_only_key) => x_only_key.fmt(f),
310-
}?;
311-
Ok(())
312-
}
316+
DescriptorPublicKey::Single(ref pk) => pk.fmt(f),
313317
DescriptorPublicKey::XPub(ref xpub) => xpub.fmt(f),
314318
DescriptorPublicKey::MultiXPub(ref xpub) => {
315319
maybe_fmt_master_id(f, &xpub.origin)?;
@@ -582,6 +586,60 @@ pub trait DescriptorInnerKey {
582586
) -> Result<bitcoin::PublicKey, ConversionError>;
583587
}
584588

589+
impl DescriptorInnerKey for DescriptorSinglePublicKey {
590+
fn master_fingerprint(&self) -> bip32::Fingerprint {
591+
if let Some((fingerprint, _)) = self.origin {
592+
fingerprint
593+
} else {
594+
let mut engine = XpubIdentifier::engine();
595+
match self.key {
596+
SinglePubKey::FullKey(pk) => {
597+
pk.write_into(&mut engine).expect("engines don't error")
598+
}
599+
SinglePubKey::XOnly(x_only_pk) => engine.input(&x_only_pk.serialize()),
600+
};
601+
bip32::Fingerprint::from(
602+
&XpubIdentifier::from_engine(engine)[..4]
603+
.try_into()
604+
.expect("4 byte slice"),
605+
)
606+
}
607+
}
608+
609+
fn full_derivation_path(&self) -> Option<bip32::DerivationPath> {
610+
Some(if let Some((_, ref path)) = self.origin {
611+
path.clone()
612+
} else {
613+
bip32::DerivationPath::from(vec![])
614+
})
615+
}
616+
617+
fn has_wildcard(&self) -> bool {
618+
false
619+
}
620+
621+
fn at_derivation_index(self, _index: u32) -> Result<DefiniteDescriptorKey, ConversionError> {
622+
Ok(
623+
DefiniteDescriptorKey::new(DescriptorPublicKey::Single(self))
624+
.expect("The key should not contain any wildcards at this point"),
625+
)
626+
}
627+
628+
fn is_multipath(&self) -> bool {
629+
false
630+
}
631+
632+
fn derive_public_key<C: Verification>(
633+
&self,
634+
_secp: &Secp256k1<C>,
635+
) -> Result<bitcoin::PublicKey, ConversionError> {
636+
match self.key {
637+
SinglePubKey::FullKey(pk) => Ok(pk),
638+
SinglePubKey::XOnly(xpk) => Ok(xpk.to_public_key()),
639+
}
640+
}
641+
}
642+
585643
impl DescriptorInnerKey for DescriptorExtendedPublicKey {
586644
/// The fingerprint of the master key associated with this key, `0x00000000` if none.
587645
fn master_fingerprint(&self) -> bip32::Fingerprint {
@@ -684,24 +742,7 @@ impl DescriptorPublicKey {
684742
xpub.xkey.fingerprint()
685743
}
686744
}
687-
DescriptorPublicKey::Single(ref single) => {
688-
if let Some((fingerprint, _)) = single.origin {
689-
fingerprint
690-
} else {
691-
let mut engine = XpubIdentifier::engine();
692-
match single.key {
693-
SinglePubKey::FullKey(pk) => {
694-
pk.write_into(&mut engine).expect("engines don't error")
695-
}
696-
SinglePubKey::XOnly(x_only_pk) => engine.input(&x_only_pk.serialize()),
697-
};
698-
bip32::Fingerprint::from(
699-
&XpubIdentifier::from_engine(engine)[..4]
700-
.try_into()
701-
.expect("4 byte slice"),
702-
)
703-
}
704-
}
745+
DescriptorPublicKey::Single(ref single) => single.master_fingerprint(),
705746
}
706747
}
707748

@@ -715,13 +756,7 @@ impl DescriptorPublicKey {
715756
pub fn full_derivation_path(&self) -> Option<bip32::DerivationPath> {
716757
match *self {
717758
DescriptorPublicKey::XPub(ref xpub) => xpub.full_derivation_path(),
718-
DescriptorPublicKey::Single(ref single) => {
719-
Some(if let Some((_, ref path)) = single.origin {
720-
path.clone()
721-
} else {
722-
bip32::DerivationPath::from(vec![])
723-
})
724-
}
759+
DescriptorPublicKey::Single(ref single) => single.full_derivation_path(),
725760
DescriptorPublicKey::MultiXPub(_) => None,
726761
}
727762
}
@@ -735,7 +770,7 @@ impl DescriptorPublicKey {
735770
/// Whether or not the key has a wildcard
736771
pub fn has_wildcard(&self) -> bool {
737772
match *self {
738-
DescriptorPublicKey::Single(..) => false,
773+
DescriptorPublicKey::Single(ref single) => single.has_wildcard(),
739774
DescriptorPublicKey::XPub(ref xpub) => xpub.has_wildcard(),
740775
DescriptorPublicKey::MultiXPub(ref xpub) => xpub.wildcard != Wildcard::None,
741776
}
@@ -761,8 +796,7 @@ impl DescriptorPublicKey {
761796
/// - If `index` is hardened.
762797
pub fn at_derivation_index(self, index: u32) -> Result<DefiniteDescriptorKey, ConversionError> {
763798
match self {
764-
DescriptorPublicKey::Single(_) => Ok(DefiniteDescriptorKey::new(self)
765-
.expect("The key should not contain any wildcards at this point")),
799+
DescriptorPublicKey::Single(single) => single.at_derivation_index(index),
766800
DescriptorPublicKey::XPub(xpub) => xpub.at_derivation_index(index),
767801
DescriptorPublicKey::MultiXPub(_) => Err(ConversionError::MultiKey),
768802
}
@@ -771,7 +805,7 @@ impl DescriptorPublicKey {
771805
/// Whether or not this key has multiple derivation paths.
772806
pub fn is_multipath(&self) -> bool {
773807
match self {
774-
DescriptorPublicKey::Single(..) => false,
808+
DescriptorPublicKey::Single(single) => single.is_multipath(),
775809
DescriptorPublicKey::XPub(xpub) => xpub.is_multipath(),
776810
DescriptorPublicKey::MultiXPub(_) => true,
777811
}
@@ -1145,10 +1179,7 @@ impl DefiniteDescriptorKey {
11451179
secp: &Secp256k1<C>,
11461180
) -> Result<bitcoin::PublicKey, ConversionError> {
11471181
match self.0 {
1148-
DescriptorPublicKey::Single(ref pk) => match pk.key {
1149-
SinglePubKey::FullKey(pk) => Ok(pk),
1150-
SinglePubKey::XOnly(xpk) => Ok(xpk.to_public_key()),
1151-
},
1182+
DescriptorPublicKey::Single(ref pk) => pk.derive_public_key(secp),
11521183
DescriptorPublicKey::XPub(ref xpk) => xpk.derive_public_key(secp),
11531184
DescriptorPublicKey::MultiXPub(_) => {
11541185
unreachable!("A definite key cannot contain a multipath key.")

0 commit comments

Comments
 (0)