bitcoincash/util/psbt/
error.rs

1// SPDX-License-Identifier: CC0-1.0
2
3use crate::prelude::*;
4
5use core::fmt;
6
7use crate::blockdata::transaction::Transaction;
8use crate::consensus::encode;
9use crate::util::psbt::raw;
10
11use crate::hashes;
12use crate::util::bip32::ExtendedPubKey;
13use crate::internal_macros::write_err;
14
15/// Enum for marking psbt hash error.
16#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
17pub enum PsbtHash {
18    Ripemd,
19    Sha256,
20    Hash160,
21    Hash256,
22}
23/// Ways that a Partially Signed Transaction might fail.
24#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
25#[non_exhaustive]
26pub enum Error {
27    /// Magic bytes for a PSBT must be the ASCII for "psbt" serialized in most
28    /// significant byte order.
29    InvalidMagic,
30    /// Missing both the witness and non-witness utxo.
31    MissingUtxo,
32    /// The separator for a PSBT must be `0xff`.
33    InvalidSeparator,
34    /// Returned when output index is out of bounds in relation to the output in non-witness UTXO.
35    PsbtUtxoOutOfbounds,
36    /// Known keys must be according to spec.
37    InvalidKey(raw::Key),
38    /// Non-proprietary key type found when proprietary key was expected
39    InvalidProprietaryKey,
40    /// Keys within key-value map should never be duplicated.
41    DuplicateKey(raw::Key),
42    /// The scriptSigs for the unsigned transaction must be empty.
43    UnsignedTxHasScriptSigs,
44    /// The scriptWitnesses for the unsigned transaction must be empty.
45    UnsignedTxHasScriptWitnesses,
46    /// A PSBT must have an unsigned transaction.
47    MustHaveUnsignedTx,
48    /// Signals that there are no more key-value pairs in a key-value map.
49    NoMorePairs,
50    /// Attempting to combine with a PSBT describing a different unsigned
51    /// transaction.
52    UnexpectedUnsignedTx {
53        /// Expected
54        expected: Box<Transaction>,
55        /// Actual
56        actual: Box<Transaction>,
57    },
58    /// Unable to parse as a standard sighash type.
59    NonStandardSighashType(u32),
60    /// Parsing errors from bitcoin_hashes
61    HashParse(hashes::Error),
62    /// The pre-image must hash to the correponding psbt hash
63    InvalidPreimageHashPair {
64        /// Hash-type
65        hash_type: PsbtHash,
66        /// Pre-image
67        preimage: Box<[u8]>,
68        /// Hash value
69        hash: Box<[u8]>,
70    },
71    /// Conflicting data during combine procedure:
72    /// global extended public key has inconsistent key sources
73    CombineInconsistentKeySources(Box<ExtendedPubKey>),
74    /// Serialization error in bitcoin consensus-encoded structures
75    ConsensusEncoding,
76}
77
78impl fmt::Display for Error {
79    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80        match *self {
81            Error::InvalidMagic => f.write_str("invalid magic"),
82            Error::MissingUtxo => f.write_str("UTXO information is not present in PSBT"),
83            Error::InvalidSeparator => f.write_str("invalid separator"),
84            Error::PsbtUtxoOutOfbounds => f.write_str("output index is out of bounds of non witness script output array"),
85            Error::InvalidKey(ref rkey) => write!(f, "invalid key: {}", rkey),
86            Error::InvalidProprietaryKey => write!(f, "non-proprietary key type found when proprietary key was expected"),
87            Error::DuplicateKey(ref rkey) => write!(f, "duplicate key: {}", rkey),
88            Error::UnsignedTxHasScriptSigs => f.write_str("the unsigned transaction has script sigs"),
89            Error::UnsignedTxHasScriptWitnesses => f.write_str("the unsigned transaction has script witnesses"),
90            Error::MustHaveUnsignedTx => {
91                f.write_str("partially signed transactions must have an unsigned transaction")
92            }
93            Error::NoMorePairs => f.write_str("no more key-value pairs for this psbt map"),
94            Error::UnexpectedUnsignedTx { expected: ref e, actual: ref a } => write!(f, "different unsigned transaction: expected {}, actual {}", e.txid(), a.txid()),
95            Error::NonStandardSighashType(ref sht) => write!(f, "non-standard sighash type: {}", sht),
96            Error::HashParse(ref e) => write_err!(f, "hash parse error"; e),
97            Error::InvalidPreimageHashPair{ref preimage, ref hash, ref hash_type} => {
98                // directly using debug forms of psbthash enums
99                write!(f, "Preimage {:?} does not match {:?} hash {:?}", preimage, hash_type, hash )
100            },
101            Error::CombineInconsistentKeySources(ref s) => { write!(f, "combine conflict: {}", s) },
102            Error::ConsensusEncoding => f.write_str("bitcoin consensus or BIP-174 encoding error"),
103        }
104    }
105}
106
107#[cfg(feature = "std")]
108#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
109impl std::error::Error for Error {
110    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
111        use self::Error::*;
112
113        match self {
114            HashParse(e) => Some(e),
115            | InvalidMagic
116            | MissingUtxo
117            | InvalidSeparator
118            | PsbtUtxoOutOfbounds
119            | InvalidKey(_)
120            | InvalidProprietaryKey
121            | DuplicateKey(_)
122            | UnsignedTxHasScriptSigs
123            | UnsignedTxHasScriptWitnesses
124            | MustHaveUnsignedTx
125            | NoMorePairs
126            | UnexpectedUnsignedTx { .. }
127            | NonStandardSighashType(_)
128            | InvalidPreimageHashPair{ .. }
129            | CombineInconsistentKeySources(_)
130            | ConsensusEncoding => None,
131        }
132    }
133}
134
135#[doc(hidden)]
136impl From<hashes::Error> for Error {
137    fn from(e: hashes::Error) -> Error {
138        Error::HashParse(e)
139    }
140}
141
142impl From<encode::Error> for Error {
143    fn from(err: encode::Error) -> Self {
144        match err {
145            encode::Error::Psbt(err) => err,
146            _ => Error::ConsensusEncoding,
147        }
148    }
149}