Skip to content

Commit 472f803

Browse files
committed
Update Psbt APIs with _mut and _input support
Adds support for finalizing individual inputs and an additional AP that does not mutuate the original Psbt, but returns a new one
1 parent daa80b7 commit 472f803

File tree

4 files changed

+78
-13
lines changed

4 files changed

+78
-13
lines changed

examples/psbt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn main() {
1717
let secp = bitcoin::secp256k1::Secp256k1::verification_only();
1818
// Assuming all partial sigs are filled in.
1919
// Construct a generic finalizer
20-
psbt.finalize(&secp).unwrap();
20+
psbt.finalize_mut(&secp).unwrap();
2121
// println!("{:?}", psbt);
2222

2323
assert_eq!(psbt, expected_finalized_psbt);

integration_test/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ fn main() {
238238
);
239239
// Finalize the transaction using psbt
240240
// Let miniscript do it's magic!
241-
if let Err(e) = psbts[i].finalize_mall(&secp) {
241+
if let Err(e) = psbts[i].finalize_mall_mut(&secp) {
242242
// All miniscripts should satisfy
243243
panic!("Could not satisfy: error{} ms:{} at ind:{}", e[0], ms, i);
244244
} else {

src/psbt/finalizer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ mod tests {
449449
let mut psbt: bitcoin::util::psbt::PartiallySignedTransaction = deserialize(&Vec::<u8>::from_hex("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000002202029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887220203089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f012202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000").unwrap()).unwrap();
450450

451451
let secp = Secp256k1::verification_only();
452-
psbt.finalize(&secp).unwrap();
452+
psbt.finalize_mut(&secp).unwrap();
453453

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

src/psbt/mod.rs

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -435,32 +435,59 @@ pub trait PsbtExt {
435435
/// See [finalizer::finalize_mall] if you want to allow malleable satisfactions
436436
///
437437
/// For finalizing individual inputs, see also [`PsbtExt::finalize_inp`]
438-
fn finalize<C: secp256k1::Verification>(
438+
fn finalize_mut<C: secp256k1::Verification>(
439439
&mut self,
440440
secp: &secp256k1::Secp256k1<C>,
441441
) -> Result<(), Vec<Error>>;
442442

443-
/// Same as [finalize], but allows for malleable satisfactions
444-
fn finalize_mall<C: secp256k1::Verification>(
443+
/// Same as [`PsbtExt::finalize_mut`], but does not mutate the input psbt and
444+
/// returns a new psbt
445+
fn finalize<C: secp256k1::Verification>(
446+
&self,
447+
secp: &secp256k1::Secp256k1<C>,
448+
) -> Result<Psbt, Vec<Error>>;
449+
450+
/// Same as [PsbtExt::finalize_mut], but allows for malleable satisfactions
451+
fn finalize_mall_mut<C: secp256k1::Verification>(
445452
&mut self,
446453
secp: &Secp256k1<C>,
447454
) -> Result<(), Vec<Error>>;
448455

449-
/// Same as [finalize], but only tries to finalize a single input leaving other
456+
/// Same as [PsbtExt::finalize], but allows for malleable satisfactions
457+
fn finalize_mall<C: secp256k1::Verification>(
458+
&self,
459+
secp: &Secp256k1<C>,
460+
) -> Result<Psbt, Vec<Error>>;
461+
462+
/// Same as [`PsbtExt::finalize_mut`], but only tries to finalize a single input leaving other
450463
/// inputs as is. Use this when not all of inputs that you are trying to
451464
/// satisfy are miniscripts
465+
fn finalize_inp_mut<C: secp256k1::Verification>(
466+
&mut self,
467+
secp: &secp256k1::Secp256k1<C>,
468+
index: usize,
469+
) -> Result<(), Error>;
470+
471+
/// Same as [`PsbtExt::finalize_inp_mut`], but does not mutate the psbt and returns a new one
452472
fn finalize_inp<C: secp256k1::Verification>(
473+
&self,
474+
secp: &secp256k1::Secp256k1<C>,
475+
index: usize,
476+
) -> Result<Psbt, Error>;
477+
478+
/// Same as [`PsbtExt::finalize_inp_mut`], but allows for malleable satisfactions
479+
fn finalize_inp_mall_mut<C: secp256k1::Verification>(
453480
&mut self,
454481
secp: &secp256k1::Secp256k1<C>,
455482
index: usize,
456483
) -> Result<(), Error>;
457484

458-
/// Same as [finalize_inp], but allows for malleable satisfactions
485+
/// Same as [`PsbtExt::finalize_inp`], but allows for malleable satisfactions
459486
fn finalize_inp_mall<C: secp256k1::Verification>(
460487
&mut self,
461488
secp: &secp256k1::Secp256k1<C>,
462489
index: usize,
463-
) -> Result<(), Error>;
490+
) -> Result<Psbt, Error>;
464491

465492
/// Psbt extractor as defined in BIP174 that takes in a psbt reference
466493
/// and outputs a extracted bitcoin::Transaction
@@ -517,7 +544,7 @@ pub trait PsbtExt {
517544
}
518545

519546
impl PsbtExt for Psbt {
520-
fn finalize<C: secp256k1::Verification>(
547+
fn finalize_mut<C: secp256k1::Verification>(
521548
&mut self,
522549
secp: &secp256k1::Secp256k1<C>,
523550
) -> Result<(), Vec<Error>> {
@@ -538,7 +565,16 @@ impl PsbtExt for Psbt {
538565
}
539566
}
540567

541-
fn finalize_mall<C: secp256k1::Verification>(
568+
fn finalize<C: secp256k1::Verification>(
569+
&self,
570+
secp: &secp256k1::Secp256k1<C>,
571+
) -> Result<Psbt, Vec<Error>> {
572+
let mut psbt = self.clone();
573+
psbt.finalize_mut(secp)?;
574+
Ok(psbt)
575+
}
576+
577+
fn finalize_mall_mut<C: secp256k1::Verification>(
542578
&mut self,
543579
secp: &secp256k1::Secp256k1<C>,
544580
) -> Result<(), Vec<Error>> {
@@ -558,7 +594,16 @@ impl PsbtExt for Psbt {
558594
}
559595
}
560596

561-
fn finalize_inp<C: secp256k1::Verification>(
597+
fn finalize_mall<C: secp256k1::Verification>(
598+
&self,
599+
secp: &Secp256k1<C>,
600+
) -> Result<Psbt, Vec<Error>> {
601+
let mut psbt = self.clone();
602+
psbt.finalize_mall_mut(secp)?;
603+
Ok(psbt)
604+
}
605+
606+
fn finalize_inp_mut<C: secp256k1::Verification>(
562607
&mut self,
563608
secp: &secp256k1::Secp256k1<C>,
564609
index: usize,
@@ -572,7 +617,17 @@ impl PsbtExt for Psbt {
572617
finalizer::finalize_input(self, index, secp, /*allow_mall*/ false)
573618
}
574619

575-
fn finalize_inp_mall<C: secp256k1::Verification>(
620+
fn finalize_inp<C: secp256k1::Verification>(
621+
&self,
622+
secp: &secp256k1::Secp256k1<C>,
623+
index: usize,
624+
) -> Result<Psbt, Error> {
625+
let mut psbt = self.clone();
626+
psbt.finalize_inp_mut(secp, index)?;
627+
Ok(psbt)
628+
}
629+
630+
fn finalize_inp_mall_mut<C: secp256k1::Verification>(
576631
&mut self,
577632
secp: &secp256k1::Secp256k1<C>,
578633
index: usize,
@@ -586,6 +641,16 @@ impl PsbtExt for Psbt {
586641
finalizer::finalize_input(self, index, secp, /*allow_mall*/ false)
587642
}
588643

644+
fn finalize_inp_mall<C: secp256k1::Verification>(
645+
&mut self,
646+
secp: &secp256k1::Secp256k1<C>,
647+
index: usize,
648+
) -> Result<Psbt, Error> {
649+
let mut psbt = self.clone();
650+
psbt.finalize_inp_mall_mut(secp, index)?;
651+
Ok(psbt)
652+
}
653+
589654
fn extract<C: secp256k1::Verification>(
590655
&self,
591656
secp: &Secp256k1<C>,

0 commit comments

Comments
 (0)