Merge rust-bitcoin/rust-bitcoin#987: Implement `std::error::Error` for the new MSRV
97a5bb1439
Implement std::error::source codebase wide (Tobin C. Harding)0a9191b429
Add parenthesis around left hand side of companion (Tobin C. Harding)7cf8af2f86
Put Error impl block below Display (Tobin C. Harding)2384712364
Re-order Display match arms (Tobin C. Harding) Pull request description: Now that we have MSRV of 1.41.1 we should use `source` instead of `cause`. Audit the whole codebase and implement `source` for _every_ error type we have. The first three patches are preparatory cleanup, patch 3 is particularly shameful (adds parenthesis to make my editor work). CC @Kixunil because he is championing the error stuff. ACKs for top commit: apoelstra: ACK97a5bb1439
Tree-SHA512: 46313a28929445f32e01e30ca3b0246b30bc9d5e43db5754d4b441e9c30d3e427efaf247100eb6b452f98beec5a4fcde1daba7943a772114aa34f78ab52cbc60
This commit is contained in:
commit
0e82376bf8
|
@ -355,7 +355,16 @@ impl fmt::Display for Bip34Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl ::std::error::Error for Bip34Error {}
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
|
impl std::error::Error for Bip34Error {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::Bip34Error::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Unsupported | NotPresent | UnexpectedPush(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -188,7 +188,20 @@ impl fmt::Display for Error {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for Error {}
|
impl std::error::Error for Error {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::Error::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
NonMinimalPush
|
||||||
|
| EarlyEndOfScript
|
||||||
|
| NumericOverflow
|
||||||
|
| BitcoinConsensus(_) // TODO: This should return `Some` but bitcoinconsensus::Error does not implement Error.
|
||||||
|
| UnknownSpentOutput(_)
|
||||||
|
| SerializationError => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Our internal error proves that we only return these two cases from `read_uint_iter`.
|
// Our internal error proves that we only return these two cases from `read_uint_iter`.
|
||||||
// Since it's private we don't bother with trait impls besides From.
|
// Since it's private we don't bother with trait impls besides From.
|
||||||
|
|
|
@ -27,7 +27,6 @@ use crate::prelude::*;
|
||||||
|
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use core::{fmt, str, default::Default};
|
use core::{fmt, str, default::Default};
|
||||||
#[cfg(feature = "std")] use std::error;
|
|
||||||
|
|
||||||
use crate::hashes::{self, Hash, sha256d};
|
use crate::hashes::{self, Hash, sha256d};
|
||||||
use crate::hashes::hex::FromHex;
|
use crate::hashes::hex::FromHex;
|
||||||
|
@ -142,12 +141,14 @@ impl fmt::Display for ParseOutPointError {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl error::Error for ParseOutPointError {
|
impl std::error::Error for ParseOutPointError {
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
match *self {
|
use self::ParseOutPointError::*;
|
||||||
ParseOutPointError::Txid(ref e) => Some(e),
|
|
||||||
ParseOutPointError::Vout(ref e) => Some(e),
|
match self {
|
||||||
_ => None,
|
Txid(e) => Some(e),
|
||||||
|
Vout(e) => Some(e),
|
||||||
|
Format | TooLong | VoutNotCanonical => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -733,7 +734,11 @@ impl fmt::Display for NonStandardSighashType {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl error::Error for NonStandardSighashType {}
|
impl std::error::Error for NonStandardSighashType {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Legacy Hashtype of an input's signature
|
/// Legacy Hashtype of an input's signature
|
||||||
#[deprecated(since = "0.28.0", note = "Please use [`EcdsaSighashType`] instead")]
|
#[deprecated(since = "0.28.0", note = "Please use [`EcdsaSighashType`] instead")]
|
||||||
|
@ -886,9 +891,13 @@ impl fmt::Display for SighashTypeParseError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl ::std::error::Error for SighashTypeParseError {}
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
|
impl std::error::Error for SighashTypeParseError {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use core::{fmt, mem, u32, convert::From};
|
use core::{fmt, mem, u32, convert::From};
|
||||||
#[cfg(feature = "std")] use std::error;
|
|
||||||
|
|
||||||
use crate::hashes::{sha256d, Hash, sha256};
|
use crate::hashes::{sha256d, Hash, sha256};
|
||||||
use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader};
|
use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader};
|
||||||
|
@ -106,18 +105,20 @@ impl fmt::Display for Error {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for Error {
|
impl std::error::Error for Error {
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
match *self {
|
use self::Error::*;
|
||||||
Error::Io(ref e) => Some(e),
|
|
||||||
Error::Psbt(ref e) => Some(e),
|
match self {
|
||||||
Error::UnexpectedNetworkMagic { .. }
|
Io(e) => Some(e),
|
||||||
| Error::OversizedVectorAllocation { .. }
|
Psbt(e) => Some(e),
|
||||||
| Error::InvalidChecksum { .. }
|
UnexpectedNetworkMagic { .. }
|
||||||
| Error::NonMinimalVarInt
|
| OversizedVectorAllocation { .. }
|
||||||
| Error::UnknownNetworkMagic(..)
|
| InvalidChecksum { .. }
|
||||||
| Error::ParseFailed(..)
|
| NonMinimalVarInt
|
||||||
| Error::UnsupportedSegwitFlag(..) => None,
|
| UnknownNetworkMagic(_)
|
||||||
|
| ParseFailed(_)
|
||||||
|
| UnsupportedSegwitFlag(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,9 +111,13 @@ impl fmt::Display for CommandStringError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl ::std::error::Error for CommandStringError {}
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
|
impl std::error::Error for CommandStringError {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A Network message
|
/// A Network message
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
#[cfg(feature = "std")] use std::error;
|
|
||||||
|
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
|
|
||||||
|
@ -79,11 +78,13 @@ impl From<io::Error> for Error {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl error::Error for Error {
|
impl std::error::Error for Error {
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
match *self {
|
use self::Error::*;
|
||||||
Error::Io(ref e) => Some(e),
|
|
||||||
Error::SocketMutexPoisoned | Error::SocketNotConnectedToPeer => None,
|
match self {
|
||||||
|
Io(e) => Some(e),
|
||||||
|
SocketMutexPoisoned | SocketNotConnectedToPeer => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ use crate::prelude::*;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::num::ParseIntError;
|
use core::num::ParseIntError;
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
#[cfg(feature = "std")] use std::error;
|
|
||||||
|
|
||||||
use secp256k1::{Secp256k1, Verification, XOnlyPublicKey};
|
use secp256k1::{Secp256k1, Verification, XOnlyPublicKey};
|
||||||
use bech32;
|
use bech32;
|
||||||
|
@ -104,13 +103,22 @@ impl fmt::Display for Error {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for Error {
|
impl std::error::Error for Error {
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
match *self {
|
use self::Error::*;
|
||||||
Error::Base58(ref e) => Some(e),
|
|
||||||
Error::Bech32(ref e) => Some(e),
|
match self {
|
||||||
Error::UnparsableWitnessVersion(ref e) => Some(e),
|
Base58(e) => Some(e),
|
||||||
_ => None,
|
Bech32(e) => Some(e),
|
||||||
|
UnparsableWitnessVersion(e) => Some(e),
|
||||||
|
EmptyBech32Payload
|
||||||
|
| InvalidBech32Variant { .. }
|
||||||
|
| InvalidWitnessVersion(_)
|
||||||
|
| MalformedWitnessVersion
|
||||||
|
| InvalidWitnessProgramLength(_)
|
||||||
|
| InvalidSegwitV0ProgramLength(_)
|
||||||
|
| UncompressedPubkey
|
||||||
|
| ExcessiveScriptSize => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,7 +192,7 @@ impl fmt::Display for ParseAmountError {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for ParseAmountError {}
|
impl std::error::Error for ParseAmountError {}
|
||||||
|
|
||||||
fn is_too_precise(s: &str, precision: usize) -> bool {
|
fn is_too_precise(s: &str, precision: usize) -> bool {
|
||||||
s.contains('.') || precision >= s.len() || s.chars().rev().take(precision).any(|d| d != '0')
|
s.contains('.') || precision >= s.len() || s.chars().rev().take(precision).any(|d| d != '0')
|
||||||
|
|
|
@ -57,8 +57,8 @@ impl fmt::Display for Error {
|
||||||
Error::BadByte(b) => write!(f, "invalid base58 character 0x{:x}", b),
|
Error::BadByte(b) => write!(f, "invalid base58 character 0x{:x}", b),
|
||||||
Error::BadChecksum(exp, actual) => write!(f, "base58ck checksum 0x{:x} does not match expected 0x{:x}", actual, exp),
|
Error::BadChecksum(exp, actual) => write!(f, "base58ck checksum 0x{:x} does not match expected 0x{:x}", actual, exp),
|
||||||
Error::InvalidLength(ell) => write!(f, "length {} invalid for this base58 type", ell),
|
Error::InvalidLength(ell) => write!(f, "length {} invalid for this base58 type", ell),
|
||||||
Error::InvalidAddressVersion(ref v) => write!(f, "address version {} is invalid for this base58 type", v),
|
|
||||||
Error::InvalidExtendedKeyVersion(ref v) => write!(f, "extended key version {:#04x?} is invalid for this base58 type", v),
|
Error::InvalidExtendedKeyVersion(ref v) => write!(f, "extended key version {:#04x?} is invalid for this base58 type", v),
|
||||||
|
Error::InvalidAddressVersion(ref v) => write!(f, "address version {} is invalid for this base58 type", v),
|
||||||
Error::TooShort(_) => write!(f, "base58ck data not even long enough for a checksum"),
|
Error::TooShort(_) => write!(f, "base58ck data not even long enough for a checksum"),
|
||||||
Error::Secp256k1(ref e) => fmt::Display::fmt(&e, f),
|
Error::Secp256k1(ref e) => fmt::Display::fmt(&e, f),
|
||||||
Error::Hex(ref e) => write!(f, "Hexadecimal decoding error: {}", e)
|
Error::Hex(ref e) => write!(f, "Hexadecimal decoding error: {}", e)
|
||||||
|
@ -68,7 +68,22 @@ impl fmt::Display for Error {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for Error {}
|
impl std::error::Error for Error {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::Error::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
BadByte(_)
|
||||||
|
| BadChecksum(_, _)
|
||||||
|
| InvalidLength(_)
|
||||||
|
| InvalidExtendedKeyVersion(_)
|
||||||
|
| InvalidAddressVersion(_)
|
||||||
|
| TooShort(_) => None,
|
||||||
|
Secp256k1(e) => Some(e),
|
||||||
|
Hex(e) => Some(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Vector-like object that holds the first 100 elements on the stack. If more space is needed it
|
/// Vector-like object that holds the first 100 elements on the stack. If more space is needed it
|
||||||
/// will be allocated on the heap.
|
/// will be allocated on the heap.
|
||||||
|
|
|
@ -74,10 +74,6 @@ pub enum Error {
|
||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
|
||||||
impl ::std::error::Error for Error {}
|
|
||||||
|
|
||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -87,6 +83,20 @@ impl Display for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
|
impl std::error::Error for Error {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::Error::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
UtxoMissing(_) => None,
|
||||||
|
Io(e) => Some(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
impl From<io::Error> for Error {
|
||||||
fn from(io: io::Error) -> Self {
|
fn from(io: io::Error) -> Self {
|
||||||
Error::Io(io)
|
Error::Io(io)
|
||||||
|
|
|
@ -22,7 +22,6 @@ use crate::prelude::*;
|
||||||
use crate::io::Write;
|
use crate::io::Write;
|
||||||
use core::{fmt, str::FromStr, default::Default};
|
use core::{fmt, str::FromStr, default::Default};
|
||||||
use core::ops::Index;
|
use core::ops::Index;
|
||||||
#[cfg(feature = "std")] use std::error;
|
|
||||||
#[cfg(feature = "serde")] use serde;
|
#[cfg(feature = "serde")] use serde;
|
||||||
|
|
||||||
use crate::hash_types::XpubIdentifier;
|
use crate::hash_types::XpubIdentifier;
|
||||||
|
@ -497,12 +496,20 @@ impl fmt::Display for Error {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl error::Error for Error {
|
impl std::error::Error for Error {
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
if let Error::Secp256k1(ref e) = *self {
|
use self::Error::*;
|
||||||
Some(e)
|
|
||||||
} else {
|
match self {
|
||||||
None
|
Secp256k1(e) => Some(e),
|
||||||
|
Base58(e) => Some(e),
|
||||||
|
Hex(e) => Some(e),
|
||||||
|
CannotDeriveFromHardenedKey
|
||||||
|
| InvalidChildNumber(_)
|
||||||
|
| InvalidChildNumberFormat
|
||||||
|
| InvalidDerivationPathFormat
|
||||||
|
| UnknownVersion(_)
|
||||||
|
| WrongExtendedKeyLength(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,20 +102,31 @@ pub enum EcdsaSigError {
|
||||||
impl fmt::Display for EcdsaSigError {
|
impl fmt::Display for EcdsaSigError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
EcdsaSigError::HexEncoding(e) =>
|
||||||
|
write!(f, "EcdsaSig hex encoding error: {}", e),
|
||||||
EcdsaSigError::NonStandardSighashType(hash_ty) =>
|
EcdsaSigError::NonStandardSighashType(hash_ty) =>
|
||||||
write!(f, "Non standard signature hash type {}", hash_ty),
|
write!(f, "Non standard signature hash type {}", hash_ty),
|
||||||
EcdsaSigError::Secp256k1(ref e) =>
|
|
||||||
write!(f, "Invalid Ecdsa signature: {}", e),
|
|
||||||
EcdsaSigError::EmptySignature =>
|
EcdsaSigError::EmptySignature =>
|
||||||
write!(f, "Empty ECDSA signature"),
|
write!(f, "Empty ECDSA signature"),
|
||||||
EcdsaSigError::HexEncoding(e) => write!(f, "EcdsaSig hex encoding error: {}", e)
|
EcdsaSigError::Secp256k1(ref e) =>
|
||||||
|
write!(f, "Invalid Ecdsa signature: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for EcdsaSigError {}
|
impl std::error::Error for EcdsaSigError {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::EcdsaSigError::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
HexEncoding(e) => Some(e),
|
||||||
|
Secp256k1(e) => Some(e),
|
||||||
|
NonStandardSighashType(_) | EmptySignature => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<secp256k1::Error> for EcdsaSigError {
|
impl From<secp256k1::Error> for EcdsaSigError {
|
||||||
fn from(e: secp256k1::Error) -> EcdsaSigError {
|
fn from(e: secp256k1::Error) -> EcdsaSigError {
|
||||||
|
|
|
@ -16,16 +16,14 @@
|
||||||
//! This module provides keys used in Bitcoin that can be roundtrip
|
//! This module provides keys used in Bitcoin that can be roundtrip
|
||||||
//! (de)serialized.
|
//! (de)serialized.
|
||||||
|
|
||||||
pub use secp256k1::{XOnlyPublicKey, KeyPair};
|
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use core::{ops, str::FromStr};
|
use core::{ops, str::FromStr};
|
||||||
use core::fmt::{self, Write};
|
use core::fmt::{self, Write};
|
||||||
use crate::io;
|
|
||||||
#[cfg(feature = "std")] use std::error;
|
|
||||||
|
|
||||||
use secp256k1::{self, Secp256k1};
|
pub use secp256k1::{self, Secp256k1, XOnlyPublicKey, KeyPair};
|
||||||
|
|
||||||
|
use crate::io;
|
||||||
use crate::network::constants::Network;
|
use crate::network::constants::Network;
|
||||||
use crate::hashes::{Hash, hash160, hex, hex::FromHex};
|
use crate::hashes::{Hash, hash160, hex, hex::FromHex};
|
||||||
use crate::hash_types::{PubkeyHash, WPubkeyHash};
|
use crate::hash_types::{PubkeyHash, WPubkeyHash};
|
||||||
|
@ -57,13 +55,15 @@ impl fmt::Display for Error {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for Error {
|
impl std::error::Error for Error {
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
match *self {
|
use self::Error::*;
|
||||||
Error::Base58(ref e) => Some(e),
|
|
||||||
Error::Secp256k1(ref e) => Some(e),
|
match self {
|
||||||
Error::InvalidKeyPrefix(_) => None,
|
Base58(e) => Some(e),
|
||||||
Error::Hex(ref e) => Some(e)
|
Secp256k1(e) => Some(e),
|
||||||
|
InvalidKeyPrefix(_) => None,
|
||||||
|
Hex(e) => Some(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ mod message_signing {
|
||||||
#[cfg(feature = "base64")] use crate::prelude::*;
|
#[cfg(feature = "base64")] use crate::prelude::*;
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
#[cfg(feature = "std")] use std::error;
|
|
||||||
|
|
||||||
use crate::hashes::sha256d;
|
use crate::hashes::sha256d;
|
||||||
use secp256k1;
|
use secp256k1;
|
||||||
|
@ -73,11 +72,13 @@ mod message_signing {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl error::Error for MessageSignatureError {
|
impl std::error::Error for MessageSignatureError {
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
match *self {
|
use self::MessageSignatureError::*;
|
||||||
MessageSignatureError::InvalidEncoding(ref e) => Some(e),
|
|
||||||
_ => None,
|
match self {
|
||||||
|
InvalidEncoding(e) => Some(e),
|
||||||
|
InvalidLength | InvalidBase64 | UnsupportedAddressType(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ pub(crate) mod endian;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
#[cfg(feature = "std")] use std::error;
|
|
||||||
|
|
||||||
use crate::network;
|
use crate::network;
|
||||||
use crate::consensus::encode;
|
use crate::consensus::encode;
|
||||||
|
@ -91,12 +90,16 @@ impl fmt::Display for Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl ::std::error::Error for Error {
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
impl std::error::Error for Error {
|
||||||
match *self {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
Error::Encode(ref e) => Some(e),
|
use self::Error::*;
|
||||||
Error::Network(ref e) => Some(e),
|
|
||||||
Error::BlockBadProofOfWork | Error::BlockBadTarget => None
|
match self {
|
||||||
|
Encode(e) => Some(e),
|
||||||
|
Network(e) => Some(e),
|
||||||
|
BlockBadProofOfWork
|
||||||
|
| BlockBadTarget => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,34 +88,59 @@ pub enum Error {
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
Error::InvalidMagic => f.write_str("invalid magic"),
|
||||||
|
Error::MissingUtxo => f.write_str("UTXO information is not present in PSBT"),
|
||||||
|
Error::InvalidSeparator => f.write_str("invalid separator"),
|
||||||
|
Error::PsbtUtxoOutOfbounds => f.write_str("output index is out of bounds of non witness script output array"),
|
||||||
Error::InvalidKey(ref rkey) => write!(f, "invalid key: {}", rkey),
|
Error::InvalidKey(ref rkey) => write!(f, "invalid key: {}", rkey),
|
||||||
Error::InvalidProprietaryKey => write!(f, "non-proprietary key type found when proprietary key was expected"),
|
Error::InvalidProprietaryKey => write!(f, "non-proprietary key type found when proprietary key was expected"),
|
||||||
Error::DuplicateKey(ref rkey) => write!(f, "duplicate key: {}", rkey),
|
Error::DuplicateKey(ref rkey) => write!(f, "duplicate key: {}", rkey),
|
||||||
Error::UnexpectedUnsignedTx { expected: ref e, actual: ref a } => write!(f, "different unsigned transaction: expected {}, actual {}", e.txid(), a.txid()),
|
|
||||||
Error::NonStandardSighashType(ref sht) => write!(f, "non-standard sighash type: {}", sht),
|
|
||||||
Error::InvalidMagic => f.write_str("invalid magic"),
|
|
||||||
Error::InvalidSeparator => f.write_str("invalid separator"),
|
|
||||||
Error::UnsignedTxHasScriptSigs => f.write_str("the unsigned transaction has script sigs"),
|
Error::UnsignedTxHasScriptSigs => f.write_str("the unsigned transaction has script sigs"),
|
||||||
Error::UnsignedTxHasScriptWitnesses => f.write_str("the unsigned transaction has script witnesses"),
|
Error::UnsignedTxHasScriptWitnesses => f.write_str("the unsigned transaction has script witnesses"),
|
||||||
Error::MustHaveUnsignedTx => {
|
Error::MustHaveUnsignedTx => {
|
||||||
f.write_str("partially signed transactions must have an unsigned transaction")
|
f.write_str("partially signed transactions must have an unsigned transaction")
|
||||||
}
|
}
|
||||||
Error::NoMorePairs => f.write_str("no more key-value pairs for this psbt map"),
|
Error::NoMorePairs => f.write_str("no more key-value pairs for this psbt map"),
|
||||||
|
Error::UnexpectedUnsignedTx { expected: ref e, actual: ref a } => write!(f, "different unsigned transaction: expected {}, actual {}", e.txid(), a.txid()),
|
||||||
|
Error::NonStandardSighashType(ref sht) => write!(f, "non-standard sighash type: {}", sht),
|
||||||
Error::HashParseError(e) => write!(f, "Hash Parse Error: {}", e),
|
Error::HashParseError(e) => write!(f, "Hash Parse Error: {}", e),
|
||||||
Error::MissingUtxo => f.write_str("UTXO information is not present in PSBT"),
|
|
||||||
Error::PsbtUtxoOutOfbounds => f.write_str("output index is out of bounds of non witness script output array"),
|
|
||||||
Error::InvalidPreimageHashPair{ref preimage, ref hash, ref hash_type} => {
|
Error::InvalidPreimageHashPair{ref preimage, ref hash, ref hash_type} => {
|
||||||
// directly using debug forms of psbthash enums
|
// directly using debug forms of psbthash enums
|
||||||
write!(f, "Preimage {:?} does not match {:?} hash {:?}", preimage, hash_type, hash )
|
write!(f, "Preimage {:?} does not match {:?} hash {:?}", preimage, hash_type, hash )
|
||||||
}
|
},
|
||||||
Error::CombineInconsistentKeySources(ref s) => { write!(f, "combine conflict: {}", s) }
|
Error::CombineInconsistentKeySources(ref s) => { write!(f, "combine conflict: {}", s) },
|
||||||
Error::ConsensusEncoding => f.write_str("bitcoin consensus or BIP-174 encoding error"),
|
Error::ConsensusEncoding => f.write_str("bitcoin consensus or BIP-174 encoding error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl ::std::error::Error for Error {}
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
|
impl std::error::Error for Error {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::Error::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
HashParseError(e) => Some(e),
|
||||||
|
| InvalidMagic
|
||||||
|
| MissingUtxo
|
||||||
|
| InvalidSeparator
|
||||||
|
| PsbtUtxoOutOfbounds
|
||||||
|
| InvalidKey(_)
|
||||||
|
| InvalidProprietaryKey
|
||||||
|
| DuplicateKey(_)
|
||||||
|
| UnsignedTxHasScriptSigs
|
||||||
|
| UnsignedTxHasScriptWitnesses
|
||||||
|
| MustHaveUnsignedTx
|
||||||
|
| NoMorePairs
|
||||||
|
| UnexpectedUnsignedTx { .. }
|
||||||
|
| NonStandardSighashType(_)
|
||||||
|
| InvalidPreimageHashPair{ .. }
|
||||||
|
| CombineInconsistentKeySources(_)
|
||||||
|
| ConsensusEncoding => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
impl From<hashes::Error> for Error {
|
impl From<hashes::Error> for Error {
|
||||||
|
|
|
@ -110,7 +110,15 @@ impl core::fmt::Display for IncompleteTapTree {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for IncompleteTapTree {}
|
impl std::error::Error for IncompleteTapTree {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::IncompleteTapTree::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
NotFinalized(_) | HiddenParts(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Taproot Tree representing a finalized [`TaprootBuilder`] (a complete binary tree).
|
/// Taproot Tree representing a finalized [`TaprootBuilder`] (a complete binary tree).
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
@ -241,7 +241,16 @@ mod display_from_str {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for PsbtParseError {}
|
impl std::error::Error for PsbtParseError {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::PsbtParseError::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
PsbtEncoding(e) => Some(e),
|
||||||
|
Base64Encoding(e) => Some(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
||||||
impl Display for PartiallySignedTransaction {
|
impl Display for PartiallySignedTransaction {
|
||||||
|
|
|
@ -286,7 +286,16 @@ impl fmt::Display for SchnorrSigError {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for SchnorrSigError {}
|
impl std::error::Error for SchnorrSigError {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::SchnorrSigError::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Secp256k1(e) => Some(e),
|
||||||
|
InvalidSighashType(_) | InvalidSchnorrSigSize(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<secp256k1::Error> for SchnorrSigError {
|
impl From<secp256k1::Error> for SchnorrSigError {
|
||||||
|
|
||||||
|
|
|
@ -224,7 +224,23 @@ impl fmt::Display for Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl ::std::error::Error for Error {}
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
|
impl std::error::Error for Error {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::Error::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Io(_)
|
||||||
|
| IndexOutOfInputsBounds { .. }
|
||||||
|
| SingleWithoutCorrespondingOutput { .. }
|
||||||
|
| PrevoutsSize
|
||||||
|
| PrevoutIndex
|
||||||
|
| PrevoutKind
|
||||||
|
| WrongAnnex
|
||||||
|
| InvalidSighashType(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'u, T> Prevouts<'u, T> where T: Borrow<TxOut> {
|
impl<'u, T> Prevouts<'u, T> where T: Borrow<TxOut> {
|
||||||
fn check_all(&self, tx: &Transaction) -> Result<(), Error> {
|
fn check_all(&self, tx: &Transaction) -> Result<(), Error> {
|
||||||
|
|
|
@ -22,8 +22,6 @@ use secp256k1::{self, Secp256k1};
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::cmp::Reverse;
|
use core::cmp::Reverse;
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::error;
|
|
||||||
|
|
||||||
use crate::hashes::{sha256, Hash, HashEngine};
|
use crate::hashes::{sha256, Hash, HashEngine};
|
||||||
use crate::schnorr::{TweakedPublicKey, UntweakedPublicKey, TapTweak};
|
use crate::schnorr::{TweakedPublicKey, UntweakedPublicKey, TapTweak};
|
||||||
|
@ -486,7 +484,7 @@ impl TaprootBuilder {
|
||||||
// We cannot insert a leaf at a lower depth while a deeper branch is unfinished. Doing
|
// We cannot insert a leaf at a lower depth while a deeper branch is unfinished. Doing
|
||||||
// so would mean the add_leaf/add_hidden invocations do not correspond to a DFS traversal of a
|
// so would mean the add_leaf/add_hidden invocations do not correspond to a DFS traversal of a
|
||||||
// binary tree.
|
// binary tree.
|
||||||
if depth as usize + 1 < self.branch.len() {
|
if (depth as usize + 1) < self.branch.len() {
|
||||||
return Err(TaprootBuilderError::NodeNotInDfsOrder);
|
return Err(TaprootBuilderError::NodeNotInDfsOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,6 +987,9 @@ pub enum TaprootBuilderError {
|
||||||
impl fmt::Display for TaprootBuilderError {
|
impl fmt::Display for TaprootBuilderError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
TaprootBuilderError::InvalidMerkleTreeDepth(d) => {
|
||||||
|
write!(f, "Merkle Tree depth({}) must be less than {}", d, TAPROOT_CONTROL_MAX_NODE_COUNT)
|
||||||
|
}
|
||||||
TaprootBuilderError::NodeNotInDfsOrder => {
|
TaprootBuilderError::NodeNotInDfsOrder => {
|
||||||
write!(f, "add_leaf/add_hidden must be called in DFS walk order",)
|
write!(f, "add_leaf/add_hidden must be called in DFS walk order",)
|
||||||
}
|
}
|
||||||
|
@ -997,9 +998,6 @@ impl fmt::Display for TaprootBuilderError {
|
||||||
"Attempted to create a tree with two nodes at depth 0. There must\
|
"Attempted to create a tree with two nodes at depth 0. There must\
|
||||||
only be a exactly one node at depth 0",
|
only be a exactly one node at depth 0",
|
||||||
),
|
),
|
||||||
TaprootBuilderError::InvalidMerkleTreeDepth(d) => {
|
|
||||||
write!(f, "Merkle Tree depth({}) must be less than {}", d, TAPROOT_CONTROL_MAX_NODE_COUNT)
|
|
||||||
}
|
|
||||||
TaprootBuilderError::InvalidInternalKey(e) => {
|
TaprootBuilderError::InvalidInternalKey(e) => {
|
||||||
write!(f, "Invalid Internal XOnly key : {}", e)
|
write!(f, "Invalid Internal XOnly key : {}", e)
|
||||||
}
|
}
|
||||||
|
@ -1015,7 +1013,20 @@ impl fmt::Display for TaprootBuilderError {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl error::Error for TaprootBuilderError {}
|
impl std::error::Error for TaprootBuilderError {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::TaprootBuilderError::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
InvalidInternalKey(e) => Some(e),
|
||||||
|
InvalidMerkleTreeDepth(_)
|
||||||
|
| NodeNotInDfsOrder
|
||||||
|
| OverCompleteTree
|
||||||
|
| IncompleteTree
|
||||||
|
| EmptyTree => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Detailed error type for taproot utilities.
|
/// Detailed error type for taproot utilities.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -1069,7 +1080,23 @@ impl fmt::Display for TaprootError {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl error::Error for TaprootError {}
|
impl std::error::Error for TaprootError {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use self::TaprootError::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
InvalidInternalKey(e) => Some(e),
|
||||||
|
InvalidMerkleBranchSize(_)
|
||||||
|
| InvalidMerkleTreeDepth(_)
|
||||||
|
| InvalidTaprootLeafVersion(_)
|
||||||
|
| InvalidControlBlockSize(_)
|
||||||
|
| InvalidParity(_)
|
||||||
|
| EmptyTree => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{Address, Network};
|
use crate::{Address, Network};
|
||||||
|
|
|
@ -528,7 +528,11 @@ impl ::core::fmt::Display for ParseLengthError {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
impl ::std::error::Error for ParseLengthError {}
|
impl std::error::Error for ParseLengthError {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Uint256 {
|
impl Uint256 {
|
||||||
/// Decay to a uint128
|
/// Decay to a uint128
|
||||||
|
|
Loading…
Reference in New Issue