1313//
1414
1515use bitcoin:: hashes:: { hash160, hex:: ToHex } ;
16+ use bitcoin:: util:: taproot;
1617use bitcoin:: { self , secp256k1} ;
1718use std:: { error, fmt} ;
1819
20+ use super :: BitcoinKey ;
21+
1922/// Detailed Error type for Interpreter
2023#[ derive( Debug ) ]
2124pub enum Error {
2225 /// Could not satisfy, absolute locktime not met
2326 AbsoluteLocktimeNotMet ( u32 ) ,
27+ /// Cannot Infer a taproot descriptor
28+ /// Key spends cannot infer the internal key of the descriptor
29+ /// Inferring script spends is possible, but is hidden nodes are currently
30+ /// not supported in descriptor spec
31+ CannotInferTrDescriptors ,
32+ /// Error parsing taproot control block
33+ ControlBlockParse ( taproot:: TaprootError ) ,
34+ /// Tap control block(merkle proofs + tweak) verification error
35+ ControlBlockVerificationError ,
2436 /// General Interpreter error.
2537 CouldNotEvaluate ,
38+ /// EcdsaSig related error
39+ EcdsaSig ( bitcoin:: EcdsaSigError ) ,
2640 /// We expected a push (including a `OP_1` but no other numeric pushes)
2741 ExpectedPush ,
2842 /// The preimage to the hash function must be exactly 32 bytes.
@@ -39,8 +53,10 @@ pub enum Error {
3953 InsufficientSignaturesMultiSig ,
4054 /// Invalid Sighash type
4155 InvalidSchnorrSigHashType ( Vec < u8 > ) ,
56+ /// ecdsa Signature failed to verify
57+ InvalidEcdsaSignature ( bitcoin:: PublicKey ) ,
4258 /// Signature failed to verify
43- InvalidSignature ( bitcoin:: PublicKey ) ,
59+ InvalidSchnorrSignature ( bitcoin:: XOnlyPublicKey ) ,
4460 /// Last byte of this signature isn't a standard sighash type
4561 NonStandardSigHash ( Vec < u8 > ) ,
4662 /// Miniscript error
@@ -60,21 +76,29 @@ pub enum Error {
6076 /// Any input witness apart from sat(sig) or nsat(0) leads to
6177 /// this error. This is network standardness assumption and miniscript only
6278 /// supports standard scripts
63- PkEvaluationError ( bitcoin:: PublicKey ) ,
79+ // note that BitcoinKey is not exported, create a data structure to convey the same
80+ // information in error
81+ PkEvaluationError ( PkEvalErrInner ) ,
6482 /// The Public Key hash check for the given pubkey. This occurs in `PkH`
6583 /// node when the given key does not match to Hash in script.
6684 PkHashVerifyFail ( hash160:: Hash ) ,
6785 /// Parse Error while parsing a `stack::Element::Push` as a Pubkey. Both
6886 /// 33 byte and 65 bytes are supported.
6987 PubkeyParseError ,
88+ /// Parse Error while parsing a `stack::Element::Push` as a XOnlyPublicKey (32 bytes)
89+ XOnlyPublicKeyParseError ,
7090 /// Could not satisfy, relative locktime not met
7191 RelativeLocktimeNotMet ( u32 ) ,
7292 /// Forward-secp related errors
7393 Secp ( secp256k1:: Error ) ,
7494 /// Miniscript requires the entire top level script to be satisfied.
7595 ScriptSatisfactionError ,
96+ /// Schnorr Signature error
97+ SchnorrSig ( bitcoin:: SchnorrSigError ) ,
7698 /// Errors in signature hash calculations
7799 SighashError ( bitcoin:: util:: sighash:: Error ) ,
100+ /// Taproot Annex Unsupported
101+ TapAnnexUnsupported ,
78102 /// An uncompressed public key was encountered in a context where it is
79103 /// disallowed (e.g. in a Segwit script or p2wpkh output)
80104 UncompressedPubkey ,
@@ -92,6 +116,34 @@ pub enum Error {
92116 VerifyFailed ,
93117}
94118
119+ /// A type of representing which keys errored during interpreter checksig evaluation
120+ // Note that we can't use BitcoinKey because it is not public
121+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
122+ pub enum PkEvalErrInner {
123+ /// Full Key
124+ FullKey ( bitcoin:: PublicKey ) ,
125+ /// XOnly Key
126+ XOnlyKey ( bitcoin:: XOnlyPublicKey ) ,
127+ }
128+
129+ impl From < BitcoinKey > for PkEvalErrInner {
130+ fn from ( pk : BitcoinKey ) -> Self {
131+ match pk {
132+ BitcoinKey :: Fullkey ( pk) => PkEvalErrInner :: FullKey ( pk) ,
133+ BitcoinKey :: XOnlyPublicKey ( xpk) => PkEvalErrInner :: XOnlyKey ( xpk) ,
134+ }
135+ }
136+ }
137+
138+ impl fmt:: Display for PkEvalErrInner {
139+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
140+ match self {
141+ PkEvalErrInner :: FullKey ( pk) => pk. fmt ( f) ,
142+ PkEvalErrInner :: XOnlyKey ( xpk) => xpk. fmt ( f) ,
143+ }
144+ }
145+ }
146+
95147#[ doc( hidden) ]
96148impl From < secp256k1:: Error > for Error {
97149 fn from ( e : secp256k1:: Error ) -> Error {
@@ -106,6 +158,20 @@ impl From<bitcoin::util::sighash::Error> for Error {
106158 }
107159}
108160
161+ #[ doc( hidden) ]
162+ impl From < bitcoin:: EcdsaSigError > for Error {
163+ fn from ( e : bitcoin:: EcdsaSigError ) -> Error {
164+ Error :: EcdsaSig ( e)
165+ }
166+ }
167+
168+ #[ doc( hidden) ]
169+ impl From < bitcoin:: SchnorrSigError > for Error {
170+ fn from ( e : bitcoin:: SchnorrSigError ) -> Error {
171+ Error :: SchnorrSig ( e)
172+ }
173+ }
174+
109175#[ doc( hidden) ]
110176impl From < :: Error > for Error {
111177 fn from ( e : :: Error ) -> Error {
@@ -130,6 +196,12 @@ impl fmt::Display for Error {
130196 "required absolute locktime CLTV of {} blocks, not met" ,
131197 n
132198 ) ,
199+ Error :: CannotInferTrDescriptors => write ! ( f, "Cannot infer taproot descriptors" ) ,
200+ Error :: ControlBlockParse ( ref e) => write ! ( f, "Control block parse error {}" , e) ,
201+ Error :: ControlBlockVerificationError => {
202+ f. write_str ( "Control block verification failed" )
203+ }
204+ Error :: EcdsaSig ( ref s) => write ! ( f, "Ecdsa sig error: {}" , s) ,
133205 Error :: ExpectedPush => f. write_str ( "expected push in script" ) ,
134206 Error :: CouldNotEvaluate => f. write_str ( "Interpreter Error: Could not evaluate" ) ,
135207 Error :: HashPreimageLengthMismatch => f. write_str ( "Hash preimage should be 32 bytes" ) ,
@@ -147,7 +219,8 @@ impl fmt::Display for Error {
147219 sig. to_hex( )
148220 )
149221 }
150- Error :: InvalidSignature ( pk) => write ! ( f, "bad signature with pk {}" , pk) ,
222+ Error :: InvalidEcdsaSignature ( pk) => write ! ( f, "bad ecdsa signature with pk {}" , pk) ,
223+ Error :: InvalidSchnorrSignature ( pk) => write ! ( f, "bad schnorr signature with pk {}" , pk) ,
151224 Error :: NonStandardSigHash ( ref sig) => {
152225 write ! (
153226 f,
@@ -165,12 +238,15 @@ impl fmt::Display for Error {
165238 Error :: PkEvaluationError ( ref key) => write ! ( f, "Incorrect Signature for pk {}" , key) ,
166239 Error :: PkHashVerifyFail ( ref hash) => write ! ( f, "Pubkey Hash check failed {}" , hash) ,
167240 Error :: PubkeyParseError => f. write_str ( "could not parse pubkey" ) ,
241+ Error :: XOnlyPublicKeyParseError => f. write_str ( "could not parse x-only pubkey" ) ,
168242 Error :: RelativeLocktimeNotMet ( n) => {
169243 write ! ( f, "required relative locktime CSV of {} blocks, not met" , n)
170244 }
171245 Error :: ScriptSatisfactionError => f. write_str ( "Top level script must be satisfied" ) ,
172246 Error :: Secp ( ref e) => fmt:: Display :: fmt ( e, f) ,
247+ Error :: SchnorrSig ( ref s) => write ! ( f, "Schnorr sig error: {}" , s) ,
173248 Error :: SighashError ( ref e) => fmt:: Display :: fmt ( e, f) ,
249+ Error :: TapAnnexUnsupported => f. write_str ( "Encountered annex element" ) ,
174250 Error :: UncompressedPubkey => {
175251 f. write_str ( "uncompressed pubkey in non-legacy descriptor" )
176252 }
0 commit comments