@@ -747,8 +747,12 @@ impl Channel {
747
747
/// have not yet committed it. Such HTLCs will only be included in transactions which are being
748
748
/// generated by the peer which proposed adding the HTLCs, and thus we need to understand both
749
749
/// which peer generated this transaction and "to whom" this transaction flows.
750
+ /// Returns (the transaction built, the number of HTLC outputs which were present in the
751
+ /// transaction, the list of HTLCs which were not ignored when building the transaction).
752
+ /// Note that below-dust HTLCs are included in the third return value, but not the second, and
753
+ /// sources are provided only for outbound HTLCs in the third return value.
750
754
#[ inline]
751
- fn build_commitment_transaction ( & self , commitment_number : u64 , keys : & TxCreationKeys , local : bool , generated_by_local : bool , feerate_per_kw : u64 ) -> ( Transaction , Vec < HTLCOutputInCommitment > , Vec < ( PaymentHash , & HTLCSource , Option < u32 > ) > ) {
755
+ fn build_commitment_transaction ( & self , commitment_number : u64 , keys : & TxCreationKeys , local : bool , generated_by_local : bool , feerate_per_kw : u64 ) -> ( Transaction , usize , Vec < ( HTLCOutputInCommitment , Option < & HTLCSource > ) > ) {
752
756
let obscured_commitment_transaction_number = self . get_commitment_transaction_number_obscure_factor ( ) ^ ( INITIAL_COMMITMENT_NUMBER - commitment_number) ;
753
757
754
758
let txins = {
@@ -915,30 +919,23 @@ impl Channel {
915
919
transaction_utils:: sort_outputs ( & mut txouts) ;
916
920
917
921
let mut outputs: Vec < TxOut > = Vec :: with_capacity ( txouts. len ( ) ) ;
918
- let mut htlcs_included: Vec < HTLCOutputInCommitment > = Vec :: with_capacity ( txouts. len ( ) ) ;
919
- let mut htlc_sources: Vec < ( PaymentHash , & HTLCSource , Option < u32 > ) > = Vec :: with_capacity ( txouts. len ( ) + included_dust_htlcs. len ( ) ) ;
920
- for ( idx, out) in txouts. drain ( ..) . enumerate ( ) {
922
+ let mut htlcs_included: Vec < ( HTLCOutputInCommitment , Option < & HTLCSource > ) > = Vec :: with_capacity ( txouts. len ( ) + included_dust_htlcs. len ( ) ) ;
923
+ for ( idx, mut out) in txouts. drain ( ..) . enumerate ( ) {
921
924
outputs. push ( out. 0 ) ;
922
- if let Some ( ( mut htlc, source_option) ) = out. 1 {
925
+ if let Some ( ( mut htlc, source_option) ) = out. 1 . take ( ) {
923
926
htlc. transaction_output_index = Some ( idx as u32 ) ;
924
- if let Some ( source) = source_option {
925
- htlc_sources. push ( ( htlc. payment_hash , source, Some ( idx as u32 ) ) ) ;
926
- }
927
- htlcs_included. push ( htlc) ;
928
- }
929
- }
930
- for ( htlc, source_option) in included_dust_htlcs. drain ( ..) {
931
- if let Some ( source) = source_option {
932
- htlc_sources. push ( ( htlc. payment_hash , source, None ) ) ;
927
+ htlcs_included. push ( ( htlc, source_option) ) ;
933
928
}
934
929
}
930
+ let non_dust_htlc_count = htlcs_included. len ( ) ;
931
+ htlcs_included. append ( & mut included_dust_htlcs) ;
935
932
936
933
( Transaction {
937
934
version : 2 ,
938
935
lock_time : ( ( 0x20 as u32 ) << 8 * 3 ) | ( ( obscured_commitment_transaction_number & 0xffffffu64 ) as u32 ) ,
939
936
input : txins,
940
937
output : outputs,
941
- } , htlcs_included , htlc_sources )
938
+ } , non_dust_htlc_count , htlcs_included )
942
939
}
943
940
944
941
#[ inline]
@@ -1451,9 +1448,9 @@ impl Channel {
1451
1448
1452
1449
// Now that we're past error-generating stuff, update our local state:
1453
1450
1454
- self . channel_monitor . provide_latest_remote_commitment_tx_info ( & remote_initial_commitment_tx, Vec :: new ( ) , Vec :: new ( ) , self . cur_remote_commitment_transaction_number , self . their_cur_commitment_point . unwrap ( ) ) ;
1451
+ self . channel_monitor . provide_latest_remote_commitment_tx_info ( & remote_initial_commitment_tx, Vec :: new ( ) , self . cur_remote_commitment_transaction_number , self . their_cur_commitment_point . unwrap ( ) ) ;
1455
1452
self . last_local_commitment_txn = vec ! [ local_initial_commitment_tx. clone( ) ] ;
1456
- self . channel_monitor . provide_latest_local_commitment_tx_info ( local_initial_commitment_tx, local_keys, self . feerate_per_kw , Vec :: new ( ) , Vec :: new ( ) ) ;
1453
+ self . channel_monitor . provide_latest_local_commitment_tx_info ( local_initial_commitment_tx, local_keys, self . feerate_per_kw , Vec :: new ( ) ) ;
1457
1454
self . channel_state = ChannelState :: FundingSent as u32 ;
1458
1455
self . channel_id = funding_txo. to_channel_id ( ) ;
1459
1456
self . cur_remote_commitment_transaction_number -= 1 ;
@@ -1490,7 +1487,7 @@ impl Channel {
1490
1487
secp_check ! ( self . secp_ctx. verify( & local_sighash, & msg. signature, & self . their_funding_pubkey. unwrap( ) ) , "Invalid funding_signed signature from peer" ) ;
1491
1488
1492
1489
self . sign_commitment_transaction ( & mut local_initial_commitment_tx, & msg. signature ) ;
1493
- self . channel_monitor . provide_latest_local_commitment_tx_info ( local_initial_commitment_tx. clone ( ) , local_keys, self . feerate_per_kw , Vec :: new ( ) , Vec :: new ( ) ) ;
1490
+ self . channel_monitor . provide_latest_local_commitment_tx_info ( local_initial_commitment_tx. clone ( ) , local_keys, self . feerate_per_kw , Vec :: new ( ) ) ;
1494
1491
self . last_local_commitment_txn = vec ! [ local_initial_commitment_tx] ;
1495
1492
self . channel_state = ChannelState :: FundingSent as u32 ;
1496
1493
self . cur_local_commitment_transaction_number -= 1 ;
@@ -1693,7 +1690,7 @@ impl Channel {
1693
1690
1694
1691
let mut local_commitment_tx = {
1695
1692
let mut commitment_tx = self . build_commitment_transaction ( self . cur_local_commitment_transaction_number , & local_keys, true , false , feerate_per_kw) ;
1696
- let htlcs_cloned: Vec < _ > = commitment_tx. 2 . drain ( ..) . map ( |htlc_source | ( htlc_source . 0 , htlc_source . 1 . clone ( ) , htlc_source . 2 ) ) . collect ( ) ;
1693
+ let htlcs_cloned: Vec < _ > = commitment_tx. 2 . drain ( ..) . map ( |htlc | ( htlc . 0 , htlc . 1 . map ( |h| h . clone ( ) ) ) ) . collect ( ) ;
1697
1694
( commitment_tx. 0 , commitment_tx. 1 , htlcs_cloned)
1698
1695
} ;
1699
1696
let local_commitment_txid = local_commitment_tx. 0 . txid ( ) ;
@@ -1702,24 +1699,24 @@ impl Channel {
1702
1699
1703
1700
//If channel fee was updated by funder confirm funder can afford the new fee rate when applied to the current local commitment transaction
1704
1701
if update_fee {
1705
- let num_htlcs = local_commitment_tx. 1 . len ( ) ;
1702
+ let num_htlcs = local_commitment_tx. 1 ;
1706
1703
let total_fee: u64 = feerate_per_kw as u64 * ( COMMITMENT_TX_BASE_WEIGHT + ( num_htlcs as u64 ) * COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ;
1707
1704
1708
1705
if self . channel_value_satoshis - self . value_to_self_msat / 1000 < total_fee + self . their_channel_reserve_satoshis {
1709
1706
return Err ( ChannelError :: Close ( "Funding remote cannot afford proposed new fee" ) ) ;
1710
1707
}
1711
1708
}
1712
1709
1713
- if msg. htlc_signatures . len ( ) != local_commitment_tx. 1 . len ( ) {
1710
+ if msg. htlc_signatures . len ( ) != local_commitment_tx. 1 {
1714
1711
return Err ( ChannelError :: Close ( "Got wrong number of HTLC signatures from remote" ) ) ;
1715
1712
}
1716
1713
1717
- let mut new_local_commitment_txn = Vec :: with_capacity ( local_commitment_tx. 1 . len ( ) + 1 ) ;
1714
+ let mut new_local_commitment_txn = Vec :: with_capacity ( local_commitment_tx. 1 + 1 ) ;
1718
1715
self . sign_commitment_transaction ( & mut local_commitment_tx. 0 , & msg. signature ) ;
1719
1716
new_local_commitment_txn. push ( local_commitment_tx. 0 . clone ( ) ) ;
1720
1717
1721
- let mut htlcs_and_sigs = Vec :: with_capacity ( local_commitment_tx. 1 . len ( ) ) ;
1722
- for ( idx, htlc) in local_commitment_tx. 1 . drain ( ..) . enumerate ( ) {
1718
+ let mut htlcs_and_sigs = Vec :: with_capacity ( local_commitment_tx. 2 . len ( ) ) ;
1719
+ for ( idx, ( htlc, source ) ) in local_commitment_tx. 2 . drain ( ..) . enumerate ( ) {
1723
1720
if let Some ( _) = htlc. transaction_output_index {
1724
1721
let mut htlc_tx = self . build_htlc_transaction ( & local_commitment_txid, & htlc, true , & local_keys, feerate_per_kw) ;
1725
1722
let htlc_redeemscript = chan_utils:: get_htlc_redeemscript ( & htlc, & local_keys) ;
@@ -1732,7 +1729,9 @@ impl Channel {
1732
1729
} else {
1733
1730
self . create_htlc_tx_signature ( & htlc_tx, & htlc, & local_keys) ?. 1
1734
1731
} ;
1735
- htlcs_and_sigs. push ( ( htlc, msg. htlc_signatures [ idx] , htlc_sig) ) ;
1732
+ htlcs_and_sigs. push ( ( htlc, Some ( ( msg. htlc_signatures [ idx] , htlc_sig) ) , source) ) ;
1733
+ } else {
1734
+ htlcs_and_sigs. push ( ( htlc, None , source) ) ;
1736
1735
}
1737
1736
}
1738
1737
@@ -1760,7 +1759,7 @@ impl Channel {
1760
1759
self . monitor_pending_order = None ;
1761
1760
}
1762
1761
1763
- self . channel_monitor . provide_latest_local_commitment_tx_info ( local_commitment_tx. 0 , local_keys, self . feerate_per_kw , htlcs_and_sigs, local_commitment_tx . 2 ) ;
1762
+ self . channel_monitor . provide_latest_local_commitment_tx_info ( local_commitment_tx. 0 , local_keys, self . feerate_per_kw , htlcs_and_sigs) ;
1764
1763
1765
1764
for htlc in self . pending_inbound_htlcs . iter_mut ( ) {
1766
1765
let new_forward = if let & InboundHTLCState :: RemoteAnnounced ( ref forward_info) = & htlc. state {
@@ -3030,7 +3029,7 @@ impl Channel {
3030
3029
let temporary_channel_id = self . channel_id ;
3031
3030
3032
3031
// Now that we're past error-generating stuff, update our local state:
3033
- self . channel_monitor . provide_latest_remote_commitment_tx_info ( & commitment_tx, Vec :: new ( ) , Vec :: new ( ) , self . cur_remote_commitment_transaction_number , self . their_cur_commitment_point . unwrap ( ) ) ;
3032
+ self . channel_monitor . provide_latest_remote_commitment_tx_info ( & commitment_tx, Vec :: new ( ) , self . cur_remote_commitment_transaction_number , self . their_cur_commitment_point . unwrap ( ) ) ;
3034
3033
self . channel_state = ChannelState :: FundingCreated as u32 ;
3035
3034
self . channel_id = funding_txo. to_channel_id ( ) ;
3036
3035
self . cur_remote_commitment_transaction_number -= 1 ;
@@ -3262,23 +3261,23 @@ impl Channel {
3262
3261
}
3263
3262
}
3264
3263
3265
- let ( res, remote_commitment_tx, htlcs, htlc_sources ) = match self . send_commitment_no_state_update ( ) {
3266
- Ok ( ( res, ( remote_commitment_tx, htlcs , mut htlc_sources ) ) ) => {
3264
+ let ( res, remote_commitment_tx, htlcs) = match self . send_commitment_no_state_update ( ) {
3265
+ Ok ( ( res, ( remote_commitment_tx, mut htlcs ) ) ) => {
3267
3266
// Update state now that we've passed all the can-fail calls...
3268
- let htlc_sources_no_ref = htlc_sources . drain ( ..) . map ( |htlc_source| ( htlc_source . 0 , htlc_source. 1 . clone ( ) , htlc_source . 2 ) ) . collect ( ) ;
3269
- ( res, remote_commitment_tx, htlcs , htlc_sources_no_ref )
3267
+ let htlcs_no_ref = htlcs . drain ( ..) . map ( |( htlc , htlc_source) | ( htlc , htlc_source. map ( |source_ref| Box :: new ( source_ref . clone ( ) ) ) ) ) . collect ( ) ;
3268
+ ( res, remote_commitment_tx, htlcs_no_ref )
3270
3269
} ,
3271
3270
Err ( e) => return Err ( e) ,
3272
3271
} ;
3273
3272
3274
- self . channel_monitor . provide_latest_remote_commitment_tx_info ( & remote_commitment_tx, htlcs, htlc_sources , self . cur_remote_commitment_transaction_number , self . their_cur_commitment_point . unwrap ( ) ) ;
3273
+ 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 ( ) ) ;
3275
3274
self . channel_state |= ChannelState :: AwaitingRemoteRevoke as u32 ;
3276
3275
Ok ( ( res, self . channel_monitor . clone ( ) ) )
3277
3276
}
3278
3277
3279
3278
/// Only fails in case of bad keys. Used for channel_reestablish commitment_signed generation
3280
3279
/// when we shouldn't change HTLC/channel state.
3281
- fn send_commitment_no_state_update ( & self ) -> Result < ( msgs:: CommitmentSigned , ( Transaction , Vec < HTLCOutputInCommitment > , Vec < ( PaymentHash , & HTLCSource , Option < u32 > ) > ) ) , ChannelError > {
3280
+ fn send_commitment_no_state_update ( & self ) -> Result < ( msgs:: CommitmentSigned , ( Transaction , Vec < ( HTLCOutputInCommitment , Option < & HTLCSource > ) > ) ) , ChannelError > {
3282
3281
let funding_script = self . get_funding_redeemscript ( ) ;
3283
3282
3284
3283
let mut feerate_per_kw = self . feerate_per_kw ;
@@ -3294,9 +3293,8 @@ impl Channel {
3294
3293
let remote_sighash = Message :: from_slice ( & bip143:: SighashComponents :: new ( & remote_commitment_tx. 0 ) . sighash_all ( & remote_commitment_tx. 0 . input [ 0 ] , & funding_script, self . channel_value_satoshis ) [ ..] ) . unwrap ( ) ;
3295
3294
let our_sig = self . secp_ctx . sign ( & remote_sighash, & self . local_keys . funding_key ) ;
3296
3295
3297
- let mut htlc_sigs = Vec :: new ( ) ;
3298
-
3299
- for ref htlc in remote_commitment_tx. 1 . iter ( ) {
3296
+ let mut htlc_sigs = Vec :: with_capacity ( remote_commitment_tx. 1 ) ;
3297
+ for & ( ref htlc, _) in remote_commitment_tx. 2 . iter ( ) {
3300
3298
if let Some ( _) = htlc. transaction_output_index {
3301
3299
let htlc_tx = self . build_htlc_transaction ( & remote_commitment_txid, htlc, false , & remote_keys, feerate_per_kw) ;
3302
3300
let htlc_redeemscript = chan_utils:: get_htlc_redeemscript ( & htlc, & remote_keys) ;
@@ -3310,7 +3308,7 @@ impl Channel {
3310
3308
channel_id : self . channel_id ,
3311
3309
signature : our_sig,
3312
3310
htlc_signatures : htlc_sigs,
3313
- } , remote_commitment_tx) )
3311
+ } , ( remote_commitment_tx. 0 , remote_commitment_tx . 2 ) ) )
3314
3312
}
3315
3313
3316
3314
/// Adds a pending outbound HTLC to this channel, and creates a signed commitment transaction
@@ -4024,8 +4022,11 @@ mod tests {
4024
4022
macro_rules! test_commitment {
4025
4023
( $their_sig_hex: expr, $our_sig_hex: expr, $tx_hex: expr) => {
4026
4024
unsigned_tx = {
4027
- let res = chan. build_commitment_transaction( 0xffffffffffff - 42 , & keys, true , false , chan. feerate_per_kw) ;
4028
- ( res. 0 , res. 1 )
4025
+ let mut res = chan. build_commitment_transaction( 0xffffffffffff - 42 , & keys, true , false , chan. feerate_per_kw) ;
4026
+ let htlcs = res. 2 . drain( ..)
4027
+ . filter_map( |( htlc, _) | if htlc. transaction_output_index. is_some( ) { Some ( htlc) } else { None } )
4028
+ . collect( ) ;
4029
+ ( res. 0 , htlcs)
4029
4030
} ;
4030
4031
let their_signature = Signature :: from_der( & secp_ctx, & hex:: decode( $their_sig_hex) . unwrap( ) [ ..] ) . unwrap( ) ;
4031
4032
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( ) ;
0 commit comments