Merge rust-bitcoin/rust-bitcoin#3045: Remove `bech32` from `address::ParseError`

9a7b1c232b Wrap the bech32 decoding error (Tobin C. Harding)

Pull request description:

  In #2381 we attempted to fully encapsulate the `bech32` crate to help with stabalizing `rust-bitcoin` however we failed to notice the `address:ParseError` has a variant that includes `bech32`. Public enums have public variant internals in Rust. Also the `From<bech32::segtiw::DecodeError` makes `bech32` public.

  Closes: #3043

ACKs for top commit:
  apoelstra:
    ACK 9a7b1c232b494dccdce091a46d916cc411a612a1; successfully ran local tests; will one-ACK merge since this is a gazillion years old and obviously right

Tree-SHA512: b5053aa43107aa47da1fe7e7db0f882cfb231b9769a7b67d8c930532c471df191f588bf98f2b00cc76d5a2e9c74e035ee96128da115363ac3952f96a766494ea
This commit is contained in:
merge-script 2024-10-28 18:15:38 +00:00
commit 4bd820b8cc
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
2 changed files with 22 additions and 7 deletions

View File

@ -166,7 +166,7 @@ impl std::error::Error for NetworkValidationError {}
#[non_exhaustive]
pub enum Bech32Error {
/// Parse segwit Bech32 error.
ParseBech32(bech32::segwit::DecodeError),
ParseBech32(ParseBech32Error),
/// A witness version conversion/parsing error.
WitnessVersion(witness_version::TryFromError),
/// A witness program error.
@ -204,10 +204,6 @@ impl std::error::Error for Bech32Error {
}
}
impl From<bech32::segwit::DecodeError> for Bech32Error {
fn from(e: bech32::segwit::DecodeError) -> Self { Self::ParseBech32(e) }
}
impl From<witness_version::TryFromError> for Bech32Error {
fn from(e: witness_version::TryFromError) -> Self { Self::WitnessVersion(e) }
}
@ -220,6 +216,24 @@ impl From<UnknownHrpError> for Bech32Error {
fn from(e: UnknownHrpError) -> Self { Self::UnknownHrp(e) }
}
/// Bech32 parsing related error.
// This wrapper exists because we do not want to expose the `bech32` crate in our public API.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseBech32Error(pub(crate) bech32::segwit::DecodeError);
internals::impl_from_infallible!(ParseBech32Error);
impl fmt::Display for ParseBech32Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write_err!(f, "bech32 parsing error"; self.0)
}
}
#[cfg(feature = "std")]
impl std::error::Error for ParseBech32Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
}
/// Base58 related error.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]

View File

@ -61,7 +61,7 @@ use crate::taproot::TapNodeHash;
pub use self::error::{
Base58Error, Bech32Error, FromScriptError, InvalidBase58PayloadLengthError,
InvalidLegacyPrefixError, LegacyAddressTooLongError, NetworkValidationError,
ParseError, UnknownAddressTypeError, UnknownHrpError
ParseError, UnknownAddressTypeError, UnknownHrpError, ParseBech32Error,
};
/// The different types of addresses.
@ -803,7 +803,8 @@ impl Address<NetworkUnchecked> {
/// Parse a bech32 Address string
pub fn from_bech32_str(s: &str) -> Result<Address<NetworkUnchecked>, Bech32Error> {
let (hrp, witness_version, data) = bech32::segwit::decode(s)?;
let (hrp, witness_version, data) = bech32::segwit::decode(s)
.map_err(|e| Bech32Error::ParseBech32(ParseBech32Error(e)))?;
let version = WitnessVersion::try_from(witness_version.to_u8())?;
let program = WitnessProgram::new(version, &data)
.expect("bech32 guarantees valid program length for witness");