@@ -42,6 +42,8 @@ use std;
4242use std:: default:: Default ;
4343use std:: { cmp, mem, fmt} ;
4444use std:: ops:: Deref ;
45+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
46+ use std:: sync:: Mutex ;
4547use bitcoin:: hashes:: hex:: ToHex ;
4648
4749#[ cfg( test) ]
@@ -386,6 +388,15 @@ pub(super) struct Channel<ChanSigner: ChannelKeys> {
386388 commitment_secrets : CounterpartyCommitmentSecrets ,
387389
388390 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 > > ,
389400}
390401
391402pub const OUR_MAX_HTLCS : u16 = 50 ; //TODO
@@ -557,6 +568,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
557568 commitment_secrets : CounterpartyCommitmentSecrets :: new ( ) ,
558569
559570 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 ) ,
560576 } )
561577 }
562578
@@ -790,6 +806,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
790806 commitment_secrets : CounterpartyCommitmentSecrets :: new ( ) ,
791807
792808 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 ) ,
793814 } ;
794815
795816 Ok ( chan)
@@ -867,7 +888,21 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
867888 InboundHTLCState :: AwaitingRemoteRevokeToAnnounce ( _) => ( !generated_by_local, "AwaitingRemoteRevokeToAnnounce" ) ,
868889 InboundHTLCState :: AwaitingAnnouncedRemoteRevoke ( _) => ( true , "AwaitingAnnouncedRemoteRevoke" ) ,
869890 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+ } ,
871906 } ;
872907
873908 if include {
@@ -890,9 +925,27 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
890925
891926 for ref htlc in self . pending_outbound_htlcs . iter ( ) {
892927 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+ } ,
894938 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+ } ,
896949 OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( _) => ( generated_by_local, "AwaitingRemoteRevokeToRemove" ) ,
897950 OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( _) => ( false , "AwaitingRemovedRemoteRevoke" ) ,
898951 } ;
@@ -1261,6 +1314,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
12611314 }
12621315 assert_eq ! ( self . channel_state & ChannelState :: ShutdownComplete as u32 , 0 ) ;
12631316
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+
12641323 // ChannelManager may generate duplicate claims/fails due to HTLC update events from
12651324 // on-chain ChannelsMonitors during block rescan. Ideally we'd figure out a way to drop
12661325 // these, but for now we just have to treat them as normal.
@@ -1312,6 +1371,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
13121371 return Ok ( None ) ;
13131372 }
13141373
1374+
13151375 {
13161376 let htlc = & mut self . pending_inbound_htlcs [ pending_idx] ;
13171377 htlc. state = InboundHTLCState :: LocalRemoved ( InboundHTLCRemovalReason :: FailRelay ( err_packet. clone ( ) ) ) ;
@@ -1740,7 +1800,18 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
17401800 }
17411801 }
17421802
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
17441815 }
17451816
17461817 // Get the commitment tx fee for the remote's next commitment transaction based on the number of
@@ -1785,10 +1856,38 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
17851856 }
17861857 }
17871858
1788- self . commit_tx_fee_msat ( included_htlcs + addl_htlcs)
1859+ let num_htlcs = included_htlcs + addl_htlcs;
1860+ let res = self . commit_tx_fee_msat ( num_htlcs) ;
1861+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
1862+ {
1863+ if fee_spike_buffer_htlc. is_none ( ) {
1864+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( res) ;
1865+ } else {
1866+ let fee = self . commit_tx_fee_msat ( num_htlcs - 1 ) ;
1867+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = Some ( fee) ;
1868+ }
1869+ }
1870+ res
1871+ }
1872+
1873+
1874+ 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 >
1875+ where F : for < ' a > Fn ( & ' a Self , PendingHTLCStatus , u16 ) -> PendingHTLCStatus , L :: Target : Logger {
1876+ match self . update_add_htlc_internal ( msg, pending_forward_status, create_pending_htlc_status, logger) {
1877+ Ok ( ( ) ) => return Ok ( ( ) ) ,
1878+ Err ( e) => {
1879+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
1880+ {
1881+ // If we errored, one of these fields still might've been set, so re-set them to None.
1882+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
1883+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
1884+ }
1885+ return Err ( e) ;
1886+ } ,
1887+ }
17891888 }
17901889
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 >
1890+ 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 >
17921891 where F : for < ' a > Fn ( & ' a Self , PendingHTLCStatus , u16 ) -> PendingHTLCStatus , L :: Target : Logger {
17931892 // We can't accept HTLCs sent after we've sent a shutdown.
17941893 let local_sent_shutdown = ( self . channel_state & ( ChannelState :: ChannelFunded as u32 | ChannelState :: LocalShutdownSent as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) ;
@@ -2019,15 +2118,23 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
20192118 ( commitment_tx. 1 , htlcs_cloned, commitment_tx. 0 , commitment_txid)
20202119 } ;
20212120
2121+ let total_fee = feerate_per_kw as u64 * ( COMMITMENT_TX_BASE_WEIGHT + ( num_htlcs as u64 ) * COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ;
20222122 //If channel fee was updated by funder confirm funder can afford the new fee rate when applied to the current local commitment transaction
20232123 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-
20262124 let counterparty_reserve_we_require = Channel :: < ChanSigner > :: get_holder_selected_channel_reserve_satoshis ( self . channel_value_satoshis ) ;
20272125 if self . channel_value_satoshis - self . value_to_self_msat / 1000 < total_fee + counterparty_reserve_we_require {
20282126 return Err ( ( None , ChannelError :: Close ( "Funding remote cannot afford proposed new fee" . to_owned ( ) ) ) ) ;
20292127 }
20302128 }
2129+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
2130+ {
2131+ if self . is_outbound ( ) {
2132+ let projected_fee = self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) . take ( ) ;
2133+ if let Some ( fee) = projected_fee {
2134+ assert_eq ! ( total_fee, fee / 1000 ) ;
2135+ }
2136+ }
2137+ }
20312138
20322139 if msg. htlc_signatures . len ( ) != num_htlcs {
20332140 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 +2383,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
22762383 return Err ( ChannelError :: Close ( "Peer sent revoke_and_ack after we'd started exchanging closing_signeds" . to_owned ( ) ) ) ;
22772384 }
22782385
2386+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
2387+ {
2388+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
2389+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
2390+ }
2391+
22792392 if let Some ( counterparty_prev_commitment_point) = self . counterparty_prev_commitment_point {
22802393 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 {
22812394 return Err ( ChannelError :: Close ( "Got a revoke commitment secret which didn't correspond to their current pubkey" . to_owned ( ) ) ) ;
@@ -2757,6 +2870,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
27572870 return Err ( ChannelError :: Close ( "Peer sent a loose channel_reestablish not after reconnect" . to_owned ( ) ) ) ;
27582871 }
27592872
2873+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
2874+ {
2875+ * self . next_local_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
2876+ * self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) = None ;
2877+ }
2878+
27602879 if msg. next_local_commitment_number >= INITIAL_COMMITMENT_NUMBER || msg. next_remote_commitment_number >= INITIAL_COMMITMENT_NUMBER ||
27612880 msg. next_local_commitment_number == 0 {
27622881 return Err ( ChannelError :: Close ( "Peer sent a garbage channel_reestablish" . to_owned ( ) ) ) ;
@@ -3726,6 +3845,28 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
37263845 /// You MUST call send_commitment prior to any other calls on this Channel
37273846 /// If an Err is returned, it's a ChannelError::Ignore!
37283847 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( any( test, feature = "fuzztarget" ) ) ]
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 > {
37293870 if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK ) ) != ( ChannelState :: ChannelFunded as u32 ) {
37303871 return Err ( ChannelError :: Ignore ( "Cannot send HTLC until channel is fully established and we haven't started shutting down" . to_owned ( ) ) ) ;
37313872 }
@@ -3921,6 +4062,17 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
39214062 let counterparty_commitment_txid = counterparty_commitment_tx. 0 . trust ( ) . txid ( ) ;
39224063 let ( signature, htlc_signatures) ;
39234064
4065+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
4066+ {
4067+ if !self . is_outbound ( ) {
4068+ let projected_fee = self . next_remote_commitment_tx_fee_cached . lock ( ) . unwrap ( ) . take ( ) ;
4069+ if let Some ( fee) = projected_fee {
4070+ let actual_fee = self . commit_tx_fee_msat ( counterparty_commitment_tx. 1 ) ;
4071+ assert_eq ! ( actual_fee, fee) ;
4072+ }
4073+ }
4074+ }
4075+
39244076 {
39254077 let mut htlcs = Vec :: with_capacity ( counterparty_commitment_tx. 2 . len ( ) ) ;
39264078 for & ( ref htlc, _) in counterparty_commitment_tx. 2 . iter ( ) {
@@ -4511,6 +4663,11 @@ impl<'a, ChanSigner: ChannelKeys, K: Deref> ReadableArgs<&'a K> for Channel<Chan
45114663 commitment_secrets,
45124664
45134665 network_sync : UpdateStatus :: Fresh ,
4666+
4667+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
4668+ next_local_commitment_tx_fee_cached : Mutex :: new ( None ) ,
4669+ #[ cfg( any( test, feature = "fuzztarget" ) ) ]
4670+ next_remote_commitment_tx_fee_cached : Mutex :: new ( None ) ,
45144671 } )
45154672 }
45164673}
0 commit comments