1use core::fmt;
4use core::str::FromStr;
5
6use bitcoin::bip32::KeySource;
7use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};
8use bitcoin::secp256k1::{self, XOnlyPublicKey};
9use bitcoin::sighash::{
10 EcdsaSighashType, InvalidSighashTypeError, NonStandardSighashTypeError, TapSighashType,
11};
12use bitcoin::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapNodeHash};
13use bitcoin::{ecdsa, taproot, PublicKey, ScriptBuf, Transaction, TxOut, Witness};
14
15use super::Map;
16use crate::prelude::*;
17use crate::serialize::Deserialize;
18use crate::{error, raw, Error};
19
20const PSBT_IN_NON_WITNESS_UTXO: u8 = 0x00;
22const PSBT_IN_WITNESS_UTXO: u8 = 0x01;
24const PSBT_IN_PARTIAL_SIG: u8 = 0x02;
26const PSBT_IN_SIGHASH_TYPE: u8 = 0x03;
28const PSBT_IN_REDEEM_SCRIPT: u8 = 0x04;
30const PSBT_IN_WITNESS_SCRIPT: u8 = 0x05;
32const PSBT_IN_BIP32_DERIVATION: u8 = 0x06;
34const PSBT_IN_FINAL_SCRIPTSIG: u8 = 0x07;
36const PSBT_IN_FINAL_SCRIPTWITNESS: u8 = 0x08;
38const PSBT_IN_RIPEMD160: u8 = 0x0a;
40const PSBT_IN_SHA256: u8 = 0x0b;
42const PSBT_IN_HASH160: u8 = 0x0c;
44const PSBT_IN_HASH256: u8 = 0x0d;
46const PSBT_IN_TAP_KEY_SIG: u8 = 0x13;
48const PSBT_IN_TAP_SCRIPT_SIG: u8 = 0x14;
50const PSBT_IN_TAP_LEAF_SCRIPT: u8 = 0x15;
52const PSBT_IN_TAP_BIP32_DERIVATION: u8 = 0x16;
54const PSBT_IN_TAP_INTERNAL_KEY: u8 = 0x17;
56const PSBT_IN_TAP_MERKLE_ROOT: u8 = 0x18;
58const PSBT_IN_PROPRIETARY: u8 = 0xFC;
60
61#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
64#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
65#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
66pub struct Input {
67 pub non_witness_utxo: Option<Transaction>,
71 pub witness_utxo: Option<TxOut>,
75 pub partial_sigs: BTreeMap<PublicKey, ecdsa::Signature>,
78 pub sighash_type: Option<PsbtSighashType>,
81 pub redeem_script: Option<ScriptBuf>,
83 pub witness_script: Option<ScriptBuf>,
85 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
88 pub bip32_derivation: BTreeMap<secp256k1::PublicKey, KeySource>,
89 pub final_script_sig: Option<ScriptBuf>,
92 pub final_script_witness: Option<Witness>,
95 #[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 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
124 pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
125 #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
127 pub unknown: BTreeMap<raw::Key, Vec<u8>>,
128}
129
130#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
137#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
138#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
139pub struct PsbtSighashType {
140 pub(crate) inner: u32,
141}
142
143impl fmt::Display for PsbtSighashType {
144 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145 match self.taproot_hash_ty() {
146 Err(_) => write!(f, "{:#x}", self.inner),
147 Ok(taproot_hash_ty) => fmt::Display::fmt(&taproot_hash_ty, f),
148 }
149 }
150}
151
152impl FromStr for PsbtSighashType {
153 type Err = ParseSighashTypeError;
154
155 #[inline]
156 fn from_str(s: &str) -> Result<Self, Self::Err> {
157 if let Ok(ty) = TapSighashType::from_str(s) {
163 return Ok(ty.into());
164 }
165
166 if let Ok(inner) = u32::from_str_radix(s.trim_start_matches("0x"), 16) {
168 return Ok(PsbtSighashType { inner });
169 }
170
171 Err(ParseSighashTypeError { unrecognized: s.to_owned() })
172 }
173}
174impl From<EcdsaSighashType> for PsbtSighashType {
175 fn from(ecdsa_hash_ty: EcdsaSighashType) -> Self {
176 PsbtSighashType { inner: ecdsa_hash_ty as u32 }
177 }
178}
179
180impl From<TapSighashType> for PsbtSighashType {
181 fn from(taproot_hash_ty: TapSighashType) -> Self {
182 PsbtSighashType { inner: taproot_hash_ty as u32 }
183 }
184}
185
186#[derive(Debug, Clone, PartialEq, Eq)]
190#[non_exhaustive]
191pub struct ParseSighashTypeError {
192 pub unrecognized: String,
194}
195
196impl fmt::Display for ParseSighashTypeError {
197 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
198 write!(f, "unrecognized SIGHASH string '{}'", self.unrecognized)
199 }
200}
201
202#[cfg(feature = "std")]
203impl std::error::Error for ParseSighashTypeError {
204 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
205}
206
207impl PsbtSighashType {
208 pub fn ecdsa_hash_ty(self) -> Result<EcdsaSighashType, NonStandardSighashTypeError> {
211 EcdsaSighashType::from_standard(self.inner)
212 }
213
214 pub fn taproot_hash_ty(self) -> Result<TapSighashType, InvalidSighashTypeError> {
217 if self.inner > 0xffu32 {
218 Err(InvalidSighashTypeError(self.inner))
219 } else {
220 TapSighashType::from_consensus_u8(self.inner as u8)
221 }
222 }
223
224 pub fn from_u32(n: u32) -> PsbtSighashType { PsbtSighashType { inner: n } }
229
230 pub fn to_u32(self) -> u32 { self.inner }
234}
235
236impl Input {
237 pub fn ecdsa_hash_ty(&self) -> Result<EcdsaSighashType, NonStandardSighashTypeError> {
244 self.sighash_type
245 .map(|sighash_type| sighash_type.ecdsa_hash_ty())
246 .unwrap_or(Ok(EcdsaSighashType::All))
247 }
248
249 pub fn taproot_hash_ty(&self) -> Result<TapSighashType, InvalidSighashTypeError> {
256 self.sighash_type
257 .map(|sighash_type| sighash_type.taproot_hash_ty())
258 .unwrap_or(Ok(TapSighashType::Default))
259 }
260
261 pub(super) fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), Error> {
262 let raw::Pair { key: raw_key, value: raw_value } = pair;
263
264 match raw_key.type_value {
265 PSBT_IN_NON_WITNESS_UTXO => {
266 impl_psbt_insert_pair! {
267 self.non_witness_utxo <= <raw_key: _>|<raw_value: Transaction>
268 }
269 }
270 PSBT_IN_WITNESS_UTXO => {
271 impl_psbt_insert_pair! {
272 self.witness_utxo <= <raw_key: _>|<raw_value: TxOut>
273 }
274 }
275 PSBT_IN_PARTIAL_SIG => {
276 impl_psbt_insert_pair! {
277 self.partial_sigs <= <raw_key: PublicKey>|<raw_value: ecdsa::Signature>
278 }
279 }
280 PSBT_IN_SIGHASH_TYPE => {
281 impl_psbt_insert_pair! {
282 self.sighash_type <= <raw_key: _>|<raw_value: PsbtSighashType>
283 }
284 }
285 PSBT_IN_REDEEM_SCRIPT => {
286 impl_psbt_insert_pair! {
287 self.redeem_script <= <raw_key: _>|<raw_value: ScriptBuf>
288 }
289 }
290 PSBT_IN_WITNESS_SCRIPT => {
291 impl_psbt_insert_pair! {
292 self.witness_script <= <raw_key: _>|<raw_value: ScriptBuf>
293 }
294 }
295 PSBT_IN_BIP32_DERIVATION => {
296 impl_psbt_insert_pair! {
297 self.bip32_derivation <= <raw_key: secp256k1::PublicKey>|<raw_value: KeySource>
298 }
299 }
300 PSBT_IN_FINAL_SCRIPTSIG => {
301 impl_psbt_insert_pair! {
302 self.final_script_sig <= <raw_key: _>|<raw_value: ScriptBuf>
303 }
304 }
305 PSBT_IN_FINAL_SCRIPTWITNESS => {
306 impl_psbt_insert_pair! {
307 self.final_script_witness <= <raw_key: _>|<raw_value: Witness>
308 }
309 }
310 PSBT_IN_RIPEMD160 => {
311 psbt_insert_hash_pair(
312 &mut self.ripemd160_preimages,
313 raw_key,
314 raw_value,
315 error::PsbtHash::Ripemd,
316 )?;
317 }
318 PSBT_IN_SHA256 => {
319 psbt_insert_hash_pair(
320 &mut self.sha256_preimages,
321 raw_key,
322 raw_value,
323 error::PsbtHash::Sha256,
324 )?;
325 }
326 PSBT_IN_HASH160 => {
327 psbt_insert_hash_pair(
328 &mut self.hash160_preimages,
329 raw_key,
330 raw_value,
331 error::PsbtHash::Hash160,
332 )?;
333 }
334 PSBT_IN_HASH256 => {
335 psbt_insert_hash_pair(
336 &mut self.hash256_preimages,
337 raw_key,
338 raw_value,
339 error::PsbtHash::Hash256,
340 )?;
341 }
342 PSBT_IN_TAP_KEY_SIG => {
343 impl_psbt_insert_pair! {
344 self.tap_key_sig <= <raw_key: _>|<raw_value: taproot::Signature>
345 }
346 }
347 PSBT_IN_TAP_SCRIPT_SIG => {
348 impl_psbt_insert_pair! {
349 self.tap_script_sigs <= <raw_key: (XOnlyPublicKey, TapLeafHash)>|<raw_value: taproot::Signature>
350 }
351 }
352 PSBT_IN_TAP_LEAF_SCRIPT => {
353 impl_psbt_insert_pair! {
354 self.tap_scripts <= <raw_key: ControlBlock>|< raw_value: (ScriptBuf, LeafVersion)>
355 }
356 }
357 PSBT_IN_TAP_BIP32_DERIVATION => {
358 impl_psbt_insert_pair! {
359 self.tap_key_origins <= <raw_key: XOnlyPublicKey>|< raw_value: (Vec<TapLeafHash>, KeySource)>
360 }
361 }
362 PSBT_IN_TAP_INTERNAL_KEY => {
363 impl_psbt_insert_pair! {
364 self.tap_internal_key <= <raw_key: _>|< raw_value: XOnlyPublicKey>
365 }
366 }
367 PSBT_IN_TAP_MERKLE_ROOT => {
368 impl_psbt_insert_pair! {
369 self.tap_merkle_root <= <raw_key: _>|< raw_value: TapNodeHash>
370 }
371 }
372 PSBT_IN_PROPRIETARY => {
373 let key = raw::ProprietaryKey::try_from(raw_key.clone())?;
374 match self.proprietary.entry(key) {
375 btree_map::Entry::Vacant(empty_key) => {
376 empty_key.insert(raw_value);
377 }
378 btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key)),
379 }
380 }
381 _ => match self.unknown.entry(raw_key) {
382 btree_map::Entry::Vacant(empty_key) => {
383 empty_key.insert(raw_value);
384 }
385 btree_map::Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone())),
386 },
387 }
388
389 Ok(())
390 }
391
392 pub fn combine(&mut self, other: Self) {
394 combine!(non_witness_utxo, self, other);
395
396 if let (&None, Some(witness_utxo)) = (&self.witness_utxo, other.witness_utxo) {
397 self.witness_utxo = Some(witness_utxo);
398 self.non_witness_utxo = None; }
400
401 self.partial_sigs.extend(other.partial_sigs);
402 self.bip32_derivation.extend(other.bip32_derivation);
403 self.ripemd160_preimages.extend(other.ripemd160_preimages);
404 self.sha256_preimages.extend(other.sha256_preimages);
405 self.hash160_preimages.extend(other.hash160_preimages);
406 self.hash256_preimages.extend(other.hash256_preimages);
407 self.tap_script_sigs.extend(other.tap_script_sigs);
408 self.tap_scripts.extend(other.tap_scripts);
409 self.tap_key_origins.extend(other.tap_key_origins);
410 self.proprietary.extend(other.proprietary);
411 self.unknown.extend(other.unknown);
412
413 combine!(redeem_script, self, other);
414 combine!(witness_script, self, other);
415 combine!(final_script_sig, self, other);
416 combine!(final_script_witness, self, other);
417 combine!(tap_key_sig, self, other);
418 combine!(tap_internal_key, self, other);
419 combine!(tap_merkle_root, self, other);
420 }
421}
422
423impl Map for Input {
424 fn get_pairs(&self) -> Vec<raw::Pair> {
425 let mut rv: Vec<raw::Pair> = Default::default();
426
427 impl_psbt_get_pair! {
428 rv.push(self.non_witness_utxo, PSBT_IN_NON_WITNESS_UTXO)
429 }
430
431 impl_psbt_get_pair! {
432 rv.push(self.witness_utxo, PSBT_IN_WITNESS_UTXO)
433 }
434
435 impl_psbt_get_pair! {
436 rv.push_map(self.partial_sigs, PSBT_IN_PARTIAL_SIG)
437 }
438
439 impl_psbt_get_pair! {
440 rv.push(self.sighash_type, PSBT_IN_SIGHASH_TYPE)
441 }
442
443 impl_psbt_get_pair! {
444 rv.push(self.redeem_script, PSBT_IN_REDEEM_SCRIPT)
445 }
446
447 impl_psbt_get_pair! {
448 rv.push(self.witness_script, PSBT_IN_WITNESS_SCRIPT)
449 }
450
451 impl_psbt_get_pair! {
452 rv.push_map(self.bip32_derivation, PSBT_IN_BIP32_DERIVATION)
453 }
454
455 impl_psbt_get_pair! {
456 rv.push(self.final_script_sig, PSBT_IN_FINAL_SCRIPTSIG)
457 }
458
459 impl_psbt_get_pair! {
460 rv.push(self.final_script_witness, PSBT_IN_FINAL_SCRIPTWITNESS)
461 }
462
463 impl_psbt_get_pair! {
464 rv.push_map(self.ripemd160_preimages, PSBT_IN_RIPEMD160)
465 }
466
467 impl_psbt_get_pair! {
468 rv.push_map(self.sha256_preimages, PSBT_IN_SHA256)
469 }
470
471 impl_psbt_get_pair! {
472 rv.push_map(self.hash160_preimages, PSBT_IN_HASH160)
473 }
474
475 impl_psbt_get_pair! {
476 rv.push_map(self.hash256_preimages, PSBT_IN_HASH256)
477 }
478
479 impl_psbt_get_pair! {
480 rv.push(self.tap_key_sig, PSBT_IN_TAP_KEY_SIG)
481 }
482
483 impl_psbt_get_pair! {
484 rv.push_map(self.tap_script_sigs, PSBT_IN_TAP_SCRIPT_SIG)
485 }
486
487 impl_psbt_get_pair! {
488 rv.push_map(self.tap_scripts, PSBT_IN_TAP_LEAF_SCRIPT)
489 }
490
491 impl_psbt_get_pair! {
492 rv.push_map(self.tap_key_origins, PSBT_IN_TAP_BIP32_DERIVATION)
493 }
494
495 impl_psbt_get_pair! {
496 rv.push(self.tap_internal_key, PSBT_IN_TAP_INTERNAL_KEY)
497 }
498
499 impl_psbt_get_pair! {
500 rv.push(self.tap_merkle_root, PSBT_IN_TAP_MERKLE_ROOT)
501 }
502 for (key, value) in self.proprietary.iter() {
503 rv.push(raw::Pair { key: key.to_key(), value: value.clone() });
504 }
505
506 for (key, value) in self.unknown.iter() {
507 rv.push(raw::Pair { key: key.clone(), value: value.clone() });
508 }
509
510 rv
511 }
512}
513
514impl_psbtmap_ser_de_serialize!(Input);
515
516fn psbt_insert_hash_pair<H>(
517 map: &mut BTreeMap<H, Vec<u8>>,
518 raw_key: raw::Key,
519 raw_value: Vec<u8>,
520 hash_type: error::PsbtHash,
521) -> Result<(), Error>
522where
523 H: bitcoin::hashes::Hash + Deserialize,
524{
525 if raw_key.key.is_empty() {
526 return Err(Error::InvalidKey(raw_key));
527 }
528 let key_val: H = Deserialize::deserialize(&raw_key.key)?;
529 match map.entry(key_val) {
530 btree_map::Entry::Vacant(empty_key) => {
531 let val: Vec<u8> = Deserialize::deserialize(&raw_value)?;
532 if <H as bitcoin::hashes::Hash>::hash(&val) != key_val {
533 return Err(Error::InvalidPreimageHashPair {
534 preimage: val.into_boxed_slice(),
535 hash: Box::from(key_val.borrow()),
536 hash_type,
537 });
538 }
539 empty_key.insert(val);
540 Ok(())
541 }
542 btree_map::Entry::Occupied(_) => Err(Error::DuplicateKey(raw_key)),
543 }
544}
545
546#[cfg(test)]
547mod test {
548 use super::*;
549
550 #[test]
551 fn psbt_sighash_type_ecdsa() {
552 for ecdsa in &[
553 EcdsaSighashType::All,
554 EcdsaSighashType::None,
555 EcdsaSighashType::Single,
556 EcdsaSighashType::AllPlusAnyoneCanPay,
557 EcdsaSighashType::NonePlusAnyoneCanPay,
558 EcdsaSighashType::SinglePlusAnyoneCanPay,
559 ] {
560 let sighash = PsbtSighashType::from(*ecdsa);
561 let s = format!("{}", sighash);
562 let back = PsbtSighashType::from_str(&s).unwrap();
563 assert_eq!(back, sighash);
564 assert_eq!(back.ecdsa_hash_ty().unwrap(), *ecdsa);
565 }
566 }
567
568 #[test]
569 fn psbt_sighash_type_taproot() {
570 for tap in &[
571 TapSighashType::Default,
572 TapSighashType::All,
573 TapSighashType::None,
574 TapSighashType::Single,
575 TapSighashType::AllPlusAnyoneCanPay,
576 TapSighashType::NonePlusAnyoneCanPay,
577 TapSighashType::SinglePlusAnyoneCanPay,
578 ] {
579 let sighash = PsbtSighashType::from(*tap);
580 let s = format!("{}", sighash);
581 let back = PsbtSighashType::from_str(&s).unwrap();
582 assert_eq!(back, sighash);
583 assert_eq!(back.taproot_hash_ty().unwrap(), *tap);
584 }
585 }
586
587 #[test]
588 fn psbt_sighash_type_notstd() {
589 let nonstd = 0xdddddddd;
590 let sighash = PsbtSighashType { inner: nonstd };
591 let s = format!("{}", sighash);
592 let back = PsbtSighashType::from_str(&s).unwrap();
593
594 assert_eq!(back, sighash);
595 assert_eq!(back.ecdsa_hash_ty(), Err(NonStandardSighashTypeError(nonstd)));
596 assert_eq!(back.taproot_hash_ty(), Err(InvalidSighashTypeError(nonstd)));
597 }
598}