1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use crate::prelude::*;
use core::fmt;
use crate::blockdata::transaction::Transaction;
use crate::consensus::encode;
use crate::util::psbt::raw;
use crate::hashes;
use crate::util::bip32::ExtendedPubKey;
use crate::internal_macros::write_err;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum PsbtHash {
Ripemd,
Sha256,
Hash160,
Hash256,
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[non_exhaustive]
pub enum Error {
InvalidMagic,
MissingUtxo,
InvalidSeparator,
PsbtUtxoOutOfbounds,
InvalidKey(raw::Key),
InvalidProprietaryKey,
DuplicateKey(raw::Key),
UnsignedTxHasScriptSigs,
UnsignedTxHasScriptWitnesses,
MustHaveUnsignedTx,
NoMorePairs,
UnexpectedUnsignedTx {
expected: Box<Transaction>,
actual: Box<Transaction>,
},
NonStandardSighashType(u32),
HashParse(hashes::Error),
InvalidPreimageHashPair {
hash_type: PsbtHash,
preimage: Box<[u8]>,
hash: Box<[u8]>,
},
CombineInconsistentKeySources(Box<ExtendedPubKey>),
ConsensusEncoding,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::InvalidMagic => f.write_str("invalid magic"),
Error::MissingUtxo => f.write_str("UTXO information is not present in PSBT"),
Error::InvalidSeparator => f.write_str("invalid separator"),
Error::PsbtUtxoOutOfbounds => f.write_str("output index is out of bounds of non witness script output array"),
Error::InvalidKey(ref rkey) => write!(f, "invalid key: {}", rkey),
Error::InvalidProprietaryKey => write!(f, "non-proprietary key type found when proprietary key was expected"),
Error::DuplicateKey(ref rkey) => write!(f, "duplicate key: {}", rkey),
Error::UnsignedTxHasScriptSigs => f.write_str("the unsigned transaction has script sigs"),
Error::UnsignedTxHasScriptWitnesses => f.write_str("the unsigned transaction has script witnesses"),
Error::MustHaveUnsignedTx => {
f.write_str("partially signed transactions must have an unsigned transaction")
}
Error::NoMorePairs => f.write_str("no more key-value pairs for this psbt map"),
Error::UnexpectedUnsignedTx { expected: ref e, actual: ref a } => write!(f, "different unsigned transaction: expected {}, actual {}", e.txid(), a.txid()),
Error::NonStandardSighashType(ref sht) => write!(f, "non-standard sighash type: {}", sht),
Error::HashParse(ref e) => write_err!(f, "hash parse error"; e),
Error::InvalidPreimageHashPair{ref preimage, ref hash, ref hash_type} => {
write!(f, "Preimage {:?} does not match {:?} hash {:?}", preimage, hash_type, hash )
},
Error::CombineInconsistentKeySources(ref s) => { write!(f, "combine conflict: {}", s) },
Error::ConsensusEncoding => f.write_str("bitcoin consensus or BIP-174 encoding error"),
}
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use self::Error::*;
match self {
HashParse(e) => Some(e),
| InvalidMagic
| MissingUtxo
| InvalidSeparator
| PsbtUtxoOutOfbounds
| InvalidKey(_)
| InvalidProprietaryKey
| DuplicateKey(_)
| UnsignedTxHasScriptSigs
| UnsignedTxHasScriptWitnesses
| MustHaveUnsignedTx
| NoMorePairs
| UnexpectedUnsignedTx { .. }
| NonStandardSighashType(_)
| InvalidPreimageHashPair{ .. }
| CombineInconsistentKeySources(_)
| ConsensusEncoding => None,
}
}
}
#[doc(hidden)]
impl From<hashes::Error> for Error {
fn from(e: hashes::Error) -> Error {
Error::HashParse(e)
}
}
impl From<encode::Error> for Error {
fn from(err: encode::Error) -> Self {
match err {
encode::Error::Psbt(err) => err,
_ => Error::ConsensusEncoding,
}
}
}