Skip to content

Commit bd5db6a

Browse files
committed
descriptor/key.rs: clean up error matching
This uses `Self::XYZ` when matching on errors, rather than writing out the full name or using wildcard imports (which are dangerous because the compiler may misinterpret typos as being variable names) (although there will be a warning and CI should fail). This also collapses a bunch of fmt impls to only write the top-level error, in cases where we weren't adding any useful context. (We should revisit these and produce rich errors which have line number information and so forth; and I believe the correct way to describe the errors is the opposite of what I've done, where we are supposed to provide context but NOT the underlying error which can be accessed by the .source() method. But this simplifies the code without making things worse and we can do a proper fix later.)
1 parent e5f50ab commit bd5db6a

File tree

1 file changed

+48
-73
lines changed

1 file changed

+48
-73
lines changed

src/descriptor/key.rs

Lines changed: 48 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -351,24 +351,22 @@ pub enum MalformedKeyDataKind {
351351

352352
impl fmt::Display for MalformedKeyDataKind {
353353
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354-
use MalformedKeyDataKind::*;
355-
356354
let err = match self {
357-
EmptyKey => "empty key",
358-
EncounteredUnprintableCharacter => "encountered an unprintable character",
359-
InvalidFullPublicKeyPrefix => "only full public keys with prefixes '02', '03' or '04' are allowed",
360-
InvalidMasterFingerprintLength => "master fingerprint should be 8 characters long",
361-
InvalidMultiIndexStep => "invalid multi index step in multipath descriptor",
362-
InvalidMultiXKeyDerivation => "can't make a multi-xpriv with hardened derivation steps that are not shared among all paths into a public key",
363-
InvalidPublicKeyLength => "public keys must be 64, 66 or 130 characters in size",
364-
InvalidWildcardInDerivationPath => "'*' may only appear as last element in a derivation path",
365-
KeyTooShort => "key too short",
366-
MultipleFingerprintsInPublicKey => "multiple ']' in Descriptor Public Key",
367-
MultipleDerivationPathIndexSteps => "'<' may only appear once in a derivation path",
368-
NoKeyAfterOrigin => "no key after origin",
369-
NoMasterFingerprintFound => "no master fingerprint found after '['",
370-
UnclosedSquareBracket => "unclosed '['",
371-
WildcardAsDerivedDescriptorKey => "cannot parse key with a wilcard as a DerivedDescriptorKey",
355+
Self::EmptyKey => "empty key",
356+
Self::EncounteredUnprintableCharacter => "encountered an unprintable character",
357+
Self::InvalidFullPublicKeyPrefix => "only full public keys with prefixes '02', '03' or '04' are allowed",
358+
Self::InvalidMasterFingerprintLength => "master fingerprint should be 8 characters long",
359+
Self::InvalidMultiIndexStep => "invalid multi index step in multipath descriptor",
360+
Self::InvalidMultiXKeyDerivation => "can't make a multi-xpriv with hardened derivation steps that are not shared among all paths into a public key",
361+
Self::InvalidPublicKeyLength => "public keys must be 64, 66 or 130 characters in size",
362+
Self::InvalidWildcardInDerivationPath => "'*' may only appear as last element in a derivation path",
363+
Self::KeyTooShort => "key too short",
364+
Self::MultipleFingerprintsInPublicKey => "multiple ']' in Descriptor Public Key",
365+
Self::MultipleDerivationPathIndexSteps => "'<' may only appear once in a derivation path",
366+
Self::NoKeyAfterOrigin => "no key after origin",
367+
Self::NoMasterFingerprintFound => "no master fingerprint found after '['",
368+
Self::UnclosedSquareBracket => "unclosed '['",
369+
Self::WildcardAsDerivedDescriptorKey => "cannot parse key with a wilcard as a DerivedDescriptorKey",
372370
};
373371

374372
f.write_str(err)
@@ -414,72 +412,54 @@ pub enum DescriptorKeyParseError {
414412
impl fmt::Display for DescriptorKeyParseError {
415413
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
416414
match self {
417-
DescriptorKeyParseError::Bip32Xpriv(err) => {
418-
write!(f, "error while parsing BIP32 Xpriv: {err}")
419-
}
420-
DescriptorKeyParseError::Bip32Xpub(err) => {
421-
write!(f, "error while parsing BIP32 Xpub: {err}")
422-
}
423-
DescriptorKeyParseError::DerivationIndexError { index, err } => {
424-
write!(f, "error while parsing derivation index '{index}': {err}")
425-
}
426-
DescriptorKeyParseError::DeriveHardenedKey(err) => {
427-
write!(f, "unable to derive the hardened steps: {err}")
428-
}
429-
DescriptorKeyParseError::MalformedKeyData(err) => {
430-
write!(f, "{err}")
431-
}
432-
DescriptorKeyParseError::MasterDerivationPath(err) => {
433-
write!(f, "error while parsing master derivation path: {err}")
434-
}
435-
DescriptorKeyParseError::MasterFingerprint { fingerprint, err } => {
436-
write!(f, "error while parsing master fingerprint '{fingerprint}': {err}")
437-
}
438-
DescriptorKeyParseError::FullPublicKey(err) => {
439-
write!(f, "error while parsing full public key: {err}")
415+
Self::Bip32Xpriv(err) => err.fmt(f),
416+
Self::Bip32Xpub(err) => err.fmt(f),
417+
Self::DerivationIndexError { index, err } => {
418+
write!(f, "at derivation index '{index}': {err}")
440419
}
441-
DescriptorKeyParseError::WifPrivateKey(err) => {
442-
write!(f, "error while parsing WIF private key: {err}")
443-
}
444-
DescriptorKeyParseError::XonlyPublicKey(err) => {
445-
write!(f, "error while parsing xonly public key: {err}")
420+
Self::DeriveHardenedKey(err) => err.fmt(f),
421+
Self::MalformedKeyData(err) => err.fmt(f),
422+
Self::MasterDerivationPath(err) => err.fmt(f),
423+
Self::MasterFingerprint { fingerprint, err } => {
424+
write!(f, "on master fingerprint '{fingerprint}': {err}")
446425
}
426+
Self::FullPublicKey(err) => err.fmt(f),
427+
Self::WifPrivateKey(err) => err.fmt(f),
428+
Self::XonlyPublicKey(err) => err.fmt(f),
447429
}
448430
}
449431
}
450432

451433
#[cfg(feature = "std")]
452434
impl error::Error for DescriptorKeyParseError {
453435
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
454-
use DescriptorKeyParseError::*;
455-
456436
match self {
457-
Bip32Xpriv(err)
458-
| Bip32Xpub(err)
459-
| DerivationIndexError { err, .. }
460-
| DeriveHardenedKey(err)
461-
| MasterDerivationPath(err) => Some(err),
462-
MasterFingerprint { err, .. } => Some(err),
463-
FullPublicKey(err) => Some(err),
464-
WifPrivateKey(err) => Some(err),
465-
XonlyPublicKey(err) => Some(err),
466-
MalformedKeyData(_) => None,
437+
Self::Bip32Xpriv(err)
438+
| Self::Bip32Xpub(err)
439+
| Self::DerivationIndexError { err, .. }
440+
| Self::DeriveHardenedKey(err)
441+
| Self::MasterDerivationPath(err) => Some(err),
442+
Self::MasterFingerprint { err, .. } => Some(err),
443+
Self::FullPublicKey(err) => Some(err),
444+
Self::WifPrivateKey(err) => Some(err),
445+
Self::XonlyPublicKey(err) => Some(err),
446+
Self::MalformedKeyData(_) => None,
467447
}
468448
}
469449
}
470450

471451
impl fmt::Display for DescriptorPublicKey {
472452
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
473453
match *self {
474-
DescriptorPublicKey::Single(ref pk) => {
454+
Self::Single(ref pk) => {
475455
maybe_fmt_master_id(f, &pk.origin)?;
476456
match pk.key {
477457
SinglePubKey::FullKey(full_key) => full_key.fmt(f),
478458
SinglePubKey::XOnly(x_only_key) => x_only_key.fmt(f),
479459
}?;
480460
Ok(())
481461
}
482-
DescriptorPublicKey::XPub(ref xpub) => {
462+
Self::XPub(ref xpub) => {
483463
maybe_fmt_master_id(f, &xpub.origin)?;
484464
xpub.xkey.fmt(f)?;
485465
fmt_derivation_path(f, &xpub.derivation_path)?;
@@ -490,7 +470,7 @@ impl fmt::Display for DescriptorPublicKey {
490470
}
491471
Ok(())
492472
}
493-
DescriptorPublicKey::MultiXPub(ref xpub) => {
473+
Self::MultiXPub(ref xpub) => {
494474
maybe_fmt_master_id(f, &xpub.origin)?;
495475
xpub.xkey.fmt(f)?;
496476
fmt_derivation_paths(f, xpub.derivation_paths.paths())?;
@@ -694,19 +674,17 @@ pub enum ConversionError {
694674
impl fmt::Display for ConversionError {
695675
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
696676
f.write_str(match *self {
697-
ConversionError::HardenedChild => "hardened child step in bip32 path",
698-
ConversionError::MultiKey => "multiple existing keys",
677+
Self::HardenedChild => "hardened child step in bip32 path",
678+
Self::MultiKey => "multiple existing keys",
699679
})
700680
}
701681
}
702682

703683
#[cfg(feature = "std")]
704684
impl error::Error for ConversionError {
705685
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
706-
use self::ConversionError::*;
707-
708686
match self {
709-
HardenedChild | MultiKey => None,
687+
Self::HardenedChild | Self::MultiKey => None,
710688
}
711689
}
712690
}
@@ -1399,14 +1377,14 @@ mod test {
13991377
let desc = "[NonHexor]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*";
14001378
assert_eq!(
14011379
DescriptorPublicKey::from_str(desc).unwrap_err().to_string(),
1402-
"error while parsing master fingerprint 'NonHexor': failed to parse hex digit"
1380+
"on master fingerprint 'NonHexor': failed to parse hex digit"
14031381
);
14041382

14051383
// And ones with invalid xpubs..
14061384
let desc = "[78412e3a]xpub1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaLcgJvLJuZZvRcEL/1/*";
14071385
assert_eq!(
14081386
DescriptorPublicKey::from_str(desc).unwrap_err().to_string(),
1409-
"error while parsing BIP32 Xpub: base58 encoding error"
1387+
"base58 encoding error"
14101388
);
14111389

14121390
// ..or invalid raw keys
@@ -1446,22 +1424,19 @@ mod test {
14461424
DescriptorSecretKey::from_str(secret_key)
14471425
.unwrap_err()
14481426
.to_string(),
1449-
"error while parsing BIP32 Xpriv: unknown version magic bytes: [4, 136, 178, 30]"
1427+
"unknown version magic bytes: [4, 136, 178, 30]"
14501428
);
14511429

14521430
// And ones with invalid fingerprints
14531431
let desc = "[NonHexor]tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/1/*";
14541432
assert_eq!(
14551433
DescriptorSecretKey::from_str(desc).unwrap_err().to_string(),
1456-
"error while parsing master fingerprint 'NonHexor': failed to parse hex digit"
1434+
"on master fingerprint 'NonHexor': failed to parse hex digit"
14571435
);
14581436

14591437
// ..or invalid raw keys
14601438
let desc = "[78412e3a]L32jTfVLei6BYTPUpwpJSkrHx8iL9GZzeErVS8y4Y/1/*";
1461-
assert_eq!(
1462-
DescriptorSecretKey::from_str(desc).unwrap_err().to_string(),
1463-
"error while parsing WIF private key: invalid base58"
1464-
);
1439+
assert_eq!(DescriptorSecretKey::from_str(desc).unwrap_err().to_string(), "invalid base58");
14651440
}
14661441

14671442
#[test]

0 commit comments

Comments
 (0)