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