From 19ba7ecc03c11e31e127c35556251405c887638e Mon Sep 17 00:00:00 2001 From: Arturo Marquez Date: Sun, 10 Jul 2022 16:25:28 -0500 Subject: [PATCH] Add custom error for unknown address type parsing Adds a custom error `UnknownAddressType(_)` which is returned in cases where an unknown address type tries to be parsed via `FromStr`. This provides more context for the error. For more info see [1]. [1] - `https://github.com/rust-bitcoin/rust-bitcoin/issues/1064` --- src/util/address.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/util/address.rs b/src/util/address.rs index f7be7f9a..ee63856d 100644 --- a/src/util/address.rs +++ b/src/util/address.rs @@ -85,6 +85,8 @@ pub enum Error { ExcessiveScriptSize, /// Script is not a p2pkh, p2sh or witness program. UnrecognizedScript, + /// Address type is either invalid or not supported in rust-bitcoin. + UnknownAddressType(String), } impl fmt::Display for Error { @@ -101,7 +103,8 @@ impl fmt::Display for Error { Error::InvalidSegwitV0ProgramLength(l) => write!(f, "a v0 witness program must be either of length 20 or 32 bytes: length={}", l), Error::UncompressedPubkey => write!(f, "an uncompressed pubkey was used where it is not allowed"), Error::ExcessiveScriptSize => write!(f, "script size exceed 520 bytes"), - Error::UnrecognizedScript => write!(f, "script is not a p2pkh, p2sh or witness program") + Error::UnrecognizedScript => write!(f, "script is not a p2pkh, p2sh or witness program"), + Error::UnknownAddressType(ref s) => write!(f, "unknown address type: '{}' is either invalid or not supported in rust-bitcoin", s), } } } @@ -124,7 +127,8 @@ impl std::error::Error for Error { | InvalidSegwitV0ProgramLength(_) | UncompressedPubkey | ExcessiveScriptSize - | UnrecognizedScript => None, + | UnrecognizedScript + | UnknownAddressType(_) => None, } } } @@ -172,7 +176,7 @@ impl fmt::Display for AddressType { } impl FromStr for AddressType { - type Err = (); + type Err = Error; fn from_str(s: &str) -> Result { match s { "p2pkh" => Ok(AddressType::P2pkh), @@ -180,7 +184,7 @@ impl FromStr for AddressType { "p2wpkh" => Ok(AddressType::P2wpkh), "p2wsh" => Ok(AddressType::P2wsh), "p2tr" => Ok(AddressType::P2tr), - _ => Err(()), + _ => Err(Error::UnknownAddressType(s.to_owned())), } } } @@ -1510,4 +1514,17 @@ mod tests { assert_eq!(Address::from_script(&bad_p2wsh, Network::Bitcoin), expected); assert_eq!(Address::from_script(&invalid_segwitv0_script, Network::Bitcoin), Err(Error::InvalidSegwitV0ProgramLength(17))); } + + #[test] + fn valid_address_parses_correctly() { + let addr = AddressType::from_str("p2tr").expect("false negative while parsing address"); + assert_eq!(addr, AddressType::P2tr); + } + + #[test] + fn invalid_address_parses_error() { + let got = AddressType::from_str("invalid"); + let want = Err(Error::UnknownAddressType("invalid".to_string())); + assert_eq!(got, want); + } }