@@ -679,16 +679,38 @@ pub fn make_funding_redeemscript(broadcaster: &PublicKey, countersignatory: &Pub
679679/// commitment transaction).
680680pub fn build_htlc_transaction ( commitment_txid : & Txid , feerate_per_kw : u32 , contest_delay : u16 , htlc : & HTLCOutputInCommitment , opt_anchors : bool , use_non_zero_fee_anchors : bool , broadcaster_delayed_payment_key : & PublicKey , revocation_key : & PublicKey ) -> Transaction {
681681 let mut txins: Vec < TxIn > = Vec :: new ( ) ;
682- txins. push ( TxIn {
682+ txins. push ( build_htlc_input ( commitment_txid, htlc, opt_anchors) ) ;
683+
684+ let mut txouts: Vec < TxOut > = Vec :: new ( ) ;
685+ txouts. push ( build_htlc_output (
686+ feerate_per_kw, contest_delay, htlc, opt_anchors, use_non_zero_fee_anchors,
687+ broadcaster_delayed_payment_key, revocation_key
688+ ) ) ;
689+
690+ Transaction {
691+ version : 2 ,
692+ lock_time : PackedLockTime ( if htlc. offered { htlc. cltv_expiry } else { 0 } ) ,
693+ input : txins,
694+ output : txouts,
695+ }
696+ }
697+
698+ pub ( crate ) fn build_htlc_input ( commitment_txid : & Txid , htlc : & HTLCOutputInCommitment , opt_anchors : bool ) -> TxIn {
699+ TxIn {
683700 previous_output : OutPoint {
684701 txid : commitment_txid. clone ( ) ,
685702 vout : htlc. transaction_output_index . expect ( "Can't build an HTLC transaction for a dust output" ) ,
686703 } ,
687704 script_sig : Script :: new ( ) ,
688705 sequence : Sequence ( if opt_anchors { 1 } else { 0 } ) ,
689706 witness : Witness :: new ( ) ,
690- } ) ;
707+ }
708+ }
691709
710+ pub ( crate ) fn build_htlc_output (
711+ feerate_per_kw : u32 , contest_delay : u16 , htlc : & HTLCOutputInCommitment , opt_anchors : bool ,
712+ use_non_zero_fee_anchors : bool , broadcaster_delayed_payment_key : & PublicKey , revocation_key : & PublicKey
713+ ) -> TxOut {
692714 let weight = if htlc. offered {
693715 htlc_timeout_tx_weight ( opt_anchors)
694716 } else {
@@ -701,18 +723,41 @@ pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, conte
701723 htlc. amount_msat / 1000 - total_fee
702724 } ;
703725
704- let mut txouts: Vec < TxOut > = Vec :: new ( ) ;
705- txouts. push ( TxOut {
726+ TxOut {
706727 script_pubkey : get_revokeable_redeemscript ( revocation_key, contest_delay, broadcaster_delayed_payment_key) . to_v0_p2wsh ( ) ,
707728 value : output_value,
708- } ) ;
729+ }
730+ }
709731
710- Transaction {
711- version : 2 ,
712- lock_time : PackedLockTime ( if htlc. offered { htlc. cltv_expiry } else { 0 } ) ,
713- input : txins,
714- output : txouts,
732+ /// Returns the witness required to satisfy and spend a HTLC input.
733+ pub fn build_htlc_input_witness (
734+ local_sig : & Signature , remote_sig : & Signature , preimage : & Option < PaymentPreimage > ,
735+ redeem_script : & Script , opt_anchors : bool ,
736+ ) -> Witness {
737+ let remote_sighash_type = if opt_anchors {
738+ EcdsaSighashType :: SinglePlusAnyoneCanPay
739+ } else {
740+ EcdsaSighashType :: All
741+ } ;
742+ let mut remote_sig = remote_sig. serialize_der ( ) . to_vec ( ) ;
743+ remote_sig. push ( remote_sighash_type as u8 ) ;
744+
745+ let mut local_sig = local_sig. serialize_der ( ) . to_vec ( ) ;
746+ local_sig. push ( EcdsaSighashType :: All as u8 ) ;
747+
748+ let mut witness = Witness :: new ( ) ;
749+ // First push the multisig dummy, note that due to BIP147 (NULLDUMMY) it must be a zero-length element.
750+ witness. push ( vec ! [ ] ) ;
751+ witness. push ( remote_sig) ;
752+ witness. push ( local_sig) ;
753+ if let Some ( preimage) = preimage {
754+ witness. push ( preimage. 0 . to_vec ( ) ) ;
755+ } else {
756+ // Due to BIP146 (MINIMALIF) this must be a zero-length element to relay.
757+ witness. push ( vec ! [ ] ) ;
715758 }
759+ witness. push ( redeem_script. to_bytes ( ) ) ;
760+ witness
716761}
717762
718763/// Gets the witnessScript for the to_remote output when anchors are enabled.
@@ -1553,26 +1598,9 @@ impl<'a> TrustedCommitmentTransaction<'a> {
15531598
15541599 let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys ( & this_htlc, self . opt_anchors ( ) , & keys. broadcaster_htlc_key , & keys. countersignatory_htlc_key , & keys. revocation_key ) ;
15551600
1556- let sighashtype = if self . opt_anchors ( ) { EcdsaSighashType :: SinglePlusAnyoneCanPay } else { EcdsaSighashType :: All } ;
1557-
1558- // First push the multisig dummy, note that due to BIP147 (NULLDUMMY) it must be a zero-length element.
1559- htlc_tx. input [ 0 ] . witness . push ( Vec :: new ( ) ) ;
1560-
1561- let mut cp_sig_ser = counterparty_signature. serialize_der ( ) . to_vec ( ) ;
1562- cp_sig_ser. push ( sighashtype as u8 ) ;
1563- htlc_tx. input [ 0 ] . witness . push ( cp_sig_ser) ;
1564- let mut holder_sig_ser = signature. serialize_der ( ) . to_vec ( ) ;
1565- holder_sig_ser. push ( EcdsaSighashType :: All as u8 ) ;
1566- htlc_tx. input [ 0 ] . witness . push ( holder_sig_ser) ;
1567-
1568- if this_htlc. offered {
1569- // Due to BIP146 (MINIMALIF) this must be a zero-length element to relay.
1570- htlc_tx. input [ 0 ] . witness . push ( Vec :: new ( ) ) ;
1571- } else {
1572- htlc_tx. input [ 0 ] . witness . push ( preimage. unwrap ( ) . 0 . to_vec ( ) ) ;
1573- }
1574-
1575- htlc_tx. input [ 0 ] . witness . push ( htlc_redeemscript. as_bytes ( ) . to_vec ( ) ) ;
1601+ htlc_tx. input [ 0 ] . witness = chan_utils:: build_htlc_input_witness (
1602+ signature, counterparty_signature, preimage, & htlc_redeemscript, self . opt_anchors ( ) ,
1603+ ) ;
15761604 htlc_tx
15771605 }
15781606}
0 commit comments