Skip to content

Commit 60732fb

Browse files
committed
desc keys: make origin key parsing a standalone function
It didn't need to be a method of an extended public key, especially not since non-extended keys can have an origin too.
1 parent fd9ef55 commit 60732fb

File tree

1 file changed

+50
-53
lines changed

1 file changed

+50
-53
lines changed

src/descriptor/key.rs

Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ impl FromStr for DescriptorPublicKey {
304304
));
305305
}
306306

307-
let (key_part, origin) = DescriptorXKey::<bip32::ExtendedPubKey>::parse_xkey_origin(s)?;
307+
let (key_part, origin) = parse_xkey_origin(s)?;
308308

309309
if key_part.contains("pub") {
310310
let (xpub, derivation_path, wildcard) =
@@ -491,7 +491,7 @@ impl FromStr for DescriptorSecretKey {
491491
type Err = DescriptorKeyParseError;
492492

493493
fn from_str(s: &str) -> Result<Self, Self::Err> {
494-
let (key_part, origin) = DescriptorXKey::<bip32::ExtendedPubKey>::parse_xkey_origin(s)?;
494+
let (key_part, origin) = parse_xkey_origin(s)?;
495495

496496
if key_part.len() <= 52 {
497497
let sk = bitcoin::PrivateKey::from_str(key_part)
@@ -513,64 +513,61 @@ impl FromStr for DescriptorSecretKey {
513513
}
514514
}
515515

516-
impl<K: InnerXKey> DescriptorXKey<K> {
517-
fn parse_xkey_origin(
518-
s: &str,
519-
) -> Result<(&str, Option<bip32::KeySource>), DescriptorKeyParseError> {
520-
for ch in s.as_bytes() {
521-
if *ch < 20 || *ch > 127 {
522-
return Err(DescriptorKeyParseError(
523-
"Encountered an unprintable character",
524-
));
525-
}
516+
// Parse the origin information part of a descriptor key.
517+
fn parse_xkey_origin(s: &str) -> Result<(&str, Option<bip32::KeySource>), DescriptorKeyParseError> {
518+
for ch in s.as_bytes() {
519+
if *ch < 20 || *ch > 127 {
520+
return Err(DescriptorKeyParseError(
521+
"Encountered an unprintable character",
522+
));
526523
}
524+
}
525+
526+
if s.is_empty() {
527+
return Err(DescriptorKeyParseError("Empty key"));
528+
}
529+
let mut parts = s[1..].split(']');
530+
531+
if let Some('[') = s.chars().next() {
532+
let mut raw_origin = parts
533+
.next()
534+
.ok_or(DescriptorKeyParseError("Unclosed '['"))?
535+
.split('/');
536+
537+
let origin_id_hex = raw_origin.next().ok_or(DescriptorKeyParseError(
538+
"No master fingerprint found after '['",
539+
))?;
527540

528-
if s.is_empty() {
529-
return Err(DescriptorKeyParseError("Empty key"));
541+
if origin_id_hex.len() != 8 {
542+
return Err(DescriptorKeyParseError(
543+
"Master fingerprint should be 8 characters long",
544+
));
530545
}
531-
let mut parts = s[1..].split(']');
532-
533-
if let Some('[') = s.chars().next() {
534-
let mut raw_origin = parts
535-
.next()
536-
.ok_or(DescriptorKeyParseError("Unclosed '['"))?
537-
.split('/');
538-
539-
let origin_id_hex = raw_origin.next().ok_or(DescriptorKeyParseError(
540-
"No master fingerprint found after '['",
541-
))?;
542-
543-
if origin_id_hex.len() != 8 {
544-
return Err(DescriptorKeyParseError(
545-
"Master fingerprint should be 8 characters long",
546-
));
547-
}
548-
let parent_fingerprint = bip32::Fingerprint::from_hex(origin_id_hex).map_err(|_| {
549-
DescriptorKeyParseError("Malformed master fingerprint, expected 8 hex chars")
550-
})?;
551-
let origin_path = raw_origin
552-
.map(bip32::ChildNumber::from_str)
553-
.collect::<Result<bip32::DerivationPath, bip32::Error>>()
554-
.map_err(|_| {
555-
DescriptorKeyParseError("Error while parsing master derivation path")
556-
})?;
557-
558-
let key = parts
559-
.next()
560-
.ok_or(DescriptorKeyParseError("No key after origin."))?;
561-
562-
if parts.next().is_some() {
563-
Err(DescriptorKeyParseError(
564-
"Multiple ']' in Descriptor Public Key",
565-
))
566-
} else {
567-
Ok((key, Some((parent_fingerprint, origin_path))))
568-
}
546+
let parent_fingerprint = bip32::Fingerprint::from_hex(origin_id_hex).map_err(|_| {
547+
DescriptorKeyParseError("Malformed master fingerprint, expected 8 hex chars")
548+
})?;
549+
let origin_path = raw_origin
550+
.map(bip32::ChildNumber::from_str)
551+
.collect::<Result<bip32::DerivationPath, bip32::Error>>()
552+
.map_err(|_| DescriptorKeyParseError("Error while parsing master derivation path"))?;
553+
554+
let key = parts
555+
.next()
556+
.ok_or(DescriptorKeyParseError("No key after origin."))?;
557+
558+
if parts.next().is_some() {
559+
Err(DescriptorKeyParseError(
560+
"Multiple ']' in Descriptor Public Key",
561+
))
569562
} else {
570-
Ok((s, None))
563+
Ok((key, Some((parent_fingerprint, origin_path))))
571564
}
565+
} else {
566+
Ok((s, None))
572567
}
568+
}
573569

570+
impl<K: InnerXKey> DescriptorXKey<K> {
574571
/// Parse an extended key concatenated to a derivation path.
575572
fn parse_xkey_deriv(
576573
key_deriv: &str,

0 commit comments

Comments
 (0)