Skip to content

Commit 49fe1ca

Browse files
committed
Introduce PsbtExt trait
1 parent 0c64a70 commit 49fe1ca

File tree

4 files changed

+432
-40
lines changed

4 files changed

+432
-40
lines changed

examples/psbt.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ extern crate miniscript;
33

44
use bitcoin::consensus::encode::deserialize;
55
use bitcoin::hashes::hex::FromHex;
6-
7-
use miniscript::psbt::{extract, finalize};
6+
use miniscript::psbt::PsbtExt;
87

98
fn main() {
109
// Test vectors from BIP 174
@@ -18,13 +17,13 @@ fn main() {
1817
let secp = bitcoin::secp256k1::Secp256k1::verification_only();
1918
// Assuming all partial sigs are filled in.
2019
// Construct a generic finalizer
21-
finalize(&mut psbt, &secp).unwrap();
20+
psbt.finalize(&secp).unwrap();
2221
// println!("{:?}", psbt);
2322

2423
assert_eq!(psbt, expected_finalized_psbt);
2524

2625
// Extract the transaction from the psbt
27-
let tx = extract(&psbt, &secp).unwrap();
26+
let tx = psbt.extract(&secp).unwrap();
2827

2928
let expected: bitcoin::Transaction = deserialize(&Vec::<u8>::from_hex("0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000").unwrap()).unwrap();
3029
// println!("{:?}", tx);

integration_test/src/main.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
1616
use bitcoin::{Amount, OutPoint, Transaction, TxIn, TxOut, Txid};
1717
mod read_file;
1818
use miniscript::miniscript::iter;
19+
use miniscript::psbt::PsbtExt;
1920
use miniscript::DescriptorTrait;
2021
use miniscript::MiniscriptKey;
2122
use miniscript::{Miniscript, Segwitv0};
@@ -196,7 +197,9 @@ fn main() {
196197
let amt = btc(1).as_sat();
197198
let mut sighash_cache = bitcoin::util::sighash::SigHashCache::new(&psbts[i].unsigned_tx);
198199
let sighash_ty = bitcoin::EcdsaSigHashType::All;
199-
let sighash = sighash_cache.segwit_signature_hash(0, &ms.encode(), amt, sighash_ty).unwrap();
200+
let sighash = sighash_cache
201+
.segwit_signature_hash(0, &ms.encode(), amt, sighash_ty)
202+
.unwrap();
200203

201204
// requires both signing and verification because we check the tx
202205
// after we psbt extract it
@@ -207,7 +210,13 @@ fn main() {
207210
for sk in sks_reqd {
208211
let sig = secp.sign_ecdsa(&msg, &sk);
209212
let pk = pks[sks.iter().position(|&x| x == sk).unwrap()];
210-
psbts[i].inputs[0].partial_sigs.insert(pk.inner, bitcoin::EcdsaSig { sig, hash_ty: sighash_ty });
213+
psbts[i].inputs[0].partial_sigs.insert(
214+
pk.inner,
215+
bitcoin::EcdsaSig {
216+
sig,
217+
hash_ty: sighash_ty,
218+
},
219+
);
211220
}
212221
// Add the hash preimages to the psbt
213222
psbts[i].inputs[0].sha256_preimages.insert(
@@ -229,11 +238,11 @@ fn main() {
229238
);
230239
// Finalize the transaction using psbt
231240
// Let miniscript do it's magic!
232-
if let Err(e) = miniscript::psbt::finalize_mall(&mut psbts[i], &secp) {
241+
if let Err(e) = psbts[i].finalize_mall(&secp) {
233242
// All miniscripts should satisfy
234243
panic!("Could not satisfy: error{} ms:{} at ind:{}", e, ms, i);
235244
} else {
236-
let tx = miniscript::psbt::extract(&psbts[i], &secp).unwrap();
245+
let tx = psbts[i].extract(&secp).unwrap();
237246

238247
// Send the transactions to bitcoin node for mining.
239248
// Regtest mode has standardness checks

src/psbt/finalizer.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ fn construct_tap_witness(
9797
}
9898

9999
// Get the scriptpubkey for the psbt input
100-
fn get_scriptpubkey(psbt: &Psbt, index: usize) -> Result<&Script, InputError> {
100+
pub(super) fn get_scriptpubkey(psbt: &Psbt, index: usize) -> Result<&Script, InputError> {
101101
get_utxo(psbt, index).map(|utxo| &utxo.script_pubkey)
102102
}
103103

104104
// Get the spending utxo for this psbt input
105-
fn get_utxo(psbt: &Psbt, index: usize) -> Result<&bitcoin::TxOut, InputError> {
105+
pub(super) fn get_utxo(psbt: &Psbt, index: usize) -> Result<&bitcoin::TxOut, InputError> {
106106
let inp = &psbt.inputs[index];
107107
let utxo = if let Some(ref witness_utxo) = inp.witness_utxo {
108108
&witness_utxo
@@ -116,7 +116,7 @@ fn get_utxo(psbt: &Psbt, index: usize) -> Result<&bitcoin::TxOut, InputError> {
116116
}
117117

118118
/// Get the Prevouts for the psbt
119-
fn prevouts<'a>(psbt: &'a Psbt) -> Result<Vec<bitcoin::TxOut>, super::Error> {
119+
pub(super) fn prevouts<'a>(psbt: &'a Psbt) -> Result<Vec<bitcoin::TxOut>, super::Error> {
120120
let mut utxos = vec![];
121121
for i in 0..psbt.inputs.len() {
122122
let utxo_ref = get_utxo(psbt, i).map_err(|e| Error::InputError(e, i))?;
@@ -322,6 +322,7 @@ pub fn interpreter_check<C: secp256k1::Verification>(
322322
/// finalized psbt which involves checking the signatures/ preimages/timelocks.
323323
/// The functions fails it is not possible to satisfy any of the inputs non-malleably
324324
/// See [finalize_mall] if you want to allow malleable satisfactions
325+
#[deprecated(since = "7.0", note = "Please use PsbtExt::finalize instead")]
325326
pub fn finalize<C: secp256k1::Verification>(
326327
psbt: &mut Psbt,
327328
secp: &Secp256k1<C>,
@@ -393,10 +394,11 @@ pub fn finalize_helper<C: secp256k1::Verification>(
393394
let desc = get_descriptor(&psbt, index).map_err(|e| Error::InputError(e, index))?;
394395

395396
//generate the satisfaction witness and scriptsig
397+
let sat = PsbtInputSatisfier::new(&psbt, index);
396398
if !allow_mall {
397-
desc.get_satisfaction(PsbtInputSatisfier::new(&psbt, index))
399+
desc.get_satisfaction(sat)
398400
} else {
399-
desc.get_satisfaction_mall(PsbtInputSatisfier::new(&psbt, index))
401+
desc.get_satisfaction_mall(sat)
400402
}
401403
.map_err(|e| Error::InputError(InputError::MiniscriptError(e), index))?
402404
}
@@ -444,6 +446,8 @@ pub fn finalize_helper<C: secp256k1::Verification>(
444446

445447
#[cfg(test)]
446448
mod tests {
449+
use psbt::PsbtExt;
450+
447451
use super::*;
448452

449453
use bitcoin::consensus::encode::deserialize;
@@ -454,7 +458,7 @@ mod tests {
454458
let mut psbt: bitcoin::util::psbt::PartiallySignedTransaction = deserialize(&Vec::<u8>::from_hex("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000002202029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887220203089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f012202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000").unwrap()).unwrap();
455459

456460
let secp = Secp256k1::verification_only();
457-
finalize(&mut psbt, &secp).unwrap();
461+
psbt.finalize(&secp).unwrap();
458462

459463
let expected: bitcoin::util::psbt::PartiallySignedTransaction = deserialize(&Vec::<u8>::from_hex("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000").unwrap()).unwrap();
460464
assert_eq!(psbt, expected);

0 commit comments

Comments
 (0)