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