1use std::io;
16use std::collections::btree_map::{BTreeMap, Entry};
17
18use blockdata::script::Script;
19use blockdata::transaction::{SigHashType, Transaction, TxOut};
20use consensus::encode;
21use util::bip32::KeySource;
22use hashes::{self, hash160, ripemd160, sha256, sha256d};
23use util::key::PublicKey;
24use util::psbt;
25use util::psbt::map::Map;
26use util::psbt::raw;
27use util::psbt::serialize::Deserialize;
28use util::psbt::{Error, error};
29
30const PSBT_IN_NON_WITNESS_UTXO: u8 = 0x00;
32const PSBT_IN_WITNESS_UTXO: u8 = 0x01;
34const PSBT_IN_PARTIAL_SIG: u8 = 0x02;
36const PSBT_IN_SIGHASH_TYPE: u8 = 0x03;
38const PSBT_IN_REDEEM_SCRIPT: u8 = 0x04;
40const PSBT_IN_WITNESS_SCRIPT: u8 = 0x05;
42const PSBT_IN_BIP32_DERIVATION: u8 = 0x06;
44const PSBT_IN_FINAL_SCRIPTSIG: u8 = 0x07;
46const PSBT_IN_FINAL_SCRIPTWITNESS: u8 = 0x08;
48const PSBT_IN_RIPEMD160: u8 = 0x0a;
50const PSBT_IN_SHA256: u8 = 0x0b;
52const PSBT_IN_HASH160: u8 = 0x0c;
54const PSBT_IN_HASH256: u8 = 0x0d;
56const PSBT_IN_PROPRIETARY: u8 = 0xFC;
58
59#[derive(Clone, Default, Debug, PartialEq)]
62#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
63pub struct Input {
64 pub non_witness_utxo: Option<Transaction>,
68 pub witness_utxo: Option<TxOut>,
72 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_byte_values"))]
75 pub partial_sigs: BTreeMap<PublicKey, Vec<u8>>,
76 pub sighash_type: Option<SigHashType>,
79 pub redeem_script: Option<Script>,
81 pub witness_script: Option<Script>,
83 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq"))]
86 pub bip32_derivation: BTreeMap<PublicKey, KeySource>,
87 pub final_script_sig: Option<Script>,
90 pub final_script_witness: Option<Vec<Vec<u8>>>,
93 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_byte_values"))]
96 pub ripemd160_preimages: BTreeMap<ripemd160::Hash, Vec<u8>>,
97 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_byte_values"))]
99 pub sha256_preimages: BTreeMap<sha256::Hash, Vec<u8>>,
100 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_byte_values"))]
102 pub hash160_preimages: BTreeMap<hash160::Hash, Vec<u8>>,
103 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_byte_values"))]
105 pub hash256_preimages: BTreeMap<sha256d::Hash, Vec<u8>>,
106 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq_byte_values"))]
108 pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
109 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq_byte_values"))]
111 pub unknown: BTreeMap<raw::Key, Vec<u8>>,
112}
113
114impl Map for Input {
115 fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), encode::Error> {
116 let raw::Pair {
117 key: raw_key,
118 value: raw_value,
119 } = pair;
120
121 match raw_key.type_value {
122 PSBT_IN_NON_WITNESS_UTXO => {
123 impl_psbt_insert_pair! {
124 self.non_witness_utxo <= <raw_key: _>|<raw_value: Transaction>
125 }
126 }
127 PSBT_IN_WITNESS_UTXO => {
128 impl_psbt_insert_pair! {
129 self.witness_utxo <= <raw_key: _>|<raw_value: TxOut>
130 }
131 }
132 PSBT_IN_PARTIAL_SIG => {
133 impl_psbt_insert_pair! {
134 self.partial_sigs <= <raw_key: PublicKey>|<raw_value: Vec<u8>>
135 }
136 }
137 PSBT_IN_SIGHASH_TYPE => {
138 impl_psbt_insert_pair! {
139 self.sighash_type <= <raw_key: _>|<raw_value: SigHashType>
140 }
141 }
142 PSBT_IN_REDEEM_SCRIPT => {
143 impl_psbt_insert_pair! {
144 self.redeem_script <= <raw_key: _>|<raw_value: Script>
145 }
146 }
147 PSBT_IN_WITNESS_SCRIPT => {
148 impl_psbt_insert_pair! {
149 self.witness_script <= <raw_key: _>|<raw_value: Script>
150 }
151 }
152 PSBT_IN_BIP32_DERIVATION => {
153 impl_psbt_insert_pair! {
154 self.bip32_derivation <= <raw_key: PublicKey>|<raw_value: KeySource>
155 }
156 }
157 PSBT_IN_FINAL_SCRIPTSIG => {
158 impl_psbt_insert_pair! {
159 self.final_script_sig <= <raw_key: _>|<raw_value: Script>
160 }
161 }
162 PSBT_IN_FINAL_SCRIPTWITNESS => {
163 impl_psbt_insert_pair! {
164 self.final_script_witness <= <raw_key: _>|<raw_value: Vec<Vec<u8>>>
165 }
166 }
167 PSBT_IN_RIPEMD160 => {
168 psbt_insert_hash_pair(&mut self.ripemd160_preimages, raw_key, raw_value, error::PsbtHash::Ripemd)?;
169 }
170 PSBT_IN_SHA256 => {
171 psbt_insert_hash_pair(&mut self.sha256_preimages, raw_key, raw_value, error::PsbtHash::Sha256)?;
172 }
173 PSBT_IN_HASH160 => {
174 psbt_insert_hash_pair(&mut self.hash160_preimages, raw_key, raw_value, error::PsbtHash::Hash160)?;
175 }
176 PSBT_IN_HASH256 => {
177 psbt_insert_hash_pair(&mut self.hash256_preimages, raw_key, raw_value, error::PsbtHash::Hash256)?;
178 }
179 PSBT_IN_PROPRIETARY => match self.proprietary.entry(raw::ProprietaryKey::from_key(raw_key.clone())?) {
180 ::std::collections::btree_map::Entry::Vacant(empty_key) => {empty_key.insert(raw_value);},
181 ::std::collections::btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key).into()),
182 }
183 _ => match self.unknown.entry(raw_key) {
184 Entry::Vacant(empty_key) => {
185 empty_key.insert(raw_value);
186 }
187 Entry::Occupied(k) => {
188 return Err(Error::DuplicateKey(k.key().clone()).into())
189 }
190 },
191 }
192
193 Ok(())
194 }
195
196 fn get_pairs(&self) -> Result<Vec<raw::Pair>, io::Error> {
197 let mut rv: Vec<raw::Pair> = Default::default();
198
199 impl_psbt_get_pair! {
200 rv.push(self.non_witness_utxo as <PSBT_IN_NON_WITNESS_UTXO, _>|<Transaction>)
201 }
202
203 impl_psbt_get_pair! {
204 rv.push(self.witness_utxo as <PSBT_IN_WITNESS_UTXO, _>|<TxOut>)
205 }
206
207 impl_psbt_get_pair! {
208 rv.push(self.partial_sigs as <PSBT_IN_PARTIAL_SIG, PublicKey>|<Vec<u8>>)
209 }
210
211 impl_psbt_get_pair! {
212 rv.push(self.sighash_type as <PSBT_IN_SIGHASH_TYPE, _>|<SigHashType>)
213 }
214
215 impl_psbt_get_pair! {
216 rv.push(self.redeem_script as <PSBT_IN_REDEEM_SCRIPT, _>|<Script>)
217 }
218
219 impl_psbt_get_pair! {
220 rv.push(self.witness_script as <PSBT_IN_WITNESS_SCRIPT, _>|<Script>)
221 }
222
223 impl_psbt_get_pair! {
224 rv.push(self.bip32_derivation as <PSBT_IN_BIP32_DERIVATION, PublicKey>|<KeySource>)
225 }
226
227 impl_psbt_get_pair! {
228 rv.push(self.final_script_sig as <PSBT_IN_FINAL_SCRIPTSIG, _>|<Script>)
229 }
230
231 impl_psbt_get_pair! {
232 rv.push(self.final_script_witness as <PSBT_IN_FINAL_SCRIPTWITNESS, _>|<Script>)
233 }
234
235 impl_psbt_get_pair! {
236 rv.push(self.ripemd160_preimages as <PSBT_IN_RIPEMD160, ripemd160::Hash>|<Vec<u8>>)
237 }
238
239 impl_psbt_get_pair! {
240 rv.push(self.sha256_preimages as <PSBT_IN_SHA256, sha256::Hash>|<Vec<u8>>)
241 }
242
243 impl_psbt_get_pair! {
244 rv.push(self.hash160_preimages as <PSBT_IN_HASH160, hash160::Hash>|<Vec<u8>>)
245 }
246
247 impl_psbt_get_pair! {
248 rv.push(self.hash256_preimages as <PSBT_IN_HASH256, sha256d::Hash>|<Vec<u8>>)
249 }
250
251 for (key, value) in self.proprietary.iter() {
252 rv.push(raw::Pair {
253 key: key.to_key(),
254 value: value.clone(),
255 });
256 }
257
258 for (key, value) in self.unknown.iter() {
259 rv.push(raw::Pair {
260 key: key.clone(),
261 value: value.clone(),
262 });
263 }
264
265 Ok(rv)
266 }
267
268 fn merge(&mut self, other: Self) -> Result<(), psbt::Error> {
269 merge!(non_witness_utxo, self, other);
270
271 if let (&None, Some(witness_utxo)) = (&self.witness_utxo, other.witness_utxo) {
272 self.witness_utxo = Some(witness_utxo);
273 self.non_witness_utxo = None; }
275
276 self.partial_sigs.extend(other.partial_sigs);
277 self.bip32_derivation.extend(other.bip32_derivation);
278 self.ripemd160_preimages.extend(other.ripemd160_preimages);
279 self.sha256_preimages.extend(other.sha256_preimages);
280 self.hash160_preimages.extend(other.hash160_preimages);
281 self.hash256_preimages.extend(other.hash256_preimages);
282 self.proprietary.extend(other.proprietary);
283 self.unknown.extend(other.unknown);
284
285 merge!(redeem_script, self, other);
286 merge!(witness_script, self, other);
287 merge!(final_script_sig, self, other);
288 merge!(final_script_witness, self, other);
289
290 Ok(())
291 }
292}
293
294impl_psbtmap_consensus_enc_dec_oding!(Input);
295
296fn psbt_insert_hash_pair<H>(
297 map: &mut BTreeMap<H, Vec<u8>>,
298 raw_key: raw::Key,
299 raw_value: Vec<u8>,
300 hash_type: error::PsbtHash,
301) -> Result<(), encode::Error>
302where
303 H: hashes::Hash + Deserialize,
304{
305 if raw_key.key.is_empty() {
306 return Err(psbt::Error::InvalidKey(raw_key).into());
307 }
308 let key_val: H = Deserialize::deserialize(&raw_key.key)?;
309 match map.entry(key_val) {
310 Entry::Vacant(empty_key) => {
311 let val: Vec<u8> = Deserialize::deserialize(&raw_value)?;
312 if <H as hashes::Hash>::hash(&val) != key_val {
313 return Err(psbt::Error::InvalidPreimageHashPair {
314 preimage: val,
315 hash: Vec::from(key_val.borrow()),
316 hash_type: hash_type,
317 }
318 .into());
319 }
320 empty_key.insert(val);
321 Ok(())
322 }
323 Entry::Occupied(_) => return Err(psbt::Error::DuplicateKey(raw_key).into()),
324 }
325}