Skip to content

Commit

Permalink
Merge rust-bitcoin/rust-miniscript#410: Implement source for error …
Browse files Browse the repository at this point in the history
…types

5935d86 Implement error::Error for all error types (Tobin C. Harding)
a5db0f0 Re-order error code blocks (Tobin C. Harding)
2eac9de Remove error::Error::description (Tobin C. Harding)
3bdeb8c Move SigType down the file (Tobin C. Harding)

Pull request description:

  Now we have MSRV of 1.41.1 we can implement `source` for improved error handling.

  Patches 1-3 are preparatory cleanup, patch 4 adds all the `source` impls.

  Resolves: rust-bitcoin#273

ACKs for top commit:
  apoelstra:
    ACK 5935d86
  sanket1729:
    ACK 5935d86. Checked that all changes correctly pass through the source. Did not check whether there are more Error types that are not covered.

Tree-SHA512: f74f0bfabba92dab6e88d26ec098a60c66eae8cbbad34433ef0f95c42d1d79352d1a408506e604b5564c0e4b15ed3a7e41ffe1d2fd1ba127b66bdba287091357
  • Loading branch information
sanket1729 committed May 26, 2022
2 parents 832fc8e + 5935d86 commit c1bba6f
Show file tree
Hide file tree
Showing 11 changed files with 431 additions and 222 deletions.
16 changes: 14 additions & 2 deletions src/descriptor/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,11 @@ impl fmt::Display for DescriptorKeyParseError {
}
}

impl error::Error for DescriptorKeyParseError {}
impl error::Error for DescriptorKeyParseError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}

impl fmt::Display for DescriptorPublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down Expand Up @@ -369,7 +373,15 @@ impl fmt::Display for ConversionError {
}
}

impl error::Error for ConversionError {}
impl error::Error for ConversionError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use self::ConversionError::*;

match self {
Wildcard | HardenedChild | HardenedWildcard => None,
}
}
}

impl DescriptorPublicKey {
/// The fingerprint of the master key associated with this key, `0x00000000` if none.
Expand Down
181 changes: 109 additions & 72 deletions src/interpreter/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,78 +118,6 @@ pub enum Error {
VerifyFailed,
}

/// A type of representing which keys errored during interpreter checksig evaluation
// Note that we can't use BitcoinKey because it is not public
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum PkEvalErrInner {
/// Full Key
FullKey(bitcoin::PublicKey),
/// XOnly Key
XOnlyKey(bitcoin::XOnlyPublicKey),
}

impl From<BitcoinKey> for PkEvalErrInner {
fn from(pk: BitcoinKey) -> Self {
match pk {
BitcoinKey::Fullkey(pk) => PkEvalErrInner::FullKey(pk),
BitcoinKey::XOnlyPublicKey(xpk) => PkEvalErrInner::XOnlyKey(xpk),
}
}
}

impl fmt::Display for PkEvalErrInner {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PkEvalErrInner::FullKey(pk) => pk.fmt(f),
PkEvalErrInner::XOnlyKey(xpk) => xpk.fmt(f),
}
}
}

#[doc(hidden)]
impl From<secp256k1::Error> for Error {
fn from(e: secp256k1::Error) -> Error {
Error::Secp(e)
}
}

#[doc(hidden)]
impl From<bitcoin::util::sighash::Error> for Error {
fn from(e: bitcoin::util::sighash::Error) -> Error {
Error::SighashError(e)
}
}

#[doc(hidden)]
impl From<bitcoin::EcdsaSigError> for Error {
fn from(e: bitcoin::EcdsaSigError) -> Error {
Error::EcdsaSig(e)
}
}

#[doc(hidden)]
impl From<bitcoin::SchnorrSigError> for Error {
fn from(e: bitcoin::SchnorrSigError) -> Error {
Error::SchnorrSig(e)
}
}

#[doc(hidden)]
impl From<crate::Error> for Error {
fn from(e: crate::Error) -> Error {
Error::Miniscript(e)
}
}

impl error::Error for Error {
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
Error::Secp(ref err) => Some(err),
ref x => Some(x),
}
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expand Down Expand Up @@ -263,3 +191,112 @@ impl fmt::Display for Error {
}
}
}

impl error::Error for Error {
fn cause(&self) -> Option<&dyn error::Error> {
use self::Error::*;

match self {
AbsoluteLocktimeNotMet(_)
| CannotInferTrDescriptors
| ControlBlockVerificationError
| CouldNotEvaluate
| ExpectedPush
| HashPreimageLengthMismatch
| IncorrectPubkeyHash
| IncorrectScriptHash
| IncorrectWPubkeyHash
| IncorrectWScriptHash
| InsufficientSignaturesMultiSig
| InvalidEcdsaSignature(_)
| InvalidSchnorrSignature(_)
| InvalidSchnorrSighashType(_)
| NonStandardSighash(_)
| MissingExtraZeroMultiSig
| MultiSigEvaluationError
| NonEmptyWitness
| NonEmptyScriptSig
| PubkeyParseError
| XOnlyPublicKeyParseError
| PkEvaluationError(_)
| PkHashVerifyFail(_)
| RelativeLocktimeNotMet(_)
| ScriptSatisfactionError
| TapAnnexUnsupported
| UncompressedPubkey
| UnexpectedStackBoolean
| UnexpectedStackEnd
| UnexpectedStackElementPush
| VerifyFailed => None,
ControlBlockParse(e) => Some(e),
EcdsaSig(e) => Some(e),
Miniscript(e) => Some(e),
Secp(e) => Some(e),
SchnorrSig(e) => Some(e),
SighashError(e) => Some(e),
}
}
}

#[doc(hidden)]
impl From<secp256k1::Error> for Error {
fn from(e: secp256k1::Error) -> Error {
Error::Secp(e)
}
}

#[doc(hidden)]
impl From<bitcoin::util::sighash::Error> for Error {
fn from(e: bitcoin::util::sighash::Error) -> Error {
Error::SighashError(e)
}
}

#[doc(hidden)]
impl From<bitcoin::EcdsaSigError> for Error {
fn from(e: bitcoin::EcdsaSigError) -> Error {
Error::EcdsaSig(e)
}
}

#[doc(hidden)]
impl From<bitcoin::SchnorrSigError> for Error {
fn from(e: bitcoin::SchnorrSigError) -> Error {
Error::SchnorrSig(e)
}
}

#[doc(hidden)]
impl From<crate::Error> for Error {
fn from(e: crate::Error) -> Error {
Error::Miniscript(e)
}
}

/// A type of representing which keys errored during interpreter checksig evaluation
// Note that we can't use BitcoinKey because it is not public
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum PkEvalErrInner {
/// Full Key
FullKey(bitcoin::PublicKey),
/// XOnly Key
XOnlyKey(bitcoin::XOnlyPublicKey),
}

impl From<BitcoinKey> for PkEvalErrInner {
fn from(pk: BitcoinKey) -> Self {
match pk {
BitcoinKey::Fullkey(pk) => PkEvalErrInner::FullKey(pk),
BitcoinKey::XOnlyPublicKey(xpk) => PkEvalErrInner::XOnlyKey(xpk),
}
}
}

impl fmt::Display for PkEvalErrInner {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PkEvalErrInner::FullKey(pk) => pk.fmt(f),
PkEvalErrInner::XOnlyKey(xpk) => xpk.fmt(f),
}
}
}
Loading

0 comments on commit c1bba6f

Please sign in to comment.