22
33use crate :: bitcoin;
44use crate :: bitcoin:: {
5- verify_sig, Address , Amount , EmptyWitnessStack , NoInputs , NotThreeWitnesses , PublicKey ,
6- TooManyInputs , Transaction , TxCancel ,
5+ build_shared_output_descriptor , verify_sig, Address , Amount , EmptyWitnessStack , NoInputs ,
6+ NotThreeWitnesses , PublicKey , TooManyInputs , Transaction , TxCancel ,
77} ;
88use :: bitcoin:: sighash:: SighashCache ;
99use :: bitcoin:: { secp256k1, ScriptBuf , Weight } ;
@@ -23,16 +23,32 @@ pub struct TxRefund {
2323 inner : Transaction ,
2424 digest : Sighash ,
2525 cancel_output_descriptor : Descriptor < :: bitcoin:: PublicKey > ,
26+ pub ( in crate :: bitcoin) amnesty_output_descriptor : Descriptor < :: bitcoin:: PublicKey > ,
2627 watch_script : ScriptBuf ,
2728}
2829
2930impl TxRefund {
30- pub fn new ( tx_cancel : & TxCancel , refund_address : & Address , spending_fee : Amount ) -> Self {
31- let tx_refund = tx_cancel. build_spend_transaction ( refund_address, None , spending_fee) ;
31+ pub fn new (
32+ tx_cancel : & TxCancel ,
33+ refund_address : & Address ,
34+ A : PublicKey ,
35+ B : PublicKey ,
36+ amnesty_amount : Amount ,
37+ spending_fee : Amount ,
38+ ) -> Result < Self > {
39+ let amnesty_output_descriptor = build_shared_output_descriptor ( A . 0 , B . 0 ) ?;
40+
41+ let tx_refund = tx_cancel. build_refund_with_amnesty_transaction (
42+ refund_address,
43+ & amnesty_output_descriptor,
44+ amnesty_amount,
45+ spending_fee,
46+ ) ;
3247
3348 let digest = SighashCache :: new ( & tx_refund)
3449 . p2wsh_signature_hash (
35- 0 , // Only one input: cancel transaction
50+ // Only one input: cancel transaction
51+ 0 ,
3652 & tx_cancel
3753 . output_descriptor
3854 . script_code ( )
@@ -42,12 +58,13 @@ impl TxRefund {
4258 )
4359 . expect ( "sighash" ) ;
4460
45- Self {
61+ Ok ( Self {
4662 inner : tx_refund,
4763 digest,
4864 cancel_output_descriptor : tx_cancel. output_descriptor . clone ( ) ,
65+ amnesty_output_descriptor,
4966 watch_script : refund_address. script_pubkey ( ) ,
50- }
67+ } )
5168 }
5269
5370 pub fn txid ( & self ) -> Txid {
@@ -58,6 +75,41 @@ impl TxRefund {
5875 self . digest
5976 }
6077
78+ pub fn amnesty_amount ( & self ) -> Amount {
79+ self . inner . output [ 1 ] . value
80+ }
81+
82+ pub fn amnesty_outpoint ( & self ) -> :: bitcoin:: OutPoint {
83+ :: bitcoin:: OutPoint :: new ( self . txid ( ) , 1 )
84+ }
85+
86+ pub fn build_amnesty_spend_transaction (
87+ & self ,
88+ refund_address : & Address ,
89+ spending_fee : Amount ,
90+ ) -> Transaction {
91+ use :: bitcoin:: { transaction:: Version , locktime:: absolute:: LockTime as PackedLockTime , Sequence , TxIn , TxOut } ;
92+
93+ let tx_in = TxIn {
94+ previous_output : self . amnesty_outpoint ( ) ,
95+ script_sig : Default :: default ( ) ,
96+ sequence : Sequence ( 0xFFFF_FFFF ) ,
97+ witness : Default :: default ( ) ,
98+ } ;
99+
100+ let tx_out = TxOut {
101+ value : self . amnesty_amount ( ) - spending_fee,
102+ script_pubkey : refund_address. script_pubkey ( ) ,
103+ } ;
104+
105+ Transaction {
106+ version : Version ( 2 ) ,
107+ lock_time : PackedLockTime :: from_height ( 0 ) . expect ( "0 to be below lock time threshold" ) ,
108+ input : vec ! [ tx_in] ,
109+ output : vec ! [ tx_out] ,
110+ }
111+ }
112+
61113 pub fn add_signatures (
62114 self ,
63115 ( A , sig_a) : ( PublicKey , Signature ) ,
@@ -77,6 +129,7 @@ impl TxRefund {
77129
78130 let sig_a = secp256k1:: ecdsa:: Signature :: from_compact ( & sig_a. to_bytes ( ) ) ?;
79131 let sig_b = secp256k1:: ecdsa:: Signature :: from_compact ( & sig_b. to_bytes ( ) ) ?;
132+
80133 // The order in which these are inserted doesn't matter
81134 satisfier. insert (
82135 A ,
0 commit comments