Skip to main content

psbt_v2/v0/bitcoin/map/
input.rs

1// SPDX-License-Identifier: CC0-1.0
2
3use 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
22/// Type: Non-Witness UTXO PSBT_IN_NON_WITNESS_UTXO = 0x00
23const PSBT_IN_NON_WITNESS_UTXO: u8 = 0x00;
24/// Type: Witness UTXO PSBT_IN_WITNESS_UTXO = 0x01
25const PSBT_IN_WITNESS_UTXO: u8 = 0x01;
26/// Type: Partial Signature PSBT_IN_PARTIAL_SIG = 0x02
27const PSBT_IN_PARTIAL_SIG: u8 = 0x02;
28/// Type: Sighash Type PSBT_IN_SIGHASH_TYPE = 0x03
29const PSBT_IN_SIGHASH_TYPE: u8 = 0x03;
30/// Type: Redeem Script PSBT_IN_REDEEM_SCRIPT = 0x04
31const PSBT_IN_REDEEM_SCRIPT: u8 = 0x04;
32/// Type: Witness Script PSBT_IN_WITNESS_SCRIPT = 0x05
33const PSBT_IN_WITNESS_SCRIPT: u8 = 0x05;
34/// Type: BIP 32 Derivation Path PSBT_IN_BIP32_DERIVATION = 0x06
35const PSBT_IN_BIP32_DERIVATION: u8 = 0x06;
36/// Type: Finalized scriptSig PSBT_IN_FINAL_SCRIPTSIG = 0x07
37const PSBT_IN_FINAL_SCRIPTSIG: u8 = 0x07;
38/// Type: Finalized scriptWitness PSBT_IN_FINAL_SCRIPTWITNESS = 0x08
39const PSBT_IN_FINAL_SCRIPTWITNESS: u8 = 0x08;
40/// Type: RIPEMD160 preimage PSBT_IN_RIPEMD160 = 0x0a
41const PSBT_IN_RIPEMD160: u8 = 0x0a;
42/// Type: SHA256 preimage PSBT_IN_SHA256 = 0x0b
43const PSBT_IN_SHA256: u8 = 0x0b;
44/// Type: Previous TXID PSBT_IN_PREVIOUS_TXID = 0x0e
45const PSBT_IN_PREVIOUS_TXID: u8 = 0x0e;
46/// Type: Spent Output Index PSBT_IN_OUTPUT_INDEX = 0x0f
47const PSBT_IN_OUTPUT_INDEX: u8 = 0x0f;
48/// Type: Sequence Number PSBT_IN_SEQUENCE = 0x10
49const PSBT_IN_SEQUENCE: u8 = 0x10;
50/// Type: Required Time-based Locktime PSBT_IN_REQUIRED_TIME_LOCKTIME = 0x11
51const PSBT_IN_REQUIRED_TIME_LOCKTIME: u8 = 0x11;
52/// Type: Required Height-based Locktime PSBT_IN_REQUIRED_HEIGHT_LOCKTIME = 0x12
53const PSBT_IN_REQUIRED_HEIGHT_LOCKTIME: u8 = 0x12;
54/// Type: HASH160 preimage PSBT_IN_HASH160 = 0x0c
55const PSBT_IN_HASH160: u8 = 0x0c;
56/// Type: HASH256 preimage PSBT_IN_HASH256 = 0x0d
57const PSBT_IN_HASH256: u8 = 0x0d;
58/// Type: Taproot Signature in Key Spend PSBT_IN_TAP_KEY_SIG = 0x13
59const PSBT_IN_TAP_KEY_SIG: u8 = 0x13;
60/// Type: Taproot Signature in Script Spend PSBT_IN_TAP_SCRIPT_SIG = 0x14
61const PSBT_IN_TAP_SCRIPT_SIG: u8 = 0x14;
62/// Type: Taproot Leaf Script PSBT_IN_TAP_LEAF_SCRIPT = 0x14
63const PSBT_IN_TAP_LEAF_SCRIPT: u8 = 0x15;
64/// Type: Taproot Key BIP 32 Derivation Path PSBT_IN_TAP_BIP32_DERIVATION = 0x16
65const PSBT_IN_TAP_BIP32_DERIVATION: u8 = 0x16;
66/// Type: Taproot Internal Key PSBT_IN_TAP_INTERNAL_KEY = 0x17
67const PSBT_IN_TAP_INTERNAL_KEY: u8 = 0x17;
68/// Type: Taproot Merkle Root PSBT_IN_TAP_MERKLE_ROOT = 0x18
69const PSBT_IN_TAP_MERKLE_ROOT: u8 = 0x18;
70/// Type: Proprietary Use Type PSBT_IN_PROPRIETARY = 0xFC
71const PSBT_IN_PROPRIETARY: u8 = 0xFC;
72
73/// A key-value map for an input of the corresponding index in the unsigned
74/// transaction.
75#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
76#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
77pub struct Input {
78    /// The non-witness transaction this input spends from. Should only be
79    /// `Option::Some` for inputs which spend non-segwit outputs or
80    /// if it is unknown whether an input spends a segwit output.
81    pub non_witness_utxo: Option<Transaction>,
82    /// The transaction output this input spends from. Should only be
83    /// `Option::Some` for inputs which spend segwit outputs,
84    /// including P2SH embedded ones.
85    pub witness_utxo: Option<TxOut>,
86    /// A map from public keys to their corresponding signature as would be
87    /// pushed to the stack from a scriptSig or witness for a non-taproot inputs.
88    pub partial_sigs: BTreeMap<PublicKey, ecdsa::Signature>,
89    /// The sighash type to be used for this input. Signatures for this input
90    /// must use the sighash type.
91    pub sighash_type: Option<PsbtSighashType>,
92    /// The redeem script for this input.
93    pub redeem_script: Option<ScriptBuf>,
94    /// The witness script for this input.
95    pub witness_script: Option<ScriptBuf>,
96    /// A map from public keys needed to sign this input to their corresponding
97    /// master key fingerprints and derivation paths.
98    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
99    pub bip32_derivation: BTreeMap<PublicKey, KeySource>,
100    /// The finalized, fully-constructed scriptSig with signatures and any other
101    /// scripts necessary for this input to pass validation.
102    pub final_script_sig: Option<ScriptBuf>,
103    /// The finalized, fully-constructed scriptWitness with signatures and any
104    /// other scripts necessary for this input to pass validation.
105    pub final_script_witness: Option<Witness>,
106    /// RIPEMD160 hash to preimage map.
107    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
108    pub ripemd160_preimages: BTreeMap<ripemd160::Hash, Vec<u8>>,
109    /// SHA256 hash to preimage map.
110    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
111    pub sha256_preimages: BTreeMap<sha256::Hash, Vec<u8>>,
112    /// HSAH160 hash to preimage map.
113    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
114    pub hash160_preimages: BTreeMap<hash160::Hash, Vec<u8>>,
115    /// HAS256 hash to preimage map.
116    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
117    pub hash256_preimages: BTreeMap<sha256d::Hash, Vec<u8>>,
118    /// Serialized taproot signature with sighash type for key spend.
119    pub tap_key_sig: Option<taproot::Signature>,
120    /// Map of `<xonlypubkey>|<leafhash>` with signature.
121    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
122    pub tap_script_sigs: BTreeMap<(XOnlyPublicKey, TapLeafHash), taproot::Signature>,
123    /// Map of Control blocks to Script version pair.
124    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
125    pub tap_scripts: BTreeMap<ControlBlock, (ScriptBuf, LeafVersion)>,
126    /// Map of tap root x only keys to origin info and leaf hashes contained in it.
127    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
128    pub tap_key_origins: BTreeMap<XOnlyPublicKey, (Vec<TapLeafHash>, KeySource)>,
129    /// Taproot Internal key.
130    pub tap_internal_key: Option<XOnlyPublicKey>,
131    /// Taproot Merkle root.
132    pub tap_merkle_root: Option<TapNodeHash>,
133    /// Proprietary key-value pairs for this input.
134    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
135    pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
136    /// Unknown key-value pairs for this input.
137    #[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    /// Obtains the [`EcdsaSighashType`] for this input if one is specified. If no sighash type is
143    /// specified, returns [`EcdsaSighashType::All`].
144    ///
145    /// # Errors
146    ///
147    /// If the `sighash_type` field is set to a non-standard ECDSA sighash value.
148    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    /// Obtains the [`TapSighashType`] for this input if one is specified. If no sighash type is
155    /// specified, returns [`TapSighashType::Default`].
156    ///
157    /// # Errors
158    ///
159    /// If the `sighash_type` field is set to a invalid Taproot sighash value.
160    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    /// Combines this [`Input`] with `other` `Input` (as described by BIP 174).
306    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; // Clear out any non-witness UTXO when we set a witness one
312        }
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}