bitcoin/util/psbt/
error.rs

1// Rust Bitcoin Library
2// Written by
3//   The Rust Bitcoin developers
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15use std::error;
16use std::fmt;
17
18use blockdata::transaction::Transaction;
19use consensus::encode;
20use util::psbt::raw;
21
22use hashes;
23
24#[derive(Copy, Clone, PartialEq, Eq, Debug)]
25/// Enum for marking psbt hash error
26pub enum PsbtHash {
27    Ripemd,
28    Sha256,
29    Hash160,
30    Hash256,
31}
32/// Ways that a Partially Signed Transaction might fail.
33#[derive(Clone, PartialEq, Eq, Debug)]
34pub enum Error {
35    /// Magic bytes for a PSBT must be the ASCII for "psbt" serialized in most
36    /// significant byte order.
37    InvalidMagic,
38    /// The separator for a PSBT must be `0xff`.
39    InvalidSeparator,
40    /// Known keys must be according to spec.
41    InvalidKey(raw::Key),
42    /// Non-proprietary key type found when proprietary key was expected
43    InvalidProprietaryKey,
44    /// Keys within key-value map should never be duplicated.
45    DuplicateKey(raw::Key),
46    /// The scriptSigs for the unsigned transaction must be empty.
47    UnsignedTxHasScriptSigs,
48    /// The scriptWitnesses for the unsigned transaction must be empty.
49    UnsignedTxHasScriptWitnesses,
50    /// A PSBT must have an unsigned transaction.
51    MustHaveUnsignedTx,
52    /// Signals that there are no more key-value pairs in a key-value map.
53    NoMorePairs,
54    /// Attempting to merge with a PSBT describing a different unsigned
55    /// transaction.
56    UnexpectedUnsignedTx {
57        /// Expected
58        expected: Transaction,
59        /// Actual
60        actual: Transaction,
61    },
62    /// Unable to parse as a standard SigHash type.
63    NonStandardSigHashType(u32),
64    /// Parsing errors from bitcoin_hashes
65    HashParseError(hashes::Error),
66    /// The pre-image must hash to the correponding psbt hash
67    InvalidPreimageHashPair {
68        /// Hash-type
69        hash_type: PsbtHash,
70        /// Pre-image
71        preimage: Vec<u8>,
72        /// Hash value
73        hash: Vec<u8>,
74    },
75    /// Data inconsistency/conflicting data during merge procedure
76    MergeConflict(String),
77    /// Serialization error in bitcoin consensus-encoded structures
78    ConsensusEncoding,
79}
80
81impl fmt::Display for Error {
82    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83        match *self {
84            Error::InvalidKey(ref rkey) => write!(f, "invalid key: {}", rkey),
85            Error::InvalidProprietaryKey => write!(f, "non-proprietary key type found when proprietary key was expected"),
86            Error::DuplicateKey(ref rkey) => write!(f, "duplicate key: {}", rkey),
87            Error::UnexpectedUnsignedTx { expected: ref e, actual: ref a } => write!(f, "different unsigned transaction: expected {}, actual {}", e.txid(), a.txid()),
88            Error::NonStandardSigHashType(ref sht) => write!(f, "non-standard sighash type: {}", sht),
89            Error::InvalidMagic => f.write_str("invalid magic"),
90            Error::InvalidSeparator => f.write_str("invalid separator"),
91            Error::UnsignedTxHasScriptSigs => f.write_str("the unsigned transaction has script sigs"),
92            Error::UnsignedTxHasScriptWitnesses => f.write_str("the unsigned transaction has script witnesses"),
93            Error::MustHaveUnsignedTx => {
94                f.write_str("partially signed transactions must have an unsigned transaction")
95            }
96            Error::NoMorePairs => f.write_str("no more key-value pairs for this psbt map"),
97            Error::HashParseError(e) => write!(f, "Hash Parse Error: {}", e),
98            Error::InvalidPreimageHashPair{ref preimage, ref hash, ref hash_type} => {
99                // directly using debug forms of psbthash enums
100                write!(f, "Preimage {:?} does not match {:?} hash {:?}", preimage, hash_type, hash )
101            }
102            Error::MergeConflict(ref s) => { write!(f, "Merge conflict: {}", s) }
103            Error::ConsensusEncoding => f.write_str("bitcoin consensus encoding error"),
104        }
105    }
106}
107
108impl error::Error for Error {}
109
110#[doc(hidden)]
111impl From<hashes::Error> for Error {
112    fn from(e: hashes::Error) -> Error {
113        Error::HashParseError(e)
114    }
115}
116
117impl From<encode::Error> for Error {
118    fn from(err: encode::Error) -> Self {
119        match err {
120            encode::Error::Psbt(err) => err,
121            _ => Error::ConsensusEncoding,
122        }
123    }
124}