diff --git a/bitcoin/src/address/error.rs b/bitcoin/src/address/error.rs index 43d11a73..3f5854cf 100644 --- a/bitcoin/src/address/error.rs +++ b/bitcoin/src/address/error.rs @@ -82,6 +82,7 @@ impl From for Error { /// Address type is either invalid or not supported in rust-bitcoin. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct UnknownAddressTypeError(pub String); impl fmt::Display for UnknownAddressTypeError { @@ -96,7 +97,7 @@ impl std::error::Error for UnknownAddressTypeError { } /// Address parsing error. -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] pub enum ParseError { /// Base58 error. diff --git a/bitcoin/src/amount.rs b/bitcoin/src/amount.rs index b93eeee6..394d469d 100644 --- a/bitcoin/src/amount.rs +++ b/bitcoin/src/amount.rs @@ -160,16 +160,17 @@ pub enum ParseAmountError { impl fmt::Display for ParseAmountError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use ParseAmountError::*; + match *self { - ParseAmountError::Negative => f.write_str("amount is negative"), - ParseAmountError::TooBig => f.write_str("amount is too big"), - ParseAmountError::TooPrecise => f.write_str("amount has a too high precision"), - ParseAmountError::InvalidFormat => f.write_str("invalid number format"), - ParseAmountError::InputTooLarge => f.write_str("input string was too large"), - ParseAmountError::InvalidCharacter(c) => write!(f, "invalid character in input: {}", c), - ParseAmountError::UnknownDenomination(ref d) => - write!(f, "unknown denomination: {}", d), - ParseAmountError::PossiblyConfusingDenomination(ref d) => { + Negative => f.write_str("amount is negative"), + TooBig => f.write_str("amount is too big"), + TooPrecise => f.write_str("amount has a too high precision"), + InvalidFormat => f.write_str("invalid number format"), + InputTooLarge => f.write_str("input string was too large"), + InvalidCharacter(c) => write!(f, "invalid character in input: {}", c), + UnknownDenomination(ref d) => write!(f, "unknown denomination: {}", d), + PossiblyConfusingDenomination(ref d) => { let (letter, upper, lower) = match d.chars().next() { Some('M') => ('M', "Mega", "milli"), Some('P') => ('P', "Peta", "pico"), @@ -185,7 +186,7 @@ impl fmt::Display for ParseAmountError { #[cfg(feature = "std")] impl std::error::Error for ParseAmountError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::ParseAmountError::*; + use ParseAmountError::*; match *self { Negative diff --git a/bitcoin/src/base58.rs b/bitcoin/src/base58.rs index f4cdc6cf..4dcd0bd1 100644 --- a/bitcoin/src/base58.rs +++ b/bitcoin/src/base58.rs @@ -213,16 +213,18 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use Error::*; + match *self { - Error::BadByte(b) => write!(f, "invalid base58 character {:#x}", b), - Error::BadChecksum(exp, actual) => + BadByte(b) => write!(f, "invalid base58 character {:#x}", b), + BadChecksum(exp, actual) => write!(f, "base58ck checksum {:#x} does not match expected {:#x}", actual, exp), - Error::InvalidLength(ell) => write!(f, "length {} invalid for this base58 type", ell), - Error::InvalidExtendedKeyVersion(ref v) => + InvalidLength(ell) => write!(f, "length {} invalid for this base58 type", ell), + InvalidExtendedKeyVersion(ref v) => write!(f, "extended key version {:#04x?} is invalid for this base58 type", v), - Error::InvalidAddressVersion(ref v) => + 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"), + TooShort(_) => write!(f, "base58ck data not even long enough for a checksum"), } } } @@ -230,7 +232,7 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; match self { BadByte(_) diff --git a/bitcoin/src/bip152.rs b/bitcoin/src/bip152.rs index 539b46b1..2ba70d73 100644 --- a/bitcoin/src/bip152.rs +++ b/bitcoin/src/bip152.rs @@ -314,7 +314,8 @@ impl Decodable for BlockTransactionsRequest { /// A transaction index is requested that is out of range from the /// corresponding block. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct TxIndexOutOfRangeError(u64); impl fmt::Display for TxIndexOutOfRangeError { diff --git a/bitcoin/src/bip158.rs b/bitcoin/src/bip158.rs index 97a4b222..cc93300d 100644 --- a/bitcoin/src/bip158.rs +++ b/bitcoin/src/bip158.rs @@ -70,9 +70,11 @@ pub enum Error { impl Display for Error { fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { + use Error::*; + match *self { - Error::UtxoMissing(ref coin) => write!(f, "unresolved UTXO {}", coin), - Error::Io(ref e) => write_err!(f, "IO error"; e), + UtxoMissing(ref coin) => write!(f, "unresolved UTXO {}", coin), + Io(ref e) => write_err!(f, "IO error"; e), } } } @@ -80,11 +82,11 @@ impl Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; - match self { + match *self { UtxoMissing(_) => None, - Io(e) => Some(e), + Io(ref e) => Some(e), } } } diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs index 43b265f8..1d481800 100644 --- a/bitcoin/src/bip32.rs +++ b/bitcoin/src/bip32.rs @@ -494,21 +494,22 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use Error::*; + match *self { - Error::CannotDeriveFromHardenedKey => + CannotDeriveFromHardenedKey => f.write_str("cannot derive hardened key from public key"), - Error::Secp256k1(ref e) => write_err!(f, "secp256k1 error"; e), - Error::InvalidChildNumber(ref n) => + Secp256k1(ref e) => write_err!(f, "secp256k1 error"; e), + InvalidChildNumber(ref n) => write!(f, "child number {} is invalid (not within [0, 2^31 - 1])", n), - Error::InvalidChildNumberFormat => f.write_str("invalid child number format"), - Error::InvalidDerivationPathFormat => f.write_str("invalid derivation path format"), - Error::UnknownVersion(ref bytes) => - write!(f, "unknown version magic bytes: {:?}", bytes), - Error::WrongExtendedKeyLength(ref len) => + InvalidChildNumberFormat => f.write_str("invalid child number format"), + InvalidDerivationPathFormat => f.write_str("invalid derivation path format"), + UnknownVersion(ref bytes) => write!(f, "unknown version magic bytes: {:?}", bytes), + WrongExtendedKeyLength(ref len) => write!(f, "encoded extended key data has wrong length {}", len), - Error::Base58(ref e) => write_err!(f, "base58 encoding error"; e), - Error::Hex(ref e) => write_err!(f, "Hexadecimal decoding error"; e), - Error::InvalidPublicKeyHexLength(got) => + Base58(ref e) => write_err!(f, "base58 encoding error"; e), + Hex(ref e) => write_err!(f, "Hexadecimal decoding error"; e), + InvalidPublicKeyHexLength(got) => write!(f, "PublicKey hex should be 66 or 130 digits long, got: {}", got), } } @@ -517,12 +518,12 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; - match self { - Secp256k1(e) => Some(e), - Base58(e) => Some(e), - Hex(e) => Some(e), + match *self { + Secp256k1(ref e) => Some(e), + Base58(ref e) => Some(e), + Hex(ref e) => Some(e), CannotDeriveFromHardenedKey | InvalidChildNumber(_) | InvalidChildNumberFormat diff --git a/bitcoin/src/blockdata/block.rs b/bitcoin/src/blockdata/block.rs index 3c103c5a..d04153b3 100644 --- a/bitcoin/src/blockdata/block.rs +++ b/bitcoin/src/blockdata/block.rs @@ -387,13 +387,15 @@ pub enum Bip34Error { impl fmt::Display for Bip34Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use Bip34Error::*; + match *self { - Bip34Error::Unsupported => write!(f, "block doesn't support BIP34"), - Bip34Error::NotPresent => write!(f, "BIP34 push not present in block's coinbase"), - Bip34Error::UnexpectedPush(ref p) => { + Unsupported => write!(f, "block doesn't support BIP34"), + NotPresent => write!(f, "BIP34 push not present in block's coinbase"), + UnexpectedPush(ref p) => { write!(f, "unexpected byte push of > 8 bytes: {:?}", p) } - Bip34Error::NegativeHeight => write!(f, "negative BIP34 height"), + NegativeHeight => write!(f, "negative BIP34 height"), } } } @@ -401,16 +403,17 @@ impl fmt::Display for Bip34Error { #[cfg(feature = "std")] impl std::error::Error for Bip34Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Bip34Error::*; + use Bip34Error::*; - match self { + match *self { Unsupported | NotPresent | UnexpectedPush(_) | NegativeHeight => None, } } } /// A block validation error. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub enum ValidationError { /// The header hash is not below the target. BadProofOfWork, diff --git a/bitcoin/src/blockdata/locktime/absolute.rs b/bitcoin/src/blockdata/locktime/absolute.rs index 2a565932..5f5a27bd 100644 --- a/bitcoin/src/blockdata/locktime/absolute.rs +++ b/bitcoin/src/blockdata/locktime/absolute.rs @@ -575,7 +575,7 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Error::*; + use Error::*; match *self { Conversion(ref e) => write_err!(f, "error converting lock time value"; e), @@ -588,7 +588,7 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; match *self { Conversion(ref e) => Some(e), @@ -614,7 +614,8 @@ impl From for Error { } /// An error that occurs when converting a `u32` to a lock time variant. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct ConversionError { /// The expected timelock unit, height (blocks) or time (seconds). unit: LockTimeUnit, @@ -671,7 +672,7 @@ pub enum OperationError { impl fmt::Display for OperationError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::OperationError::*; + use OperationError::*; match *self { InvalidComparison => @@ -682,7 +683,13 @@ impl fmt::Display for OperationError { #[cfg(feature = "std")] impl std::error::Error for OperationError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use OperationError::*; + + match *self { + InvalidComparison => None, + } + } } #[cfg(test)] diff --git a/bitcoin/src/blockdata/locktime/relative.rs b/bitcoin/src/blockdata/locktime/relative.rs index a61117c1..fca20938 100644 --- a/bitcoin/src/blockdata/locktime/relative.rs +++ b/bitcoin/src/blockdata/locktime/relative.rs @@ -311,15 +311,17 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use Error::*; + match *self { - Self::IntegerOverflow(val) => write!( + IntegerOverflow(val) => write!( f, "{} seconds is too large to be encoded to a 16 bit 512 second interval", val ), - Self::IncompatibleHeight(lock, height) => + IncompatibleHeight(lock, height) => write!(f, "tried to satisfy lock {} with height: {}", lock, height), - Self::IncompatibleTime(lock, time) => + IncompatibleTime(lock, time) => write!(f, "tried to satisfy lock {} with time: {}", lock, time), } } @@ -328,7 +330,7 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; match *self { IntegerOverflow(_) | IncompatibleHeight(_, _) | IncompatibleTime(_, _) => None, diff --git a/bitcoin/src/blockdata/script/mod.rs b/bitcoin/src/blockdata/script/mod.rs index 9fb09360..489bc716 100644 --- a/bitcoin/src/blockdata/script/mod.rs +++ b/bitcoin/src/blockdata/script/mod.rs @@ -698,13 +698,15 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use Error::*; + match *self { - Error::NonMinimalPush => f.write_str("non-minimal datapush"), - Error::EarlyEndOfScript => f.write_str("unexpected end of script"), - Error::NumericOverflow => + NonMinimalPush => f.write_str("non-minimal datapush"), + EarlyEndOfScript => f.write_str("unexpected end of script"), + NumericOverflow => f.write_str("numeric overflow (number on stack larger than 4 bytes)"), - Error::UnknownSpentOutput(ref point) => write!(f, "unknown spent output: {}", point), - Error::Serialization => + UnknownSpentOutput(ref point) => write!(f, "unknown spent output: {}", point), + Serialization => f.write_str("can not serialize the spending transaction in Transaction::verify()"), } } @@ -713,7 +715,7 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; match *self { NonMinimalPush diff --git a/bitcoin/src/blockdata/script/witness_program.rs b/bitcoin/src/blockdata/script/witness_program.rs index 446e44c5..d030f64c 100644 --- a/bitcoin/src/blockdata/script/witness_program.rs +++ b/bitcoin/src/blockdata/script/witness_program.rs @@ -66,7 +66,7 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Error::*; + use Error::*; match *self { InvalidLength(len) => @@ -80,9 +80,9 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; - match self { + match *self { InvalidLength(_) | InvalidSegwitV0Length(_) => None, } } diff --git a/bitcoin/src/blockdata/script/witness_version.rs b/bitcoin/src/blockdata/script/witness_version.rs index 9dbb449e..cf933432 100644 --- a/bitcoin/src/blockdata/script/witness_version.rs +++ b/bitcoin/src/blockdata/script/witness_version.rs @@ -168,6 +168,7 @@ impl From for Opcode { /// Error parsing [`WitnessVersion`] from a string. #[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] pub enum FromStrError { /// Unable to parse integer from string. Unparsable(ParseIntError), @@ -204,6 +205,7 @@ impl From for FromStrError { /// Error attempting to create a [`WitnessVersion`] from an [`Instruction`] #[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] pub enum TryFromInstructionError { /// Cannot not convert OP to a witness version. TryFrom(TryFromError), @@ -240,6 +242,7 @@ impl From for TryFromInstructionError { /// Error attempting to create a [`WitnessVersion`] from an integer. #[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] pub struct TryFromError { /// The invalid non-witness version integer. pub invalid: u8, diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs index 27db0e61..08a926db 100644 --- a/bitcoin/src/blockdata/transaction.rs +++ b/bitcoin/src/blockdata/transaction.rs @@ -116,13 +116,14 @@ pub enum ParseOutPointError { impl fmt::Display for ParseOutPointError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use ParseOutPointError::*; + match *self { - ParseOutPointError::Txid(ref e) => write_err!(f, "error parsing TXID"; e), - ParseOutPointError::Vout(ref e) => write_err!(f, "error parsing vout"; e), - ParseOutPointError::Format => write!(f, "OutPoint not in : format"), - ParseOutPointError::TooLong => write!(f, "vout should be at most 10 digits"), - ParseOutPointError::VoutNotCanonical => - write!(f, "no leading zeroes or + allowed in vout part"), + Txid(ref e) => write_err!(f, "error parsing TXID"; e), + Vout(ref e) => write_err!(f, "error parsing vout"; e), + Format => write!(f, "OutPoint not in : format"), + TooLong => write!(f, "vout should be at most 10 digits"), + VoutNotCanonical => write!(f, "no leading zeroes or + allowed in vout part"), } } } @@ -130,7 +131,7 @@ impl fmt::Display for ParseOutPointError { #[cfg(feature = "std")] impl std::error::Error for ParseOutPointError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::ParseOutPointError::*; + use ParseOutPointError::*; match self { Txid(e) => Some(e), diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index 798cff30..a5c6a1db 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -63,15 +63,17 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use Error::*; + match *self { - Error::Io(ref e) => write_err!(f, "IO error"; e), - Error::OversizedVectorAllocation { requested: ref r, max: ref m } => + Io(ref e) => write_err!(f, "IO error"; e), + OversizedVectorAllocation { requested: ref r, max: ref m } => write!(f, "allocation of oversized vector: requested {}, maximum {}", r, m), - Error::InvalidChecksum { expected: ref e, actual: ref a } => + InvalidChecksum { expected: ref e, actual: ref a } => write!(f, "invalid checksum: expected {:x}, actual {:x}", e.as_hex(), a.as_hex()), - Error::NonMinimalVarInt => write!(f, "non-minimal varint"), - Error::ParseFailed(ref s) => write!(f, "parse failed: {}", s), - Error::UnsupportedSegwitFlag(ref swflag) => + NonMinimalVarInt => write!(f, "non-minimal varint"), + ParseFailed(ref s) => write!(f, "parse failed: {}", s), + UnsupportedSegwitFlag(ref swflag) => write!(f, "unsupported segwit version: {}", swflag), } } @@ -80,7 +82,7 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; match self { Io(e) => Some(e), diff --git a/bitcoin/src/consensus/validation.rs b/bitcoin/src/consensus/validation.rs index 7667cc9d..988e1837 100644 --- a/bitcoin/src/consensus/validation.rs +++ b/bitcoin/src/consensus/validation.rs @@ -179,6 +179,7 @@ impl Transaction { // 2. We want to implement `std::error::Error` if the "std" feature is enabled in `rust-bitcoin` but // not in `bitcoinconsensus`. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct BitcoinconsensusError(bitcoinconsensus::Error); impl fmt::Display for BitcoinconsensusError { @@ -203,6 +204,7 @@ impl From for BitcoinconsensusError { /// An error during transaction validation. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub enum TxVerifyError { /// Error validating the script with bitcoinconsensus library. ScriptVerification(BitcoinconsensusError), diff --git a/bitcoin/src/crypto/ecdsa.rs b/bitcoin/src/crypto/ecdsa.rs index c93fa33f..e982e522 100644 --- a/bitcoin/src/crypto/ecdsa.rs +++ b/bitcoin/src/crypto/ecdsa.rs @@ -212,12 +212,12 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; - match self { - Hex(e) => Some(e), - Secp256k1(e) => Some(e), - SighashType(e) => Some(e), + match *self { + Hex(ref e) => Some(e), + Secp256k1(ref e) => Some(e), + SighashType(ref e) => Some(e), EmptySignature => None, } } diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs index 557ca32c..32b30f64 100644 --- a/bitcoin/src/crypto/key.rs +++ b/bitcoin/src/crypto/key.rs @@ -720,12 +720,12 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; - match self { - Base58(e) => Some(e), - Secp256k1(e) => Some(e), - Hex(e) => Some(e), + match *self { + Base58(ref e) => Some(e), + Secp256k1(ref e) => Some(e), + Hex(ref e) => Some(e), InvalidKeyPrefix(_) | InvalidHexLength(_) => None, } } diff --git a/bitcoin/src/crypto/sighash.rs b/bitcoin/src/crypto/sighash.rs index 0e73c808..d6593119 100644 --- a/bitcoin/src/crypto/sighash.rs +++ b/bitcoin/src/crypto/sighash.rs @@ -247,7 +247,7 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use Error::*; - match self { + match *self { Io(error_kind) => write!(f, "writer errored: {:?}", error_kind), IndexOutOfInputsBounds { index, inputs_size } => write!(f, "requested index ({}) is greater or equal than the number of transaction inputs ({})", index, inputs_size), SingleWithoutCorrespondingOutput { index, outputs_size } => write!(f, "SIGHASH_SINGLE for input ({}) haven't a corresponding output (#outputs:{})", index, outputs_size), @@ -266,7 +266,7 @@ impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { use Error::*; - match self { + match *self { Io(_) | IndexOutOfInputsBounds { .. } | SingleWithoutCorrespondingOutput { .. } @@ -523,7 +523,8 @@ impl TapSighashType { } /// Integer is not a consensus valid sighash type. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct InvalidSighashTypeError(pub u32); impl fmt::Display for InvalidSighashTypeError { @@ -539,7 +540,8 @@ impl std::error::Error for InvalidSighashTypeError { /// This type is consensus valid but an input including it would prevent the transaction from /// being relayed on today's Bitcoin network. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct NonStandardSighashTypeError(pub u32); impl fmt::Display for NonStandardSighashTypeError { @@ -557,6 +559,7 @@ impl std::error::Error for NonStandardSighashTypeError { /// /// This is currently returned for unrecognized sighash strings. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct SighashTypeParseError { /// The unrecognized string we attempted to parse. pub unrecognized: String, diff --git a/bitcoin/src/crypto/taproot.rs b/bitcoin/src/crypto/taproot.rs index 360b0e62..737a8bf6 100644 --- a/bitcoin/src/crypto/taproot.rs +++ b/bitcoin/src/crypto/taproot.rs @@ -87,9 +87,9 @@ impl std::error::Error for SigFromSliceError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { use SigFromSliceError::*; - match self { - Secp256k1(e) => Some(e), - SighashType(e) => Some(e), + match *self { + Secp256k1(ref e) => Some(e), + SighashType(ref e) => Some(e), InvalidSignatureSize(_) => None, } } diff --git a/bitcoin/src/merkle_tree/block.rs b/bitcoin/src/merkle_tree/block.rs index 95d51bdd..a8e3c3cc 100644 --- a/bitcoin/src/merkle_tree/block.rs +++ b/bitcoin/src/merkle_tree/block.rs @@ -497,7 +497,7 @@ pub enum MerkleBlockError { impl fmt::Display for MerkleBlockError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::MerkleBlockError::*; + use MerkleBlockError::*; match *self { MerkleRootMismatch => write!(f, "merkle header root doesn't match to the root calculated from the partial merkle tree"), @@ -517,7 +517,7 @@ impl fmt::Display for MerkleBlockError { #[cfg(feature = "std")] impl std::error::Error for MerkleBlockError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::MerkleBlockError::*; + use MerkleBlockError::*; match *self { MerkleRootMismatch | NoTransactions | TooManyTransactions | TooManyHashes diff --git a/bitcoin/src/network.rs b/bitcoin/src/network.rs index 67807e96..cd3d3042 100644 --- a/bitcoin/src/network.rs +++ b/bitcoin/src/network.rs @@ -194,6 +194,7 @@ pub mod as_core_arg { /// An error in parsing network string. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct ParseNetworkError(String); impl fmt::Display for ParseNetworkError { @@ -241,6 +242,7 @@ impl fmt::Display for Network { /// Error in parsing network from chain hash. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct UnknownChainHashError(ChainHash); impl Display for UnknownChainHashError { diff --git a/bitcoin/src/p2p/message.rs b/bitcoin/src/p2p/message.rs index ee0c64b2..7914dfb8 100644 --- a/bitcoin/src/p2p/message.rs +++ b/bitcoin/src/p2p/message.rs @@ -129,6 +129,7 @@ impl Decodable for CommandString { /// /// This is currently returned for command strings longer than 12. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct CommandStringError { cow: Cow<'static, str>, } diff --git a/bitcoin/src/p2p/mod.rs b/bitcoin/src/p2p/mod.rs index 0e32c620..c7f67570 100644 --- a/bitcoin/src/p2p/mod.rs +++ b/bitcoin/src/p2p/mod.rs @@ -325,7 +325,8 @@ impl BorrowMut<[u8; 4]> for Magic { } /// An error in parsing magic bytes. -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct ParseMagicError { /// The error that occurred when parsing the string. error: hex::HexToArrayError, @@ -346,6 +347,7 @@ impl std::error::Error for ParseMagicError { /// Error in creating a Network from Magic bytes. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct UnknownMagicError(Magic); impl fmt::Display for UnknownMagicError { diff --git a/bitcoin/src/parse.rs b/bitcoin/src/parse.rs index 1826c5c3..aebc5f8d 100644 --- a/bitcoin/src/parse.rs +++ b/bitcoin/src/parse.rs @@ -18,6 +18,7 @@ use crate::prelude::*; /// in a performance-critical application you may want to box it or throw away the context by /// converting to `core` type. #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct ParseIntError { input: String, // for displaying - see Display impl with nice error message below diff --git a/bitcoin/src/pow.rs b/bitcoin/src/pow.rs index bb28427c..40ca27a2 100644 --- a/bitcoin/src/pow.rs +++ b/bitcoin/src/pow.rs @@ -707,7 +707,8 @@ impl> From for U256 { } /// Error from `TryFrom` implementations, occurs when input is negative. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct TryFromError(i128); impl fmt::Display for TryFromError { diff --git a/bitcoin/src/psbt/error.rs b/bitcoin/src/psbt/error.rs index f490700a..2ded0e26 100644 --- a/bitcoin/src/psbt/error.rs +++ b/bitcoin/src/psbt/error.rs @@ -106,57 +106,56 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use Error::*; + 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 => + InvalidMagic => f.write_str("invalid magic"), + MissingUtxo => f.write_str("UTXO information is not present in PSBT"), + InvalidSeparator => f.write_str("invalid separator"), + 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 => + InvalidKey(ref rkey) => write!(f, "invalid key: {}", rkey), + InvalidProprietaryKey => write!(f, "non-proprietary key type found when proprietary key was expected"), - Error::DuplicateKey(ref rkey) => write!(f, "duplicate key: {}", rkey), - Error::UnsignedTxHasScriptSigs => - f.write_str("the unsigned transaction has script sigs"), - Error::UnsignedTxHasScriptWitnesses => + DuplicateKey(ref rkey) => write!(f, "duplicate key: {}", rkey), + UnsignedTxHasScriptSigs => f.write_str("the unsigned transaction has script sigs"), + UnsignedTxHasScriptWitnesses => f.write_str("the unsigned transaction has script witnesses"), - Error::MustHaveUnsignedTx => + 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!( + NoMorePairs => f.write_str("no more key-value pairs for this psbt map"), + 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::InvalidHash(ref e) => write_err!(f, "invalid hash when parsing slice"; e), - Error::InvalidPreimageHashPair { ref preimage, ref hash, ref hash_type } => { + NonStandardSighashType(ref sht) => write!(f, "non-standard sighash type: {}", sht), + InvalidHash(ref e) => write_err!(f, "invalid hash when parsing slice"; e), + 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) => { + CombineInconsistentKeySources(ref s) => { write!(f, "combine conflict: {}", s) } - Error::ConsensusEncoding(ref e) => write_err!(f, "bitcoin consensus encoding error"; e), - Error::NegativeFee => f.write_str("PSBT has a negative fee which is not allowed"), - Error::FeeOverflow => f.write_str("integer overflow in fee calculation"), - Error::InvalidPublicKey(ref e) => write_err!(f, "invalid public key"; e), - Error::InvalidSecp256k1PublicKey(ref e) => - write_err!(f, "invalid secp256k1 public key"; e), - Error::InvalidXOnlyPublicKey => f.write_str("invalid xonly public key"), - Error::InvalidEcdsaSignature(ref e) => write_err!(f, "invalid ECDSA signature"; e), - Error::InvalidTaprootSignature(ref e) => write_err!(f, "invalid taproot signature"; e), - Error::InvalidControlBlock => f.write_str("invalid control block"), - Error::InvalidLeafVersion => f.write_str("invalid leaf version"), - Error::Taproot(s) => write!(f, "taproot error - {}", s), - Error::TapTree(ref e) => write_err!(f, "taproot tree error"; e), - Error::XPubKey(s) => write!(f, "xpub key error - {}", s), - Error::Version(s) => write!(f, "version error {}", s), - Error::PartialDataConsumption => + ConsensusEncoding(ref e) => write_err!(f, "bitcoin consensus encoding error"; e), + NegativeFee => f.write_str("PSBT has a negative fee which is not allowed"), + FeeOverflow => f.write_str("integer overflow in fee calculation"), + InvalidPublicKey(ref e) => write_err!(f, "invalid public key"; e), + InvalidSecp256k1PublicKey(ref e) => write_err!(f, "invalid secp256k1 public key"; e), + InvalidXOnlyPublicKey => f.write_str("invalid xonly public key"), + InvalidEcdsaSignature(ref e) => write_err!(f, "invalid ECDSA signature"; e), + InvalidTaprootSignature(ref e) => write_err!(f, "invalid taproot signature"; e), + InvalidControlBlock => f.write_str("invalid control block"), + InvalidLeafVersion => f.write_str("invalid leaf version"), + Taproot(s) => write!(f, "taproot error - {}", s), + TapTree(ref e) => write_err!(f, "taproot tree error"; e), + XPubKey(s) => write!(f, "xpub key error - {}", s), + Version(s) => write!(f, "version error {}", s), + PartialDataConsumption => f.write_str("data not consumed entirely when explicitly deserializing"), - Error::Io(ref e) => write_err!(f, "I/O error"; e), + Io(ref e) => write_err!(f, "I/O error"; e), } } } @@ -164,12 +163,12 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; + use Error::*; - match self { - InvalidHash(e) => Some(e), - ConsensusEncoding(e) => Some(e), - Io(e) => Some(e), + match *self { + InvalidHash(ref e) => Some(e), + ConsensusEncoding(ref e) => Some(e), + Io(ref e) => Some(e), InvalidMagic | MissingUtxo | InvalidSeparator diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs index a1b1e103..2d6a360a 100644 --- a/bitcoin/src/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -796,7 +796,7 @@ pub enum SignError { impl fmt::Display for SignError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use self::SignError::*; + use SignError::*; match *self { IndexOutOfBounds(ref e) => write_err!(f, "index out of bounds"; e), @@ -821,9 +821,11 @@ impl fmt::Display for SignError { #[cfg(feature = "std")] impl std::error::Error for SignError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::SignError::*; + use SignError::*; match *self { + SighashComputation(ref e) => Some(e), + IndexOutOfBounds(ref e) => Some(e), InvalidSighashType | MissingInputUtxo | MissingRedeemScript @@ -836,8 +838,6 @@ impl std::error::Error for SignError { | KeyNotFound | WrongSigningAlgorithm | Unsupported => None, - SighashComputation(ref e) => Some(e), - IndexOutOfBounds(ref e) => Some(e), } } } @@ -850,8 +850,9 @@ impl From for SignError { fn from(e: IndexOutOfBoundsError) -> Self { SignError::IndexOutOfBounds(e) } } -#[derive(Debug, Clone, PartialEq, Eq)] /// This error is returned when extracting a [`Transaction`] from a [`Psbt`]. +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub enum ExtractTxError { /// The [`FeeRate`] is too high AbsurdFeeRate { @@ -874,14 +875,16 @@ pub enum ExtractTxError { impl fmt::Display for ExtractTxError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ExtractTxError::AbsurdFeeRate { fee_rate, .. } => + use ExtractTxError::*; + + match *self { + AbsurdFeeRate { fee_rate, .. } => write!(f, "An absurdly high fee rate of {}", fee_rate), - ExtractTxError::MissingInputValue { .. } => write!( + MissingInputValue { .. } => write!( f, "One of the inputs lacked value information (witness_utxo or non_witness_utxo)" ), - ExtractTxError::SendingTooMuch { .. } => write!( + SendingTooMuch { .. } => write!( f, "Transaction would be invalid due to output value being greater than input value." ), @@ -891,11 +894,18 @@ impl fmt::Display for ExtractTxError { #[cfg(feature = "std")] impl std::error::Error for ExtractTxError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use ExtractTxError::*; + + match *self { + AbsurdFeeRate { .. } | MissingInputValue { .. } | SendingTooMuch { .. } => None, + } + } } /// Input index out of bounds (actual index, maximum index allowed). -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub enum IndexOutOfBoundsError { /// The index is out of bounds for the `psbt.inputs` vector. Inputs { @@ -934,7 +944,13 @@ impl fmt::Display for IndexOutOfBoundsError { #[cfg(feature = "std")] impl std::error::Error for IndexOutOfBoundsError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use IndexOutOfBoundsError::*; + + match *self { + Inputs { .. } | TxInput { .. } => None, + } + } } #[cfg(feature = "base64")] diff --git a/bitcoin/src/sign_message.rs b/bitcoin/src/sign_message.rs index 80cdb7a6..87953ad8 100644 --- a/bitcoin/src/sign_message.rs +++ b/bitcoin/src/sign_message.rs @@ -43,12 +43,13 @@ mod message_signing { impl fmt::Display for MessageSignatureError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use MessageSignatureError::*; + match *self { - MessageSignatureError::InvalidLength => write!(f, "length not 65 bytes"), - MessageSignatureError::InvalidEncoding(ref e) => - write_err!(f, "invalid encoding"; e), - MessageSignatureError::InvalidBase64 => write!(f, "invalid base64"), - MessageSignatureError::UnsupportedAddressType(ref address_type) => + InvalidLength => write!(f, "length not 65 bytes"), + InvalidEncoding(ref e) => write_err!(f, "invalid encoding"; e), + InvalidBase64 => write!(f, "invalid base64"), + UnsupportedAddressType(ref address_type) => write!(f, "unsupported address type: {}", address_type), } } @@ -57,10 +58,10 @@ mod message_signing { #[cfg(feature = "std")] impl std::error::Error for MessageSignatureError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::MessageSignatureError::*; + use MessageSignatureError::*; - match self { - InvalidEncoding(e) => Some(e), + match *self { + InvalidEncoding(ref e) => Some(e), InvalidLength | InvalidBase64 | UnsupportedAddressType(_) => None, } } diff --git a/bitcoin/src/string.rs b/bitcoin/src/string.rs index fd28e7c3..efe6ea30 100644 --- a/bitcoin/src/string.rs +++ b/bitcoin/src/string.rs @@ -36,6 +36,7 @@ pub trait FromHexStr: Sized { /// Hex parsing error #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub enum FromHexError { /// The input was not a valid hex string, contains the error that occurred while parsing. ParseHex(E), @@ -49,7 +50,7 @@ impl From for FromHexError { impl fmt::Display for FromHexError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::FromHexError::*; + use FromHexError::*; match *self { ParseHex(ref e) => write_err!(f, "failed to parse hex string"; e), @@ -65,7 +66,7 @@ where E: std::error::Error + 'static, { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::FromHexError::*; + use FromHexError::*; match *self { ParseHex(ref e) => Some(e), diff --git a/bitcoin/src/taproot.rs b/bitcoin/src/taproot.rs index 40ba5aa3..477587fa 100644 --- a/bitcoin/src/taproot.rs +++ b/bitcoin/src/taproot.rs @@ -574,7 +574,7 @@ impl Default for TaprootBuilder { /// Error happening when [`TapTree`] is constructed from a [`TaprootBuilder`] /// having hidden branches or not being finalized. -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] pub enum IncompleteBuilderError { /// Indicates an attempt to construct a tap tree from a builder containing incomplete branches. @@ -620,7 +620,7 @@ impl std::error::Error for IncompleteBuilderError { /// Error happening when [`TapTree`] is constructed from a [`NodeInfo`] /// having hidden branches. -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] pub enum HiddenNodesError { /// Indicates an attempt to construct a tap tree from a builder containing hidden parts. @@ -630,16 +630,20 @@ pub enum HiddenNodesError { impl HiddenNodesError { /// Converts error into the original incomplete [`NodeInfo`] instance. pub fn into_node_info(self) -> NodeInfo { + use HiddenNodesError::*; + match self { - HiddenNodesError::HiddenParts(node_info) => node_info, + HiddenParts(node_info) => node_info, } } } impl core::fmt::Display for HiddenNodesError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + use HiddenNodesError::*; + f.write_str(match self { - HiddenNodesError::HiddenParts(_) => + HiddenParts(_) => "an attempt to construct a tap tree from a node_info containing hidden parts.", }) } @@ -648,7 +652,7 @@ impl core::fmt::Display for HiddenNodesError { #[cfg(feature = "std")] impl std::error::Error for HiddenNodesError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::HiddenNodesError::*; + use HiddenNodesError::*; match self { HiddenParts(_) => None, @@ -1447,26 +1451,28 @@ pub enum TaprootBuilderError { impl fmt::Display for TaprootBuilderError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use TaprootBuilderError::*; + match *self { - TaprootBuilderError::InvalidMerkleTreeDepth(d) => { + InvalidMerkleTreeDepth(d) => { write!( f, "Merkle Tree depth({}) must be less than {}", d, TAPROOT_CONTROL_MAX_NODE_COUNT ) } - TaprootBuilderError::NodeNotInDfsOrder => { + NodeNotInDfsOrder => { write!(f, "add_leaf/add_hidden must be called in DFS walk order",) } - TaprootBuilderError::OverCompleteTree => write!( + OverCompleteTree => write!( f, "Attempted to create a tree with two nodes at depth 0. There must\ only be a exactly one node at depth 0", ), - TaprootBuilderError::InvalidInternalKey(ref e) => { + InvalidInternalKey(ref e) => { write_err!(f, "invalid internal x-only key"; e) } - TaprootBuilderError::EmptyTree => { + EmptyTree => { write!(f, "Called finalize on an empty tree") } } @@ -1476,7 +1482,7 @@ impl fmt::Display for TaprootBuilderError { #[cfg(feature = "std")] impl std::error::Error for TaprootBuilderError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::TaprootBuilderError::*; + use TaprootBuilderError::*; match self { InvalidInternalKey(e) => Some(e), @@ -1507,30 +1513,32 @@ pub enum TaprootError { impl fmt::Display for TaprootError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use TaprootError::*; + match *self { - TaprootError::InvalidMerkleBranchSize(sz) => write!( + InvalidMerkleBranchSize(sz) => write!( f, "Merkle branch size({}) must be a multiple of {}", sz, TAPROOT_CONTROL_NODE_SIZE ), - TaprootError::InvalidMerkleTreeDepth(d) => write!( + InvalidMerkleTreeDepth(d) => write!( f, "Merkle Tree depth({}) must be less than {}", d, TAPROOT_CONTROL_MAX_NODE_COUNT ), - TaprootError::InvalidTaprootLeafVersion(v) => { + InvalidTaprootLeafVersion(v) => { write!(f, "Leaf version({}) must have the least significant bit 0", v) } - TaprootError::InvalidControlBlockSize(sz) => write!( + InvalidControlBlockSize(sz) => write!( f, "Control Block size({}) must be of the form 33 + 32*m where 0 <= m <= {} ", sz, TAPROOT_CONTROL_MAX_NODE_COUNT ), - TaprootError::InvalidInternalKey(ref e) => { + InvalidInternalKey(ref e) => { write_err!(f, "invalid internal x-only key"; e) } - TaprootError::InvalidParity(_) => write!(f, "invalid parity value for internal key"), - TaprootError::EmptyTree => write!(f, "Taproot Tree must contain at least one script"), + InvalidParity(_) => write!(f, "invalid parity value for internal key"), + EmptyTree => write!(f, "Taproot Tree must contain at least one script"), } } } @@ -1538,7 +1546,7 @@ impl fmt::Display for TaprootError { #[cfg(feature = "std")] impl std::error::Error for TaprootError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::TaprootError::*; + use TaprootError::*; match self { InvalidInternalKey(e) => Some(e), diff --git a/hashes/src/lib.rs b/hashes/src/lib.rs index fa92397a..667d2df9 100644 --- a/hashes/src/lib.rs +++ b/hashes/src/lib.rs @@ -225,7 +225,8 @@ pub trait Hash: } /// Attempted to create a hash from an invalid length slice. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct FromSliceError { expected: usize, got: usize,