@@ -42,6 +42,8 @@ use std;
42
42
use std:: default:: Default ;
43
43
use std:: { cmp, mem, fmt} ;
44
44
use std:: ops:: Deref ;
45
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
46
+ use std:: sync:: Mutex ;
45
47
use bitcoin:: hashes:: hex:: ToHex ;
46
48
47
49
#[ cfg( test) ]
@@ -386,6 +388,15 @@ pub(super) struct Channel<ChanSigner: ChannelKeys> {
386
388
commitment_secrets : CounterpartyCommitmentSecrets ,
387
389
388
390
network_sync : UpdateStatus ,
391
+
392
+ // We save these values so we can make sure `next_local_commit_tx_fee_msat` and
393
+ // `next_remote_commit_tx_fee_msat` properly predict what the next commitment transaction fee will
394
+ // be, by comparing the cached values to the fee of the tranaction generated by
395
+ // `build_commitment_transaction`.
396
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
397
+ next_local_commitment_tx_fee_cached : Mutex < Option < u64 > > ,
398
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
399
+ next_remote_commitment_tx_fee_cached : Mutex < Option < u64 > > ,
389
400
}
390
401
391
402
pub const OUR_MAX_HTLCS : u16 = 50 ; //TODO
@@ -557,6 +568,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
557
568
commitment_secrets : CounterpartyCommitmentSecrets :: new ( ) ,
558
569
559
570
network_sync : UpdateStatus :: Fresh ,
571
+
572
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
573
+ next_local_commitment_tx_fee_cached : Mutex :: new ( None ) ,
574
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
575
+ next_remote_commitment_tx_fee_cached : Mutex :: new ( None ) ,
560
576
} )
561
577
}
562
578
@@ -790,6 +806,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
790
806
commitment_secrets : CounterpartyCommitmentSecrets :: new ( ) ,
791
807
792
808
network_sync : UpdateStatus :: Fresh ,
809
+
810
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
811
+ next_local_commitment_tx_fee_cached : Mutex :: new ( None ) ,
812
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
813
+ next_remote_commitment_tx_fee_cached : Mutex :: new ( None ) ,
793
814
} ;
794
815
795
816
Ok ( chan)
@@ -867,7 +888,21 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
867
888
InboundHTLCState :: AwaitingRemoteRevokeToAnnounce ( _) => ( !generated_by_local, "AwaitingRemoteRevokeToAnnounce" ) ,
868
889
InboundHTLCState :: AwaitingAnnouncedRemoteRevoke ( _) => ( true , "AwaitingAnnouncedRemoteRevoke" ) ,
869
890
InboundHTLCState :: Committed => ( true , "Committed" ) ,
870
- InboundHTLCState :: LocalRemoved ( _) => ( !generated_by_local, "LocalRemoved" ) ,
891
+ InboundHTLCState :: LocalRemoved ( _) => {
892
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
893
+ {
894
+ // Remote commitment transactions generated by us won't include our locally removed
895
+ // HTLCs, even though we include them when deciding whether to accept/send new HTLCs and
896
+ // setting these cached values. Therefore, set these values to None here so we don't
897
+ // assert that the transaction generated in this function has the same fee as the cached
898
+ // fee. Similar reasoning applies to LocalAnnounced and RemoveRemoved HTLCs below.
899
+ if !local && generated_by_local {
900
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
901
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
902
+ }
903
+ }
904
+ ( !generated_by_local, "LocalRemoved" )
905
+ } ,
871
906
} ;
872
907
873
908
if include {
@@ -890,9 +925,27 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
890
925
891
926
for ref htlc in self . pending_outbound_htlcs . iter ( ) {
892
927
let ( include, state_name) = match htlc. state {
893
- OutboundHTLCState :: LocalAnnounced ( _) => ( generated_by_local, "LocalAnnounced" ) ,
928
+ OutboundHTLCState :: LocalAnnounced ( _) => {
929
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
930
+ {
931
+ if local && !generated_by_local {
932
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
933
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
934
+ }
935
+ }
936
+ ( generated_by_local, "LocalAnnounced" )
937
+ } ,
894
938
OutboundHTLCState :: Committed => ( true , "Committed" ) ,
895
- OutboundHTLCState :: RemoteRemoved ( _) => ( generated_by_local, "RemoteRemoved" ) ,
939
+ OutboundHTLCState :: RemoteRemoved ( _) => {
940
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
941
+ {
942
+ if local && !generated_by_local {
943
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
944
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
945
+ }
946
+ }
947
+ ( generated_by_local, "RemoteRemoved" )
948
+ } ,
896
949
OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( _) => ( generated_by_local, "AwaitingRemoteRevokeToRemove" ) ,
897
950
OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( _) => ( false , "AwaitingRemovedRemoteRevoke" ) ,
898
951
} ;
@@ -1261,6 +1314,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1261
1314
}
1262
1315
assert_eq ! ( self . channel_state & ChannelState :: ShutdownComplete as u32 , 0 ) ;
1263
1316
1317
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
1318
+ {
1319
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
1320
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
1321
+ }
1322
+
1264
1323
// ChannelManager may generate duplicate claims/fails due to HTLC update events from
1265
1324
// on-chain ChannelsMonitors during block rescan. Ideally we'd figure out a way to drop
1266
1325
// these, but for now we just have to treat them as normal.
@@ -1312,6 +1371,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1312
1371
return Ok ( None ) ;
1313
1372
}
1314
1373
1374
+
1315
1375
{
1316
1376
let htlc = & mut self . pending_inbound_htlcs [ pending_idx] ;
1317
1377
htlc. state = InboundHTLCState :: LocalRemoved ( InboundHTLCRemovalReason :: FailRelay ( err_packet. clone ( ) ) ) ;
@@ -1740,7 +1800,18 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1740
1800
}
1741
1801
}
1742
1802
1743
- self . commit_tx_fee_msat ( included_htlcs + addl_htlcs)
1803
+ let num_htlcs = included_htlcs + addl_htlcs;
1804
+ let res = self . commit_tx_fee_msat ( num_htlcs) ;
1805
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
1806
+ {
1807
+ if fee_spike_buffer_htlc. is_none ( ) {
1808
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( res) ;
1809
+ } else {
1810
+ let fee = self . commit_tx_fee_msat ( num_htlcs - 1 ) ;
1811
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( fee) ;
1812
+ }
1813
+ }
1814
+ res
1744
1815
}
1745
1816
1746
1817
// Get the commitment tx fee for the remote's next commitment transaction based on the number of
@@ -1781,14 +1852,43 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1781
1852
match htlc. state {
1782
1853
OutboundHTLCState :: Committed => included_htlcs += 1 ,
1783
1854
OutboundHTLCState :: RemoteRemoved { ..} => included_htlcs += 1 ,
1855
+ OutboundHTLCState :: LocalAnnounced { .. } => included_htlcs += 1 ,
1784
1856
_ => { } ,
1785
1857
}
1786
1858
}
1787
1859
1788
- self . commit_tx_fee_msat ( included_htlcs + addl_htlcs)
1860
+ let num_htlcs = included_htlcs + addl_htlcs;
1861
+ let res = self . commit_tx_fee_msat ( num_htlcs) ;
1862
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
1863
+ {
1864
+ if fee_spike_buffer_htlc. is_none ( ) {
1865
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( res) ;
1866
+ } else {
1867
+ let fee = self . commit_tx_fee_msat ( num_htlcs - 1 ) ;
1868
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( fee) ;
1869
+ }
1870
+ }
1871
+ res
1872
+ }
1873
+
1874
+
1875
+ pub fn update_add_htlc < F , L : Deref > ( & mut self , msg : & msgs:: UpdateAddHTLC , pending_forward_status : PendingHTLCStatus , create_pending_htlc_status : F , logger : & L ) -> Result < ( ) , ChannelError >
1876
+ where F : for < ' a > Fn ( & ' a Self , PendingHTLCStatus , u16 ) -> PendingHTLCStatus , L :: Target : Logger {
1877
+ match self . update_add_htlc_internal ( msg, pending_forward_status, create_pending_htlc_status, logger) {
1878
+ Ok ( ( ) ) => return Ok ( ( ) ) ,
1879
+ Err ( e) => {
1880
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
1881
+ {
1882
+ // If we errored, one of these fields still might've been set, so re-set them to None.
1883
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
1884
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
1885
+ }
1886
+ return Err ( e) ;
1887
+ } ,
1888
+ }
1789
1889
}
1790
1890
1791
- pub fn update_add_htlc < F , L : Deref > ( & mut self , msg : & msgs:: UpdateAddHTLC , mut pending_forward_status : PendingHTLCStatus , create_pending_htlc_status : F , logger : & L ) -> Result < ( ) , ChannelError >
1891
+ fn update_add_htlc_internal < F , L : Deref > ( & mut self , msg : & msgs:: UpdateAddHTLC , mut pending_forward_status : PendingHTLCStatus , create_pending_htlc_status : F , logger : & L ) -> Result < ( ) , ChannelError >
1792
1892
where F : for < ' a > Fn ( & ' a Self , PendingHTLCStatus , u16 ) -> PendingHTLCStatus , L :: Target : Logger {
1793
1893
// We can't accept HTLCs sent after we've sent a shutdown.
1794
1894
let local_sent_shutdown = ( self . channel_state & ( ChannelState :: ChannelFunded as u32 | ChannelState :: LocalShutdownSent as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) ;
@@ -2019,15 +2119,23 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
2019
2119
( commitment_tx. 1 , htlcs_cloned, commitment_tx. 0 , commitment_txid)
2020
2120
} ;
2021
2121
2122
+ let total_fee = feerate_per_kw as u64 * ( COMMITMENT_TX_BASE_WEIGHT + ( num_htlcs as u64 ) * COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ;
2022
2123
//If channel fee was updated by funder confirm funder can afford the new fee rate when applied to the current local commitment transaction
2023
2124
if update_fee {
2024
- let total_fee = feerate_per_kw as u64 * ( COMMITMENT_TX_BASE_WEIGHT + ( num_htlcs as u64 ) * COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ;
2025
-
2026
2125
let counterparty_reserve_we_require = Channel :: < ChanSigner > :: get_holder_selected_channel_reserve_satoshis ( self . channel_value_satoshis ) ;
2027
2126
if self . channel_value_satoshis - self . value_to_self_msat / 1000 < total_fee + counterparty_reserve_we_require {
2028
2127
return Err ( ( None , ChannelError :: Close ( "Funding remote cannot afford proposed new fee" . to_owned ( ) ) ) ) ;
2029
2128
}
2030
2129
}
2130
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
2131
+ {
2132
+ if self . is_outbound ( ) {
2133
+ let projected_fee = self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) . take ( ) ;
2134
+ if let Some ( fee) = projected_fee {
2135
+ assert_eq ! ( total_fee, fee / 1000 ) ;
2136
+ }
2137
+ }
2138
+ }
2031
2139
2032
2140
if msg. htlc_signatures . len ( ) != num_htlcs {
2033
2141
return Err ( ( None , ChannelError :: Close ( format ! ( "Got wrong number of HTLC signatures ({}) from remote. It must be {}" , msg. htlc_signatures. len( ) , num_htlcs) ) ) ) ;
@@ -2276,6 +2384,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
2276
2384
return Err ( ChannelError :: Close ( "Peer sent revoke_and_ack after we'd started exchanging closing_signeds" . to_owned ( ) ) ) ;
2277
2385
}
2278
2386
2387
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
2388
+ {
2389
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
2390
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
2391
+ }
2392
+
2279
2393
if let Some ( counterparty_prev_commitment_point) = self . counterparty_prev_commitment_point {
2280
2394
if PublicKey :: from_secret_key ( & self . secp_ctx , & secp_check ! ( SecretKey :: from_slice( & msg. per_commitment_secret) , "Peer provided an invalid per_commitment_secret" . to_owned( ) ) ) != counterparty_prev_commitment_point {
2281
2395
return Err ( ChannelError :: Close ( "Got a revoke commitment secret which didn't correspond to their current pubkey" . to_owned ( ) ) ) ;
@@ -2757,6 +2871,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
2757
2871
return Err ( ChannelError :: Close ( "Peer sent a loose channel_reestablish not after reconnect" . to_owned ( ) ) ) ;
2758
2872
}
2759
2873
2874
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
2875
+ {
2876
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
2877
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
2878
+ }
2879
+
2760
2880
if msg. next_local_commitment_number >= INITIAL_COMMITMENT_NUMBER || msg. next_remote_commitment_number >= INITIAL_COMMITMENT_NUMBER ||
2761
2881
msg. next_local_commitment_number == 0 {
2762
2882
return Err ( ChannelError :: Close ( "Peer sent a garbage channel_reestablish" . to_owned ( ) ) ) ;
@@ -3726,6 +3846,28 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
3726
3846
/// You MUST call send_commitment prior to any other calls on this Channel
3727
3847
/// If an Err is returned, it's a ChannelError::Ignore!
3728
3848
pub fn send_htlc ( & mut self , amount_msat : u64 , payment_hash : PaymentHash , cltv_expiry : u32 , source : HTLCSource , onion_routing_packet : msgs:: OnionPacket ) -> Result < Option < msgs:: UpdateAddHTLC > , ChannelError > {
3849
+ match self . send_htlc_internal ( amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet) {
3850
+ Ok ( res) => return Ok ( res) ,
3851
+ Err ( e) => {
3852
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
3853
+ {
3854
+ // If we errored, one of these fields still might've been set, so re-set them to None.
3855
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
3856
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
3857
+ }
3858
+ return Err ( e) ;
3859
+ }
3860
+ }
3861
+ }
3862
+
3863
+ /// Adds a pending outbound HTLC to this channel, note that you probably want
3864
+ /// send_htlc_and_commit instead cause you'll want both messages at once.
3865
+ /// This returns an option instead of a pure UpdateAddHTLC as we may be in a state where we are
3866
+ /// waiting on the remote peer to send us a revoke_and_ack during which time we cannot add new
3867
+ /// HTLCs on the wire or we wouldn't be able to determine what they actually ACK'ed.
3868
+ /// You MUST call send_commitment prior to any other calls on this Channel
3869
+ /// If an Err is returned, it's a ChannelError::Ignore!
3870
+ fn send_htlc_internal ( & mut self , amount_msat : u64 , payment_hash : PaymentHash , cltv_expiry : u32 , source : HTLCSource , onion_routing_packet : msgs:: OnionPacket ) -> Result < Option < msgs:: UpdateAddHTLC > , ChannelError > {
3729
3871
if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK ) ) != ( ChannelState :: ChannelFunded as u32 ) {
3730
3872
return Err ( ChannelError :: Ignore ( "Cannot send HTLC until channel is fully established and we haven't started shutting down" . to_owned ( ) ) ) ;
3731
3873
}
@@ -3921,6 +4063,17 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
3921
4063
let counterparty_commitment_txid = counterparty_commitment_tx. 0 . trust ( ) . txid ( ) ;
3922
4064
let ( signature, htlc_signatures) ;
3923
4065
4066
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
4067
+ {
4068
+ if !self . is_outbound ( ) {
4069
+ let projected_fee = self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) . take ( ) ;
4070
+ if let Some ( expected_fee) = projected_fee {
4071
+ let actual_fee = self . commit_tx_fee_msat ( counterparty_commitment_tx. 1 ) ;
4072
+ assert_eq ! ( actual_fee, expected_fee) ;
4073
+ }
4074
+ }
4075
+ }
4076
+
3924
4077
{
3925
4078
let mut htlcs = Vec :: with_capacity ( counterparty_commitment_tx. 2 . len ( ) ) ;
3926
4079
for & ( ref htlc, _) in counterparty_commitment_tx. 2 . iter ( ) {
@@ -4511,6 +4664,11 @@ impl<'a, ChanSigner: ChannelKeys, K: Deref> ReadableArgs<&'a K> for Channel<Chan
4511
4664
commitment_secrets,
4512
4665
4513
4666
network_sync : UpdateStatus :: Fresh ,
4667
+
4668
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
4669
+ next_local_commitment_tx_fee_cached : Mutex :: new ( None ) ,
4670
+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
4671
+ next_remote_commitment_tx_fee_cached : Mutex :: new ( None ) ,
4514
4672
} )
4515
4673
}
4516
4674
}
0 commit comments