@@ -16,13 +16,22 @@ use bitcoin::hashes::{hash160, hex::ToHex};
16
16
use bitcoin:: { self , secp256k1} ;
17
17
use std:: { error, fmt} ;
18
18
19
+ use super :: BitcoinKey ;
20
+
19
21
/// Detailed Error type for Interpreter
20
22
#[ derive( Debug ) ]
21
23
pub enum Error {
22
24
/// Could not satisfy, absolute locktime not met
23
25
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 ,
24
31
/// General Interpreter error.
25
32
CouldNotEvaluate ,
33
+ /// EcdsaSig related error
34
+ EcdsaSig ( bitcoin:: EcdsaSigError ) ,
26
35
/// We expected a push (including a `OP_1` but no other numeric pushes)
27
36
ExpectedPush ,
28
37
/// The preimage to the hash function must be exactly 32 bytes.
@@ -39,8 +48,10 @@ pub enum Error {
39
48
InsufficientSignaturesMultiSig ,
40
49
/// Invalid Sighash type
41
50
InvalidSchnorrSigHashType ( Vec < u8 > ) ,
51
+ /// ecdsa Signature failed to verify
52
+ InvalidEcdsaSignature ( bitcoin:: PublicKey ) ,
42
53
/// Signature failed to verify
43
- InvalidSignature ( bitcoin:: PublicKey ) ,
54
+ InvalidSchnorrSignature ( bitcoin:: XOnlyPublicKey ) ,
44
55
/// Last byte of this signature isn't a standard sighash type
45
56
NonStandardSigHash ( Vec < u8 > ) ,
46
57
/// Miniscript error
@@ -60,19 +71,25 @@ pub enum Error {
60
71
/// Any input witness apart from sat(sig) or nsat(0) leads to
61
72
/// this error. This is network standardness assumption and miniscript only
62
73
/// 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 ) ,
64
77
/// The Public Key hash check for the given pubkey. This occurs in `PkH`
65
78
/// node when the given key does not match to Hash in script.
66
79
PkHashVerifyFail ( hash160:: Hash ) ,
67
80
/// Parse Error while parsing a `stack::Element::Push` as a Pubkey. Both
68
81
/// 33 byte and 65 bytes are supported.
69
82
PubkeyParseError ,
83
+ /// Parse Error while parsing a `stack::Element::Push` as a XOnlyPublicKey (32 bytes)
84
+ XOnlyPublicKeyParseError ,
70
85
/// Could not satisfy, relative locktime not met
71
86
RelativeLocktimeNotMet ( u32 ) ,
72
87
/// Forward-secp related errors
73
88
Secp ( secp256k1:: Error ) ,
74
89
/// Miniscript requires the entire top level script to be satisfied.
75
90
ScriptSatisfactionError ,
91
+ /// Schnorr Signature error
92
+ SchnorrSig ( bitcoin:: SchnorrSigError ) ,
76
93
/// Errors in signature hash calculations
77
94
SighashError ( bitcoin:: util:: sighash:: Error ) ,
78
95
/// An uncompressed public key was encountered in a context where it is
@@ -92,6 +109,34 @@ pub enum Error {
92
109
VerifyFailed ,
93
110
}
94
111
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
+
95
140
#[ doc( hidden) ]
96
141
impl From < secp256k1:: Error > for Error {
97
142
fn from ( e : secp256k1:: Error ) -> Error {
@@ -106,6 +151,20 @@ impl From<bitcoin::util::sighash::Error> for Error {
106
151
}
107
152
}
108
153
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
+
109
168
#[ doc( hidden) ]
110
169
impl From < :: Error > for Error {
111
170
fn from ( e : :: Error ) -> Error {
@@ -130,6 +189,8 @@ impl fmt::Display for Error {
130
189
"required absolute locktime CLTV of {} blocks, not met" ,
131
190
n
132
191
) ,
192
+ Error :: CannotInferTrDescriptors => write ! ( f, "Cannot infer taproot descriptors" ) ,
193
+ Error :: EcdsaSig ( ref s) => write ! ( f, "Ecdsa sig error: {}" , s) ,
133
194
Error :: ExpectedPush => f. write_str ( "expected push in script" ) ,
134
195
Error :: CouldNotEvaluate => f. write_str ( "Interpreter Error: Could not evaluate" ) ,
135
196
Error :: HashPreimageLengthMismatch => f. write_str ( "Hash preimage should be 32 bytes" ) ,
@@ -147,7 +208,8 @@ impl fmt::Display for Error {
147
208
sig. to_hex( )
148
209
)
149
210
}
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) ,
151
213
Error :: NonStandardSigHash ( ref sig) => {
152
214
write ! (
153
215
f,
@@ -165,11 +227,13 @@ impl fmt::Display for Error {
165
227
Error :: PkEvaluationError ( ref key) => write ! ( f, "Incorrect Signature for pk {}" , key) ,
166
228
Error :: PkHashVerifyFail ( ref hash) => write ! ( f, "Pubkey Hash check failed {}" , hash) ,
167
229
Error :: PubkeyParseError => f. write_str ( "could not parse pubkey" ) ,
230
+ Error :: XOnlyPublicKeyParseError => f. write_str ( "could not parse x-only pubkey" ) ,
168
231
Error :: RelativeLocktimeNotMet ( n) => {
169
232
write ! ( f, "required relative locktime CSV of {} blocks, not met" , n)
170
233
}
171
234
Error :: ScriptSatisfactionError => f. write_str ( "Top level script must be satisfied" ) ,
172
235
Error :: Secp ( ref e) => fmt:: Display :: fmt ( e, f) ,
236
+ Error :: SchnorrSig ( ref s) => write ! ( f, "Schnorr sig error: {}" , s) ,
173
237
Error :: SighashError ( ref e) => fmt:: Display :: fmt ( e, f) ,
174
238
Error :: UncompressedPubkey => {
175
239
f. write_str ( "uncompressed pubkey in non-legacy descriptor" )
0 commit comments