2023-10-10 04:08:50 +00:00
|
|
|
//! Error code for the address module.
|
|
|
|
|
2023-08-04 00:07:59 +00:00
|
|
|
use core::fmt;
|
|
|
|
|
|
|
|
use internals::write_err;
|
|
|
|
|
|
|
|
use crate::address::{Address, NetworkUnchecked};
|
|
|
|
use crate::blockdata::script::{witness_program, witness_version};
|
|
|
|
use crate::prelude::String;
|
|
|
|
use crate::{base58, Network};
|
|
|
|
|
|
|
|
/// Address error.
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
|
|
#[non_exhaustive]
|
|
|
|
pub enum Error {
|
|
|
|
/// A witness version construction error.
|
|
|
|
WitnessVersion(witness_version::TryFromError),
|
|
|
|
/// A witness program error.
|
|
|
|
WitnessProgram(witness_program::Error),
|
|
|
|
/// An uncompressed pubkey was used where it is not allowed.
|
|
|
|
UncompressedPubkey,
|
|
|
|
/// Address size more than 520 bytes is not allowed.
|
|
|
|
ExcessiveScriptSize,
|
|
|
|
/// Script is not a p2pkh, p2sh or witness program.
|
|
|
|
UnrecognizedScript,
|
|
|
|
/// Address's network differs from required one.
|
|
|
|
NetworkValidation {
|
|
|
|
/// Network that was required.
|
|
|
|
required: Network,
|
|
|
|
/// Network on which the address was found to be valid.
|
|
|
|
found: Network,
|
|
|
|
/// The address itself
|
|
|
|
address: Address<NetworkUnchecked>,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2023-08-04 00:12:45 +00:00
|
|
|
use Error::*;
|
|
|
|
|
2023-08-04 00:07:59 +00:00
|
|
|
match *self {
|
2023-08-04 00:12:45 +00:00
|
|
|
WitnessVersion(ref e) => write_err!(f, "witness version construction error"; e),
|
|
|
|
WitnessProgram(ref e) => write_err!(f, "witness program error"; e),
|
|
|
|
UncompressedPubkey =>
|
2023-08-04 00:07:59 +00:00
|
|
|
write!(f, "an uncompressed pubkey was used where it is not allowed"),
|
2023-08-04 00:12:45 +00:00
|
|
|
ExcessiveScriptSize => write!(f, "script size exceed 520 bytes"),
|
|
|
|
UnrecognizedScript => write!(f, "script is not a p2pkh, p2sh or witness program"),
|
|
|
|
NetworkValidation { required, found, ref address } => {
|
2023-08-04 00:07:59 +00:00
|
|
|
write!(f, "address ")?;
|
|
|
|
address.fmt_internal(f)?; // Using fmt_internal in order to remove the "Address<NetworkUnchecked>(..)" wrapper
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
" belongs to network {} which is different from required {}",
|
|
|
|
found, required
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "std")]
|
|
|
|
impl std::error::Error for Error {
|
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
2023-08-04 00:11:26 +00:00
|
|
|
use Error::*;
|
2023-08-04 00:07:59 +00:00
|
|
|
|
|
|
|
match self {
|
|
|
|
WitnessVersion(e) => Some(e),
|
|
|
|
WitnessProgram(e) => Some(e),
|
2023-08-04 00:36:48 +00:00
|
|
|
UncompressedPubkey
|
2023-08-04 00:07:59 +00:00
|
|
|
| ExcessiveScriptSize
|
|
|
|
| UnrecognizedScript
|
|
|
|
| NetworkValidation { .. } => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<witness_version::TryFromError> for Error {
|
|
|
|
fn from(e: witness_version::TryFromError) -> Error { Error::WitnessVersion(e) }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<witness_program::Error> for Error {
|
|
|
|
fn from(e: witness_program::Error) -> Error { Error::WitnessProgram(e) }
|
|
|
|
}
|
2023-08-04 00:29:27 +00:00
|
|
|
|
|
|
|
/// Address type is either invalid or not supported in rust-bitcoin.
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
Make error types uniform
On our way to v1.0.0 we are defining a standard for our error types,
this includes:
- Uses the following derives (unless not possible, usually because of `io::Error`)
`#[derive(Debug, Clone, PartialEq, Eq)]`
- Has `non_exhaustive` unless we really know we can commit to not adding
anything.
Furthermore, we are trying to make the codebase easy to read. Error code
is write-once-read-many (well it should be) so if we make all the error
code super uniform the users can flick to an error and quickly see what
it includes. In an effort to achieve this I have made up a style and
over recent times have change much of the error code to that new style,
this PR audits _all_ error types in the code base and enforces the
style, specifically:
- Is layed out: definition, [impl block], Display impl, error::Error impl, From impls
- `error::Error` impl matches on enum even if it returns `None` for all variants
- Display/Error impls import enum variants locally
- match uses *self and `ref e`
- error::Error variants that return `Some` come first, `None` after
Re: non_exhaustive
To make dev and review easier I have added `non_exhaustive` to _every_
error type. We can then remove it error by error as we see fit. This is
because it takes a bit of thinking to do and review where as this patch
should not take much brain power to review.
2023-10-04 02:55:45 +00:00
|
|
|
#[non_exhaustive]
|
2023-08-04 00:29:27 +00:00
|
|
|
pub struct UnknownAddressTypeError(pub String);
|
|
|
|
|
|
|
|
impl fmt::Display for UnknownAddressTypeError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write_err!(f, "failed to parse {} as address type", self.0; self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-04 01:35:01 +00:00
|
|
|
#[cfg(feature = "std")]
|
|
|
|
impl std::error::Error for UnknownAddressTypeError {
|
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
|
|
|
|
}
|
2023-08-04 00:36:48 +00:00
|
|
|
|
|
|
|
/// Address parsing error.
|
Make error types uniform
On our way to v1.0.0 we are defining a standard for our error types,
this includes:
- Uses the following derives (unless not possible, usually because of `io::Error`)
`#[derive(Debug, Clone, PartialEq, Eq)]`
- Has `non_exhaustive` unless we really know we can commit to not adding
anything.
Furthermore, we are trying to make the codebase easy to read. Error code
is write-once-read-many (well it should be) so if we make all the error
code super uniform the users can flick to an error and quickly see what
it includes. In an effort to achieve this I have made up a style and
over recent times have change much of the error code to that new style,
this PR audits _all_ error types in the code base and enforces the
style, specifically:
- Is layed out: definition, [impl block], Display impl, error::Error impl, From impls
- `error::Error` impl matches on enum even if it returns `None` for all variants
- Display/Error impls import enum variants locally
- match uses *self and `ref e`
- error::Error variants that return `Some` come first, `None` after
Re: non_exhaustive
To make dev and review easier I have added `non_exhaustive` to _every_
error type. We can then remove it error by error as we see fit. This is
because it takes a bit of thinking to do and review where as this patch
should not take much brain power to review.
2023-10-04 02:55:45 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
2023-08-04 00:36:48 +00:00
|
|
|
#[non_exhaustive]
|
|
|
|
pub enum ParseError {
|
|
|
|
/// Base58 error.
|
|
|
|
Base58(base58::Error),
|
2023-08-04 01:05:15 +00:00
|
|
|
/// Bech32 segwit decoding error.
|
2023-10-09 18:17:26 +00:00
|
|
|
Bech32(bech32::segwit::DecodeError),
|
2023-08-04 00:36:48 +00:00
|
|
|
/// A witness version conversion/parsing error.
|
|
|
|
WitnessVersion(witness_version::TryFromError),
|
|
|
|
/// A witness program error.
|
|
|
|
WitnessProgram(witness_program::Error),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for ParseError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
use ParseError::*;
|
|
|
|
|
|
|
|
match *self {
|
|
|
|
Base58(ref e) => write_err!(f, "base58 error"; e),
|
2023-08-04 01:05:15 +00:00
|
|
|
Bech32(ref e) => write_err!(f, "bech32 segwit decoding error"; e),
|
2023-08-04 00:36:48 +00:00
|
|
|
WitnessVersion(ref e) => write_err!(f, "witness version conversion/parsing error"; e),
|
|
|
|
WitnessProgram(ref e) => write_err!(f, "witness program error"; e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "std")]
|
|
|
|
impl std::error::Error for ParseError {
|
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
|
|
use ParseError::*;
|
|
|
|
|
|
|
|
match *self {
|
|
|
|
Base58(ref e) => Some(e),
|
|
|
|
Bech32(ref e) => Some(e),
|
|
|
|
WitnessVersion(ref e) => Some(e),
|
|
|
|
WitnessProgram(ref e) => Some(e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<base58::Error> for ParseError {
|
|
|
|
fn from(e: base58::Error) -> Self { Self::Base58(e) }
|
|
|
|
}
|
|
|
|
|
2023-10-09 18:17:26 +00:00
|
|
|
impl From<bech32::segwit::DecodeError> for ParseError {
|
|
|
|
fn from(e: bech32::segwit::DecodeError) -> Self { Self::Bech32(e) }
|
2023-08-04 00:36:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<witness_version::TryFromError> for ParseError {
|
|
|
|
fn from(e: witness_version::TryFromError) -> Self { Self::WitnessVersion(e) }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<witness_program::Error> for ParseError {
|
|
|
|
fn from(e: witness_program::Error) -> Self { Self::WitnessProgram(e) }
|
|
|
|
}
|