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")]
|
||||
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)]
|
||||
mod tests {
|
||||
|
|
|
@ -188,7 +188,20 @@ impl fmt::Display for Error {
|
|||
|
||||
#[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`.
|
||||
// Since it's private we don't bother with trait impls besides From.
|
||||
|
|
|
@ -27,7 +27,6 @@ use crate::prelude::*;
|
|||
|
||||
use crate::io;
|
||||
use core::{fmt, str, default::Default};
|
||||
#[cfg(feature = "std")] use std::error;
|
||||
|
||||
use crate::hashes::{self, Hash, sha256d};
|
||||
use crate::hashes::hex::FromHex;
|
||||
|
@ -142,12 +141,14 @@ impl fmt::Display for ParseOutPointError {
|
|||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl error::Error for ParseOutPointError {
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
match *self {
|
||||
ParseOutPointError::Txid(ref e) => Some(e),
|
||||
ParseOutPointError::Vout(ref e) => Some(e),
|
||||
_ => None,
|
||||
impl std::error::Error for ParseOutPointError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
use self::ParseOutPointError::*;
|
||||
|
||||
match self {
|
||||
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_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
|
||||
#[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")]
|
||||
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)]
|
||||
mod tests {
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
use core::{fmt, mem, u32, convert::From};
|
||||
#[cfg(feature = "std")] use std::error;
|
||||
|
||||
use crate::hashes::{sha256d, Hash, sha256};
|
||||
use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader};
|
||||
|
@ -106,18 +105,20 @@ impl fmt::Display for Error {
|
|||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl ::std::error::Error for Error {
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
match *self {
|
||||
Error::Io(ref e) => Some(e),
|
||||
Error::Psbt(ref e) => Some(e),
|
||||
Error::UnexpectedNetworkMagic { .. }
|
||||
| Error::OversizedVectorAllocation { .. }
|
||||
| Error::InvalidChecksum { .. }
|
||||
| Error::NonMinimalVarInt
|
||||
| Error::UnknownNetworkMagic(..)
|
||||
| Error::ParseFailed(..)
|
||||
| Error::UnsupportedSegwitFlag(..) => None,
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
use self::Error::*;
|
||||
|
||||
match self {
|
||||
Io(e) => Some(e),
|
||||
Psbt(e) => Some(e),
|
||||
UnexpectedNetworkMagic { .. }
|
||||
| OversizedVectorAllocation { .. }
|
||||
| InvalidChecksum { .. }
|
||||
| NonMinimalVarInt
|
||||
| UnknownNetworkMagic(_)
|
||||
| ParseFailed(_)
|
||||
| UnsupportedSegwitFlag(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,9 +111,13 @@ impl fmt::Display for CommandStringError {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(docsrs, doc(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
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
use crate::io;
|
||||
use core::fmt;
|
||||
#[cfg(feature = "std")] use std::error;
|
||||
|
||||
pub mod constants;
|
||||
|
||||
|
@ -79,11 +78,13 @@ impl From<io::Error> for Error {
|
|||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl error::Error for Error {
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
match *self {
|
||||
Error::Io(ref e) => Some(e),
|
||||
Error::SocketMutexPoisoned | Error::SocketNotConnectedToPeer => None,
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
use self::Error::*;
|
||||
|
||||
match self {
|
||||
Io(e) => Some(e),
|
||||
SocketMutexPoisoned | SocketNotConnectedToPeer => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ use crate::prelude::*;
|
|||
use core::fmt;
|
||||
use core::num::ParseIntError;
|
||||
use core::str::FromStr;
|
||||
#[cfg(feature = "std")] use std::error;
|
||||
|
||||
use secp256k1::{Secp256k1, Verification, XOnlyPublicKey};
|
||||
use bech32;
|
||||
|
@ -104,13 +103,22 @@ impl fmt::Display for Error {
|
|||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl ::std::error::Error for Error {
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
match *self {
|
||||
Error::Base58(ref e) => Some(e),
|
||||
Error::Bech32(ref e) => Some(e),
|
||||
Error::UnparsableWitnessVersion(ref e) => Some(e),
|
||||
_ => None,
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
use self::Error::*;
|
||||
|
||||
match self {
|
||||
Base58(e) => Some(e),
|
||||
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_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 {
|
||||
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::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::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::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::Secp256k1(ref e) => fmt::Display::fmt(&e, f),
|
||||
Error::Hex(ref e) => write!(f, "Hexadecimal decoding error: {}", e)
|
||||
|
@ -68,7 +68,22 @@ impl fmt::Display for Error {
|
|||
|
||||
#[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
|
||||
/// will be allocated on the heap.
|
||||
|
|
|
@ -74,10 +74,6 @@ pub enum Error {
|
|||
Io(io::Error),
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl ::std::error::Error for Error {}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
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 {
|
||||
fn from(io: io::Error) -> Self {
|
||||
Error::Io(io)
|
||||
|
|
|
@ -22,7 +22,6 @@ use crate::prelude::*;
|
|||
use crate::io::Write;
|
||||
use core::{fmt, str::FromStr, default::Default};
|
||||
use core::ops::Index;
|
||||
#[cfg(feature = "std")] use std::error;
|
||||
#[cfg(feature = "serde")] use serde;
|
||||
|
||||
use crate::hash_types::XpubIdentifier;
|
||||
|
@ -497,12 +496,20 @@ impl fmt::Display for Error {
|
|||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl error::Error for Error {
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
if let Error::Secp256k1(ref e) = *self {
|
||||
Some(e)
|
||||
} else {
|
||||
None
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
use self::Error::*;
|
||||
|
||||
match self {
|
||||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
EcdsaSigError::HexEncoding(e) =>
|
||||
write!(f, "EcdsaSig hex encoding error: {}", e),
|
||||
EcdsaSigError::NonStandardSighashType(hash_ty) =>
|
||||
write!(f, "Non standard signature hash type {}", hash_ty),
|
||||
EcdsaSigError::Secp256k1(ref e) =>
|
||||
write!(f, "Invalid Ecdsa signature: {}", e),
|
||||
EcdsaSigError::EmptySignature =>
|
||||
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_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 {
|
||||
fn from(e: secp256k1::Error) -> EcdsaSigError {
|
||||
|
|
|
@ -16,16 +16,14 @@
|
|||
//! This module provides keys used in Bitcoin that can be roundtrip
|
||||
//! (de)serialized.
|
||||
|
||||
pub use secp256k1::{XOnlyPublicKey, KeyPair};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use core::{ops, str::FromStr};
|
||||
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::hashes::{Hash, hash160, hex, hex::FromHex};
|
||||
use crate::hash_types::{PubkeyHash, WPubkeyHash};
|
||||
|
@ -57,13 +55,15 @@ impl fmt::Display for Error {
|
|||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl ::std::error::Error for Error {
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
match *self {
|
||||
Error::Base58(ref e) => Some(e),
|
||||
Error::Secp256k1(ref e) => Some(e),
|
||||
Error::InvalidKeyPrefix(_) => None,
|
||||
Error::Hex(ref e) => Some(e)
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
use self::Error::*;
|
||||
|
||||
match self {
|
||||
Base58(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::*;
|
||||
|
||||
use core::fmt;
|
||||
#[cfg(feature = "std")] use std::error;
|
||||
|
||||
use crate::hashes::sha256d;
|
||||
use secp256k1;
|
||||
|
@ -73,11 +72,13 @@ mod message_signing {
|
|||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl error::Error for MessageSignatureError {
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
match *self {
|
||||
MessageSignatureError::InvalidEncoding(ref e) => Some(e),
|
||||
_ => None,
|
||||
impl std::error::Error for MessageSignatureError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
use self::MessageSignatureError::*;
|
||||
|
||||
match self {
|
||||
InvalidEncoding(e) => Some(e),
|
||||
InvalidLength | InvalidBase64 | UnsupportedAddressType(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ pub(crate) mod endian;
|
|||
use crate::prelude::*;
|
||||
use crate::io;
|
||||
use core::fmt;
|
||||
#[cfg(feature = "std")] use std::error;
|
||||
|
||||
use crate::network;
|
||||
use crate::consensus::encode;
|
||||
|
@ -91,12 +90,16 @@ impl fmt::Display for Error {
|
|||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl ::std::error::Error for Error {
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
match *self {
|
||||
Error::Encode(ref e) => Some(e),
|
||||
Error::Network(ref e) => Some(e),
|
||||
Error::BlockBadProofOfWork | Error::BlockBadTarget => None
|
||||
#[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 {
|
||||
Encode(e) => Some(e),
|
||||
Network(e) => Some(e),
|
||||
BlockBadProofOfWork
|
||||
| BlockBadTarget => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,34 +88,59 @@ pub enum Error {
|
|||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
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::InvalidProprietaryKey => write!(f, "non-proprietary key type found when proprietary key was expected"),
|
||||
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::UnsignedTxHasScriptWitnesses => f.write_str("the unsigned transaction has script witnesses"),
|
||||
Error::MustHaveUnsignedTx => {
|
||||
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::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::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} => {
|
||||
// directly using debug forms of psbthash enums
|
||||
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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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)]
|
||||
impl From<hashes::Error> for Error {
|
||||
|
|
|
@ -110,7 +110,15 @@ impl core::fmt::Display for IncompleteTapTree {
|
|||
|
||||
#[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).
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -241,7 +241,16 @@ mod display_from_str {
|
|||
|
||||
#[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")))]
|
||||
impl Display for PartiallySignedTransaction {
|
||||
|
|
|
@ -286,7 +286,16 @@ impl fmt::Display for SchnorrSigError {
|
|||
|
||||
#[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 {
|
||||
|
||||
|
|
|
@ -224,7 +224,23 @@ impl fmt::Display for Error {
|
|||
}
|
||||
|
||||
#[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> {
|
||||
fn check_all(&self, tx: &Transaction) -> Result<(), Error> {
|
||||
|
|
|
@ -22,8 +22,6 @@ use secp256k1::{self, Secp256k1};
|
|||
|
||||
use core::fmt;
|
||||
use core::cmp::Reverse;
|
||||
#[cfg(feature = "std")]
|
||||
use std::error;
|
||||
|
||||
use crate::hashes::{sha256, Hash, HashEngine};
|
||||
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
|
||||
// so would mean the add_leaf/add_hidden invocations do not correspond to a DFS traversal of a
|
||||
// binary tree.
|
||||
if depth as usize + 1 < self.branch.len() {
|
||||
if (depth as usize + 1) < self.branch.len() {
|
||||
return Err(TaprootBuilderError::NodeNotInDfsOrder);
|
||||
}
|
||||
|
||||
|
@ -989,6 +987,9 @@ pub enum TaprootBuilderError {
|
|||
impl fmt::Display for TaprootBuilderError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
TaprootBuilderError::InvalidMerkleTreeDepth(d) => {
|
||||
write!(f, "Merkle Tree depth({}) must be less than {}", d, TAPROOT_CONTROL_MAX_NODE_COUNT)
|
||||
}
|
||||
TaprootBuilderError::NodeNotInDfsOrder => {
|
||||
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\
|
||||
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) => {
|
||||
write!(f, "Invalid Internal XOnly key : {}", e)
|
||||
}
|
||||
|
@ -1015,7 +1013,20 @@ impl fmt::Display for TaprootBuilderError {
|
|||
|
||||
#[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.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -1069,7 +1080,23 @@ impl fmt::Display for TaprootError {
|
|||
|
||||
#[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)]
|
||||
mod test {
|
||||
use crate::{Address, Network};
|
||||
|
|
|
@ -528,7 +528,11 @@ impl ::core::fmt::Display for ParseLengthError {
|
|||
|
||||
#[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 {
|
||||
/// Decay to a uint128
|
||||
|
|
Loading…
Reference in New Issue