13
13
//
14
14
15
15
use bitcoin:: hashes:: { hash160, hex:: ToHex } ;
16
+ use bitcoin:: util:: taproot;
16
17
use bitcoin:: { self , secp256k1} ;
17
18
use std:: { error, fmt} ;
18
19
20
+ use super :: BitcoinKey ;
21
+
19
22
/// Detailed Error type for Interpreter
20
23
#[ derive( Debug ) ]
21
24
pub enum Error {
22
25
/// Could not satisfy, absolute locktime not met
23
26
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 ,
24
36
/// General Interpreter error.
25
37
CouldNotEvaluate ,
38
+ /// EcdsaSig related error
39
+ EcdsaSig ( bitcoin:: EcdsaSigError ) ,
26
40
/// We expected a push (including a `OP_1` but no other numeric pushes)
27
41
ExpectedPush ,
28
42
/// The preimage to the hash function must be exactly 32 bytes.
@@ -39,8 +53,10 @@ pub enum Error {
39
53
InsufficientSignaturesMultiSig ,
40
54
/// Invalid Sighash type
41
55
InvalidSchnorrSigHashType ( Vec < u8 > ) ,
56
+ /// ecdsa Signature failed to verify
57
+ InvalidEcdsaSignature ( bitcoin:: PublicKey ) ,
42
58
/// Signature failed to verify
43
- InvalidSignature ( bitcoin:: PublicKey ) ,
59
+ InvalidSchnorrSignature ( bitcoin:: XOnlyPublicKey ) ,
44
60
/// Last byte of this signature isn't a standard sighash type
45
61
NonStandardSigHash ( Vec < u8 > ) ,
46
62
/// Miniscript error
@@ -60,21 +76,29 @@ pub enum Error {
60
76
/// Any input witness apart from sat(sig) or nsat(0) leads to
61
77
/// this error. This is network standardness assumption and miniscript only
62
78
/// 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 ) ,
64
82
/// The Public Key hash check for the given pubkey. This occurs in `PkH`
65
83
/// node when the given key does not match to Hash in script.
66
84
PkHashVerifyFail ( hash160:: Hash ) ,
67
85
/// Parse Error while parsing a `stack::Element::Push` as a Pubkey. Both
68
86
/// 33 byte and 65 bytes are supported.
69
87
PubkeyParseError ,
88
+ /// Parse Error while parsing a `stack::Element::Push` as a XOnlyPublicKey (32 bytes)
89
+ XOnlyPublicKeyParseError ,
70
90
/// Could not satisfy, relative locktime not met
71
91
RelativeLocktimeNotMet ( u32 ) ,
72
92
/// Forward-secp related errors
73
93
Secp ( secp256k1:: Error ) ,
74
94
/// Miniscript requires the entire top level script to be satisfied.
75
95
ScriptSatisfactionError ,
96
+ /// Schnorr Signature error
97
+ SchnorrSig ( bitcoin:: SchnorrSigError ) ,
76
98
/// Errors in signature hash calculations
77
99
SighashError ( bitcoin:: util:: sighash:: Error ) ,
100
+ /// Taproot Annex Unsupported
101
+ TapAnnexUnsupported ,
78
102
/// An uncompressed public key was encountered in a context where it is
79
103
/// disallowed (e.g. in a Segwit script or p2wpkh output)
80
104
UncompressedPubkey ,
@@ -92,6 +116,34 @@ pub enum Error {
92
116
VerifyFailed ,
93
117
}
94
118
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
+
95
147
#[ doc( hidden) ]
96
148
impl From < secp256k1:: Error > for Error {
97
149
fn from ( e : secp256k1:: Error ) -> Error {
@@ -106,6 +158,20 @@ impl From<bitcoin::util::sighash::Error> for Error {
106
158
}
107
159
}
108
160
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
+
109
175
#[ doc( hidden) ]
110
176
impl From < :: Error > for Error {
111
177
fn from ( e : :: Error ) -> Error {
@@ -130,6 +196,12 @@ impl fmt::Display for Error {
130
196
"required absolute locktime CLTV of {} blocks, not met" ,
131
197
n
132
198
) ,
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) ,
133
205
Error :: ExpectedPush => f. write_str ( "expected push in script" ) ,
134
206
Error :: CouldNotEvaluate => f. write_str ( "Interpreter Error: Could not evaluate" ) ,
135
207
Error :: HashPreimageLengthMismatch => f. write_str ( "Hash preimage should be 32 bytes" ) ,
@@ -147,7 +219,8 @@ impl fmt::Display for Error {
147
219
sig. to_hex( )
148
220
)
149
221
}
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) ,
151
224
Error :: NonStandardSigHash ( ref sig) => {
152
225
write ! (
153
226
f,
@@ -165,12 +238,15 @@ impl fmt::Display for Error {
165
238
Error :: PkEvaluationError ( ref key) => write ! ( f, "Incorrect Signature for pk {}" , key) ,
166
239
Error :: PkHashVerifyFail ( ref hash) => write ! ( f, "Pubkey Hash check failed {}" , hash) ,
167
240
Error :: PubkeyParseError => f. write_str ( "could not parse pubkey" ) ,
241
+ Error :: XOnlyPublicKeyParseError => f. write_str ( "could not parse x-only pubkey" ) ,
168
242
Error :: RelativeLocktimeNotMet ( n) => {
169
243
write ! ( f, "required relative locktime CSV of {} blocks, not met" , n)
170
244
}
171
245
Error :: ScriptSatisfactionError => f. write_str ( "Top level script must be satisfied" ) ,
172
246
Error :: Secp ( ref e) => fmt:: Display :: fmt ( e, f) ,
247
+ Error :: SchnorrSig ( ref s) => write ! ( f, "Schnorr sig error: {}" , s) ,
173
248
Error :: SighashError ( ref e) => fmt:: Display :: fmt ( e, f) ,
249
+ Error :: TapAnnexUnsupported => f. write_str ( "Encountered annex element" ) ,
174
250
Error :: UncompressedPubkey => {
175
251
f. write_str ( "uncompressed pubkey in non-legacy descriptor" )
176
252
}
0 commit comments