1use core::fmt;
4
5use bitcoin::bip32::Xpub;
6use bitcoin::blockdata::transaction::Transaction;
7use bitcoin::consensus::encode;
8use bitcoin::{hashes, secp256k1};
9
10use crate::error::write_err;
11use crate::io;
12use crate::prelude::*;
13use crate::v0::bitcoin::raw;
14
15#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
17pub enum PsbtHash {
18 Ripemd,
19 Sha256,
20 Hash160,
21 Hash256,
22}
23#[derive(Debug)]
25#[non_exhaustive]
26pub enum Error {
27 InvalidMagic,
30 MissingUtxo,
32 InvalidSeparator,
34 PsbtUtxoOutOfbounds,
36 InvalidKey(raw::Key),
38 InvalidProprietaryKey,
40 DuplicateKey(raw::Key),
42 UnsignedTxHasScriptSigs,
44 UnsignedTxHasScriptWitnesses,
46 MustHaveUnsignedTx,
48 NoMorePairs,
50 UnexpectedUnsignedTx {
53 expected: Box<Transaction>,
55 actual: Box<Transaction>,
57 },
58 NonStandardSighashType(u32),
60 InvalidHash(hashes::FromSliceError),
62 InvalidPreimageHashPair {
64 hash_type: PsbtHash,
66 preimage: Box<[u8]>,
68 hash: Box<[u8]>,
70 },
71 CombineInconsistentKeySources(Box<Xpub>),
74 ConsensusEncoding(encode::Error),
76 NegativeFee,
78 FeeOverflow,
80 InvalidPublicKey(bitcoin::key::FromSliceError),
82 InvalidSecp256k1PublicKey(secp256k1::Error),
84 InvalidXOnlyPublicKey,
86 InvalidEcdsaSignature(bitcoin::ecdsa::Error),
88 InvalidTaprootSignature(bitcoin::taproot::SigFromSliceError),
90 InvalidControlBlock,
92 InvalidLeafVersion,
94 Taproot(&'static str),
96 TapTree(bitcoin::taproot::IncompleteBuilderError),
98 XPubKey(&'static str),
100 Version(&'static str),
102 PartialDataConsumption,
104 Io(io::Error),
106 ExcludedKey {
108 key_type_value: u8,
110 },
111}
112
113impl fmt::Display for Error {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 use Error::*;
116
117 match *self {
118 InvalidMagic => f.write_str("invalid magic"),
119 MissingUtxo => f.write_str("UTXO information is not present in PSBT"),
120 InvalidSeparator => f.write_str("invalid separator"),
121 PsbtUtxoOutOfbounds =>
122 f.write_str("output index is out of bounds of non witness script output array"),
123 InvalidKey(ref rkey) => write!(f, "invalid key: {}", rkey),
124 InvalidProprietaryKey =>
125 write!(f, "non-proprietary key type found when proprietary key was expected"),
126 DuplicateKey(ref rkey) => write!(f, "duplicate key: {}", rkey),
127 UnsignedTxHasScriptSigs => f.write_str("the unsigned transaction has script sigs"),
128 UnsignedTxHasScriptWitnesses =>
129 f.write_str("the unsigned transaction has script witnesses"),
130 MustHaveUnsignedTx =>
131 f.write_str("partially signed transactions must have an unsigned transaction"),
132 NoMorePairs => f.write_str("no more key-value pairs for this psbt map"),
133 UnexpectedUnsignedTx { expected: ref e, actual: ref a } => write!(
134 f,
135 "different unsigned transaction: expected {}, actual {}",
136 e.compute_txid(),
137 a.compute_txid()
138 ),
139 NonStandardSighashType(ref sht) => write!(f, "non-standard sighash type: {}", sht),
140 InvalidHash(ref e) => write_err!(f, "invalid hash when parsing slice"; e),
141 InvalidPreimageHashPair { ref preimage, ref hash, ref hash_type } => {
142 write!(f, "Preimage {:?} does not match {:?} hash {:?}", preimage, hash_type, hash)
144 }
145 CombineInconsistentKeySources(ref s) => {
146 write!(f, "combine conflict: {}", s)
147 }
148 ConsensusEncoding(ref e) => write_err!(f, "bitcoin consensus encoding error"; e),
149 NegativeFee => f.write_str("PSBT has a negative fee which is not allowed"),
150 FeeOverflow => f.write_str("integer overflow in fee calculation"),
151 InvalidPublicKey(ref e) => write_err!(f, "invalid public key"; e),
152 InvalidSecp256k1PublicKey(ref e) => write_err!(f, "invalid secp256k1 public key"; e),
153 InvalidXOnlyPublicKey => f.write_str("invalid xonly public key"),
154 InvalidEcdsaSignature(ref e) => write_err!(f, "invalid ECDSA signature"; e),
155 InvalidTaprootSignature(ref e) => write_err!(f, "invalid taproot signature"; e),
156 InvalidControlBlock => f.write_str("invalid control block"),
157 InvalidLeafVersion => f.write_str("invalid leaf version"),
158 Taproot(s) => write!(f, "taproot error - {}", s),
159 TapTree(ref e) => write_err!(f, "taproot tree error"; e),
160 XPubKey(s) => write!(f, "xpub key error - {}", s),
161 Version(s) => write!(f, "version error {}", s),
162 PartialDataConsumption =>
163 f.write_str("data not consumed entirely when explicitly deserializing"),
164 Io(ref e) => write_err!(f, "I/O error"; e),
165 ExcludedKey { key_type_value } => write!(
166 f,
167 "found a keypair type that is explicitly excluded: {}",
168 crate::consts::psbt_in_key_type_value_to_str(key_type_value)
169 ),
170 }
171 }
172}
173
174#[cfg(feature = "std")]
175impl std::error::Error for Error {
176 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
177 use Error::*;
178
179 match *self {
180 InvalidHash(ref e) => Some(e),
181 ConsensusEncoding(ref e) => Some(e),
182 Io(ref e) => Some(e),
183 InvalidMagic
184 | MissingUtxo
185 | InvalidSeparator
186 | PsbtUtxoOutOfbounds
187 | InvalidKey(_)
188 | InvalidProprietaryKey
189 | DuplicateKey(_)
190 | UnsignedTxHasScriptSigs
191 | UnsignedTxHasScriptWitnesses
192 | MustHaveUnsignedTx
193 | NoMorePairs
194 | UnexpectedUnsignedTx { .. }
195 | NonStandardSighashType(_)
196 | InvalidPreimageHashPair { .. }
197 | CombineInconsistentKeySources(_)
198 | NegativeFee
199 | FeeOverflow
200 | InvalidPublicKey(_)
201 | InvalidSecp256k1PublicKey(_)
202 | InvalidXOnlyPublicKey
203 | InvalidEcdsaSignature(_)
204 | InvalidTaprootSignature(_)
205 | InvalidControlBlock
206 | InvalidLeafVersion
207 | Taproot(_)
208 | TapTree(_)
209 | XPubKey(_)
210 | Version(_)
211 | PartialDataConsumption
212 | ExcludedKey { .. } => None,
213 }
214 }
215}
216
217impl From<hashes::FromSliceError> for Error {
218 fn from(e: hashes::FromSliceError) -> Error { Error::InvalidHash(e) }
219}
220
221impl From<encode::Error> for Error {
222 fn from(e: encode::Error) -> Self { Error::ConsensusEncoding(e) }
223}
224
225impl From<io::Error> for Error {
226 fn from(e: io::Error) -> Self { Error::Io(e) }
227}