diff --git a/bitcoin/src/address/error.rs b/bitcoin/src/address/error.rs index 0bddd213..c522656e 100644 --- a/bitcoin/src/address/error.rs +++ b/bitcoin/src/address/error.rs @@ -13,8 +13,6 @@ use crate::{base58, Network}; #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] pub enum Error { - /// Address size more than 520 bytes is not allowed. - ExcessiveScriptSize, /// Address's network differs from required one. NetworkValidation { /// Network that was required. @@ -31,7 +29,6 @@ impl fmt::Display for Error { use Error::*; match *self { - ExcessiveScriptSize => write!(f, "script size exceed 520 bytes"), NetworkValidation { required, ref address } => { write!(f, "address ")?; fmt::Display::fmt(&address.0, f)?; @@ -47,15 +44,16 @@ impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { use Error::*; - match self { - UnknownHrp(e) => Some(e), - ExcessiveScriptSize | NetworkValidation { .. } => None, + match *self { + UnknownHrp(ref e) => Some(e), + NetworkValidation { .. } => None, } } } /// Error while generating address from script. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub enum FromScriptError { /// Script is not a p2pkh, p2sh or witness program. UnrecognizedScript, @@ -82,20 +80,49 @@ impl std::error::Error for FromScriptError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { use FromScriptError::*; - match self { - WitnessVersion(e) => Some(e), - WitnessProgram(e) => Some(e), + match *self { UnrecognizedScript => None, + WitnessVersion(ref e) => Some(e), + WitnessProgram(ref e) => Some(e), } } } impl From for FromScriptError { - fn from(e : witness_program::Error) -> Self { FromScriptError::WitnessProgram(e)} + fn from(e : witness_program::Error) -> Self { Self::WitnessProgram(e) } } impl From for FromScriptError { - fn from(e: witness_version::TryFromError) -> Self { FromScriptError::WitnessVersion(e) } + fn from(e: witness_version::TryFromError) -> Self { Self::WitnessVersion(e) } +} + +/// Error while generating address from a p2sh script. +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] +pub enum P2shError { + /// Address size more than 520 bytes is not allowed. + ExcessiveScriptSize, +} + +impl fmt::Display for P2shError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use P2shError::*; + + match *self { + ExcessiveScriptSize => write!(f, "script size exceed 520 bytes"), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for P2shError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use P2shError::*; + + match self { + ExcessiveScriptSize => None, + } + } } /// Address type is either invalid or not supported in rust-bitcoin. diff --git a/bitcoin/src/address/mod.rs b/bitcoin/src/address/mod.rs index 4059853d..a8e058e6 100644 --- a/bitcoin/src/address/mod.rs +++ b/bitcoin/src/address/mod.rs @@ -51,6 +51,7 @@ use crate::network::{Network, NetworkKind}; use crate::prelude::*; use crate::taproot::TapNodeHash; +use self::error::P2shError; #[rustfmt::skip] // Keep public re-exports separate. #[doc(inline)] pub use self::{ @@ -373,9 +374,9 @@ impl Address { /// This address type was introduced with BIP16 and is the popular type to implement multi-sig /// these days. #[inline] - pub fn p2sh(script: &Script, network: impl Into) -> Result { + pub fn p2sh(script: &Script, network: impl Into) -> Result { if script.len() > MAX_SCRIPT_ELEMENT_SIZE { - return Err(Error::ExcessiveScriptSize); + return Err(P2shError::ExcessiveScriptSize); } let hash = script.script_hash(); Ok(Address::p2sh_from_hash(hash, network)) @@ -861,7 +862,7 @@ mod tests { #[test] fn test_p2sh_parse_for_large_script() { let script = ScriptBuf::from_hex("552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123").unwrap(); - assert_eq!(Address::p2sh(&script, NetworkKind::Test), Err(Error::ExcessiveScriptSize)); + assert_eq!(Address::p2sh(&script, NetworkKind::Test), Err(P2shError::ExcessiveScriptSize)); } #[test]