@@ -16,13 +16,22 @@ use bitcoin::hashes::{hash160, hex::ToHex};
1616use bitcoin:: { self , secp256k1} ;
1717use std:: { error, fmt} ;
1818
19+ use super :: BitcoinKey ;
20+
1921/// Detailed Error type for Interpreter
2022#[ derive( Debug ) ]
2123pub enum Error {
2224 /// Could not satisfy, absolute locktime not met
2325 AbsoluteLocktimeNotMet ( u32 ) ,
26+ /// Cannot Infer a taproot descriptor
27+ /// Key spends cannot infer the internal key of the descriptor
28+ /// Inferring script spends is possible, but is hidden nodes are currently
29+ /// not supported in descriptor spec
30+ CannotInferTrDescriptors ,
2431 /// General Interpreter error.
2532 CouldNotEvaluate ,
33+ /// EcdsaSig related error
34+ EcdsaSig ( bitcoin:: EcdsaSigError ) ,
2635 /// We expected a push (including a `OP_1` but no other numeric pushes)
2736 ExpectedPush ,
2837 /// The preimage to the hash function must be exactly 32 bytes.
@@ -39,8 +48,10 @@ pub enum Error {
3948 InsufficientSignaturesMultiSig ,
4049 /// Invalid Sighash type
4150 InvalidSchnorrSigHashType ( Vec < u8 > ) ,
51+ /// ecdsa Signature failed to verify
52+ InvalidEcdsaSignature ( bitcoin:: PublicKey ) ,
4253 /// Signature failed to verify
43- InvalidSignature ( bitcoin:: PublicKey ) ,
54+ InvalidSchnorrSignature ( bitcoin:: XOnlyPublicKey ) ,
4455 /// Last byte of this signature isn't a standard sighash type
4556 NonStandardSigHash ( Vec < u8 > ) ,
4657 /// Miniscript error
@@ -60,19 +71,25 @@ pub enum Error {
6071 /// Any input witness apart from sat(sig) or nsat(0) leads to
6172 /// this error. This is network standardness assumption and miniscript only
6273 /// supports standard scripts
63- PkEvaluationError ( bitcoin:: PublicKey ) ,
74+ // note that BitcoinKey is not exported, create a data structure to convey the same
75+ // information in error
76+ PkEvaluationError ( PkEvalErrInner ) ,
6477 /// The Public Key hash check for the given pubkey. This occurs in `PkH`
6578 /// node when the given key does not match to Hash in script.
6679 PkHashVerifyFail ( hash160:: Hash ) ,
6780 /// Parse Error while parsing a `stack::Element::Push` as a Pubkey. Both
6881 /// 33 byte and 65 bytes are supported.
6982 PubkeyParseError ,
83+ /// Parse Error while parsing a `stack::Element::Push` as a XOnlyPublicKey (32 bytes)
84+ XOnlyPublicKeyParseError ,
7085 /// Could not satisfy, relative locktime not met
7186 RelativeLocktimeNotMet ( u32 ) ,
7287 /// Forward-secp related errors
7388 Secp ( secp256k1:: Error ) ,
7489 /// Miniscript requires the entire top level script to be satisfied.
7590 ScriptSatisfactionError ,
91+ /// Schnorr Signature error
92+ SchnorrSig ( bitcoin:: SchnorrSigError ) ,
7693 /// Errors in signature hash calculations
7794 SighashError ( bitcoin:: util:: sighash:: Error ) ,
7895 /// An uncompressed public key was encountered in a context where it is
@@ -92,6 +109,34 @@ pub enum Error {
92109 VerifyFailed ,
93110}
94111
112+ /// A type of representing which keys errored during interpreter checksig evaluation
113+ // Note that we can't use BitcoinKey because it is not public
114+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
115+ pub enum PkEvalErrInner {
116+ /// Full Key
117+ FullKey ( bitcoin:: PublicKey ) ,
118+ /// XOnly Key
119+ XOnlyKey ( bitcoin:: XOnlyPublicKey ) ,
120+ }
121+
122+ impl From < BitcoinKey > for PkEvalErrInner {
123+ fn from ( pk : BitcoinKey ) -> Self {
124+ match pk {
125+ BitcoinKey :: Fullkey ( pk) => PkEvalErrInner :: FullKey ( pk) ,
126+ BitcoinKey :: XOnlyPublicKey ( xpk) => PkEvalErrInner :: XOnlyKey ( xpk) ,
127+ }
128+ }
129+ }
130+
131+ impl fmt:: Display for PkEvalErrInner {
132+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
133+ match self {
134+ PkEvalErrInner :: FullKey ( pk) => pk. fmt ( f) ,
135+ PkEvalErrInner :: XOnlyKey ( xpk) => xpk. fmt ( f) ,
136+ }
137+ }
138+ }
139+
95140#[ doc( hidden) ]
96141impl From < secp256k1:: Error > for Error {
97142 fn from ( e : secp256k1:: Error ) -> Error {
@@ -106,6 +151,20 @@ impl From<bitcoin::util::sighash::Error> for Error {
106151 }
107152}
108153
154+ #[ doc( hidden) ]
155+ impl From < bitcoin:: EcdsaSigError > for Error {
156+ fn from ( e : bitcoin:: EcdsaSigError ) -> Error {
157+ Error :: EcdsaSig ( e)
158+ }
159+ }
160+
161+ #[ doc( hidden) ]
162+ impl From < bitcoin:: SchnorrSigError > for Error {
163+ fn from ( e : bitcoin:: SchnorrSigError ) -> Error {
164+ Error :: SchnorrSig ( e)
165+ }
166+ }
167+
109168#[ doc( hidden) ]
110169impl From < :: Error > for Error {
111170 fn from ( e : :: Error ) -> Error {
@@ -130,6 +189,8 @@ impl fmt::Display for Error {
130189 "required absolute locktime CLTV of {} blocks, not met" ,
131190 n
132191 ) ,
192+ Error :: CannotInferTrDescriptors => write ! ( f, "Cannot infer taproot descriptors" ) ,
193+ Error :: EcdsaSig ( ref s) => write ! ( f, "Ecdsa sig error: {}" , s) ,
133194 Error :: ExpectedPush => f. write_str ( "expected push in script" ) ,
134195 Error :: CouldNotEvaluate => f. write_str ( "Interpreter Error: Could not evaluate" ) ,
135196 Error :: HashPreimageLengthMismatch => f. write_str ( "Hash preimage should be 32 bytes" ) ,
@@ -147,7 +208,8 @@ impl fmt::Display for Error {
147208 sig. to_hex( )
148209 )
149210 }
150- Error :: InvalidSignature ( pk) => write ! ( f, "bad signature with pk {}" , pk) ,
211+ Error :: InvalidEcdsaSignature ( pk) => write ! ( f, "bad ecdsa signature with pk {}" , pk) ,
212+ Error :: InvalidSchnorrSignature ( pk) => write ! ( f, "bad schnorr signature with pk {}" , pk) ,
151213 Error :: NonStandardSigHash ( ref sig) => {
152214 write ! (
153215 f,
@@ -165,11 +227,13 @@ impl fmt::Display for Error {
165227 Error :: PkEvaluationError ( ref key) => write ! ( f, "Incorrect Signature for pk {}" , key) ,
166228 Error :: PkHashVerifyFail ( ref hash) => write ! ( f, "Pubkey Hash check failed {}" , hash) ,
167229 Error :: PubkeyParseError => f. write_str ( "could not parse pubkey" ) ,
230+ Error :: XOnlyPublicKeyParseError => f. write_str ( "could not parse x-only pubkey" ) ,
168231 Error :: RelativeLocktimeNotMet ( n) => {
169232 write ! ( f, "required relative locktime CSV of {} blocks, not met" , n)
170233 }
171234 Error :: ScriptSatisfactionError => f. write_str ( "Top level script must be satisfied" ) ,
172235 Error :: Secp ( ref e) => fmt:: Display :: fmt ( e, f) ,
236+ Error :: SchnorrSig ( ref s) => write ! ( f, "Schnorr sig error: {}" , s) ,
173237 Error :: SighashError ( ref e) => fmt:: Display :: fmt ( e, f) ,
174238 Error :: UncompressedPubkey => {
175239 f. write_str ( "uncompressed pubkey in non-legacy descriptor" )
0 commit comments