@@ -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( test) ]
46
+ use std:: sync:: Mutex ;
45
47
use bitcoin:: hashes:: hex:: ToHex ;
46
48
47
49
#[ cfg( test) ]
@@ -391,6 +393,15 @@ pub(super) struct Channel<ChanSigner: ChannelKeys> {
391
393
commitment_secrets : CounterpartyCommitmentSecrets ,
392
394
393
395
network_sync : UpdateStatus ,
396
+
397
+ // We save these values so we can make sure `next_local_commit_tx_fee_msat` and
398
+ // `next_remote_commit_tx_fee_msat` properly predict what the next commitment transaction fee will
399
+ // be, by comparing the cached values to the fee of the tranaction generated by
400
+ // `build_commitment_transaction`.
401
+ #[ cfg( test) ]
402
+ next_local_commitment_tx_fee_cached : Mutex < Option < u64 > > ,
403
+ #[ cfg( test) ]
404
+ next_remote_commitment_tx_fee_cached : Mutex < Option < u64 > > ,
394
405
}
395
406
396
407
pub const OUR_MAX_HTLCS : u16 = 50 ; //TODO
@@ -559,6 +570,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
559
570
commitment_secrets : CounterpartyCommitmentSecrets :: new ( ) ,
560
571
561
572
network_sync : UpdateStatus :: Fresh ,
573
+
574
+ #[ cfg( test) ]
575
+ next_local_commitment_tx_fee_cached : Mutex :: new ( None ) ,
576
+ #[ cfg( test) ]
577
+ next_remote_commitment_tx_fee_cached : Mutex :: new ( None ) ,
562
578
} )
563
579
}
564
580
@@ -787,6 +803,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
787
803
commitment_secrets : CounterpartyCommitmentSecrets :: new ( ) ,
788
804
789
805
network_sync : UpdateStatus :: Fresh ,
806
+
807
+ #[ cfg( test) ]
808
+ next_local_commitment_tx_fee_cached : Mutex :: new ( None ) ,
809
+ #[ cfg( test) ]
810
+ next_remote_commitment_tx_fee_cached : Mutex :: new ( None ) ,
790
811
} ;
791
812
792
813
Ok ( chan)
@@ -905,7 +926,21 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
905
926
InboundHTLCState :: AwaitingRemoteRevokeToAnnounce ( _) => ( !generated_by_local, "AwaitingRemoteRevokeToAnnounce" ) ,
906
927
InboundHTLCState :: AwaitingAnnouncedRemoteRevoke ( _) => ( true , "AwaitingAnnouncedRemoteRevoke" ) ,
907
928
InboundHTLCState :: Committed => ( true , "Committed" ) ,
908
- InboundHTLCState :: LocalRemoved ( _) => ( !generated_by_local, "LocalRemoved" ) ,
929
+ InboundHTLCState :: LocalRemoved ( _) => {
930
+ #[ cfg( test) ]
931
+ {
932
+ // Remote commitment transactions generated by us won't include our locally removed
933
+ // HTLCs, even though we include them when deciding whether to accept/send new HTLCs and
934
+ // setting these cached values. Therefore, set these values to None here so we don't
935
+ // assert that the transaction generated in this function has the same fee as the cached
936
+ // fee. Similar reasoning applies to LocalAnnounced and RemoveRemoved HTLCs below.
937
+ if !local && generated_by_local {
938
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
939
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
940
+ }
941
+ }
942
+ ( !generated_by_local, "LocalRemoved" )
943
+ } ,
909
944
} ;
910
945
911
946
if include {
@@ -928,9 +963,27 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
928
963
929
964
for ref htlc in self . pending_outbound_htlcs . iter ( ) {
930
965
let ( include, state_name) = match htlc. state {
931
- OutboundHTLCState :: LocalAnnounced ( _) => ( generated_by_local, "LocalAnnounced" ) ,
966
+ OutboundHTLCState :: LocalAnnounced ( _) => {
967
+ #[ cfg( test) ]
968
+ {
969
+ if local && !generated_by_local {
970
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
971
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
972
+ }
973
+ }
974
+ ( generated_by_local, "LocalAnnounced" )
975
+ } ,
932
976
OutboundHTLCState :: Committed => ( true , "Committed" ) ,
933
- OutboundHTLCState :: RemoteRemoved ( _) => ( generated_by_local, "RemoteRemoved" ) ,
977
+ OutboundHTLCState :: RemoteRemoved ( _) => {
978
+ #[ cfg( test) ]
979
+ {
980
+ if local && !generated_by_local {
981
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
982
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
983
+ }
984
+ }
985
+ ( generated_by_local, "RemoteRemoved" )
986
+ } ,
934
987
OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( _) => ( generated_by_local, "AwaitingRemoteRevokeToRemove" ) ,
935
988
OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( _) => ( false , "AwaitingRemovedRemoteRevoke" ) ,
936
989
} ;
@@ -1780,7 +1833,18 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1780
1833
}
1781
1834
}
1782
1835
1783
- self . commit_tx_fee_msat ( included_htlcs + addl_htlcs)
1836
+ let num_htlcs = included_htlcs + addl_htlcs;
1837
+ let res = self . commit_tx_fee_msat ( num_htlcs) ;
1838
+ #[ cfg( test) ]
1839
+ {
1840
+ if fee_spike_buffer_htlc. is_none ( ) {
1841
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( res) ;
1842
+ } else {
1843
+ let fee = self . commit_tx_fee_msat ( num_htlcs - 1 ) ;
1844
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( fee) ;
1845
+ }
1846
+ }
1847
+ res
1784
1848
}
1785
1849
1786
1850
// Get the commitment tx fee for the remote's next commitment transaction based on the number of
@@ -1825,10 +1889,38 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
1825
1889
}
1826
1890
}
1827
1891
1828
- self . commit_tx_fee_msat ( included_htlcs + addl_htlcs)
1892
+ let num_htlcs = included_htlcs + addl_htlcs;
1893
+ let res = self . commit_tx_fee_msat ( num_htlcs) ;
1894
+ #[ cfg( test) ]
1895
+ {
1896
+ if fee_spike_buffer_htlc. is_none ( ) {
1897
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( res) ;
1898
+ } else {
1899
+ let fee = self . commit_tx_fee_msat ( num_htlcs - 1 ) ;
1900
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( fee) ;
1901
+ }
1902
+ }
1903
+ res
1904
+ }
1905
+
1906
+
1907
+ 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 >
1908
+ where F : for < ' a > Fn ( & ' a Self , PendingHTLCStatus , u16 ) -> PendingHTLCStatus , L :: Target : Logger {
1909
+ match self . update_add_htlc_internal ( msg, pending_forward_status, create_pending_htlc_status, logger) {
1910
+ Ok ( ( ) ) => return Ok ( ( ) ) ,
1911
+ Err ( e) => {
1912
+ #[ cfg( test) ]
1913
+ {
1914
+ // If we errored, one of these fields still might've been set, so re-set them to None.
1915
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
1916
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
1917
+ }
1918
+ return Err ( e) ;
1919
+ } ,
1920
+ }
1829
1921
}
1830
1922
1831
- 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 >
1923
+ 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 >
1832
1924
where F : for < ' a > Fn ( & ' a Self , PendingHTLCStatus , u16 ) -> PendingHTLCStatus , L :: Target : Logger {
1833
1925
// We can't accept HTLCs sent after we've sent a shutdown.
1834
1926
let local_sent_shutdown = ( self . channel_state & ( ChannelState :: ChannelFunded as u32 | ChannelState :: LocalShutdownSent as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) ;
@@ -2054,16 +2146,25 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
2054
2146
return Err ( ( None , ChannelError :: Close ( "Invalid commitment tx signature from peer" . to_owned ( ) ) ) ) ;
2055
2147
}
2056
2148
2149
+ let num_htlcs = commitment_tx. 1 ;
2150
+ let total_fee = feerate_per_kw as u64 * ( COMMITMENT_TX_BASE_WEIGHT + ( num_htlcs as u64 ) * COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ;
2057
2151
//If channel fee was updated by funder confirm funder can afford the new fee rate when applied to the current local commitment transaction
2058
2152
if update_fee {
2059
- let num_htlcs = commitment_tx. 1 ;
2060
- let total_fee = feerate_per_kw as u64 * ( COMMITMENT_TX_BASE_WEIGHT + ( num_htlcs as u64 ) * COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ;
2061
-
2062
2153
let counterparty_reserve_we_require = Channel :: < ChanSigner > :: get_holder_selected_channel_reserve_satoshis ( self . channel_value_satoshis ) ;
2063
2154
if self . channel_value_satoshis - self . value_to_self_msat / 1000 < total_fee + counterparty_reserve_we_require {
2064
2155
return Err ( ( None , ChannelError :: Close ( "Funding remote cannot afford proposed new fee" . to_owned ( ) ) ) ) ;
2065
2156
}
2066
2157
}
2158
+ #[ cfg( test) ]
2159
+ {
2160
+ let projected_fee = match self . channel_outbound {
2161
+ true => self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) . take ( ) ,
2162
+ false => self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) . take ( )
2163
+ } ;
2164
+ if let Some ( fee) = projected_fee {
2165
+ assert_eq ! ( total_fee, fee / 1000 ) ;
2166
+ }
2167
+ }
2067
2168
2068
2169
if msg. htlc_signatures . len ( ) != commitment_tx. 1 {
2069
2170
return Err ( ( None , ChannelError :: Close ( format ! ( "Got wrong number of HTLC signatures ({}) from remote. It must be {}" , msg. htlc_signatures. len( ) , commitment_tx. 1 ) ) ) ) ;
@@ -3744,6 +3845,28 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
3744
3845
/// You MUST call send_commitment prior to any other calls on this Channel
3745
3846
/// If an Err is returned, it's a ChannelError::Ignore!
3746
3847
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 > {
3848
+ match self . send_htlc_internal ( amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet) {
3849
+ Ok ( res) => return Ok ( res) ,
3850
+ Err ( e) => {
3851
+ #[ cfg( test) ]
3852
+ {
3853
+ // If we errored, one of these fields still might've been set, so re-set them to None.
3854
+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
3855
+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
3856
+ }
3857
+ return Err ( e) ;
3858
+ }
3859
+ }
3860
+ }
3861
+
3862
+ /// Adds a pending outbound HTLC to this channel, note that you probably want
3863
+ /// send_htlc_and_commit instead cause you'll want both messages at once.
3864
+ /// This returns an option instead of a pure UpdateAddHTLC as we may be in a state where we are
3865
+ /// waiting on the remote peer to send us a revoke_and_ack during which time we cannot add new
3866
+ /// HTLCs on the wire or we wouldn't be able to determine what they actually ACK'ed.
3867
+ /// You MUST call send_commitment prior to any other calls on this Channel
3868
+ /// If an Err is returned, it's a ChannelError::Ignore!
3869
+ 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 > {
3747
3870
if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK ) ) != ( ChannelState :: ChannelFunded as u32 ) {
3748
3871
return Err ( ChannelError :: Ignore ( "Cannot send HTLC until channel is fully established and we haven't started shutting down" . to_owned ( ) ) ) ;
3749
3872
}
@@ -3938,6 +4061,18 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
3938
4061
let counterparty_commitment_tx = self . build_commitment_transaction ( self . cur_counterparty_commitment_transaction_number , & counterparty_keys, false , true , feerate_per_kw, logger) ;
3939
4062
let ( signature, htlc_signatures) ;
3940
4063
4064
+ #[ cfg( test) ]
4065
+ {
4066
+ let projected_fee = match self . channel_outbound {
4067
+ true => self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) . take ( ) ,
4068
+ false => self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) . take ( )
4069
+ } ;
4070
+ if let Some ( fee) = projected_fee {
4071
+ let actual_fee = self . commit_tx_fee_msat ( counterparty_commitment_tx. 1 ) ;
4072
+ assert_eq ! ( actual_fee, fee) ;
4073
+ }
4074
+ }
4075
+
3941
4076
{
3942
4077
let mut htlcs = Vec :: with_capacity ( counterparty_commitment_tx. 2 . len ( ) ) ;
3943
4078
for & ( ref htlc, _) in counterparty_commitment_tx. 2 . iter ( ) {
@@ -4524,6 +4659,11 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
4524
4659
commitment_secrets,
4525
4660
4526
4661
network_sync : UpdateStatus :: Fresh ,
4662
+
4663
+ #[ cfg( test) ]
4664
+ next_local_commitment_tx_fee_cached : Mutex :: new ( None ) ,
4665
+ #[ cfg( test) ]
4666
+ next_remote_commitment_tx_fee_cached : Mutex :: new ( None ) ,
4527
4667
} )
4528
4668
}
4529
4669
}
0 commit comments