1use core::convert::TryFrom;
4
5use bitcoin::bip32::KeySource;
6use bitcoin::blockdata::script::ScriptBuf;
7use bitcoin::blockdata::transaction::{Transaction, TxOut};
8use bitcoin::blockdata::witness::Witness;
9use bitcoin::hashes::{self, hash160, ripemd160, sha256, sha256d};
10use bitcoin::key::PublicKey;
11use bitcoin::secp256k1::XOnlyPublicKey;
12use bitcoin::sighash::{EcdsaSighashType, NonStandardSighashTypeError, TapSighashType};
13use bitcoin::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapNodeHash};
14use bitcoin::{ecdsa, taproot};
15
16use crate::prelude::*;
17use crate::sighash_type::*;
18use crate::v0::bitcoin::map::Map;
19use crate::v0::bitcoin::serialize::Deserialize;
20use crate::v0::bitcoin::{self as psbt, error, raw, Error};
21
22const PSBT_IN_NON_WITNESS_UTXO: u8 = 0x00;
24const PSBT_IN_WITNESS_UTXO: u8 = 0x01;
26const PSBT_IN_PARTIAL_SIG: u8 = 0x02;
28const PSBT_IN_SIGHASH_TYPE: u8 = 0x03;
30const PSBT_IN_REDEEM_SCRIPT: u8 = 0x04;
32const PSBT_IN_WITNESS_SCRIPT: u8 = 0x05;
34const PSBT_IN_BIP32_DERIVATION: u8 = 0x06;
36const PSBT_IN_FINAL_SCRIPTSIG: u8 = 0x07;
38const PSBT_IN_FINAL_SCRIPTWITNESS: u8 = 0x08;
40const PSBT_IN_RIPEMD160: u8 = 0x0a;
42const PSBT_IN_SHA256: u8 = 0x0b;
44const PSBT_IN_PREVIOUS_TXID: u8 = 0x0e;
46const PSBT_IN_OUTPUT_INDEX: u8 = 0x0f;
48const PSBT_IN_SEQUENCE: u8 = 0x10;
50const PSBT_IN_REQUIRED_TIME_LOCKTIME: u8 = 0x11;
52const PSBT_IN_REQUIRED_HEIGHT_LOCKTIME: u8 = 0x12;
54const PSBT_IN_HASH160: u8 = 0x0c;
56const PSBT_IN_HASH256: u8 = 0x0d;
58const PSBT_IN_TAP_KEY_SIG: u8 = 0x13;
60const PSBT_IN_TAP_SCRIPT_SIG: u8 = 0x14;
62const PSBT_IN_TAP_LEAF_SCRIPT: u8 = 0x15;
64const PSBT_IN_TAP_BIP32_DERIVATION: u8 = 0x16;
66const PSBT_IN_TAP_INTERNAL_KEY: u8 = 0x17;
68const PSBT_IN_TAP_MERKLE_ROOT: u8 = 0x18;
70const PSBT_IN_PROPRIETARY: u8 = 0xFC;
72
73#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
76#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
77pub struct Input {
78 pub non_witness_utxo: Option<Transaction>,
82 pub witness_utxo: Option<TxOut>,
86 pub partial_sigs: BTreeMap<PublicKey, ecdsa::Signature>,
89 pub sighash_type: Option<PsbtSighashType>,
92 pub redeem_script: Option<ScriptBuf>,
94 pub witness_script: Option<ScriptBuf>,
96 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
99 pub bip32_derivation: BTreeMap<PublicKey, KeySource>,
100 pub final_script_sig: Option<ScriptBuf>,
103 pub final_script_witness: Option<Witness>,
106 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
108 pub ripemd160_preimages: BTreeMap<ripemd160::Hash, Vec<u8>>,
109 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
111 pub sha256_preimages: BTreeMap<sha256::Hash, Vec<u8>>,
112 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
114 pub hash160_preimages: BTreeMap<hash160::Hash, Vec<u8>>,
115 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
117 pub hash256_preimages: BTreeMap<sha256d::Hash, Vec<u8>>,
118 pub tap_key_sig: Option<taproot::Signature>,
120 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
122 pub tap_script_sigs: BTreeMap<(XOnlyPublicKey, TapLeafHash), taproot::Signature>,
123 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
125 pub tap_scripts: BTreeMap<ControlBlock, (ScriptBuf, LeafVersion)>,
126 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
128 pub tap_key_origins: BTreeMap<XOnlyPublicKey, (Vec<TapLeafHash>, KeySource)>,
129 pub tap_internal_key: Option<XOnlyPublicKey>,
131 pub tap_merkle_root: Option<TapNodeHash>,
133 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
135 pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
136 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
138 pub unknown: BTreeMap<raw::Key, Vec<u8>>,
139}
140
141impl Input {
142 pub fn ecdsa_hash_ty(&self) -> Result<EcdsaSighashType, NonStandardSighashTypeError> {
149 self.sighash_type
150 .map(|sighash_type| sighash_type.ecdsa_hash_ty())
151 .unwrap_or(Ok(EcdsaSighashType::All))
152 }
153
154 pub fn taproot_hash_ty(&self) -> Result<TapSighashType, InvalidSighashTypeError> {
161 self.sighash_type
162 .map(|sighash_type| sighash_type.taproot_hash_ty())
163 .unwrap_or(Ok(TapSighashType::Default))
164 }
165
166 pub(super) fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), Error> {
167 let raw::Pair { key: raw_key, value: raw_value } = pair;
168
169 match raw_key.type_value {
170 PSBT_IN_NON_WITNESS_UTXO => {
171 impl_psbt_insert_pair! {
172 self.non_witness_utxo <= <raw_key: _>|<raw_value: Transaction>
173 }
174 }
175 PSBT_IN_WITNESS_UTXO => {
176 impl_psbt_insert_pair! {
177 self.witness_utxo <= <raw_key: _>|<raw_value: TxOut>
178 }
179 }
180 PSBT_IN_PARTIAL_SIG => {
181 impl_psbt_insert_pair! {
182 self.partial_sigs <= <raw_key: PublicKey>|<raw_value: ecdsa::Signature>
183 }
184 }
185 PSBT_IN_SIGHASH_TYPE => {
186 impl_psbt_insert_pair! {
187 self.sighash_type <= <raw_key: _>|<raw_value: PsbtSighashType>
188 }
189 }
190 PSBT_IN_REDEEM_SCRIPT => {
191 impl_psbt_insert_pair! {
192 self.redeem_script <= <raw_key: _>|<raw_value: ScriptBuf>
193 }
194 }
195 PSBT_IN_WITNESS_SCRIPT => {
196 impl_psbt_insert_pair! {
197 self.witness_script <= <raw_key: _>|<raw_value: ScriptBuf>
198 }
199 }
200 PSBT_IN_BIP32_DERIVATION => {
201 impl_psbt_insert_pair! {
202 self.bip32_derivation <= <raw_key: PublicKey>|<raw_value: KeySource>
203 }
204 }
205 PSBT_IN_FINAL_SCRIPTSIG => {
206 impl_psbt_insert_pair! {
207 self.final_script_sig <= <raw_key: _>|<raw_value: ScriptBuf>
208 }
209 }
210 PSBT_IN_FINAL_SCRIPTWITNESS => {
211 impl_psbt_insert_pair! {
212 self.final_script_witness <= <raw_key: _>|<raw_value: Witness>
213 }
214 }
215 PSBT_IN_RIPEMD160 => {
216 psbt_insert_hash_pair(
217 &mut self.ripemd160_preimages,
218 raw_key,
219 raw_value,
220 error::PsbtHash::Ripemd,
221 )?;
222 }
223 PSBT_IN_SHA256 => {
224 psbt_insert_hash_pair(
225 &mut self.sha256_preimages,
226 raw_key,
227 raw_value,
228 error::PsbtHash::Sha256,
229 )?;
230 }
231 PSBT_IN_HASH160 => {
232 psbt_insert_hash_pair(
233 &mut self.hash160_preimages,
234 raw_key,
235 raw_value,
236 error::PsbtHash::Hash160,
237 )?;
238 }
239 PSBT_IN_HASH256 => {
240 psbt_insert_hash_pair(
241 &mut self.hash256_preimages,
242 raw_key,
243 raw_value,
244 error::PsbtHash::Hash256,
245 )?;
246 }
247 PSBT_IN_TAP_KEY_SIG => {
248 impl_psbt_insert_pair! {
249 self.tap_key_sig <= <raw_key: _>|<raw_value: taproot::Signature>
250 }
251 }
252 PSBT_IN_TAP_SCRIPT_SIG => {
253 impl_psbt_insert_pair! {
254 self.tap_script_sigs <= <raw_key: (XOnlyPublicKey, TapLeafHash)>|<raw_value: taproot::Signature>
255 }
256 }
257 PSBT_IN_TAP_LEAF_SCRIPT => {
258 impl_psbt_insert_pair! {
259 self.tap_scripts <= <raw_key: ControlBlock>|< raw_value: (ScriptBuf, LeafVersion)>
260 }
261 }
262 PSBT_IN_TAP_BIP32_DERIVATION => {
263 impl_psbt_insert_pair! {
264 self.tap_key_origins <= <raw_key: XOnlyPublicKey>|< raw_value: (Vec<TapLeafHash>, KeySource)>
265 }
266 }
267 PSBT_IN_TAP_INTERNAL_KEY => {
268 impl_psbt_insert_pair! {
269 self.tap_internal_key <= <raw_key: _>|< raw_value: XOnlyPublicKey>
270 }
271 }
272 PSBT_IN_TAP_MERKLE_ROOT => {
273 impl_psbt_insert_pair! {
274 self.tap_merkle_root <= <raw_key: _>|< raw_value: TapNodeHash>
275 }
276 }
277 PSBT_IN_PROPRIETARY => {
278 let key = raw::ProprietaryKey::try_from(raw_key.clone())?;
279 match self.proprietary.entry(key) {
280 btree_map::Entry::Vacant(empty_key) => {
281 empty_key.insert(raw_value);
282 }
283 btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key)),
284 }
285 }
286 v if v == PSBT_IN_PREVIOUS_TXID
287 || v == PSBT_IN_OUTPUT_INDEX
288 || v == PSBT_IN_SEQUENCE
289 || v == PSBT_IN_REQUIRED_TIME_LOCKTIME
290 || v == PSBT_IN_REQUIRED_HEIGHT_LOCKTIME =>
291 {
292 return Err(Error::ExcludedKey { key_type_value: v });
293 }
294 _ => match self.unknown.entry(raw_key) {
295 btree_map::Entry::Vacant(empty_key) => {
296 empty_key.insert(raw_value);
297 }
298 btree_map::Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone())),
299 },
300 }
301
302 Ok(())
303 }
304
305 pub fn combine(&mut self, other: Self) {
307 combine!(non_witness_utxo, self, other);
308
309 if let (&None, Some(witness_utxo)) = (&self.witness_utxo, other.witness_utxo) {
310 self.witness_utxo = Some(witness_utxo);
311 self.non_witness_utxo = None; }
313
314 self.partial_sigs.extend(other.partial_sigs);
315 self.bip32_derivation.extend(other.bip32_derivation);
316 self.ripemd160_preimages.extend(other.ripemd160_preimages);
317 self.sha256_preimages.extend(other.sha256_preimages);
318 self.hash160_preimages.extend(other.hash160_preimages);
319 self.hash256_preimages.extend(other.hash256_preimages);
320 self.tap_script_sigs.extend(other.tap_script_sigs);
321 self.tap_scripts.extend(other.tap_scripts);
322 self.tap_key_origins.extend(other.tap_key_origins);
323 self.proprietary.extend(other.proprietary);
324 self.unknown.extend(other.unknown);
325
326 combine!(redeem_script, self, other);
327 combine!(witness_script, self, other);
328 combine!(final_script_sig, self, other);
329 combine!(final_script_witness, self, other);
330 combine!(tap_key_sig, self, other);
331 combine!(tap_internal_key, self, other);
332 combine!(tap_merkle_root, self, other);
333 }
334}
335
336impl Map for Input {
337 fn get_pairs(&self) -> Vec<raw::Pair> {
338 let mut rv: Vec<raw::Pair> = Default::default();
339
340 impl_psbt_get_pair! {
341 rv.push(self.non_witness_utxo, PSBT_IN_NON_WITNESS_UTXO)
342 }
343
344 impl_psbt_get_pair! {
345 rv.push(self.witness_utxo, PSBT_IN_WITNESS_UTXO)
346 }
347
348 impl_psbt_get_pair! {
349 rv.push_map(self.partial_sigs, PSBT_IN_PARTIAL_SIG)
350 }
351
352 impl_psbt_get_pair! {
353 rv.push(self.sighash_type, PSBT_IN_SIGHASH_TYPE)
354 }
355
356 impl_psbt_get_pair! {
357 rv.push(self.redeem_script, PSBT_IN_REDEEM_SCRIPT)
358 }
359
360 impl_psbt_get_pair! {
361 rv.push(self.witness_script, PSBT_IN_WITNESS_SCRIPT)
362 }
363
364 impl_psbt_get_pair! {
365 rv.push_map(self.bip32_derivation, PSBT_IN_BIP32_DERIVATION)
366 }
367
368 impl_psbt_get_pair! {
369 rv.push(self.final_script_sig, PSBT_IN_FINAL_SCRIPTSIG)
370 }
371
372 impl_psbt_get_pair! {
373 rv.push(self.final_script_witness, PSBT_IN_FINAL_SCRIPTWITNESS)
374 }
375
376 impl_psbt_get_pair! {
377 rv.push_map(self.ripemd160_preimages, PSBT_IN_RIPEMD160)
378 }
379
380 impl_psbt_get_pair! {
381 rv.push_map(self.sha256_preimages, PSBT_IN_SHA256)
382 }
383
384 impl_psbt_get_pair! {
385 rv.push_map(self.hash160_preimages, PSBT_IN_HASH160)
386 }
387
388 impl_psbt_get_pair! {
389 rv.push_map(self.hash256_preimages, PSBT_IN_HASH256)
390 }
391
392 impl_psbt_get_pair! {
393 rv.push(self.tap_key_sig, PSBT_IN_TAP_KEY_SIG)
394 }
395
396 impl_psbt_get_pair! {
397 rv.push_map(self.tap_script_sigs, PSBT_IN_TAP_SCRIPT_SIG)
398 }
399
400 impl_psbt_get_pair! {
401 rv.push_map(self.tap_scripts, PSBT_IN_TAP_LEAF_SCRIPT)
402 }
403
404 impl_psbt_get_pair! {
405 rv.push_map(self.tap_key_origins, PSBT_IN_TAP_BIP32_DERIVATION)
406 }
407
408 impl_psbt_get_pair! {
409 rv.push(self.tap_internal_key, PSBT_IN_TAP_INTERNAL_KEY)
410 }
411
412 impl_psbt_get_pair! {
413 rv.push(self.tap_merkle_root, PSBT_IN_TAP_MERKLE_ROOT)
414 }
415 for (key, value) in self.proprietary.iter() {
416 rv.push(raw::Pair { key: key.to_key(), value: value.clone() });
417 }
418
419 for (key, value) in self.unknown.iter() {
420 rv.push(raw::Pair { key: key.clone(), value: value.clone() });
421 }
422
423 rv
424 }
425}
426
427impl_psbtmap_ser_de_serialize!(Input);
428
429fn psbt_insert_hash_pair<H>(
430 map: &mut BTreeMap<H, Vec<u8>>,
431 raw_key: raw::Key,
432 raw_value: Vec<u8>,
433 hash_type: error::PsbtHash,
434) -> Result<(), Error>
435where
436 H: hashes::Hash + Deserialize,
437{
438 if raw_key.key.is_empty() {
439 return Err(crate::v0::bitcoin::Error::InvalidKey(raw_key));
440 }
441 let key_val: H = Deserialize::deserialize(&raw_key.key)?;
442 match map.entry(key_val) {
443 btree_map::Entry::Vacant(empty_key) => {
444 let val: Vec<u8> = Deserialize::deserialize(&raw_value)?;
445 if <H as hashes::Hash>::hash(&val) != key_val {
446 return Err(crate::v0::bitcoin::Error::InvalidPreimageHashPair {
447 preimage: val.into_boxed_slice(),
448 hash: Box::from(key_val.borrow()),
449 hash_type,
450 });
451 }
452 empty_key.insert(val);
453 Ok(())
454 }
455 btree_map::Entry::Occupied(_) => Err(psbt::Error::DuplicateKey(raw_key)),
456 }
457}