Skip to content

Commit f611162

Browse files
committed
Fix unreachable code from calling derive_public_key
DescriptorPublicKey::derive_public_key API hit an unreachable line when executing. public_key.derive_public_key(&secp).unwrap_err(); This commit removes the API altogether and only exposes the method via `DefiniteDescriptorKey`. Unfortunately, non-wildcard users would need to pass a dummy value to .at_derivation_index to get this struct, but I think this is okay.
1 parent 2f1535e commit f611162

File tree

1 file changed

+27
-40
lines changed

1 file changed

+27
-40
lines changed

src/descriptor/key.rs

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -485,39 +485,6 @@ impl DescriptorPublicKey {
485485
DefiniteDescriptorKey::new(definite)
486486
.expect("The key should not contain any wildcards at this point")
487487
}
488-
489-
/// Computes the public key corresponding to this descriptor key.
490-
/// When deriving from an XOnlyPublicKey, it adds the default 0x02 y-coordinate
491-
/// and returns the obtained full [`bitcoin::PublicKey`]. All BIP32 derivations
492-
/// always return a compressed key
493-
///
494-
/// Will return an error if the descriptor key has any hardened derivation steps in its path. To
495-
/// avoid this error you should replace any such public keys first with [`translate_pk`].
496-
///
497-
/// [`translate_pk`]: crate::TranslatePk::translate_pk
498-
pub fn derive_public_key<C: Verification>(
499-
&self,
500-
secp: &Secp256k1<C>,
501-
) -> Result<bitcoin::PublicKey, ConversionError> {
502-
match *self {
503-
DescriptorPublicKey::Single(ref pk) => match pk.key {
504-
SinglePubKey::FullKey(pk) => Ok(pk),
505-
SinglePubKey::XOnly(xpk) => Ok(xpk.to_public_key()),
506-
},
507-
DescriptorPublicKey::XPub(ref xpk) => match xpk.wildcard {
508-
Wildcard::Unhardened | Wildcard::Hardened => {
509-
unreachable!("we've excluded this error case")
510-
}
511-
Wildcard::None => match xpk.xkey.derive_pub(secp, &xpk.derivation_path.as_ref()) {
512-
Ok(xpub) => Ok(bitcoin::PublicKey::new(xpub.public_key)),
513-
Err(bip32::Error::CannotDeriveFromHardenedKey) => {
514-
Err(ConversionError::HardenedChild)
515-
}
516-
Err(e) => unreachable!("cryptographically unreachable: {}", e),
517-
},
518-
},
519-
}
520-
}
521488
}
522489

523490
impl FromStr for DescriptorSecretKey {
@@ -763,17 +730,37 @@ impl MiniscriptKey for DescriptorPublicKey {
763730
}
764731

765732
impl DefiniteDescriptorKey {
766-
/// Computes the raw [`bitcoin::PublicKey`] for this descriptor key.
733+
/// Computes the public key corresponding to this descriptor key.
734+
/// When deriving from an XOnlyPublicKey, it adds the default 0x02 y-coordinate
735+
/// and returns the obtained full [`bitcoin::PublicKey`]. All BIP32 derivations
736+
/// always return a compressed key
767737
///
768-
/// Will return an error if the key has any hardened derivation steps
769-
/// in its path, but unlike [`DescriptorPublicKey::derive_public_key`]
770-
/// this won't error in case of wildcards, because derived keys are
771-
/// guaranteed to never contain one.
738+
/// Will return an error if the descriptor key has any hardened derivation steps in its path. To
739+
/// avoid this error you should replace any such public keys first with [`translate_pk`].
740+
///
741+
/// [`translate_pk`]: crate::TranslatePk::translate_pk
772742
pub fn derive_public_key<C: Verification>(
773743
&self,
774744
secp: &Secp256k1<C>,
775745
) -> Result<bitcoin::PublicKey, ConversionError> {
776-
self.0.derive_public_key(secp)
746+
match self.0 {
747+
DescriptorPublicKey::Single(ref pk) => match pk.key {
748+
SinglePubKey::FullKey(pk) => Ok(pk),
749+
SinglePubKey::XOnly(xpk) => Ok(xpk.to_public_key()),
750+
},
751+
DescriptorPublicKey::XPub(ref xpk) => match xpk.wildcard {
752+
Wildcard::Unhardened | Wildcard::Hardened => {
753+
unreachable!("we've excluded this error case")
754+
}
755+
Wildcard::None => match xpk.xkey.derive_pub(secp, &xpk.derivation_path.as_ref()) {
756+
Ok(xpub) => Ok(bitcoin::PublicKey::new(xpub.public_key)),
757+
Err(bip32::Error::CannotDeriveFromHardenedKey) => {
758+
Err(ConversionError::HardenedChild)
759+
}
760+
Err(e) => unreachable!("cryptographically unreachable: {}", e),
761+
},
762+
},
763+
}
777764
}
778765

779766
/// Construct an instance from a descriptor key and a derivation index
@@ -841,7 +828,7 @@ impl MiniscriptKey for DefiniteDescriptorKey {
841828
impl ToPublicKey for DefiniteDescriptorKey {
842829
fn to_public_key(&self) -> bitcoin::PublicKey {
843830
let secp = Secp256k1::verification_only();
844-
self.0.derive_public_key(&secp).unwrap()
831+
self.derive_public_key(&secp).unwrap()
845832
}
846833

847834
fn hash_to_hash160(hash: &Self) -> hash160::Hash {

0 commit comments

Comments
 (0)