@@ -751,7 +751,7 @@ impl Channel {
751
751
/// generated by the peer which proposed adding the HTLCs, and thus we need to understand both
752
752
/// which peer generated this transaction and "to whom" this transaction flows.
753
753
#[ inline]
754
- fn build_commitment_transaction ( & self , commitment_number : u64 , keys : & TxCreationKeys , local : bool , generated_by_local : bool , feerate_per_kw : u64 ) -> ( Transaction , Vec < ( HTLCOutputInCommitment , Option < HTLCSource > ) > ) {
754
+ fn build_commitment_transaction ( & self , commitment_number : u64 , keys : & TxCreationKeys , local : bool , generated_by_local : bool , feerate_per_kw : u64 ) -> ( Transaction , Vec < ( HTLCOutputInCommitment , Option < & HTLCSource > ) > ) {
755
755
let obscured_commitment_transaction_number = self . get_commitment_transaction_number_obscure_factor ( ) ^ ( INITIAL_COMMITMENT_NUMBER - commitment_number) ;
756
756
757
757
let txins = {
@@ -765,7 +765,7 @@ impl Channel {
765
765
ins
766
766
} ;
767
767
768
- let mut txouts: Vec < ( TxOut , Option < ( HTLCOutputInCommitment , Option < HTLCSource > ) > ) > = Vec :: with_capacity ( self . pending_inbound_htlcs . len ( ) + self . pending_outbound_htlcs . len ( ) + 2 ) ;
768
+ let mut txouts: Vec < ( TxOut , Option < ( HTLCOutputInCommitment , Option < & HTLCSource > ) > ) > = Vec :: with_capacity ( self . pending_inbound_htlcs . len ( ) + self . pending_outbound_htlcs . len ( ) + 2 ) ;
769
769
770
770
let dust_limit_satoshis = if local { self . our_dust_limit_satoshis } else { self . their_dust_limit_satoshis } ;
771
771
let mut remote_htlc_total_msat = 0 ;
@@ -830,7 +830,7 @@ impl Channel {
830
830
} ;
831
831
832
832
if include {
833
- add_htlc_output ! ( htlc, true , Some ( htlc. source. clone ( ) ) ) ;
833
+ add_htlc_output ! ( htlc, true , Some ( & htlc. source) ) ;
834
834
local_htlc_total_msat += htlc. amount_msat ;
835
835
} else {
836
836
match htlc. state {
@@ -901,7 +901,7 @@ impl Channel {
901
901
transaction_utils:: sort_outputs ( & mut txouts) ;
902
902
903
903
let mut outputs: Vec < TxOut > = Vec :: with_capacity ( txouts. len ( ) ) ;
904
- let mut htlcs_used: Vec < ( HTLCOutputInCommitment , Option < HTLCSource > ) > = Vec :: with_capacity ( txouts. len ( ) ) ;
904
+ let mut htlcs_used: Vec < ( HTLCOutputInCommitment , Option < & HTLCSource > ) > = Vec :: with_capacity ( txouts. len ( ) ) ;
905
905
for ( idx, out) in txouts. drain ( ..) . enumerate ( ) {
906
906
outputs. push ( out. 0 ) ;
907
907
if let Some ( mut out_htlc) = out. 1 {
@@ -1668,7 +1668,11 @@ impl Channel {
1668
1668
self . feerate_per_kw
1669
1669
} ;
1670
1670
1671
- let mut local_commitment_tx = self . build_commitment_transaction ( self . cur_local_commitment_transaction_number , & local_keys, true , false , feerate_per_kw) ;
1671
+ let mut local_commitment_tx = {
1672
+ let mut commitment_tx = self . build_commitment_transaction ( self . cur_local_commitment_transaction_number , & local_keys, true , false , feerate_per_kw) ;
1673
+ let htlcs_cloned: Vec < _ > = commitment_tx. 1 . drain ( ..) . map ( |htlc_pair| ( htlc_pair. 0 , htlc_pair. 1 . map ( |source| ( * source) . clone ( ) ) ) ) . collect ( ) ;
1674
+ ( commitment_tx. 0 , htlcs_cloned)
1675
+ } ;
1672
1676
let local_commitment_txid = local_commitment_tx. 0 . txid ( ) ;
1673
1677
let local_sighash = Message :: from_slice ( & bip143:: SighashComponents :: new ( & local_commitment_tx. 0 ) . sighash_all ( & local_commitment_tx. 0 . input [ 0 ] , & funding_script, self . channel_value_satoshis ) [ ..] ) . unwrap ( ) ;
1674
1678
secp_check ! ( self . secp_ctx. verify( & local_sighash, & msg. signature, & self . their_funding_pubkey. unwrap( ) ) , "Invalid commitment tx signature from peer" ) ;
@@ -1692,19 +1696,19 @@ impl Channel {
1692
1696
new_local_commitment_txn. push ( local_commitment_tx. 0 . clone ( ) ) ;
1693
1697
1694
1698
let mut htlcs_and_sigs = Vec :: with_capacity ( local_commitment_tx. 1 . len ( ) ) ;
1695
- for ( idx, & ( ref htlc, ref htlc_source) ) in local_commitment_tx. 1 . iter ( ) . enumerate ( ) {
1696
- let mut htlc_tx = self . build_htlc_transaction ( & local_commitment_txid, htlc, true , & local_keys, feerate_per_kw) ;
1699
+ for ( idx, ( htlc, htlc_source) ) in local_commitment_tx. 1 . drain ( .. ) . enumerate ( ) {
1700
+ let mut htlc_tx = self . build_htlc_transaction ( & local_commitment_txid, & htlc, true , & local_keys, feerate_per_kw) ;
1697
1701
let htlc_redeemscript = chan_utils:: get_htlc_redeemscript ( & htlc, & local_keys) ;
1698
1702
let htlc_sighash = Message :: from_slice ( & bip143:: SighashComponents :: new ( & htlc_tx) . sighash_all ( & htlc_tx. input [ 0 ] , & htlc_redeemscript, htlc. amount_msat / 1000 ) [ ..] ) . unwrap ( ) ;
1699
1703
secp_check ! ( self . secp_ctx. verify( & htlc_sighash, & msg. htlc_signatures[ idx] , & local_keys. b_htlc_key) , "Invalid HTLC tx signature from peer" ) ;
1700
1704
let htlc_sig = if htlc. offered {
1701
- let htlc_sig = self . sign_htlc_transaction ( & mut htlc_tx, & msg. htlc_signatures [ idx] , & None , htlc, & local_keys) ?;
1705
+ let htlc_sig = self . sign_htlc_transaction ( & mut htlc_tx, & msg. htlc_signatures [ idx] , & None , & htlc, & local_keys) ?;
1702
1706
new_local_commitment_txn. push ( htlc_tx) ;
1703
1707
htlc_sig
1704
1708
} else {
1705
- self . create_htlc_tx_signature ( & htlc_tx, htlc, & local_keys) ?. 1
1709
+ self . create_htlc_tx_signature ( & htlc_tx, & htlc, & local_keys) ?. 1
1706
1710
} ;
1707
- htlcs_and_sigs. push ( ( ( * htlc) . clone ( ) , msg. htlc_signatures [ idx] , htlc_sig, ( * htlc_source) . clone ( ) ) ) ;
1711
+ htlcs_and_sigs. push ( ( htlc, msg. htlc_signatures [ idx] , htlc_sig, htlc_source) ) ;
1708
1712
}
1709
1713
1710
1714
let next_per_commitment_point = PublicKey :: from_secret_key ( & self . secp_ctx , & self . build_local_commitment_secret ( self . cur_local_commitment_transaction_number - 1 ) ) ;
@@ -3227,20 +3231,23 @@ impl Channel {
3227
3231
}
3228
3232
}
3229
3233
3230
- match self . send_commitment_no_state_update ( ) {
3231
- Ok ( ( res, remote_commitment_tx) ) => {
3234
+ let ( res , remote_commitment_tx , htlcs ) = match self . send_commitment_no_state_update ( ) {
3235
+ Ok ( ( res, ( remote_commitment_tx, mut htlcs ) ) ) => {
3232
3236
// Update state now that we've passed all the can-fail calls...
3233
- self . channel_monitor . provide_latest_remote_commitment_tx_info ( & remote_commitment_tx. 0 , remote_commitment_tx. 1 , self . cur_remote_commitment_transaction_number , self . their_cur_commitment_point . unwrap ( ) ) ;
3234
- self . channel_state |= ChannelState :: AwaitingRemoteRevoke as u32 ;
3235
- Ok ( ( res, self . channel_monitor . clone ( ) ) )
3237
+ let htlcs_no_ref = htlcs. drain ( ..) . map ( |htlc_pair| ( htlc_pair. 0 , htlc_pair. 1 . map ( |source| source. clone ( ) ) ) ) . collect ( ) ;
3238
+ ( res, remote_commitment_tx, htlcs_no_ref)
3236
3239
} ,
3237
- Err ( e) => Err ( e) ,
3238
- }
3240
+ Err ( e) => return Err ( e) ,
3241
+ } ;
3242
+
3243
+ self . channel_monitor . provide_latest_remote_commitment_tx_info ( & remote_commitment_tx, htlcs, self . cur_remote_commitment_transaction_number , self . their_cur_commitment_point . unwrap ( ) ) ;
3244
+ self . channel_state |= ChannelState :: AwaitingRemoteRevoke as u32 ;
3245
+ Ok ( ( res, self . channel_monitor . clone ( ) ) )
3239
3246
}
3240
3247
3241
3248
/// Only fails in case of bad keys. Used for channel_reestablish commitment_signed generation
3242
3249
/// when we shouldn't change HTLC/channel state.
3243
- fn send_commitment_no_state_update ( & self ) -> Result < ( msgs:: CommitmentSigned , ( Transaction , Vec < ( HTLCOutputInCommitment , Option < HTLCSource > ) > ) ) , ChannelError > {
3250
+ fn send_commitment_no_state_update ( & self ) -> Result < ( msgs:: CommitmentSigned , ( Transaction , Vec < ( HTLCOutputInCommitment , Option < & HTLCSource > ) > ) ) , ChannelError > {
3244
3251
let funding_script = self . get_funding_redeemscript ( ) ;
3245
3252
3246
3253
let mut feerate_per_kw = self . feerate_per_kw ;
@@ -3979,11 +3986,15 @@ mod tests {
3979
3986
let htlc_basepoint = PublicKey :: from_secret_key ( & secp_ctx, & chan. local_keys . htlc_base_key ) ;
3980
3987
let keys = TxCreationKeys :: new ( & secp_ctx, & per_commitment_point, & delayed_payment_base, & htlc_basepoint, & chan. their_revocation_basepoint . unwrap ( ) , & chan. their_payment_basepoint . unwrap ( ) , & chan. their_htlc_basepoint . unwrap ( ) ) . unwrap ( ) ;
3981
3988
3982
- let mut unsigned_tx: ( Transaction , Vec < ( HTLCOutputInCommitment , Option < HTLCSource > ) > ) ;
3989
+ let mut unsigned_tx: ( Transaction , Vec < HTLCOutputInCommitment > ) ;
3983
3990
3984
3991
macro_rules! test_commitment {
3985
3992
( $their_sig_hex: expr, $our_sig_hex: expr, $tx_hex: expr) => {
3986
- unsigned_tx = chan. build_commitment_transaction( 0xffffffffffff - 42 , & keys, true , false , chan. feerate_per_kw) ;
3993
+ unsigned_tx = {
3994
+ let mut tx = chan. build_commitment_transaction( 0xffffffffffff - 42 , & keys, true , false , chan. feerate_per_kw) ;
3995
+ let htlcs = tx. 1 . drain( ..) . map( |htlc_pair| htlc_pair. 0 ) . collect( ) ;
3996
+ ( tx. 0 , htlcs)
3997
+ } ;
3987
3998
let their_signature = Signature :: from_der( & secp_ctx, & hex:: decode( $their_sig_hex) . unwrap( ) [ ..] ) . unwrap( ) ;
3988
3999
let sighash = Message :: from_slice( & bip143:: SighashComponents :: new( & unsigned_tx. 0 ) . sighash_all( & unsigned_tx. 0 . input[ 0 ] , & chan. get_funding_redeemscript( ) , chan. channel_value_satoshis) [ ..] ) . unwrap( ) ;
3989
4000
secp_ctx. verify( & sighash, & their_signature, & chan. their_funding_pubkey. unwrap( ) ) . unwrap( ) ;
@@ -3999,7 +4010,7 @@ mod tests {
3999
4010
( $htlc_idx: expr, $their_sig_hex: expr, $our_sig_hex: expr, $tx_hex: expr ) => {
4000
4011
let remote_signature = Signature :: from_der( & secp_ctx, & hex:: decode( $their_sig_hex) . unwrap( ) [ ..] ) . unwrap( ) ;
4001
4012
4002
- let ( ref htlc, _ ) = unsigned_tx. 1 [ $htlc_idx] ;
4013
+ let ref htlc = unsigned_tx. 1 [ $htlc_idx] ;
4003
4014
let mut htlc_tx = chan. build_htlc_transaction( & unsigned_tx. 0 . txid( ) , & htlc, true , & keys, chan. feerate_per_kw) ;
4004
4015
let htlc_redeemscript = chan_utils:: get_htlc_redeemscript( & htlc, & keys) ;
4005
4016
let htlc_sighash = Message :: from_slice( & bip143:: SighashComponents :: new( & htlc_tx) . sighash_all( & htlc_tx. input[ 0 ] , & htlc_redeemscript, htlc. amount_msat / 1000 ) [ ..] ) . unwrap( ) ;
0 commit comments