miniscript_debug/interpreter/
error.rs1use core::fmt;
16#[cfg(feature = "std")]
17use std::error;
18
19use bitcoin::hashes::hash160;
20use bitcoin::hashes::hex::ToHex;
21use bitcoin::util::taproot;
22use bitcoin::{self, secp256k1};
23
24use super::BitcoinKey;
25use crate::prelude::*;
26
27#[derive(Debug)]
29pub enum Error {
30 AbsoluteLocktimeNotMet(u32),
32 AbsoluteLocktimeComparisonInvalid(u32, u32),
34 CannotInferTrDescriptors,
39 ControlBlockParse(taproot::TaprootError),
41 ControlBlockVerificationError,
43 CouldNotEvaluate,
45 EcdsaSig(bitcoin::EcdsaSigError),
47 ExpectedPush,
49 HashPreimageLengthMismatch,
51 IncorrectPubkeyHash,
53 IncorrectScriptHash,
55 IncorrectWPubkeyHash,
57 IncorrectWScriptHash,
59 InsufficientSignaturesMultiSig,
61 InvalidSchnorrSighashType(Vec<u8>),
63 InvalidEcdsaSignature(bitcoin::PublicKey),
65 InvalidSchnorrSignature(bitcoin::XOnlyPublicKey),
67 NonStandardSighash(Vec<u8>),
69 Miniscript(crate::Error),
71 MissingExtraZeroMultiSig,
73 MultiSigEvaluationError,
78 NonEmptyWitness,
80 NonEmptyScriptSig,
82 PkEvaluationError(PkEvalErrInner),
89 PkHashVerifyFail(hash160::Hash),
92 PubkeyParseError,
95 XOnlyPublicKeyParseError,
97 RelativeLocktimeNotMet(u32),
99 Secp(secp256k1::Error),
101 ScriptSatisfactionError,
103 SchnorrSig(bitcoin::SchnorrSigError),
105 SighashError(bitcoin::util::sighash::Error),
107 TapAnnexUnsupported,
109 UncompressedPubkey,
112 UnexpectedStackBoolean,
115 UnexpectedStackEnd,
117 UnexpectedStackElementPush,
121 VerifyFailed,
124}
125
126impl fmt::Display for Error {
127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128 match *self {
129 Error::AbsoluteLocktimeNotMet(n) => write!(
130 f,
131 "required absolute locktime CLTV of {} blocks, not met",
132 n
133 ),
134 Error::AbsoluteLocktimeComparisonInvalid(n, lock_time) => write!(
135 f,
136 "could not satisfy, lock time values are different units n: {} lock_time: {}",
137 n, lock_time
138 ),
139 Error::CannotInferTrDescriptors => write!(f, "Cannot infer taproot descriptors"),
140 Error::ControlBlockParse(ref e) => write!(f, "Control block parse error {}", e),
141 Error::ControlBlockVerificationError => {
142 f.write_str("Control block verification failed")
143 }
144 Error::EcdsaSig(ref s) => write!(f, "Ecdsa sig error: {}", s),
145 Error::ExpectedPush => f.write_str("expected push in script"),
146 Error::CouldNotEvaluate => f.write_str("Interpreter Error: Could not evaluate"),
147 Error::HashPreimageLengthMismatch => f.write_str("Hash preimage should be 32 bytes"),
148 Error::IncorrectPubkeyHash => f.write_str("public key did not match scriptpubkey"),
149 Error::IncorrectScriptHash => f.write_str("redeem script did not match scriptpubkey"),
150 Error::IncorrectWPubkeyHash => {
151 f.write_str("public key did not match scriptpubkey (segwit v0)")
152 }
153 Error::IncorrectWScriptHash => f.write_str("witness script did not match scriptpubkey"),
154 Error::InsufficientSignaturesMultiSig => f.write_str("Insufficient signatures for CMS"),
155 Error::InvalidSchnorrSighashType(ref sig) => write!(
156 f,
157 "Invalid sighash type for schnorr signature '{}'",
158 sig.to_hex()
159 ),
160 Error::InvalidEcdsaSignature(pk) => write!(f, "bad ecdsa signature with pk {}", pk),
161 Error::InvalidSchnorrSignature(pk) => write!(f, "bad schnorr signature with pk {}", pk),
162 Error::NonStandardSighash(ref sig) => write!(
163 f,
164 "Non standard sighash type for signature '{}'",
165 sig.to_hex()
166 ),
167 Error::NonEmptyWitness => f.write_str("legacy spend had nonempty witness"),
168 Error::NonEmptyScriptSig => f.write_str("segwit spend had nonempty scriptsig"),
169 Error::Miniscript(ref e) => write!(f, "parse error: {}", e),
170 Error::MissingExtraZeroMultiSig => f.write_str("CMS missing extra zero"),
171 Error::MultiSigEvaluationError => {
172 f.write_str("CMS script aborted, incorrect satisfaction/dissatisfaction")
173 }
174 Error::PkEvaluationError(ref key) => write!(f, "Incorrect Signature for pk {}", key),
175 Error::PkHashVerifyFail(ref hash) => write!(f, "Pubkey Hash check failed {}", hash),
176 Error::PubkeyParseError => f.write_str("could not parse pubkey"),
177 Error::XOnlyPublicKeyParseError => f.write_str("could not parse x-only pubkey"),
178 Error::RelativeLocktimeNotMet(n) => {
179 write!(f, "required relative locktime CSV of {} blocks, not met", n)
180 }
181 Error::ScriptSatisfactionError => f.write_str("Top level script must be satisfied"),
182 Error::Secp(ref e) => fmt::Display::fmt(e, f),
183 Error::SchnorrSig(ref s) => write!(f, "Schnorr sig error: {}", s),
184 Error::SighashError(ref e) => fmt::Display::fmt(e, f),
185 Error::TapAnnexUnsupported => f.write_str("Encountered annex element"),
186 Error::UncompressedPubkey => {
187 f.write_str("uncompressed pubkey in non-legacy descriptor")
188 }
189 Error::UnexpectedStackBoolean => {
190 f.write_str("Expected Stack Push operation, found stack bool")
191 }
192 Error::UnexpectedStackElementPush => write!(f, "Got {}, expected Stack Boolean", 1),
193 Error::UnexpectedStackEnd => f.write_str("unexpected end of stack"),
194 Error::VerifyFailed => {
195 f.write_str("Expected Satisfied Boolean at stack top for VERIFY")
196 }
197 }
198 }
199}
200
201#[cfg(feature = "std")]
202impl error::Error for Error {
203 fn cause(&self) -> Option<&dyn error::Error> {
204 use self::Error::*;
205
206 match self {
207 AbsoluteLocktimeNotMet(_)
208 | AbsoluteLocktimeComparisonInvalid(_, _)
209 | CannotInferTrDescriptors
210 | ControlBlockVerificationError
211 | CouldNotEvaluate
212 | ExpectedPush
213 | HashPreimageLengthMismatch
214 | IncorrectPubkeyHash
215 | IncorrectScriptHash
216 | IncorrectWPubkeyHash
217 | IncorrectWScriptHash
218 | InsufficientSignaturesMultiSig
219 | InvalidEcdsaSignature(_)
220 | InvalidSchnorrSignature(_)
221 | InvalidSchnorrSighashType(_)
222 | NonStandardSighash(_)
223 | MissingExtraZeroMultiSig
224 | MultiSigEvaluationError
225 | NonEmptyWitness
226 | NonEmptyScriptSig
227 | PubkeyParseError
228 | XOnlyPublicKeyParseError
229 | PkEvaluationError(_)
230 | PkHashVerifyFail(_)
231 | RelativeLocktimeNotMet(_)
232 | ScriptSatisfactionError
233 | TapAnnexUnsupported
234 | UncompressedPubkey
235 | UnexpectedStackBoolean
236 | UnexpectedStackEnd
237 | UnexpectedStackElementPush
238 | VerifyFailed => None,
239 ControlBlockParse(e) => Some(e),
240 EcdsaSig(e) => Some(e),
241 Miniscript(e) => Some(e),
242 Secp(e) => Some(e),
243 SchnorrSig(e) => Some(e),
244 SighashError(e) => Some(e),
245 }
246 }
247}
248
249#[doc(hidden)]
250impl From<secp256k1::Error> for Error {
251 fn from(e: secp256k1::Error) -> Error {
252 Error::Secp(e)
253 }
254}
255
256#[doc(hidden)]
257impl From<bitcoin::util::sighash::Error> for Error {
258 fn from(e: bitcoin::util::sighash::Error) -> Error {
259 Error::SighashError(e)
260 }
261}
262
263#[doc(hidden)]
264impl From<bitcoin::EcdsaSigError> for Error {
265 fn from(e: bitcoin::EcdsaSigError) -> Error {
266 Error::EcdsaSig(e)
267 }
268}
269
270#[doc(hidden)]
271impl From<bitcoin::SchnorrSigError> for Error {
272 fn from(e: bitcoin::SchnorrSigError) -> Error {
273 Error::SchnorrSig(e)
274 }
275}
276
277#[doc(hidden)]
278impl From<crate::Error> for Error {
279 fn from(e: crate::Error) -> Error {
280 Error::Miniscript(e)
281 }
282}
283
284#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
287pub enum PkEvalErrInner {
288 FullKey(bitcoin::PublicKey),
290 XOnlyKey(bitcoin::XOnlyPublicKey),
292}
293
294impl From<BitcoinKey> for PkEvalErrInner {
295 fn from(pk: BitcoinKey) -> Self {
296 match pk {
297 BitcoinKey::Fullkey(pk) => PkEvalErrInner::FullKey(pk),
298 BitcoinKey::XOnlyPublicKey(xpk) => PkEvalErrInner::XOnlyKey(xpk),
299 }
300 }
301}
302
303impl fmt::Display for PkEvalErrInner {
304 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305 match self {
306 PkEvalErrInner::FullKey(pk) => pk.fmt(f),
307 PkEvalErrInner::XOnlyKey(xpk) => xpk.fmt(f),
308 }
309 }
310}