miniscript_qtum/psbt/
mod.rs

1// Written in 2019 by Andrew Poelstra <apoelstra@wpsoftware.net>
2// SPDX-License-Identifier: CC0-1.0
3
4//! # Partially-Signed Bitcoin Transactions
5//!
6//! This module implements the Finalizer and Extractor roles defined in
7//! BIP 174, PSBT, described at
8//! `https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki`
9//!
10
11use core::convert::TryFrom;
12use core::fmt;
13#[cfg(feature = "std")]
14use std::error;
15
16use qtum::hashes::{hash160, sha256d, Hash};
17use qtum::psbt::{self, Psbt};
18use qtum::secp256k1::{self, Secp256k1, VerifyOnly};
19use qtum::sighash::{self, SighashCache};
20use qtum::taproot::{self, ControlBlock, LeafVersion, TapLeafHash};
21use qtum::{absolute, bip32, Script, ScriptBuf, Sequence};
22
23use crate::miniscript::context::SigType;
24use crate::prelude::*;
25use crate::{
26    descriptor, interpreter, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey,
27    Preimage32, Satisfier, ToPublicKey, TranslatePk, Translator,
28};
29
30mod finalizer;
31
32#[allow(deprecated)]
33pub use self::finalizer::{finalize, finalize_mall, interpreter_check};
34
35/// Error type for entire Psbt
36#[derive(Debug)]
37pub enum Error {
38    /// Input Error type
39    InputError(InputError, usize),
40    /// Wrong Input Count
41    WrongInputCount {
42        /// Input count in tx
43        in_tx: usize,
44        /// Input count in psbt
45        in_map: usize,
46    },
47    /// Psbt Input index out of bounds
48    InputIdxOutofBounds {
49        /// Inputs in pbst
50        psbt_inp: usize,
51        /// requested index
52        index: usize,
53    },
54}
55
56impl fmt::Display for Error {
57    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58        match *self {
59            Error::InputError(ref inp_err, index) => write!(f, "{} at index {}", inp_err, index),
60            Error::WrongInputCount { in_tx, in_map } => write!(
61                f,
62                "PSBT had {} inputs in transaction but {} inputs in map",
63                in_tx, in_map
64            ),
65            Error::InputIdxOutofBounds { psbt_inp, index } => write!(
66                f,
67                "psbt input index {} out of bounds: psbt.inputs.len() {}",
68                index, psbt_inp
69            ),
70        }
71    }
72}
73
74#[cfg(feature = "std")]
75impl error::Error for Error {
76    fn cause(&self) -> Option<&dyn error::Error> {
77        use self::Error::*;
78
79        match self {
80            InputError(e, _) => Some(e),
81            WrongInputCount { .. } | InputIdxOutofBounds { .. } => None,
82        }
83    }
84}
85
86/// Error type for Pbst Input
87#[derive(Debug)]
88pub enum InputError {
89    /// Get the secp Errors directly
90    SecpErr(qtum::secp256k1::Error),
91    /// Key errors
92    KeyErr(qtum::key::Error),
93    /// Could not satisfy taproot descriptor
94    /// This error is returned when both script path and key paths could not be
95    /// satisfied. We cannot return a detailed error because we try all miniscripts
96    /// in script spend path, we cannot know which miniscript failed.
97    CouldNotSatisfyTr,
98    /// Error doing an interpreter-check on a finalized psbt
99    Interpreter(interpreter::Error),
100    /// Redeem script does not match the p2sh hash
101    InvalidRedeemScript {
102        /// Redeem script
103        redeem: ScriptBuf,
104        /// Expected p2sh Script
105        p2sh_expected: ScriptBuf,
106    },
107    /// Witness script does not match the p2wsh hash
108    InvalidWitnessScript {
109        /// Witness Script
110        witness_script: ScriptBuf,
111        /// Expected p2wsh script
112        p2wsh_expected: ScriptBuf,
113    },
114    /// Invalid sig
115    InvalidSignature {
116        /// The bitcoin public key
117        pubkey: qtum::PublicKey,
118        /// The (incorrect) signature
119        sig: Vec<u8>,
120    },
121    /// Pass through the underlying errors in miniscript
122    MiniscriptError(super::Error),
123    /// Missing redeem script for p2sh
124    MissingRedeemScript,
125    /// Missing witness
126    MissingWitness,
127    /// used for public key corresponding to pkh/wpkh
128    MissingPubkey,
129    /// Missing witness script for segwit descriptors
130    MissingWitnessScript,
131    ///Missing both the witness and non-witness utxo
132    MissingUtxo,
133    /// Non empty Witness script for p2sh
134    NonEmptyWitnessScript,
135    /// Non empty Redeem script
136    NonEmptyRedeemScript,
137    /// Non Standard sighash type
138    NonStandardSighashType(sighash::NonStandardSighashType),
139    /// Sighash did not match
140    WrongSighashFlag {
141        /// required sighash type
142        required: sighash::EcdsaSighashType,
143        /// the sighash type we got
144        got: sighash::EcdsaSighashType,
145        /// the corresponding publickey
146        pubkey: qtum::PublicKey,
147    },
148}
149
150#[cfg(feature = "std")]
151impl error::Error for InputError {
152    fn cause(&self) -> Option<&dyn error::Error> {
153        use self::InputError::*;
154
155        match self {
156            CouldNotSatisfyTr
157            | InvalidRedeemScript { .. }
158            | InvalidWitnessScript { .. }
159            | InvalidSignature { .. }
160            | MissingRedeemScript
161            | MissingWitness
162            | MissingPubkey
163            | MissingWitnessScript
164            | MissingUtxo
165            | NonEmptyWitnessScript
166            | NonEmptyRedeemScript
167            | NonStandardSighashType(_)
168            | WrongSighashFlag { .. } => None,
169            SecpErr(e) => Some(e),
170            KeyErr(e) => Some(e),
171            Interpreter(e) => Some(e),
172            MiniscriptError(e) => Some(e),
173        }
174    }
175}
176
177impl fmt::Display for InputError {
178    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
179        match *self {
180            InputError::InvalidSignature {
181                ref pubkey,
182                ref sig,
183            } => write!(f, "PSBT: bad signature {} for key {:?}", pubkey, sig),
184            InputError::KeyErr(ref e) => write!(f, "Key Err: {}", e),
185            InputError::Interpreter(ref e) => write!(f, "Interpreter: {}", e),
186            InputError::SecpErr(ref e) => write!(f, "Secp Err: {}", e),
187            InputError::InvalidRedeemScript {
188                ref redeem,
189                ref p2sh_expected,
190            } => write!(
191                f,
192                "Redeem script {} does not match the p2sh script {}",
193                redeem, p2sh_expected
194            ),
195            InputError::InvalidWitnessScript {
196                ref witness_script,
197                ref p2wsh_expected,
198            } => write!(
199                f,
200                "Witness script {} does not match the p2wsh script {}",
201                witness_script, p2wsh_expected
202            ),
203            InputError::MiniscriptError(ref e) => write!(f, "Miniscript Error: {}", e),
204            InputError::MissingWitness => write!(f, "PSBT is missing witness"),
205            InputError::MissingRedeemScript => write!(f, "PSBT is Redeem script"),
206            InputError::MissingUtxo => {
207                write!(f, "PSBT is missing both witness and non-witness UTXO")
208            }
209            InputError::MissingWitnessScript => write!(f, "PSBT is missing witness script"),
210            InputError::MissingPubkey => write!(f, "Missing pubkey for a pkh/wpkh"),
211            InputError::NonEmptyRedeemScript => write!(
212                f,
213                "PSBT has non-empty redeem script at for legacy transactions"
214            ),
215            InputError::NonEmptyWitnessScript => {
216                write!(f, "PSBT has non-empty witness script at for legacy input")
217            }
218            InputError::WrongSighashFlag {
219                required,
220                got,
221                pubkey,
222            } => write!(
223                f,
224                "PSBT: signature with key {:?} had \
225                 sighashflag {:?} rather than required {:?}",
226                pubkey, got, required
227            ),
228            InputError::CouldNotSatisfyTr => write!(f, "Could not satisfy Tr descriptor"),
229            InputError::NonStandardSighashType(e) => write!(f, "Non-standard sighash type {}", e),
230        }
231    }
232}
233
234#[doc(hidden)]
235impl From<super::Error> for InputError {
236    fn from(e: super::Error) -> InputError {
237        InputError::MiniscriptError(e)
238    }
239}
240
241#[doc(hidden)]
242impl From<qtum::secp256k1::Error> for InputError {
243    fn from(e: qtum::secp256k1::Error) -> InputError {
244        InputError::SecpErr(e)
245    }
246}
247
248#[doc(hidden)]
249impl From<qtum::key::Error> for InputError {
250    fn from(e: qtum::key::Error) -> InputError {
251        InputError::KeyErr(e)
252    }
253}
254
255/// Psbt satisfier for at inputs at a particular index
256/// Takes in &psbt because multiple inputs will share
257/// the same psbt structure
258/// All operations on this structure will panic if index
259/// is more than number of inputs in pbst
260pub struct PsbtInputSatisfier<'psbt> {
261    /// pbst
262    pub psbt: &'psbt Psbt,
263    /// input index
264    pub index: usize,
265}
266
267impl<'psbt> PsbtInputSatisfier<'psbt> {
268    /// create a new PsbtInputsatisfier from
269    /// psbt and index
270    pub fn new(psbt: &'psbt Psbt, index: usize) -> Self {
271        Self { psbt, index }
272    }
273}
274
275impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'psbt> {
276    fn lookup_tap_key_spend_sig(&self) -> Option<qtum::taproot::Signature> {
277        self.psbt.inputs[self.index].tap_key_sig
278    }
279
280    fn lookup_tap_leaf_script_sig(
281        &self,
282        pk: &Pk,
283        lh: &TapLeafHash,
284    ) -> Option<qtum::taproot::Signature> {
285        self.psbt.inputs[self.index]
286            .tap_script_sigs
287            .get(&(pk.to_x_only_pubkey(), *lh))
288            .copied()
289    }
290
291    fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<qtum::PublicKey> {
292        self.psbt.inputs[self.index]
293            .bip32_derivation
294            .iter()
295            .find(|&(pubkey, _)| pubkey.to_pubkeyhash(SigType::Ecdsa) == *pkh)
296            .map(|(pubkey, _)| qtum::PublicKey::new(*pubkey))
297    }
298
299    fn lookup_tap_control_block_map(
300        &self,
301    ) -> Option<&BTreeMap<ControlBlock, (qtum::ScriptBuf, LeafVersion)>> {
302        Some(&self.psbt.inputs[self.index].tap_scripts)
303    }
304
305    fn lookup_raw_pkh_tap_leaf_script_sig(
306        &self,
307        pkh: &(hash160::Hash, TapLeafHash),
308    ) -> Option<(
309        qtum::secp256k1::XOnlyPublicKey,
310        qtum::taproot::Signature,
311    )> {
312        self.psbt.inputs[self.index]
313            .tap_script_sigs
314            .iter()
315            .find(|&((pubkey, lh), _sig)| {
316                pubkey.to_pubkeyhash(SigType::Schnorr) == pkh.0 && *lh == pkh.1
317            })
318            .map(|((x_only_pk, _leaf_hash), sig)| (*x_only_pk, *sig))
319    }
320
321    fn lookup_ecdsa_sig(&self, pk: &Pk) -> Option<qtum::ecdsa::Signature> {
322        self.psbt.inputs[self.index]
323            .partial_sigs
324            .get(&pk.to_public_key())
325            .copied()
326    }
327
328    fn lookup_raw_pkh_ecdsa_sig(
329        &self,
330        pkh: &hash160::Hash,
331    ) -> Option<(qtum::PublicKey, qtum::ecdsa::Signature)> {
332        self.psbt.inputs[self.index]
333            .partial_sigs
334            .iter()
335            .find(|&(pubkey, _sig)| pubkey.to_pubkeyhash(SigType::Ecdsa) == *pkh)
336            .map(|(pk, sig)| (*pk, *sig))
337    }
338
339    fn check_after(&self, n: absolute::LockTime) -> bool {
340        if !self.psbt.unsigned_tx.input[self.index].enables_lock_time() {
341            return false;
342        }
343
344        let lock_time = absolute::LockTime::from(self.psbt.unsigned_tx.lock_time);
345
346        <dyn Satisfier<Pk>>::check_after(&lock_time, n)
347    }
348
349    fn check_older(&self, n: Sequence) -> bool {
350        let seq = self.psbt.unsigned_tx.input[self.index].sequence;
351
352        // https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki
353        // Disable flag set => return true.
354        if !n.is_relative_lock_time() {
355            return true;
356        }
357
358        if self.psbt.unsigned_tx.version < 2 || !seq.is_relative_lock_time() {
359            return false;
360        }
361
362        <dyn Satisfier<Pk>>::check_older(&seq, n)
363    }
364
365    fn lookup_hash160(&self, h: &Pk::Hash160) -> Option<Preimage32> {
366        self.psbt.inputs[self.index]
367            .hash160_preimages
368            .get(&Pk::to_hash160(h))
369            .and_then(try_vec_as_preimage32)
370    }
371
372    fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> {
373        self.psbt.inputs[self.index]
374            .sha256_preimages
375            .get(&Pk::to_sha256(h))
376            .and_then(try_vec_as_preimage32)
377    }
378
379    fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> {
380        self.psbt.inputs[self.index]
381            .hash256_preimages
382            .get(&sha256d::Hash::from_byte_array(
383                Pk::to_hash256(h).to_byte_array(),
384            )) // upstream psbt operates on hash256
385            .and_then(try_vec_as_preimage32)
386    }
387
388    fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
389        self.psbt.inputs[self.index]
390            .ripemd160_preimages
391            .get(&Pk::to_ripemd160(h))
392            .and_then(try_vec_as_preimage32)
393    }
394}
395
396fn try_vec_as_preimage32(vec: &Vec<u8>) -> Option<Preimage32> {
397    if vec.len() == 32 {
398        let mut arr = [0u8; 32];
399        arr.copy_from_slice(vec);
400        Some(arr)
401    } else {
402        None
403    }
404}
405
406// Basic sanity checks on psbts.
407// rust-bitcoin TODO: (Long term)
408// Brainstorm about how we can enforce these in type system while having a nice API
409fn sanity_check(psbt: &Psbt) -> Result<(), Error> {
410    if psbt.unsigned_tx.input.len() != psbt.inputs.len() {
411        return Err(Error::WrongInputCount {
412            in_tx: psbt.unsigned_tx.input.len(),
413            in_map: psbt.inputs.len(),
414        });
415    }
416
417    // Check well-formedness of input data
418    for (index, input) in psbt.inputs.iter().enumerate() {
419        // TODO: fix this after https://github.com/rust-bitcoin/rust-bitcoin/issues/838
420        let target_ecdsa_sighash_ty = match input.sighash_type {
421            Some(psbt_hash_ty) => psbt_hash_ty
422                .ecdsa_hash_ty()
423                .map_err(|e| Error::InputError(InputError::NonStandardSighashType(e), index))?,
424            None => sighash::EcdsaSighashType::All,
425        };
426        for (key, ecdsa_sig) in &input.partial_sigs {
427            let flag = sighash::EcdsaSighashType::from_standard(ecdsa_sig.hash_ty as u32).map_err(
428                |_| {
429                    Error::InputError(
430                        InputError::Interpreter(interpreter::Error::NonStandardSighash(
431                            ecdsa_sig.to_vec(),
432                        )),
433                        index,
434                    )
435                },
436            )?;
437            if target_ecdsa_sighash_ty != flag {
438                return Err(Error::InputError(
439                    InputError::WrongSighashFlag {
440                        required: target_ecdsa_sighash_ty,
441                        got: flag,
442                        pubkey: *key,
443                    },
444                    index,
445                ));
446            }
447            // Signatures are well-formed in psbt partial sigs
448        }
449    }
450
451    Ok(())
452}
453
454/// Additional operations for miniscript descriptors for various psbt roles.
455/// Note that these APIs would generally error when used on scripts that are not
456/// miniscripts.
457pub trait PsbtExt {
458    /// Finalize the psbt. This function takes in a mutable reference to psbt
459    /// and populates the final_witness and final_scriptsig
460    /// for all miniscript inputs.
461    ///
462    /// Finalizes all inputs that it can finalize, and returns an error for each input
463    /// that it cannot finalize. Also performs a sanity interpreter check on the
464    /// finalized psbt which involves checking the signatures/ preimages/timelocks.
465    ///
466    /// Input finalization also fails if it is not possible to satisfy any of the inputs non-malleably
467    /// See [finalizer::finalize_mall] if you want to allow malleable satisfactions
468    ///
469    /// For finalizing individual inputs, see also [`PsbtExt::finalize_inp`]
470    ///
471    /// # Errors:
472    ///
473    /// - A vector of errors, one of each of failed finalized input
474    fn finalize_mut<C: secp256k1::Verification>(
475        &mut self,
476        secp: &secp256k1::Secp256k1<C>,
477    ) -> Result<(), Vec<Error>>;
478
479    /// Same as [`PsbtExt::finalize_mut`], but does not mutate the input psbt and
480    /// returns a new psbt
481    ///
482    /// # Errors:
483    ///
484    /// - Returns a mutated psbt with all inputs `finalize_mut` could finalize
485    /// - A vector of input errors, one of each of failed finalized input
486    fn finalize<C: secp256k1::Verification>(
487        self,
488        secp: &secp256k1::Secp256k1<C>,
489    ) -> Result<Psbt, (Psbt, Vec<Error>)>;
490
491    /// Same as [PsbtExt::finalize_mut], but allows for malleable satisfactions
492    fn finalize_mall_mut<C: secp256k1::Verification>(
493        &mut self,
494        secp: &Secp256k1<C>,
495    ) -> Result<(), Vec<Error>>;
496
497    /// Same as [PsbtExt::finalize], but allows for malleable satisfactions
498    fn finalize_mall<C: secp256k1::Verification>(
499        self,
500        secp: &Secp256k1<C>,
501    ) -> Result<Psbt, (Psbt, Vec<Error>)>;
502
503    /// Same as [`PsbtExt::finalize_mut`], but only tries to finalize a single input leaving other
504    /// inputs as is. Use this when not all of inputs that you are trying to
505    /// satisfy are miniscripts
506    ///
507    /// # Errors:
508    ///
509    /// - Input error detailing why the finalization failed. The psbt is not mutated when the finalization fails
510    fn finalize_inp_mut<C: secp256k1::Verification>(
511        &mut self,
512        secp: &secp256k1::Secp256k1<C>,
513        index: usize,
514    ) -> Result<(), Error>;
515
516    /// Same as [`PsbtExt::finalize_inp_mut`], but does not mutate the psbt and returns a new one
517    ///
518    /// # Errors:
519    ///  Returns a tuple containing
520    /// - Original psbt
521    /// - Input Error detailing why the input finalization failed
522    fn finalize_inp<C: secp256k1::Verification>(
523        self,
524        secp: &secp256k1::Secp256k1<C>,
525        index: usize,
526    ) -> Result<Psbt, (Psbt, Error)>;
527
528    /// Same as [`PsbtExt::finalize_inp_mut`], but allows for malleable satisfactions
529    fn finalize_inp_mall_mut<C: secp256k1::Verification>(
530        &mut self,
531        secp: &secp256k1::Secp256k1<C>,
532        index: usize,
533    ) -> Result<(), Error>;
534
535    /// Same as [`PsbtExt::finalize_inp`], but allows for malleable satisfactions
536    fn finalize_inp_mall<C: secp256k1::Verification>(
537        self,
538        secp: &secp256k1::Secp256k1<C>,
539        index: usize,
540    ) -> Result<Psbt, (Psbt, Error)>;
541
542    /// Psbt extractor as defined in BIP174 that takes in a psbt reference
543    /// and outputs a extracted qtum::Transaction
544    /// Also does the interpreter sanity check
545    /// Will error if the final ScriptSig or final Witness are missing
546    /// or the interpreter check fails.
547    fn extract<C: secp256k1::Verification>(
548        &self,
549        secp: &Secp256k1<C>,
550    ) -> Result<qtum::Transaction, Error>;
551
552    /// Update PSBT input with a descriptor and check consistency of `*_utxo` fields.
553    ///
554    /// This is the checked version of [`update_with_descriptor_unchecked`]. It checks that the
555    /// `witness_utxo` and `non_witness_utxo` are sane and have a `script_pubkey` that matches the
556    /// descriptor. In particular, it makes sure pre-segwit descriptors always have `non_witness_utxo`
557    /// present (and the txid matches). If both `witness_utxo` and `non_witness_utxo` are present
558    /// then it also checks they are consistent with each other.
559    ///
560    /// Hint: because of the *[segwit bug]* some PSBT signers require that `non_witness_utxo` is
561    /// present on segwitv0 inputs regardless but this function doesn't enforce this so you will
562    /// have to do this check its presence manually (if it is present this *will* check its
563    /// validity).
564    ///
565    /// The `descriptor` **must not have any wildcards** in it
566    /// otherwise an error will be returned however it can (and should) have extended keys in it.
567    ///
568    /// [`update_with_descriptor_unchecked`]: PsbtInputExt::update_with_descriptor_unchecked
569    /// [segwit bug]: https://bitcoinhackers.org/@lukedashjr/104287698361196952
570    fn update_input_with_descriptor(
571        &mut self,
572        input_index: usize,
573        descriptor: &Descriptor<DefiniteDescriptorKey>,
574    ) -> Result<(), UtxoUpdateError>;
575
576    /// Update PSBT output with a descriptor and check consistency of the output's `script_pubkey`
577    ///
578    /// This is the checked version of [`update_with_descriptor_unchecked`]. It checks that the
579    /// output's `script_pubkey` matches the descriptor.
580    ///
581    /// The `descriptor` **must not have any wildcards** in it
582    /// otherwise an error will be returned however it can (and should) have extended keys in it.
583    ///
584    /// [`update_with_descriptor_unchecked`]: PsbtOutputExt::update_with_descriptor_unchecked
585    fn update_output_with_descriptor(
586        &mut self,
587        output_index: usize,
588        descriptor: &Descriptor<DefiniteDescriptorKey>,
589    ) -> Result<(), OutputUpdateError>;
590
591    /// Get the sighash message(data to sign) at input index `idx`.
592    ///
593    /// Based on the sighash
594    /// flag specified in the [`Psbt`] sighash field. If the input sighash flag psbt field is `None`
595    /// the [`sighash::TapSighashType::Default`](qtum::sighash::TapSighashType::Default) is chosen
596    /// for for taproot spends, otherwise [`EcdsaSighashType::All`](qtum::sighash::EcdsaSighashType::All) is chosen.
597    /// If the utxo at `idx` is a taproot output, returns a [`PsbtSighashMsg::TapSighash`] variant.
598    /// If the utxo at `idx` is a pre-taproot segwit output, returns a [`PsbtSighashMsg::SegwitV0Sighash`] variant.
599    /// For legacy outputs, returns a [`PsbtSighashMsg::LegacySighash`] variant.
600    /// The `tapleaf_hash` parameter can be used to specify which tapleaf script hash has to be computed. If
601    /// `tapleaf_hash` is [`None`], and the output is taproot output, the key spend hash is computed. This parameter must be
602    /// set to [`None`] while computing sighash for pre-taproot outputs.
603    /// The function also updates the sighash cache with transaction computed during sighash computation of this input
604    ///
605    /// # Arguments:
606    ///
607    /// * `idx`: The input index of psbt to sign
608    /// * `cache`: The [`SighashCache`] for used to cache/read previously cached computations
609    /// * `tapleaf_hash`: If the output is taproot, compute the sighash for this particular leaf.
610    ///
611    /// [`SighashCache`]: qtum::sighash::SighashCache
612    fn sighash_msg<T: Borrow<qtum::Transaction>>(
613        &self,
614        idx: usize,
615        cache: &mut SighashCache<T>,
616        tapleaf_hash: Option<TapLeafHash>,
617    ) -> Result<PsbtSighashMsg, SighashError>;
618}
619
620impl PsbtExt for Psbt {
621    fn finalize_mut<C: secp256k1::Verification>(
622        &mut self,
623        secp: &secp256k1::Secp256k1<C>,
624    ) -> Result<(), Vec<Error>> {
625        // Actually construct the witnesses
626        let mut errors = vec![];
627        for index in 0..self.inputs.len() {
628            match finalizer::finalize_input(self, index, secp, /*allow_mall*/ false) {
629                Ok(..) => {}
630                Err(e) => {
631                    errors.push(e);
632                }
633            }
634        }
635        if errors.is_empty() {
636            Ok(())
637        } else {
638            Err(errors)
639        }
640    }
641
642    fn finalize<C: secp256k1::Verification>(
643        mut self,
644        secp: &secp256k1::Secp256k1<C>,
645    ) -> Result<Psbt, (Psbt, Vec<Error>)> {
646        match self.finalize_mut(secp) {
647            Ok(..) => Ok(self),
648            Err(e) => Err((self, e)),
649        }
650    }
651
652    fn finalize_mall_mut<C: secp256k1::Verification>(
653        &mut self,
654        secp: &secp256k1::Secp256k1<C>,
655    ) -> Result<(), Vec<Error>> {
656        let mut errors = vec![];
657        for index in 0..self.inputs.len() {
658            match finalizer::finalize_input(self, index, secp, /*allow_mall*/ true) {
659                Ok(..) => {}
660                Err(e) => {
661                    errors.push(e);
662                }
663            }
664        }
665        if errors.is_empty() {
666            Ok(())
667        } else {
668            Err(errors)
669        }
670    }
671
672    fn finalize_mall<C: secp256k1::Verification>(
673        mut self,
674        secp: &Secp256k1<C>,
675    ) -> Result<Psbt, (Psbt, Vec<Error>)> {
676        match self.finalize_mall_mut(secp) {
677            Ok(..) => Ok(self),
678            Err(e) => Err((self, e)),
679        }
680    }
681
682    fn finalize_inp_mut<C: secp256k1::Verification>(
683        &mut self,
684        secp: &secp256k1::Secp256k1<C>,
685        index: usize,
686    ) -> Result<(), Error> {
687        if index >= self.inputs.len() {
688            return Err(Error::InputIdxOutofBounds {
689                psbt_inp: self.inputs.len(),
690                index,
691            });
692        }
693        finalizer::finalize_input(self, index, secp, /*allow_mall*/ false)
694    }
695
696    fn finalize_inp<C: secp256k1::Verification>(
697        mut self,
698        secp: &secp256k1::Secp256k1<C>,
699        index: usize,
700    ) -> Result<Psbt, (Psbt, Error)> {
701        match self.finalize_inp_mut(secp, index) {
702            Ok(..) => Ok(self),
703            Err(e) => Err((self, e)),
704        }
705    }
706
707    fn finalize_inp_mall_mut<C: secp256k1::Verification>(
708        &mut self,
709        secp: &secp256k1::Secp256k1<C>,
710        index: usize,
711    ) -> Result<(), Error> {
712        if index >= self.inputs.len() {
713            return Err(Error::InputIdxOutofBounds {
714                psbt_inp: self.inputs.len(),
715                index,
716            });
717        }
718        finalizer::finalize_input(self, index, secp, /*allow_mall*/ false)
719    }
720
721    fn finalize_inp_mall<C: secp256k1::Verification>(
722        mut self,
723        secp: &secp256k1::Secp256k1<C>,
724        index: usize,
725    ) -> Result<Psbt, (Psbt, Error)> {
726        match self.finalize_inp_mall_mut(secp, index) {
727            Ok(..) => Ok(self),
728            Err(e) => Err((self, e)),
729        }
730    }
731
732    fn extract<C: secp256k1::Verification>(
733        &self,
734        secp: &Secp256k1<C>,
735    ) -> Result<qtum::Transaction, Error> {
736        sanity_check(self)?;
737
738        let mut ret = self.unsigned_tx.clone();
739        for (n, input) in self.inputs.iter().enumerate() {
740            if input.final_script_sig.is_none() && input.final_script_witness.is_none() {
741                return Err(Error::InputError(InputError::MissingWitness, n));
742            }
743
744            if let Some(witness) = input.final_script_witness.as_ref() {
745                ret.input[n].witness = witness.clone();
746            }
747            if let Some(script_sig) = input.final_script_sig.as_ref() {
748                ret.input[n].script_sig = script_sig.clone();
749            }
750        }
751        interpreter_check(self, secp)?;
752        Ok(ret)
753    }
754
755    fn update_input_with_descriptor(
756        &mut self,
757        input_index: usize,
758        desc: &Descriptor<DefiniteDescriptorKey>,
759    ) -> Result<(), UtxoUpdateError> {
760        let n_inputs = self.inputs.len();
761        let input = self
762            .inputs
763            .get_mut(input_index)
764            .ok_or(UtxoUpdateError::IndexOutOfBounds(input_index, n_inputs))?;
765        let txin = self
766            .unsigned_tx
767            .input
768            .get(input_index)
769            .ok_or(UtxoUpdateError::MissingInputUtxo)?;
770
771        let desc_type = desc.desc_type();
772
773        if let Some(non_witness_utxo) = &input.non_witness_utxo {
774            if txin.previous_output.txid != non_witness_utxo.txid() {
775                return Err(UtxoUpdateError::UtxoCheck);
776            }
777        }
778
779        let expected_spk = {
780            match (&input.witness_utxo, &input.non_witness_utxo) {
781                (Some(witness_utxo), None) => {
782                    if desc_type.segwit_version().is_some() {
783                        witness_utxo.script_pubkey.clone()
784                    } else {
785                        return Err(UtxoUpdateError::UtxoCheck);
786                    }
787                }
788                (None, Some(non_witness_utxo)) => non_witness_utxo
789                    .output
790                    .get(txin.previous_output.vout as usize)
791                    .ok_or(UtxoUpdateError::UtxoCheck)?
792                    .script_pubkey
793                    .clone(),
794                (Some(witness_utxo), Some(non_witness_utxo)) => {
795                    if witness_utxo
796                        != non_witness_utxo
797                            .output
798                            .get(txin.previous_output.vout as usize)
799                            .ok_or(UtxoUpdateError::UtxoCheck)?
800                    {
801                        return Err(UtxoUpdateError::UtxoCheck);
802                    }
803
804                    witness_utxo.script_pubkey.clone()
805                }
806                (None, None) => return Err(UtxoUpdateError::UtxoCheck),
807            }
808        };
809
810        let (_, spk_check_passed) =
811            update_item_with_descriptor_helper(input, desc, Some(&expected_spk))
812                .map_err(UtxoUpdateError::DerivationError)?;
813
814        if !spk_check_passed {
815            return Err(UtxoUpdateError::MismatchedScriptPubkey);
816        }
817
818        Ok(())
819    }
820
821    fn update_output_with_descriptor(
822        &mut self,
823        output_index: usize,
824        desc: &Descriptor<DefiniteDescriptorKey>,
825    ) -> Result<(), OutputUpdateError> {
826        let n_outputs = self.outputs.len();
827        let output = self
828            .outputs
829            .get_mut(output_index)
830            .ok_or(OutputUpdateError::IndexOutOfBounds(output_index, n_outputs))?;
831        let txout = self
832            .unsigned_tx
833            .output
834            .get(output_index)
835            .ok_or(OutputUpdateError::MissingTxOut)?;
836
837        let (_, spk_check_passed) =
838            update_item_with_descriptor_helper(output, desc, Some(&txout.script_pubkey))
839                .map_err(OutputUpdateError::DerivationError)?;
840
841        if !spk_check_passed {
842            return Err(OutputUpdateError::MismatchedScriptPubkey);
843        }
844
845        Ok(())
846    }
847
848    fn sighash_msg<T: Borrow<qtum::Transaction>>(
849        &self,
850        idx: usize,
851        cache: &mut SighashCache<T>,
852        tapleaf_hash: Option<TapLeafHash>,
853    ) -> Result<PsbtSighashMsg, SighashError> {
854        // Infer a descriptor at idx
855        if idx >= self.inputs.len() {
856            return Err(SighashError::IndexOutOfBounds(idx, self.inputs.len()));
857        }
858        let inp = &self.inputs[idx];
859        let prevouts = finalizer::prevouts(self).map_err(|_e| SighashError::MissingSpendUtxos)?;
860        // Note that as per Psbt spec we should have access to spent_utxos for the transaction
861        // Even if the transaction does not require SighashAll, we create `Prevouts::All` for code simplicity
862        let prevouts = qtum::sighash::Prevouts::All(&prevouts);
863        let inp_spk =
864            finalizer::get_scriptpubkey(self, idx).map_err(|_e| SighashError::MissingInputUtxo)?;
865        if inp_spk.is_v1_p2tr() {
866            let hash_ty = inp
867                .sighash_type
868                .map(|sighash_type| sighash_type.taproot_hash_ty())
869                .unwrap_or(Ok(sighash::TapSighashType::Default))
870                .map_err(|_e| SighashError::InvalidSighashType)?;
871            match tapleaf_hash {
872                Some(leaf_hash) => {
873                    let tap_sighash_msg = cache
874                        .taproot_script_spend_signature_hash(idx, &prevouts, leaf_hash, hash_ty)?;
875                    Ok(PsbtSighashMsg::TapSighash(tap_sighash_msg))
876                }
877                None => {
878                    let tap_sighash_msg =
879                        cache.taproot_key_spend_signature_hash(idx, &prevouts, hash_ty)?;
880                    Ok(PsbtSighashMsg::TapSighash(tap_sighash_msg))
881                }
882            }
883        } else {
884            let hash_ty = inp
885                .sighash_type
886                .map(|sighash_type| sighash_type.ecdsa_hash_ty())
887                .unwrap_or(Ok(sighash::EcdsaSighashType::All))
888                .map_err(|_e| SighashError::InvalidSighashType)?;
889            let amt = finalizer::get_utxo(self, idx)
890                .map_err(|_e| SighashError::MissingInputUtxo)?
891                .value;
892            let is_nested_wpkh = inp_spk.is_p2sh()
893                && inp
894                    .redeem_script
895                    .as_ref()
896                    .map(|x| x.is_v0_p2wpkh())
897                    .unwrap_or(false);
898            let is_nested_wsh = inp_spk.is_p2sh()
899                && inp
900                    .redeem_script
901                    .as_ref()
902                    .map(|x| x.is_v0_p2wsh())
903                    .unwrap_or(false);
904            if inp_spk.is_v0_p2wpkh() || inp_spk.is_v0_p2wsh() || is_nested_wpkh || is_nested_wsh {
905                let msg = if inp_spk.is_v0_p2wpkh() {
906                    let script_code = inp_spk
907                        .p2wpkh_script_code()
908                        .expect("checked is p2wpkh above");
909                    cache.segwit_signature_hash(idx, &script_code, amt, hash_ty)?
910                } else if is_nested_wpkh {
911                    let script_code = inp
912                        .redeem_script
913                        .as_ref()
914                        .expect("redeem script non-empty checked earlier")
915                        .p2wpkh_script_code()
916                        .expect("checked is p2wpkh above");
917                    cache.segwit_signature_hash(idx, &script_code, amt, hash_ty)?
918                } else {
919                    // wsh and nested wsh, script code is witness script
920                    let script_code = inp
921                        .witness_script
922                        .as_ref()
923                        .ok_or(SighashError::MissingWitnessScript)?;
924                    cache.segwit_signature_hash(idx, script_code, amt, hash_ty)?
925                };
926                Ok(PsbtSighashMsg::SegwitV0Sighash(msg))
927            } else {
928                // legacy sighash case
929                let script_code = if inp_spk.is_p2sh() {
930                    inp.redeem_script
931                        .as_ref()
932                        .ok_or(SighashError::MissingRedeemScript)?
933                } else {
934                    &inp_spk
935                };
936                let msg = cache.legacy_signature_hash(idx, script_code, hash_ty.to_u32())?;
937                Ok(PsbtSighashMsg::LegacySighash(msg))
938            }
939        }
940    }
941}
942
943/// Extension trait for PSBT inputs
944pub trait PsbtInputExt {
945    /// Given the descriptor for a utxo being spent populate the PSBT input's fields so it can be signed.
946    ///
947    /// If the descriptor contains wildcards or otherwise cannot be transformed into a concrete
948    /// descriptor an error will be returned. The descriptor *can* (and should) have extended keys in
949    /// it so PSBT fields like `bip32_derivation` and `tap_key_origins` can be populated.
950    ///
951    /// Note that his method doesn't check that the `witness_utxo` or `non_witness_utxo` is
952    /// consistent with the descriptor. To do that see [`update_input_with_descriptor`].
953    ///
954    /// ## Return value
955    ///
956    /// For convenience, this returns the concrete descriptor that is computed internally to fill
957    /// out the PSBT input fields. This can be used to manually check that the `script_pubkey` in
958    /// `witness_utxo` and/or `non_witness_utxo` is consistent with the descriptor.
959    ///
960    /// [`update_input_with_descriptor`]: PsbtExt::update_input_with_descriptor
961    fn update_with_descriptor_unchecked(
962        &mut self,
963        descriptor: &Descriptor<DefiniteDescriptorKey>,
964    ) -> Result<Descriptor<qtum::PublicKey>, descriptor::ConversionError>;
965}
966
967impl PsbtInputExt for psbt::Input {
968    fn update_with_descriptor_unchecked(
969        &mut self,
970        descriptor: &Descriptor<DefiniteDescriptorKey>,
971    ) -> Result<Descriptor<qtum::PublicKey>, descriptor::ConversionError> {
972        let (derived, _) = update_item_with_descriptor_helper(self, descriptor, None)?;
973        Ok(derived)
974    }
975}
976
977/// Extension trait for PSBT outputs
978pub trait PsbtOutputExt {
979    /// Given the descriptor of a PSBT output populate the relevant metadata
980    ///
981    /// If the descriptor contains wildcards or otherwise cannot be transformed into a concrete
982    /// descriptor an error will be returned. The descriptor *can* (and should) have extended keys in
983    /// it so PSBT fields like `bip32_derivation` and `tap_key_origins` can be populated.
984    ///
985    /// Note that this method doesn't check that the `script_pubkey` of the output being
986    /// updated matches the descriptor. To do that see [`update_output_with_descriptor`].
987    ///
988    /// ## Return value
989    ///
990    /// For convenience, this returns the concrete descriptor that is computed internally to fill
991    /// out the PSBT output fields. This can be used to manually check that the `script_pubkey` is
992    /// consistent with the descriptor.
993    ///
994    /// [`update_output_with_descriptor`]: PsbtExt::update_output_with_descriptor
995    fn update_with_descriptor_unchecked(
996        &mut self,
997        descriptor: &Descriptor<DefiniteDescriptorKey>,
998    ) -> Result<Descriptor<qtum::PublicKey>, descriptor::ConversionError>;
999}
1000
1001impl PsbtOutputExt for psbt::Output {
1002    fn update_with_descriptor_unchecked(
1003        &mut self,
1004        descriptor: &Descriptor<DefiniteDescriptorKey>,
1005    ) -> Result<Descriptor<qtum::PublicKey>, descriptor::ConversionError> {
1006        let (derived, _) = update_item_with_descriptor_helper(self, descriptor, None)?;
1007        Ok(derived)
1008    }
1009}
1010
1011// Traverse the pkh lookup while maintaining a reverse map for storing the map
1012// hash160 -> (XonlyPublicKey)/PublicKey
1013struct KeySourceLookUp(
1014    pub BTreeMap<secp256k1::PublicKey, bip32::KeySource>,
1015    pub secp256k1::Secp256k1<VerifyOnly>,
1016);
1017
1018impl Translator<DefiniteDescriptorKey, qtum::PublicKey, descriptor::ConversionError>
1019    for KeySourceLookUp
1020{
1021    fn pk(
1022        &mut self,
1023        xpk: &DefiniteDescriptorKey,
1024    ) -> Result<qtum::PublicKey, descriptor::ConversionError> {
1025        let derived = xpk.derive_public_key(&self.1)?;
1026        self.0.insert(
1027            derived.to_public_key().inner,
1028            (
1029                xpk.master_fingerprint(),
1030                xpk.full_derivation_path()
1031                    .ok_or(descriptor::ConversionError::MultiKey)?,
1032            ),
1033        );
1034        Ok(derived)
1035    }
1036
1037    translate_hash_clone!(
1038        DescriptorPublicKey,
1039        qtum::PublicKey,
1040        descriptor::ConversionError
1041    );
1042}
1043
1044// Provides generalized access to PSBT fields common to inputs and outputs
1045trait PsbtFields {
1046    // Common fields are returned as a mutable ref of the same type
1047    fn redeem_script(&mut self) -> &mut Option<ScriptBuf>;
1048    fn witness_script(&mut self) -> &mut Option<ScriptBuf>;
1049    fn bip32_derivation(&mut self) -> &mut BTreeMap<secp256k1::PublicKey, bip32::KeySource>;
1050    fn tap_internal_key(&mut self) -> &mut Option<qtum::key::XOnlyPublicKey>;
1051    fn tap_key_origins(
1052        &mut self,
1053    ) -> &mut BTreeMap<qtum::key::XOnlyPublicKey, (Vec<TapLeafHash>, bip32::KeySource)>;
1054    fn proprietary(&mut self) -> &mut BTreeMap<psbt::raw::ProprietaryKey, Vec<u8>>;
1055    fn unknown(&mut self) -> &mut BTreeMap<psbt::raw::Key, Vec<u8>>;
1056
1057    // `tap_tree` only appears in psbt::Output, so it's returned as an option of a mutable ref
1058    fn tap_tree(&mut self) -> Option<&mut Option<taproot::TapTree>> {
1059        None
1060    }
1061
1062    // `tap_scripts` and `tap_merkle_root` only appear in psbt::Input
1063    fn tap_scripts(&mut self) -> Option<&mut BTreeMap<ControlBlock, (ScriptBuf, LeafVersion)>> {
1064        None
1065    }
1066    fn tap_merkle_root(&mut self) -> Option<&mut Option<taproot::TapNodeHash>> {
1067        None
1068    }
1069}
1070
1071impl PsbtFields for psbt::Input {
1072    fn redeem_script(&mut self) -> &mut Option<ScriptBuf> {
1073        &mut self.redeem_script
1074    }
1075    fn witness_script(&mut self) -> &mut Option<ScriptBuf> {
1076        &mut self.witness_script
1077    }
1078    fn bip32_derivation(&mut self) -> &mut BTreeMap<secp256k1::PublicKey, bip32::KeySource> {
1079        &mut self.bip32_derivation
1080    }
1081    fn tap_internal_key(&mut self) -> &mut Option<qtum::key::XOnlyPublicKey> {
1082        &mut self.tap_internal_key
1083    }
1084    fn tap_key_origins(
1085        &mut self,
1086    ) -> &mut BTreeMap<qtum::key::XOnlyPublicKey, (Vec<TapLeafHash>, bip32::KeySource)> {
1087        &mut self.tap_key_origins
1088    }
1089    fn proprietary(&mut self) -> &mut BTreeMap<psbt::raw::ProprietaryKey, Vec<u8>> {
1090        &mut self.proprietary
1091    }
1092    fn unknown(&mut self) -> &mut BTreeMap<psbt::raw::Key, Vec<u8>> {
1093        &mut self.unknown
1094    }
1095
1096    fn tap_scripts(&mut self) -> Option<&mut BTreeMap<ControlBlock, (ScriptBuf, LeafVersion)>> {
1097        Some(&mut self.tap_scripts)
1098    }
1099    fn tap_merkle_root(&mut self) -> Option<&mut Option<taproot::TapNodeHash>> {
1100        Some(&mut self.tap_merkle_root)
1101    }
1102}
1103
1104impl PsbtFields for psbt::Output {
1105    fn redeem_script(&mut self) -> &mut Option<ScriptBuf> {
1106        &mut self.redeem_script
1107    }
1108    fn witness_script(&mut self) -> &mut Option<ScriptBuf> {
1109        &mut self.witness_script
1110    }
1111    fn bip32_derivation(&mut self) -> &mut BTreeMap<secp256k1::PublicKey, bip32::KeySource> {
1112        &mut self.bip32_derivation
1113    }
1114    fn tap_internal_key(&mut self) -> &mut Option<qtum::key::XOnlyPublicKey> {
1115        &mut self.tap_internal_key
1116    }
1117    fn tap_key_origins(
1118        &mut self,
1119    ) -> &mut BTreeMap<qtum::key::XOnlyPublicKey, (Vec<TapLeafHash>, bip32::KeySource)> {
1120        &mut self.tap_key_origins
1121    }
1122    fn proprietary(&mut self) -> &mut BTreeMap<psbt::raw::ProprietaryKey, Vec<u8>> {
1123        &mut self.proprietary
1124    }
1125    fn unknown(&mut self) -> &mut BTreeMap<psbt::raw::Key, Vec<u8>> {
1126        &mut self.unknown
1127    }
1128
1129    fn tap_tree(&mut self) -> Option<&mut Option<taproot::TapTree>> {
1130        Some(&mut self.tap_tree)
1131    }
1132}
1133
1134fn update_item_with_descriptor_helper<F: PsbtFields>(
1135    item: &mut F,
1136    descriptor: &Descriptor<DefiniteDescriptorKey>,
1137    check_script: Option<&Script>,
1138    // the return value is a tuple here since the two internal calls to it require different info.
1139    // One needs the derived descriptor and the other needs to know whether the script_pubkey check
1140    // failed.
1141) -> Result<(Descriptor<qtum::PublicKey>, bool), descriptor::ConversionError> {
1142    let secp = secp256k1::Secp256k1::verification_only();
1143
1144    let derived = if let Descriptor::Tr(_) = &descriptor {
1145        let derived = descriptor.derived_descriptor(&secp)?;
1146
1147        if let Some(check_script) = check_script {
1148            if check_script != &derived.script_pubkey() {
1149                return Ok((derived, false));
1150            }
1151        }
1152
1153        // NOTE: they will both always be Tr
1154        if let (Descriptor::Tr(tr_derived), Descriptor::Tr(tr_xpk)) = (&derived, descriptor) {
1155            let spend_info = tr_derived.spend_info();
1156            let ik_derived = spend_info.internal_key();
1157            let ik_xpk = tr_xpk.internal_key();
1158            if let Some(merkle_root) = item.tap_merkle_root() {
1159                *merkle_root = spend_info.merkle_root();
1160            }
1161            *item.tap_internal_key() = Some(ik_derived);
1162            item.tap_key_origins().insert(
1163                ik_derived,
1164                (
1165                    vec![],
1166                    (
1167                        ik_xpk.master_fingerprint(),
1168                        ik_xpk
1169                            .full_derivation_path()
1170                            .ok_or(descriptor::ConversionError::MultiKey)?,
1171                    ),
1172                ),
1173            );
1174
1175            let mut builder = taproot::TaprootBuilder::new();
1176
1177            for ((_depth_der, ms_derived), (depth, ms)) in
1178                tr_derived.iter_scripts().zip(tr_xpk.iter_scripts())
1179            {
1180                debug_assert_eq!(_depth_der, depth);
1181                let leaf_script = (ms_derived.encode(), LeafVersion::TapScript);
1182                let tapleaf_hash = TapLeafHash::from_script(&leaf_script.0, leaf_script.1);
1183                builder = builder
1184                    .add_leaf(depth, leaf_script.0.clone())
1185                    .expect("Computing spend data on a valid tree should always succeed");
1186                if let Some(tap_scripts) = item.tap_scripts() {
1187                    let control_block = spend_info
1188                        .control_block(&leaf_script)
1189                        .expect("Control block must exist in script map for every known leaf");
1190                    tap_scripts.insert(control_block, leaf_script);
1191                }
1192
1193                for (pk_pkh_derived, pk_pkh_xpk) in ms_derived.iter_pk().zip(ms.iter_pk()) {
1194                    let (xonly, xpk) = (pk_pkh_derived.to_x_only_pubkey(), pk_pkh_xpk);
1195
1196                    let xpk_full_derivation_path = xpk
1197                        .full_derivation_path()
1198                        .ok_or(descriptor::ConversionError::MultiKey)?;
1199                    item.tap_key_origins()
1200                        .entry(xonly)
1201                        .and_modify(|(tapleaf_hashes, _)| {
1202                            if tapleaf_hashes.last() != Some(&tapleaf_hash) {
1203                                tapleaf_hashes.push(tapleaf_hash);
1204                            }
1205                        })
1206                        .or_insert_with(|| {
1207                            (
1208                                vec![tapleaf_hash],
1209                                (xpk.master_fingerprint(), xpk_full_derivation_path),
1210                            )
1211                        });
1212                }
1213            }
1214
1215            // Ensure there are no duplicated leaf hashes. This can happen if some of them were
1216            // already present in the map when this function is called, since this only appends new
1217            // data to the psbt without checking what's already present.
1218            for (tapleaf_hashes, _) in item.tap_key_origins().values_mut() {
1219                tapleaf_hashes.sort();
1220                tapleaf_hashes.dedup();
1221            }
1222
1223            match item.tap_tree() {
1224                // Only set the tap_tree if the item supports it (it's an output) and the descriptor actually
1225                // contains one, otherwise it'll just be empty
1226                Some(tap_tree) if tr_derived.taptree().is_some() => {
1227                    *tap_tree = Some(
1228                        taproot::TapTree::try_from(builder)
1229                            .expect("The tree should always be valid"),
1230                    );
1231                }
1232                _ => {}
1233            }
1234        }
1235
1236        derived
1237    } else {
1238        let mut bip32_derivation = KeySourceLookUp(BTreeMap::new(), Secp256k1::verification_only());
1239        let derived = descriptor
1240            .translate_pk(&mut bip32_derivation)
1241            .map_err(|e| e.expect_translator_err("No Outer Context errors in translations"))?;
1242
1243        if let Some(check_script) = check_script {
1244            if check_script != &derived.script_pubkey() {
1245                return Ok((derived, false));
1246            }
1247        }
1248
1249        item.bip32_derivation().append(&mut bip32_derivation.0);
1250
1251        match &derived {
1252            Descriptor::Bare(_) | Descriptor::Pkh(_) | Descriptor::Wpkh(_) => {}
1253            Descriptor::Sh(sh) => match sh.as_inner() {
1254                descriptor::ShInner::Wsh(wsh) => {
1255                    *item.witness_script() = Some(wsh.inner_script());
1256                    *item.redeem_script() = Some(wsh.inner_script().to_v0_p2wsh());
1257                }
1258                descriptor::ShInner::Wpkh(..) => *item.redeem_script() = Some(sh.inner_script()),
1259                descriptor::ShInner::SortedMulti(_) | descriptor::ShInner::Ms(_) => {
1260                    *item.redeem_script() = Some(sh.inner_script())
1261                }
1262            },
1263            Descriptor::Wsh(wsh) => *item.witness_script() = Some(wsh.inner_script()),
1264            Descriptor::Tr(_) => unreachable!("Tr is dealt with separately"),
1265        }
1266
1267        derived
1268    };
1269
1270    Ok((derived, true))
1271}
1272
1273/// Return error type for [`PsbtExt::update_input_with_descriptor`]
1274#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
1275pub enum UtxoUpdateError {
1276    /// Index out of bounds
1277    IndexOutOfBounds(usize, usize),
1278    /// The unsigned transaction didn't have an input at that index
1279    MissingInputUtxo,
1280    /// Derivation error
1281    DerivationError(descriptor::ConversionError),
1282    /// The PSBT's `witness_utxo` and/or `non_witness_utxo` were invalid or missing
1283    UtxoCheck,
1284    /// The PSBT's `witness_utxo` and/or `non_witness_utxo` had a script_pubkey that did not match
1285    /// the descriptor
1286    MismatchedScriptPubkey,
1287}
1288
1289impl fmt::Display for UtxoUpdateError {
1290    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1291        match self {
1292            UtxoUpdateError::IndexOutOfBounds(ind, len) => {
1293                write!(f, "index {}, psbt input len: {}", ind, len)
1294            }
1295            UtxoUpdateError::MissingInputUtxo => {
1296                write!(f, "Missing input in unsigned transaction")
1297            }
1298            UtxoUpdateError::DerivationError(e) => write!(f, "Key derivation error {}", e),
1299            UtxoUpdateError::UtxoCheck => write!(
1300                f,
1301                "The input's witness_utxo and/or non_witness_utxo were invalid or missing"
1302            ),
1303            UtxoUpdateError::MismatchedScriptPubkey => {
1304                write!(f, "The input's witness_utxo and/or non_witness_utxo had a script pubkey that didn't match the descriptor")
1305            }
1306        }
1307    }
1308}
1309
1310#[cfg(feature = "std")]
1311impl error::Error for UtxoUpdateError {
1312    fn cause(&self) -> Option<&dyn error::Error> {
1313        use self::UtxoUpdateError::*;
1314
1315        match self {
1316            IndexOutOfBounds(_, _) | MissingInputUtxo | UtxoCheck | MismatchedScriptPubkey => None,
1317            DerivationError(e) => Some(e),
1318        }
1319    }
1320}
1321
1322/// Return error type for [`PsbtExt::update_output_with_descriptor`]
1323#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
1324pub enum OutputUpdateError {
1325    /// Index out of bounds
1326    IndexOutOfBounds(usize, usize),
1327    /// The raw unsigned transaction didn't have an output at that index
1328    MissingTxOut,
1329    /// Derivation error
1330    DerivationError(descriptor::ConversionError),
1331    /// The output's script_pubkey did not match the descriptor
1332    MismatchedScriptPubkey,
1333}
1334
1335impl fmt::Display for OutputUpdateError {
1336    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1337        match self {
1338            OutputUpdateError::IndexOutOfBounds(ind, len) => {
1339                write!(f, "index {}, psbt output len: {}", ind, len)
1340            }
1341            OutputUpdateError::MissingTxOut => {
1342                write!(f, "Missing txout in the unsigned transaction")
1343            }
1344            OutputUpdateError::DerivationError(e) => write!(f, "Key derivation error {}", e),
1345            OutputUpdateError::MismatchedScriptPubkey => {
1346                write!(f, "The output's script pubkey didn't match the descriptor")
1347            }
1348        }
1349    }
1350}
1351
1352#[cfg(feature = "std")]
1353impl error::Error for OutputUpdateError {
1354    fn cause(&self) -> Option<&dyn error::Error> {
1355        use self::OutputUpdateError::*;
1356
1357        match self {
1358            IndexOutOfBounds(_, _) | MissingTxOut | MismatchedScriptPubkey => None,
1359            DerivationError(e) => Some(e),
1360        }
1361    }
1362}
1363
1364/// Return error type for [`PsbtExt::sighash_msg`]
1365#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
1366pub enum SighashError {
1367    /// Index out of bounds
1368    IndexOutOfBounds(usize, usize),
1369    /// Missing input utxo
1370    MissingInputUtxo,
1371    /// Missing Prevouts
1372    MissingSpendUtxos,
1373    /// Invalid Sighash type
1374    InvalidSighashType,
1375    /// Sighash computation error
1376    /// Only happens when single does not have corresponding output as psbts
1377    /// already have information to compute the sighash
1378    SighashComputationError(sighash::Error),
1379    /// Missing Witness script
1380    MissingWitnessScript,
1381    /// Missing Redeem script,
1382    MissingRedeemScript,
1383}
1384
1385impl fmt::Display for SighashError {
1386    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1387        match self {
1388            SighashError::IndexOutOfBounds(ind, len) => {
1389                write!(f, "index {}, psbt input len: {}", ind, len)
1390            }
1391            SighashError::MissingInputUtxo => write!(f, "Missing input utxo in pbst"),
1392            SighashError::MissingSpendUtxos => write!(f, "Missing Psbt spend utxos"),
1393            SighashError::InvalidSighashType => write!(f, "Invalid Sighash type"),
1394            SighashError::SighashComputationError(e) => {
1395                write!(f, "Sighash computation error : {}", e)
1396            }
1397            SighashError::MissingWitnessScript => write!(f, "Missing Witness Script"),
1398            SighashError::MissingRedeemScript => write!(f, "Missing Redeem Script"),
1399        }
1400    }
1401}
1402
1403#[cfg(feature = "std")]
1404impl error::Error for SighashError {
1405    fn cause(&self) -> Option<&dyn error::Error> {
1406        use self::SighashError::*;
1407
1408        match self {
1409            IndexOutOfBounds(_, _)
1410            | MissingInputUtxo
1411            | MissingSpendUtxos
1412            | InvalidSighashType
1413            | MissingWitnessScript
1414            | MissingRedeemScript => None,
1415            SighashComputationError(e) => Some(e),
1416        }
1417    }
1418}
1419
1420impl From<sighash::Error> for SighashError {
1421    fn from(e: sighash::Error) -> Self {
1422        SighashError::SighashComputationError(e)
1423    }
1424}
1425
1426/// Sighash message(signing data) for a given psbt transaction input.
1427#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
1428pub enum PsbtSighashMsg {
1429    /// Taproot Signature hash
1430    TapSighash(sighash::TapSighash),
1431    /// Legacy ECDSA sighash message.
1432    LegacySighash(sighash::LegacySighash),
1433    /// Segwit v0 ECDSA sighash message.
1434    SegwitV0Sighash(sighash::SegwitV0Sighash),
1435}
1436
1437impl PsbtSighashMsg {
1438    /// Convert the message to a [`secp256k1::Message`].
1439    pub fn to_secp_msg(&self) -> secp256k1::Message {
1440        match *self {
1441            PsbtSighashMsg::TapSighash(msg) => {
1442                secp256k1::Message::from_slice(msg.as_ref()).expect("Sighashes are 32 bytes")
1443            }
1444            PsbtSighashMsg::LegacySighash(msg) => {
1445                secp256k1::Message::from_slice(msg.as_ref()).expect("Sighashes are 32 bytes")
1446            }
1447            PsbtSighashMsg::SegwitV0Sighash(msg) => {
1448                secp256k1::Message::from_slice(msg.as_ref()).expect("Sighashes are 32 bytes")
1449            }
1450        }
1451    }
1452}
1453
1454#[cfg(test)]
1455mod tests {
1456    use std::str::FromStr;
1457
1458    use qtum::bip32::{DerivationPath, ExtendedPubKey};
1459    use qtum::consensus::encode::deserialize;
1460    use qtum::hashes::hex::FromHex;
1461    use qtum::key::XOnlyPublicKey;
1462    use qtum::secp256k1::PublicKey;
1463    use qtum::{absolute, OutPoint, TxIn, TxOut};
1464
1465    use super::*;
1466    use crate::Miniscript;
1467
1468    #[test]
1469    fn test_extract_bip174() {
1470        let psbt = qtum::psbt::PartiallySignedTransaction::deserialize(&Vec::<u8>::from_hex("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000").unwrap()).unwrap();
1471        let secp = Secp256k1::verification_only();
1472        let tx = psbt.extract(&secp).unwrap();
1473        let expected: qtum::Transaction = deserialize(&Vec::<u8>::from_hex("0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000").unwrap()).unwrap();
1474        assert_eq!(tx, expected);
1475    }
1476
1477    #[test]
1478    fn test_update_item_tr_no_script() {
1479        // keys taken from: https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki#Specifications
1480        let root_xpub = ExtendedPubKey::from_str("xpub661MyMwAqRbcFkPHucMnrGNzDwb6teAX1RbKQmqtEF8kK3Z7LZ59qafCjB9eCRLiTVG3uxBxgKvRgbubRhqSKXnGGb1aoaqLrpMBDrVxga8").unwrap();
1481        let fingerprint = root_xpub.fingerprint();
1482        let desc = format!("tr([{}/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)", fingerprint);
1483        let desc = Descriptor::from_str(&desc).unwrap();
1484        let mut psbt_input = psbt::Input::default();
1485        psbt_input.update_with_descriptor_unchecked(&desc).unwrap();
1486        let mut psbt_output = psbt::Output::default();
1487        psbt_output.update_with_descriptor_unchecked(&desc).unwrap();
1488        let internal_key = XOnlyPublicKey::from_str(
1489            "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115",
1490        )
1491        .unwrap();
1492        assert_eq!(psbt_input.tap_internal_key, Some(internal_key));
1493        assert_eq!(
1494            psbt_input.tap_key_origins.get(&internal_key),
1495            Some(&(
1496                vec![],
1497                (
1498                    fingerprint,
1499                    DerivationPath::from_str("m/86'/0'/0'/0/0").unwrap()
1500                )
1501            ))
1502        );
1503        assert_eq!(psbt_input.tap_key_origins.len(), 1);
1504        assert_eq!(psbt_input.tap_scripts.len(), 0);
1505        assert_eq!(psbt_input.tap_merkle_root, None);
1506
1507        assert_eq!(psbt_output.tap_internal_key, psbt_input.tap_internal_key);
1508        assert_eq!(psbt_output.tap_key_origins, psbt_input.tap_key_origins);
1509        assert_eq!(psbt_output.tap_tree, None);
1510    }
1511
1512    #[test]
1513    fn test_update_item_tr_with_tapscript() {
1514        use crate::Tap;
1515        // keys taken from: https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki#Specifications
1516        let root_xpub = ExtendedPubKey::from_str("xpub661MyMwAqRbcFkPHucMnrGNzDwb6teAX1RbKQmqtEF8kK3Z7LZ59qafCjB9eCRLiTVG3uxBxgKvRgbubRhqSKXnGGb1aoaqLrpMBDrVxga8").unwrap();
1517        let fingerprint = root_xpub.fingerprint();
1518        let xpub = format!("[{}/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ", fingerprint);
1519        let desc = format!(
1520            "tr({}/0/0,{{pkh({}/0/1),multi_a(2,{}/0/1,{}/1/0)}})",
1521            xpub, xpub, xpub, xpub
1522        );
1523
1524        let desc = Descriptor::from_str(&desc).unwrap();
1525        let internal_key = XOnlyPublicKey::from_str(
1526            "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115",
1527        )
1528        .unwrap();
1529        let mut psbt_input = psbt::Input::default();
1530        psbt_input.update_with_descriptor_unchecked(&desc).unwrap();
1531        let mut psbt_output = psbt::Output::default();
1532        psbt_output.update_with_descriptor_unchecked(&desc).unwrap();
1533        assert_eq!(psbt_input.tap_internal_key, Some(internal_key));
1534        assert_eq!(
1535            psbt_input.tap_key_origins.get(&internal_key),
1536            Some(&(
1537                vec![],
1538                (
1539                    fingerprint,
1540                    DerivationPath::from_str("m/86'/0'/0'/0/0").unwrap()
1541                )
1542            ))
1543        );
1544        assert_eq!(psbt_input.tap_key_origins.len(), 3);
1545        assert_eq!(psbt_input.tap_scripts.len(), 2);
1546        assert!(psbt_input.tap_merkle_root.is_some());
1547
1548        assert_eq!(psbt_output.tap_internal_key, psbt_input.tap_internal_key);
1549        assert_eq!(psbt_output.tap_key_origins, psbt_input.tap_key_origins);
1550        assert!(psbt_output.tap_tree.is_some());
1551
1552        let key_0_1 = XOnlyPublicKey::from_str(
1553            "83dfe85a3151d2517290da461fe2815591ef69f2b18a2ce63f01697a8b313145",
1554        )
1555        .unwrap();
1556        let first_leaf_hash = {
1557            let ms =
1558                Miniscript::<XOnlyPublicKey, Tap>::from_str(&format!("pkh({})", &key_0_1)).unwrap();
1559            let first_script = ms.encode();
1560            assert!(psbt_input
1561                .tap_scripts
1562                .values()
1563                .any(|value| *value == (first_script.clone(), LeafVersion::TapScript)));
1564            TapLeafHash::from_script(&first_script, LeafVersion::TapScript)
1565        };
1566
1567        {
1568            // check 0/1
1569            let (leaf_hashes, (key_fingerprint, deriv_path)) =
1570                psbt_input.tap_key_origins.get(&key_0_1).unwrap();
1571            assert_eq!(key_fingerprint, &fingerprint);
1572            assert_eq!(&deriv_path.to_string(), "m/86'/0'/0'/0/1");
1573            assert_eq!(leaf_hashes.len(), 2);
1574            assert!(leaf_hashes.contains(&first_leaf_hash));
1575        }
1576
1577        {
1578            // check 1/0
1579            let key_1_0 = XOnlyPublicKey::from_str(
1580                "399f1b2f4393f29a18c937859c5dd8a77350103157eb880f02e8c08214277cef",
1581            )
1582            .unwrap();
1583            let (leaf_hashes, (key_fingerprint, deriv_path)) =
1584                psbt_input.tap_key_origins.get(&key_1_0).unwrap();
1585            assert_eq!(key_fingerprint, &fingerprint);
1586            assert_eq!(&deriv_path.to_string(), "m/86'/0'/0'/1/0");
1587            assert_eq!(leaf_hashes.len(), 1);
1588            assert!(!leaf_hashes.contains(&first_leaf_hash));
1589        }
1590    }
1591
1592    #[test]
1593    fn test_update_item_non_tr_multi() {
1594        // values taken from https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki (after removing zpub thingy)
1595        let root_xpub = ExtendedPubKey::from_str("xpub661MyMwAqRbcFkPHucMnrGNzDwb6teAX1RbKQmqtEF8kK3Z7LZ59qafCjB9eCRLiTVG3uxBxgKvRgbubRhqSKXnGGb1aoaqLrpMBDrVxga8").unwrap();
1596        let fingerprint = root_xpub.fingerprint();
1597        let xpub = format!("[{}/84'/0'/0']xpub6CatWdiZiodmUeTDp8LT5or8nmbKNcuyvz7WyksVFkKB4RHwCD3XyuvPEbvqAQY3rAPshWcMLoP2fMFMKHPJ4ZeZXYVUhLv1VMrjPC7PW6V", fingerprint);
1598        let pubkeys = [
1599            "0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c",
1600            "03e775fd51f0dfb8cd865d9ff1cca2a158cf651fe997fdc9fee9c1d3b5e995ea77",
1601            "03025324888e429ab8e3dbaf1f7802648b9cd01e9b418485c5fa4c1b9b5700e1a6",
1602        ];
1603
1604        let expected_bip32 = pubkeys
1605            .iter()
1606            .zip(["0/0", "0/1", "1/0"].iter())
1607            .map(|(pubkey, path)| {
1608                (
1609                    PublicKey::from_str(pubkey).unwrap(),
1610                    (
1611                        fingerprint,
1612                        DerivationPath::from_str(&format!("m/84'/0'/0'/{}", path)).unwrap(),
1613                    ),
1614                )
1615            })
1616            .collect::<BTreeMap<_, _>>();
1617
1618        {
1619            // test segwit
1620            let desc = format!("wsh(multi(2,{}/0/0,{}/0/1,{}/1/0))", xpub, xpub, xpub);
1621            let desc = Descriptor::from_str(&desc).unwrap();
1622            let derived = format!("wsh(multi(2,{}))", pubkeys.join(","));
1623            let derived = Descriptor::<qtum::PublicKey>::from_str(&derived).unwrap();
1624
1625            let mut psbt_input = psbt::Input::default();
1626            psbt_input.update_with_descriptor_unchecked(&desc).unwrap();
1627
1628            let mut psbt_output = psbt::Output::default();
1629            psbt_output.update_with_descriptor_unchecked(&desc).unwrap();
1630
1631            assert_eq!(expected_bip32, psbt_input.bip32_derivation);
1632            assert_eq!(
1633                psbt_input.witness_script,
1634                Some(derived.explicit_script().unwrap())
1635            );
1636
1637            assert_eq!(psbt_output.bip32_derivation, psbt_input.bip32_derivation);
1638            assert_eq!(psbt_output.witness_script, psbt_input.witness_script);
1639        }
1640
1641        {
1642            // test non-segwit
1643            let desc = format!("sh(multi(2,{}/0/0,{}/0/1,{}/1/0))", xpub, xpub, xpub);
1644            let desc = Descriptor::from_str(&desc).unwrap();
1645            let derived = format!("sh(multi(2,{}))", pubkeys.join(","));
1646            let derived = Descriptor::<qtum::PublicKey>::from_str(&derived).unwrap();
1647
1648            let mut psbt_input = psbt::Input::default();
1649            psbt_input.update_with_descriptor_unchecked(&desc).unwrap();
1650
1651            let mut psbt_output = psbt::Output::default();
1652            psbt_output.update_with_descriptor_unchecked(&desc).unwrap();
1653
1654            assert_eq!(psbt_input.bip32_derivation, expected_bip32);
1655            assert_eq!(psbt_input.witness_script, None);
1656            assert_eq!(
1657                psbt_input.redeem_script,
1658                Some(derived.explicit_script().unwrap())
1659            );
1660
1661            assert_eq!(psbt_output.bip32_derivation, psbt_input.bip32_derivation);
1662            assert_eq!(psbt_output.witness_script, psbt_input.witness_script);
1663            assert_eq!(psbt_output.redeem_script, psbt_input.redeem_script);
1664        }
1665    }
1666
1667    #[test]
1668    fn test_update_input_checks() {
1669        let desc = "tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)";
1670        let desc = Descriptor::<DefiniteDescriptorKey>::from_str(&desc).unwrap();
1671
1672        let mut non_witness_utxo = qtum::Transaction {
1673            version: 1,
1674            lock_time: absolute::LockTime::ZERO,
1675            input: vec![],
1676            output: vec![TxOut {
1677                value: 1_000,
1678                script_pubkey: ScriptBuf::from_hex(
1679                    "5120a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c",
1680                )
1681                .unwrap(),
1682            }],
1683        };
1684
1685        let tx = qtum::Transaction {
1686            version: 1,
1687            lock_time: absolute::LockTime::ZERO,
1688            input: vec![TxIn {
1689                previous_output: OutPoint {
1690                    txid: non_witness_utxo.txid(),
1691                    vout: 0,
1692                },
1693                ..Default::default()
1694            }],
1695            output: vec![],
1696        };
1697
1698        let mut psbt = Psbt::from_unsigned_tx(tx).unwrap();
1699        assert_eq!(
1700            psbt.update_input_with_descriptor(0, &desc),
1701            Err(UtxoUpdateError::UtxoCheck),
1702            "neither *_utxo are not set"
1703        );
1704        psbt.inputs[0].witness_utxo = Some(non_witness_utxo.output[0].clone());
1705        assert_eq!(
1706            psbt.update_input_with_descriptor(0, &desc),
1707            Ok(()),
1708            "witness_utxo is set which is ok"
1709        );
1710        psbt.inputs[0].non_witness_utxo = Some(non_witness_utxo.clone());
1711        assert_eq!(
1712            psbt.update_input_with_descriptor(0, &desc),
1713            Ok(()),
1714            "matching non_witness_utxo"
1715        );
1716        non_witness_utxo.version = 0;
1717        psbt.inputs[0].non_witness_utxo = Some(non_witness_utxo);
1718        assert_eq!(
1719            psbt.update_input_with_descriptor(0, &desc),
1720            Err(UtxoUpdateError::UtxoCheck),
1721            "non_witness_utxo no longer matches"
1722        );
1723        psbt.inputs[0].non_witness_utxo = None;
1724        psbt.inputs[0].witness_utxo.as_mut().unwrap().script_pubkey = ScriptBuf::default();
1725        assert_eq!(
1726            psbt.update_input_with_descriptor(0, &desc),
1727            Err(UtxoUpdateError::MismatchedScriptPubkey),
1728            "non_witness_utxo no longer matches"
1729        );
1730    }
1731
1732    #[test]
1733    fn test_update_output_checks() {
1734        let desc = "tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)";
1735        let desc = Descriptor::<DefiniteDescriptorKey>::from_str(&desc).unwrap();
1736
1737        let tx = qtum::Transaction {
1738            version: 1,
1739            lock_time: absolute::LockTime::ZERO,
1740            input: vec![],
1741            output: vec![TxOut {
1742                value: 1_000,
1743                script_pubkey: ScriptBuf::from_hex(
1744                    "5120a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c",
1745                )
1746                .unwrap(),
1747            }],
1748        };
1749
1750        let mut psbt = Psbt::from_unsigned_tx(tx).unwrap();
1751        assert_eq!(
1752            psbt.update_output_with_descriptor(1, &desc),
1753            Err(OutputUpdateError::IndexOutOfBounds(1, 1)),
1754            "output index doesn't exist"
1755        );
1756        assert_eq!(
1757            psbt.update_output_with_descriptor(0, &desc),
1758            Ok(()),
1759            "script_pubkey should match"
1760        );
1761        psbt.unsigned_tx.output[0].script_pubkey = ScriptBuf::default();
1762        assert_eq!(
1763            psbt.update_output_with_descriptor(0, &desc),
1764            Err(OutputUpdateError::MismatchedScriptPubkey),
1765            "output script_pubkey no longer matches"
1766        );
1767    }
1768}