1use core::convert::TryFrom;
4use core::fmt;
5
6use bitcoin::bip32::KeySource;
7use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash as _};
8use bitcoin::hex::DisplayHex;
9use bitcoin::io::Read;
10use bitcoin::key::{PublicKey, XOnlyPublicKey};
11use bitcoin::locktime::absolute;
12use bitcoin::sighash::{EcdsaSighashType, NonStandardSighashTypeError, TapSighashType};
13use bitcoin::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapNodeHash};
14#[cfg(feature = "silent-payments")]
15use bitcoin::CompressedPublicKey;
16use bitcoin::{
17 ecdsa, hashes, taproot, OutPoint, ScriptBuf, Sequence, Transaction, TxIn, TxOut, Txid, Witness,
18};
19
20use crate::consts::{
21 PSBT_IN_BIP32_DERIVATION, PSBT_IN_FINAL_SCRIPTSIG, PSBT_IN_FINAL_SCRIPTWITNESS,
22 PSBT_IN_HASH160, PSBT_IN_HASH256, PSBT_IN_NON_WITNESS_UTXO, PSBT_IN_OUTPUT_INDEX,
23 PSBT_IN_PARTIAL_SIG, PSBT_IN_PREVIOUS_TXID, PSBT_IN_PROPRIETARY, PSBT_IN_REDEEM_SCRIPT,
24 PSBT_IN_REQUIRED_HEIGHT_LOCKTIME, PSBT_IN_REQUIRED_TIME_LOCKTIME, PSBT_IN_RIPEMD160,
25 PSBT_IN_SEQUENCE, PSBT_IN_SHA256, PSBT_IN_SIGHASH_TYPE, PSBT_IN_TAP_BIP32_DERIVATION,
26 PSBT_IN_TAP_INTERNAL_KEY, PSBT_IN_TAP_KEY_SIG, PSBT_IN_TAP_LEAF_SCRIPT,
27 PSBT_IN_TAP_MERKLE_ROOT, PSBT_IN_TAP_SCRIPT_SIG, PSBT_IN_WITNESS_SCRIPT, PSBT_IN_WITNESS_UTXO,
28};
29#[cfg(feature = "silent-payments")]
30use crate::consts::{PSBT_IN_SP_DLEQ, PSBT_IN_SP_ECDH_SHARE};
31use crate::error::{write_err, FundingUtxoError};
32use crate::prelude::*;
33use crate::serialize::{Deserialize, Serialize};
34use crate::sighash_type::{InvalidSighashTypeError, PsbtSighashType};
35#[cfg(feature = "silent-payments")]
36use crate::v2::dleq::DleqProof;
37use crate::v2::map::Map;
38use crate::{raw, serialize};
39
40#[derive(Debug, Clone, PartialEq, Eq, Hash)]
43#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44pub struct Input {
45 pub previous_txid: Txid,
51
52 pub spent_output_index: u32,
54
55 pub sequence: Option<Sequence>,
59
60 pub min_time: Option<absolute::Time>,
62
63 pub min_height: Option<absolute::Height>,
65
66 pub non_witness_utxo: Option<Transaction>,
70 pub witness_utxo: Option<TxOut>,
74 pub partial_sigs: BTreeMap<PublicKey, ecdsa::Signature>,
77 pub sighash_type: Option<PsbtSighashType>,
80 pub redeem_script: Option<ScriptBuf>,
82 pub witness_script: Option<ScriptBuf>,
84 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
87 pub bip32_derivations: BTreeMap<PublicKey, KeySource>,
88 pub final_script_sig: Option<ScriptBuf>,
91 pub final_script_witness: Option<Witness>,
94 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
97 pub ripemd160_preimages: BTreeMap<ripemd160::Hash, Vec<u8>>,
98 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
100 pub sha256_preimages: BTreeMap<sha256::Hash, Vec<u8>>,
101 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
103 pub hash160_preimages: BTreeMap<hash160::Hash, Vec<u8>>,
104 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
106 pub hash256_preimages: BTreeMap<sha256d::Hash, Vec<u8>>,
107 pub tap_key_sig: Option<taproot::Signature>,
109 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
111 pub tap_script_sigs: BTreeMap<(XOnlyPublicKey, TapLeafHash), taproot::Signature>,
112 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
114 pub tap_scripts: BTreeMap<ControlBlock, (ScriptBuf, LeafVersion)>,
115 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
117 pub tap_key_origins: BTreeMap<XOnlyPublicKey, (Vec<TapLeafHash>, KeySource)>,
118 pub tap_internal_key: Option<XOnlyPublicKey>,
120 pub tap_merkle_root: Option<TapNodeHash>,
122
123 #[cfg(feature = "silent-payments")]
125 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
126 pub sp_ecdh_shares: BTreeMap<CompressedPublicKey, CompressedPublicKey>,
127
128 #[cfg(feature = "silent-payments")]
130 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
131 pub sp_dleq_proofs: BTreeMap<CompressedPublicKey, DleqProof>,
132
133 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
135 pub proprietaries: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
136 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
138 pub unknowns: BTreeMap<raw::Key, Vec<u8>>,
139}
140
141impl Input {
142 pub fn new(previous_output: &OutPoint) -> Self {
144 Input {
145 previous_txid: previous_output.txid,
146 spent_output_index: previous_output.vout,
147 sequence: None,
148 min_time: None,
149 min_height: None,
150 non_witness_utxo: None,
151 witness_utxo: None,
152 partial_sigs: BTreeMap::new(),
153 sighash_type: None,
154 redeem_script: None,
155 witness_script: None,
156 bip32_derivations: BTreeMap::new(),
157 final_script_sig: None,
158 final_script_witness: None,
159 ripemd160_preimages: BTreeMap::new(),
160 sha256_preimages: BTreeMap::new(),
161 hash160_preimages: BTreeMap::new(),
162 hash256_preimages: BTreeMap::new(),
163 tap_key_sig: None,
164 tap_script_sigs: BTreeMap::new(),
165 tap_scripts: BTreeMap::new(),
166 tap_key_origins: BTreeMap::new(),
167 tap_internal_key: None,
168 tap_merkle_root: None,
169 #[cfg(feature = "silent-payments")]
170 sp_ecdh_shares: BTreeMap::new(),
171 #[cfg(feature = "silent-payments")]
172 sp_dleq_proofs: BTreeMap::new(),
173 proprietaries: BTreeMap::new(),
174 unknowns: BTreeMap::new(),
175 }
176 }
177
178 #[cfg(feature = "miniscript")]
212 pub(crate) fn finalize(
213 &self,
214 final_script_sig: ScriptBuf,
215 final_script_witness: Witness,
216 ) -> Result<Input, FinalizeError> {
217 debug_assert!(self.has_funding_utxo());
218
219 let mut ret = Input {
220 previous_txid: self.previous_txid,
221 spent_output_index: self.spent_output_index,
222 non_witness_utxo: self.non_witness_utxo.clone(),
223 witness_utxo: self.witness_utxo.clone(),
224
225 final_script_sig: None,
227 final_script_witness: None,
228
229 sequence: None,
231 min_time: None,
232 min_height: None,
233 partial_sigs: BTreeMap::new(),
234 sighash_type: None,
235 redeem_script: None,
236 witness_script: None,
237 bip32_derivations: BTreeMap::new(),
238 ripemd160_preimages: BTreeMap::new(),
239 sha256_preimages: BTreeMap::new(),
240 hash160_preimages: BTreeMap::new(),
241 hash256_preimages: BTreeMap::new(),
242 tap_key_sig: None,
243 tap_script_sigs: BTreeMap::new(),
244 tap_scripts: BTreeMap::new(),
245 tap_key_origins: BTreeMap::new(),
246 tap_internal_key: None,
247 tap_merkle_root: None,
248 #[cfg(feature = "silent-payments")]
249 sp_ecdh_shares: BTreeMap::new(),
250 #[cfg(feature = "silent-payments")]
251 sp_dleq_proofs: BTreeMap::new(),
252 proprietaries: BTreeMap::new(),
253 unknowns: BTreeMap::new(),
254 };
255
256 if self.witness_utxo.is_some() {
259 if final_script_witness.is_empty() {
260 return Err(FinalizeError::EmptyWitness);
261 }
262 ret.final_script_sig = Some(final_script_sig);
263 ret.final_script_witness = Some(final_script_witness);
264 } else {
265 ret.final_script_sig = Some(final_script_sig);
267 }
268
269 Ok(ret)
270 }
271
272 #[cfg(feature = "miniscript")]
274 pub(crate) fn lock_time(&self) -> absolute::LockTime {
275 match (self.min_height, self.min_time) {
276 (Some(height), Some(_)) => height.into(),
278 (Some(height), None) => height.into(),
279 (None, Some(time)) => time.into(),
280 (None, None) => absolute::LockTime::ZERO,
282 }
283 }
284
285 pub(crate) fn has_lock_time(&self) -> bool {
286 self.min_time.is_some() || self.min_height.is_some()
287 }
288
289 pub(crate) fn is_satisfied_with_height_based_lock_time(&self) -> bool {
290 self.requires_height_based_lock_time()
291 || self.min_time.is_some() && self.min_height.is_some()
292 || self.min_time.is_none() && self.min_height.is_none()
293 }
294
295 pub(crate) fn requires_time_based_lock_time(&self) -> bool {
296 self.min_time.is_some() && self.min_height.is_none()
297 }
298
299 pub(crate) fn requires_height_based_lock_time(&self) -> bool {
300 self.min_height.is_some() && self.min_time.is_none()
301 }
302
303 pub(crate) fn unsigned_tx_in(&self) -> TxIn {
305 TxIn {
306 previous_output: self.out_point(),
307 script_sig: ScriptBuf::default(),
308 sequence: self.sequence.unwrap_or(Sequence::ZERO),
310 witness: Witness::default(),
311 }
312 }
313
314 pub(crate) fn signed_tx_in(&self) -> TxIn {
318 debug_assert!(self.is_finalized());
319
320 let script_sig = self.final_script_sig.as_ref().expect("checked by is_finalized");
321 let witness = self.final_script_witness.as_ref().expect("checked by is_finalized");
322
323 TxIn {
324 previous_output: self.out_point(),
325 script_sig: script_sig.clone(),
326 sequence: self.sequence.unwrap_or(Sequence::MAX),
328 witness: witness.clone(),
329 }
330 }
331
332 #[cfg(feature = "miniscript")]
333 pub(crate) fn has_funding_utxo(&self) -> bool { self.funding_utxo().is_ok() }
334
335 pub fn funding_utxo(&self) -> Result<&TxOut, FundingUtxoError> {
337 if let Some(ref utxo) = self.witness_utxo {
338 Ok(utxo)
339 } else if let Some(ref tx) = self.non_witness_utxo {
340 let vout = self.spent_output_index as usize;
341 tx.output.get(vout).ok_or(FundingUtxoError::OutOfBounds { vout, len: tx.output.len() })
342 } else {
343 Err(FundingUtxoError::MissingUtxo)
344 }
345 }
346
347 pub fn is_finalized(&self) -> bool {
355 self.final_script_sig.is_some() && self.final_script_witness.is_some()
356 }
357
358 #[allow(dead_code)]
360 fn has_sig_data(&self) -> bool {
361 !(self.partial_sigs.is_empty()
362 && self.tap_key_sig.is_none()
363 && self.tap_script_sigs.is_empty())
364 }
365
366 fn out_point(&self) -> OutPoint {
367 OutPoint { txid: self.previous_txid, vout: self.spent_output_index }
368 }
369
370 pub fn ecdsa_hash_ty(&self) -> Result<EcdsaSighashType, NonStandardSighashTypeError> {
377 self.sighash_type
378 .map(|sighash_type| sighash_type.ecdsa_hash_ty())
379 .unwrap_or(Ok(EcdsaSighashType::All))
380 }
381
382 pub fn taproot_hash_ty(&self) -> Result<TapSighashType, InvalidSighashTypeError> {
389 self.sighash_type
390 .map(|sighash_type| sighash_type.taproot_hash_ty())
391 .unwrap_or(Ok(TapSighashType::Default))
392 }
393
394 pub(in crate::v2) fn decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, DecodeError> {
395 let invalid = OutPoint { txid: Txid::all_zeros(), vout: u32::MAX };
397 let mut rv = Self::new(&invalid);
398
399 loop {
400 match raw::Pair::decode(r) {
401 Ok(pair) => rv.insert_pair(pair)?,
402 Err(serialize::Error::NoMorePairs) => break,
403 Err(e) => return Err(DecodeError::DeserPair(e)),
404 }
405 }
406
407 if rv.previous_txid == Txid::all_zeros() {
408 return Err(DecodeError::MissingPreviousTxid);
409 }
410 if rv.spent_output_index == u32::MAX {
411 return Err(DecodeError::MissingSpentOutputIndex);
412 }
413
414 #[cfg(feature = "silent-payments")]
415 {
416 let has_ecdh = !rv.sp_ecdh_shares.is_empty();
417 let has_dleq = !rv.sp_dleq_proofs.is_empty();
418 if has_ecdh != has_dleq {
419 return Err(DecodeError::FieldMismatch);
420 }
421 }
422
423 Ok(rv)
424 }
425
426 fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), InsertPairError> {
427 let raw::Pair { key: raw_key, value: raw_value } = pair;
428
429 match raw_key.type_value {
430 PSBT_IN_PREVIOUS_TXID => {
431 if self.previous_txid != Txid::all_zeros() {
432 return Err(InsertPairError::DuplicateKey(raw_key));
433 }
434 let txid: Txid = Deserialize::deserialize(&raw_value)?;
435 self.previous_txid = txid;
436 }
437 PSBT_IN_OUTPUT_INDEX => {
438 if self.spent_output_index != u32::MAX {
439 return Err(InsertPairError::DuplicateKey(raw_key));
440 }
441 let vout: u32 = Deserialize::deserialize(&raw_value)?;
442 self.spent_output_index = vout;
443 }
444 PSBT_IN_SEQUENCE => {
445 v2_impl_psbt_insert_pair! {
446 self.sequence <= <raw_key: _>|<raw_value: Sequence>
447 }
448 }
449 PSBT_IN_REQUIRED_TIME_LOCKTIME => {
450 v2_impl_psbt_insert_pair! {
451 self.min_time <= <raw_key: _>|<raw_value: absolute::Time>
452 }
453 }
454 PSBT_IN_REQUIRED_HEIGHT_LOCKTIME => {
455 v2_impl_psbt_insert_pair! {
456 self.min_height <= <raw_key: _>|<raw_value: absolute::Height>
457 }
458 }
459 PSBT_IN_NON_WITNESS_UTXO => {
460 v2_impl_psbt_insert_pair! {
461 self.non_witness_utxo <= <raw_key: _>|<raw_value: Transaction>
462 }
463 }
464 PSBT_IN_WITNESS_UTXO => {
465 v2_impl_psbt_insert_pair! {
466 self.witness_utxo <= <raw_key: _>|<raw_value: TxOut>
467 }
468 }
469 PSBT_IN_PARTIAL_SIG => {
470 v2_impl_psbt_insert_pair! {
471 self.partial_sigs <= <raw_key: PublicKey>|<raw_value: ecdsa::Signature>
472 }
473 }
474 PSBT_IN_SIGHASH_TYPE => {
475 v2_impl_psbt_insert_pair! {
476 self.sighash_type <= <raw_key: _>|<raw_value: PsbtSighashType>
477 }
478 }
479 PSBT_IN_REDEEM_SCRIPT => {
480 v2_impl_psbt_insert_pair! {
481 self.redeem_script <= <raw_key: _>|<raw_value: ScriptBuf>
482 }
483 }
484 PSBT_IN_WITNESS_SCRIPT => {
485 v2_impl_psbt_insert_pair! {
486 self.witness_script <= <raw_key: _>|<raw_value: ScriptBuf>
487 }
488 }
489 PSBT_IN_BIP32_DERIVATION => {
490 v2_impl_psbt_insert_pair! {
491 self.bip32_derivations <= <raw_key: PublicKey>|<raw_value: KeySource>
492 }
493 }
494 PSBT_IN_FINAL_SCRIPTSIG => {
495 v2_impl_psbt_insert_pair! {
496 self.final_script_sig <= <raw_key: _>|<raw_value: ScriptBuf>
497 }
498 }
499 PSBT_IN_FINAL_SCRIPTWITNESS => {
500 v2_impl_psbt_insert_pair! {
501 self.final_script_witness <= <raw_key: _>|<raw_value: Witness>
502 }
503 }
504 PSBT_IN_RIPEMD160 => {
505 psbt_insert_hash_pair(
506 &mut self.ripemd160_preimages,
507 raw_key,
508 raw_value,
509 HashType::Ripemd,
510 )?;
511 }
512 PSBT_IN_SHA256 => {
513 psbt_insert_hash_pair(
514 &mut self.sha256_preimages,
515 raw_key,
516 raw_value,
517 HashType::Sha256,
518 )?;
519 }
520 PSBT_IN_HASH160 => {
521 psbt_insert_hash_pair(
522 &mut self.hash160_preimages,
523 raw_key,
524 raw_value,
525 HashType::Hash160,
526 )?;
527 }
528 PSBT_IN_HASH256 => {
529 psbt_insert_hash_pair(
530 &mut self.hash256_preimages,
531 raw_key,
532 raw_value,
533 HashType::Hash256,
534 )?;
535 }
536 PSBT_IN_TAP_KEY_SIG => {
537 v2_impl_psbt_insert_pair! {
538 self.tap_key_sig <= <raw_key: _>|<raw_value: taproot::Signature>
539 }
540 }
541 PSBT_IN_TAP_SCRIPT_SIG => {
542 v2_impl_psbt_insert_pair! {
543 self.tap_script_sigs <= <raw_key: (XOnlyPublicKey, TapLeafHash)>|<raw_value: taproot::Signature>
544 }
545 }
546 PSBT_IN_TAP_LEAF_SCRIPT => {
547 v2_impl_psbt_insert_pair! {
548 self.tap_scripts <= <raw_key: ControlBlock>|< raw_value: (ScriptBuf, LeafVersion)>
549 }
550 }
551 PSBT_IN_TAP_BIP32_DERIVATION => {
552 v2_impl_psbt_insert_pair! {
553 self.tap_key_origins <= <raw_key: XOnlyPublicKey>|< raw_value: (Vec<TapLeafHash>, KeySource)>
554 }
555 }
556 PSBT_IN_TAP_INTERNAL_KEY => {
557 v2_impl_psbt_insert_pair! {
558 self.tap_internal_key <= <raw_key: _>|< raw_value: XOnlyPublicKey>
559 }
560 }
561 PSBT_IN_TAP_MERKLE_ROOT => {
562 v2_impl_psbt_insert_pair! {
563 self.tap_merkle_root <= <raw_key: _>|< raw_value: TapNodeHash>
564 }
565 }
566 #[cfg(feature = "silent-payments")]
567 PSBT_IN_SP_ECDH_SHARE => {
568 v2_impl_psbt_insert_sp_pair!(
569 self.sp_ecdh_shares,
570 raw_key,
571 raw_value,
572 compressed_pubkey
573 );
574 }
575 #[cfg(feature = "silent-payments")]
576 PSBT_IN_SP_DLEQ => {
577 v2_impl_psbt_insert_sp_pair!(self.sp_dleq_proofs, raw_key, raw_value, dleq_proof);
578 }
579 PSBT_IN_PROPRIETARY => {
580 let key = raw::ProprietaryKey::try_from(raw_key.clone())?;
581 match self.proprietaries.entry(key) {
582 btree_map::Entry::Vacant(empty_key) => {
583 empty_key.insert(raw_value);
584 }
585 btree_map::Entry::Occupied(_) =>
586 return Err(InsertPairError::DuplicateKey(raw_key)),
587 }
588 }
589 _ => match self.unknowns.entry(raw_key) {
591 btree_map::Entry::Vacant(empty_key) => {
592 empty_key.insert(raw_value);
593 }
594 btree_map::Entry::Occupied(k) =>
595 return Err(InsertPairError::DuplicateKey(k.key().clone())),
596 },
597 }
598
599 Ok(())
600 }
601
602 pub fn combine(&mut self, other: Self) -> Result<(), CombineError> {
604 if self.previous_txid != other.previous_txid {
605 return Err(CombineError::PreviousTxidMismatch {
606 this: self.previous_txid,
607 that: other.previous_txid,
608 });
609 }
610
611 if self.spent_output_index != other.spent_output_index {
612 return Err(CombineError::SpentOutputIndexMismatch {
613 this: self.spent_output_index,
614 that: other.spent_output_index,
615 });
616 }
617
618 v2_combine_option!(sequence, self, other);
620 v2_combine_option!(min_time, self, other);
621 v2_combine_option!(min_height, self, other);
622 v2_combine_option!(non_witness_utxo, self, other);
623
624 if let (&None, Some(witness_utxo)) = (&self.witness_utxo, other.witness_utxo) {
626 self.witness_utxo = Some(witness_utxo);
627 self.non_witness_utxo = None; }
629
630 v2_combine_map!(partial_sigs, self, other);
631 v2_combine_option!(redeem_script, self, other);
633 v2_combine_option!(witness_script, self, other);
634 v2_combine_map!(bip32_derivations, self, other);
635 v2_combine_option!(final_script_sig, self, other);
636 v2_combine_option!(final_script_witness, self, other);
637 v2_combine_map!(ripemd160_preimages, self, other);
638 v2_combine_map!(sha256_preimages, self, other);
639 v2_combine_map!(hash160_preimages, self, other);
640 v2_combine_map!(hash256_preimages, self, other);
641 v2_combine_option!(tap_key_sig, self, other);
642 v2_combine_map!(tap_script_sigs, self, other);
643 v2_combine_map!(tap_scripts, self, other);
644 v2_combine_map!(tap_key_origins, self, other);
645 v2_combine_option!(tap_internal_key, self, other);
646 v2_combine_option!(tap_merkle_root, self, other);
647 #[cfg(feature = "silent-payments")]
648 v2_combine_map!(sp_ecdh_shares, self, other);
649 #[cfg(feature = "silent-payments")]
650 v2_combine_map!(sp_dleq_proofs, self, other);
651 v2_combine_map!(proprietaries, self, other);
652 v2_combine_map!(unknowns, self, other);
653
654 Ok(())
655 }
656}
657
658impl Map for Input {
659 fn get_pairs(&self) -> Vec<raw::Pair> {
660 let mut rv: Vec<raw::Pair> = Default::default();
661
662 rv.push(raw::Pair {
663 key: raw::Key { type_value: PSBT_IN_PREVIOUS_TXID, key: vec![] },
664 value: self.previous_txid.serialize(),
665 });
666
667 rv.push(raw::Pair {
668 key: raw::Key { type_value: PSBT_IN_OUTPUT_INDEX, key: vec![] },
669 value: self.spent_output_index.serialize(),
670 });
671
672 v2_impl_psbt_get_pair! {
673 rv.push(self.sequence, PSBT_IN_SEQUENCE)
674 }
675 v2_impl_psbt_get_pair! {
676 rv.push(self.min_time, PSBT_IN_REQUIRED_TIME_LOCKTIME)
677 }
678 v2_impl_psbt_get_pair! {
679 rv.push(self.min_height, PSBT_IN_REQUIRED_HEIGHT_LOCKTIME)
680 }
681
682 v2_impl_psbt_get_pair! {
683 rv.push(self.non_witness_utxo, PSBT_IN_NON_WITNESS_UTXO)
684 }
685
686 v2_impl_psbt_get_pair! {
687 rv.push(self.witness_utxo, PSBT_IN_WITNESS_UTXO)
688 }
689
690 v2_impl_psbt_get_pair! {
691 rv.push_map(self.partial_sigs, PSBT_IN_PARTIAL_SIG)
692 }
693
694 v2_impl_psbt_get_pair! {
695 rv.push(self.sighash_type, PSBT_IN_SIGHASH_TYPE)
696 }
697
698 v2_impl_psbt_get_pair! {
699 rv.push(self.redeem_script, PSBT_IN_REDEEM_SCRIPT)
700 }
701
702 v2_impl_psbt_get_pair! {
703 rv.push(self.witness_script, PSBT_IN_WITNESS_SCRIPT)
704 }
705
706 v2_impl_psbt_get_pair! {
707 rv.push_map(self.bip32_derivations, PSBT_IN_BIP32_DERIVATION)
708 }
709
710 v2_impl_psbt_get_pair! {
711 rv.push(self.final_script_sig, PSBT_IN_FINAL_SCRIPTSIG)
712 }
713
714 v2_impl_psbt_get_pair! {
715 rv.push(self.final_script_witness, PSBT_IN_FINAL_SCRIPTWITNESS)
716 }
717
718 v2_impl_psbt_get_pair! {
719 rv.push_map(self.ripemd160_preimages, PSBT_IN_RIPEMD160)
720 }
721
722 v2_impl_psbt_get_pair! {
723 rv.push_map(self.sha256_preimages, PSBT_IN_SHA256)
724 }
725
726 v2_impl_psbt_get_pair! {
727 rv.push_map(self.hash160_preimages, PSBT_IN_HASH160)
728 }
729
730 v2_impl_psbt_get_pair! {
731 rv.push_map(self.hash256_preimages, PSBT_IN_HASH256)
732 }
733
734 v2_impl_psbt_get_pair! {
735 rv.push(self.tap_key_sig, PSBT_IN_TAP_KEY_SIG)
736 }
737
738 v2_impl_psbt_get_pair! {
739 rv.push_map(self.tap_script_sigs, PSBT_IN_TAP_SCRIPT_SIG)
740 }
741
742 v2_impl_psbt_get_pair! {
743 rv.push_map(self.tap_scripts, PSBT_IN_TAP_LEAF_SCRIPT)
744 }
745
746 v2_impl_psbt_get_pair! {
747 rv.push_map(self.tap_key_origins, PSBT_IN_TAP_BIP32_DERIVATION)
748 }
749
750 v2_impl_psbt_get_pair! {
751 rv.push(self.tap_internal_key, PSBT_IN_TAP_INTERNAL_KEY)
752 }
753
754 v2_impl_psbt_get_pair! {
755 rv.push(self.tap_merkle_root, PSBT_IN_TAP_MERKLE_ROOT)
756 }
757
758 #[cfg(feature = "silent-payments")]
759 for (scan_key, ecdh_share) in &self.sp_ecdh_shares {
760 rv.push(raw::Pair {
761 key: raw::Key {
762 type_value: PSBT_IN_SP_ECDH_SHARE,
763 key: scan_key.to_bytes().to_vec(),
764 },
765 value: ecdh_share.to_bytes().to_vec(),
766 });
767 }
768
769 #[cfg(feature = "silent-payments")]
770 for (scan_key, dleq_proof) in &self.sp_dleq_proofs {
771 rv.push(raw::Pair {
772 key: raw::Key { type_value: PSBT_IN_SP_DLEQ, key: scan_key.to_bytes().to_vec() },
773 value: dleq_proof.as_bytes().to_vec(),
774 });
775 }
776
777 for (key, value) in self.proprietaries.iter() {
778 rv.push(raw::Pair { key: key.to_key(), value: value.clone() });
779 }
780
781 for (key, value) in self.unknowns.iter() {
782 rv.push(raw::Pair { key: key.clone(), value: value.clone() });
783 }
784
785 rv
786 }
787}
788
789fn psbt_insert_hash_pair<H>(
791 map: &mut BTreeMap<H, Vec<u8>>,
792 raw_key: raw::Key,
793 raw_value: Vec<u8>,
794 hash_type: HashType,
795) -> Result<(), InsertPairError>
796where
797 H: hashes::Hash + Deserialize,
798{
799 if raw_key.key.is_empty() {
800 return Err(InsertPairError::InvalidKeyDataEmpty(raw_key));
801 }
802
803 let key_val: H = Deserialize::deserialize(&raw_key.key)?;
804 match map.entry(key_val) {
805 btree_map::Entry::Vacant(empty_key) => {
806 let val: Vec<u8> = Deserialize::deserialize(&raw_value)?;
807
808 if <H as hashes::Hash>::hash(&val) != key_val {
809 return Err(HashPreimageError {
810 preimage: val.into_boxed_slice(),
811 hash: Box::from(key_val.borrow()),
812 hash_type,
813 }
814 .into());
815 }
816 empty_key.insert(val);
817 Ok(())
818 }
819 btree_map::Entry::Occupied(_) => Err(InsertPairError::DuplicateKey(raw_key)),
820 }
821}
822
823pub struct InputBuilder(Input);
825
826impl InputBuilder {
827 pub fn new(previous_output: &OutPoint) -> Self { Self(Input::new(previous_output)) }
829
830 pub fn minimum_required_time_based_lock_time(mut self, lock: absolute::Time) -> Self {
832 self.0.min_time = Some(lock);
833 self
834 }
835
836 pub fn minimum_required_height_based_lock_time(mut self, lock: absolute::Height) -> Self {
838 self.0.min_height = Some(lock);
839 self
840 }
841
842 pub fn segwit_fund(mut self, utxo: TxOut) -> Self {
844 self.0.witness_utxo = Some(utxo);
845 self
846 }
847
848 pub fn legacy_fund(mut self, tx: Transaction) -> Self {
854 self.0.non_witness_utxo = Some(tx);
855 self
856 }
857
858 pub fn build(self) -> Input { self.0 }
860}
861
862#[derive(Debug)]
864#[non_exhaustive]
865pub enum DecodeError {
866 InsertPair(InsertPairError),
868 DeserPair(serialize::Error),
870 MissingPreviousTxid,
872 MissingSpentOutputIndex,
874 FieldMismatch,
876}
877
878impl fmt::Display for DecodeError {
879 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
880 use DecodeError::*;
881
882 match *self {
883 InsertPair(ref e) => write_err!(f, "error inserting a key-value pair"; e),
884 DeserPair(ref e) => write_err!(f, "error decoding pair"; e),
885 MissingPreviousTxid => write!(f, "input must contain a previous txid"),
886 MissingSpentOutputIndex => write!(f, "input must contain a spent output index"),
887 FieldMismatch => {
888 write!(f, "ECDH shares and DLEQ proofs must both be present or both absent")
889 }
890 }
891 }
892}
893
894#[cfg(feature = "std")]
895impl std::error::Error for DecodeError {
896 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
897 use DecodeError::*;
898
899 match *self {
900 InsertPair(ref e) => Some(e),
901 DeserPair(ref e) => Some(e),
902 MissingPreviousTxid | MissingSpentOutputIndex => None,
903 FieldMismatch => None,
904 }
905 }
906}
907
908impl From<InsertPairError> for DecodeError {
909 fn from(e: InsertPairError) -> Self { Self::InsertPair(e) }
910}
911
912#[derive(Debug)]
914pub enum InsertPairError {
915 DuplicateKey(raw::Key),
917 Deser(serialize::Error),
919 InvalidKeyDataEmpty(raw::Key),
921 InvalidKeyDataNotEmpty(raw::Key),
923 HashPreimage(HashPreimageError),
925 KeyWrongLength(usize, usize),
927 ValueWrongLength(usize, usize),
929}
930
931impl fmt::Display for InsertPairError {
932 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
933 use InsertPairError::*;
934
935 match *self {
936 DuplicateKey(ref key) => write!(f, "duplicate key: {}", key),
937 Deser(ref e) => write_err!(f, "error deserializing raw value"; e),
938 InvalidKeyDataEmpty(ref key) => write!(f, "key should contain data: {}", key),
939 InvalidKeyDataNotEmpty(ref key) => write!(f, "key should not contain data: {}", key),
940 HashPreimage(ref e) => write_err!(f, "invalid hash preimage"; e),
941 KeyWrongLength(got, expected) => {
942 write!(f, "key wrong length (got: {}, expected: {})", got, expected)
943 }
944 ValueWrongLength(got, expected) => {
945 write!(f, "value wrong length (got: {}, expected: {})", got, expected)
946 }
947 }
948 }
949}
950
951#[cfg(feature = "std")]
952impl std::error::Error for InsertPairError {
953 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
954 use InsertPairError::*;
955
956 match *self {
957 Deser(ref e) => Some(e),
958 HashPreimage(ref e) => Some(e),
959 DuplicateKey(_)
960 | InvalidKeyDataEmpty(_)
961 | InvalidKeyDataNotEmpty(_)
962 | KeyWrongLength(..)
963 | ValueWrongLength(..) => None,
964 }
965 }
966}
967
968impl From<serialize::Error> for InsertPairError {
969 fn from(e: serialize::Error) -> Self { Self::Deser(e) }
970}
971
972impl From<HashPreimageError> for InsertPairError {
973 fn from(e: HashPreimageError) -> Self { Self::HashPreimage(e) }
974}
975
976#[derive(Debug, Clone, PartialEq, Eq)]
978pub struct HashPreimageError {
979 hash_type: HashType,
981 preimage: Box<[u8]>,
983 hash: Box<[u8]>,
985}
986
987impl fmt::Display for HashPreimageError {
988 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
989 write!(
990 f,
991 "invalid hash preimage {} {:x} {:x}",
992 self.hash_type,
993 self.preimage.as_hex(),
994 self.hash.as_hex()
995 )
996 }
997}
998
999#[cfg(feature = "std")]
1000impl std::error::Error for HashPreimageError {
1001 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
1002}
1003
1004#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1006#[non_exhaustive]
1007pub enum HashType {
1008 Ripemd,
1010 Sha256,
1012 Hash160,
1014 Hash256,
1016}
1017
1018impl fmt::Display for HashType {
1019 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", stringify!(self)) }
1020}
1021
1022#[cfg(feature = "miniscript")]
1024#[derive(Debug, Clone, PartialEq, Eq)]
1025pub enum FinalizeError {
1026 EmptyWitness,
1028 UnexpectedWitness,
1030}
1031
1032#[cfg(feature = "miniscript")]
1033impl fmt::Display for FinalizeError {
1034 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1035 use FinalizeError::*;
1036
1037 match *self {
1038 EmptyWitness => write!(f, "failed to create a final witness"),
1039 UnexpectedWitness => write!(f, "unexpected witness data"),
1040 }
1041 }
1042}
1043
1044#[cfg(all(feature = "std", feature = "miniscript"))]
1045impl std::error::Error for FinalizeError {
1046 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
1047}
1048
1049#[derive(Debug, Clone, PartialEq, Eq)]
1051#[non_exhaustive]
1052pub enum CombineError {
1053 PreviousTxidMismatch {
1055 this: Txid,
1057 that: Txid,
1059 },
1060 SpentOutputIndexMismatch {
1062 this: u32,
1064 that: u32,
1066 },
1067}
1068impl fmt::Display for CombineError {
1069 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1070 use CombineError::*;
1071
1072 match *self {
1073 PreviousTxidMismatch { ref this, ref that } => {
1074 write!(f, "combine two PSBTs with different previous txids: {:?} {:?}", this, that)
1075 }
1076 SpentOutputIndexMismatch { ref this, ref that } => write!(
1077 f,
1078 "combine two PSBTs with different spent output indecies: {:?} {:?}",
1079 this, that
1080 ),
1081 }
1082 }
1083}
1084
1085#[cfg(feature = "std")]
1086impl std::error::Error for CombineError {
1087 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1088 use CombineError::*;
1089
1090 match *self {
1091 PreviousTxidMismatch { .. } | SpentOutputIndexMismatch { .. } => None,
1092 }
1093 }
1094}
1095
1096#[cfg(test)]
1097#[cfg(feature = "std")]
1098mod test {
1099 use super::*;
1100
1101 fn out_point() -> OutPoint {
1102 let txid = Txid::hash(b"some arbitrary bytes");
1103 let vout = 0xab;
1104 OutPoint { txid, vout }
1105 }
1106
1107 #[test]
1108 fn serialize_roundtrip() {
1109 use bitcoin::io::Cursor;
1110
1111 let input = Input::new(&out_point());
1112
1113 let ser = input.serialize_map();
1114 let mut d = Cursor::new(ser);
1115
1116 let decoded = Input::decode(&mut d).expect("failed to decode");
1117
1118 assert_eq!(decoded, input);
1119 }
1120}