Merge rust-bitcoin/rust-bitcoin#1091: Add custom error for invalid parsing of address types

19ba7ecc03 Add custom error for unknown address type parsing (Arturo Marquez)

Pull request description:

  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, since it contains the `String` that tried to be parsed.

  Closes https://github.com/rust-bitcoin/rust-bitcoin/issues/1064

ACKs for top commit:
  Kixunil:
    ACK 19ba7ecc03
  dunxen:
    ACK 19ba7ec
  tcharding:
    ACK 19ba7ecc03
  apoelstra:
    ACK 19ba7ecc03

Tree-SHA512: 2f94eb2e122c1acafcb8c852f7bfe22cb3725806541ae40f82d3a882011fb911ce8fc430153ebea4066f43c5a51813359a4c9b95d2a9077ce8f6dcaa58eee6fd
This commit is contained in:
Andrew Poelstra 2022-07-12 01:17:20 +00:00
commit 3f27131823
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 21 additions and 4 deletions

View File

@ -75,6 +75,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 {
@ -91,7 +93,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),
}
}
}
@ -114,7 +117,8 @@ impl std::error::Error for Error {
| InvalidSegwitV0ProgramLength(_)
| UncompressedPubkey
| ExcessiveScriptSize
| UnrecognizedScript => None,
| UnrecognizedScript
| UnknownAddressType(_) => None,
}
}
}
@ -162,7 +166,7 @@ impl fmt::Display for AddressType {
}
impl FromStr for AddressType {
type Err = ();
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"p2pkh" => Ok(AddressType::P2pkh),
@ -170,7 +174,7 @@ impl FromStr for AddressType {
"p2wpkh" => Ok(AddressType::P2wpkh),
"p2wsh" => Ok(AddressType::P2wsh),
"p2tr" => Ok(AddressType::P2tr),
_ => Err(()),
_ => Err(Error::UnknownAddressType(s.to_owned())),
}
}
}
@ -1500,4 +1504,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);
}
}