Merge rust-bitcoin/rust-bitcoin#6870: crypto: Flatten nested error constructors
What changed, and why it matters
This commit is a code cleanup that rewrites how errors are wrapped in the Bitcoin crypto library. It changes nested error constructors into chained map_err calls but keeps the exact same error values and public behavior. There is no security-relevant change.
No action required. This is a non-security refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch flattens nested error construction patterns (e.g., .map_err(|| OuterError(InnerError)) into .map_err(|| InnerError).map_err(OuterError)) across ecdsa.rs, key.rs, and taproot.rs. The PR description explicitly states it preserves exact error values, intentional source-error discarding, and public APIs. No logic, parsing rules, or cryptographic checks are altered.
Changed components
crypto/src/ecdsa.rscrypto/src/key.rscrypto/src/taproot.rsInspect captured patch +15 / −15
### crypto/src/ecdsa.rs
@@ -70,7 +70,8 @@ impl Signature {
let (sighash_type, sig) = sl.split_last().ok_or(DecodeError::EmptySignature)?;
let sighash_type = EcdsaSighashType::from_consensus(u32::from(*sighash_type));
let signature = secp256k1::ecdsa::Signature::from_der(sig)
- .map_err(|_| DecodeError::InvalidDer(InvalidDerError))?;
+ .map_err(|_| InvalidDerError)
+ .map_err(DecodeError::InvalidDer)?;
Ok(Self { signature, sighash_type })
}
### crypto/src/key.rs
@@ -792,7 +792,8 @@ impl LegacyPublicKey {
}
let secp_key = secp256k1::PublicKey::from_slice(data)
- .map_err(|_| FromSliceError::InvalidPublicKey(InvalidPublicKeyError))?;
+ .map_err(|_| InvalidPublicKeyError)
+ .map_err(FromSliceError::InvalidPublicKey)?;
Ok(match compressed {
true => Self::from_secp(secp_key),
false => Self::from_secp_uncompressed(secp_key),
@@ -1093,7 +1094,8 @@ impl PrivateKey {
pub fn from_secret_bytes(data: &[u8; 32]) -> Result<Self, FromSecretBytesError> {
secp256k1::SecretKey::from_secret_bytes(*data)
.map(Self::from_secp)
- .map_err(|_| FromSecretBytesError(FromSecretBytesErrorInner::InvalidSecretKey))
+ .map_err(|_| FromSecretBytesErrorInner::InvalidSecretKey)
+ .map_err(FromSecretBytesError)
}
/// Deserializes a private key from a slice.
@@ -1213,9 +1215,8 @@ impl WifKey {
base58::decode_check_to_array::<34>(wif).map_err(FromWifError::Base58)?;
let (compressed_flag, data) = data.split_last::<33>();
if *compressed_flag != 1 {
- return Err(FromWifError::InvalidWifCompressionFlag(
- InvalidWifCompressionFlagError { invalid: *compressed_flag },
- ));
+ return Err(InvalidWifCompressionFlagError { invalid: *compressed_flag })
+ .map_err(FromWifError::InvalidWifCompressionFlag);
}
Ok((true, *data))
@@ -1226,17 +1227,15 @@ impl WifKey {
128 => NetworkKind::Main,
239 => NetworkKind::Test,
invalid => {
- return Err(FromWifError::InvalidAddressVersion(InvalidAddressVersionError {
- invalid,
- }));
+ return Err(InvalidAddressVersionError { invalid })
+ .map_err(FromWifError::InvalidAddressVersion);
}
};
- let sec_key = secp256k1::SecretKey::from_secret_bytes(*key).map_err(|_| {
- FromWifError::FromSecretBytes(FromSecretBytesError(
- FromSecretBytesErrorInner::InvalidSecretKey,
- ))
- })?;
+ let sec_key = secp256k1::SecretKey::from_secret_bytes(*key)
+ .map_err(|_| FromSecretBytesErrorInner::InvalidSecretKey)
+ .map_err(FromSecretBytesError)
+ .map_err(FromWifError::FromSecretBytes)?;
let priv_key = match compressed {
true => PrivateKey::from_secp(sec_key),
false => PrivateKey::from_secp_uncompressed(sec_key),
### crypto/src/taproot.rs
@@ -63,7 +63,7 @@ impl Signature {
// per BIP-341: if the sig is 65 bytes long, return Fail if sig[64] = 0x00
// https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#taproot-key-path-spending-signature-validation
if sighash_type == TapSighashType::Default {
- return Err(SigFromSliceError::SighashType(InvalidSighashTypeError(0)));
+ return Err(InvalidSighashTypeError(0)).map_err(SigFromSliceError::SighashType);
}
let signature = secp256k1::schnorr::Signature::from_byte_array(*signature);
Ok(Self { signature, sighash_type })Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.