@@ -295,6 +295,7 @@ struct HTLCStats {
295295 on_holder_tx_dust_exposure_msat : u64 ,
296296 holding_cell_msat : u64 ,
297297 on_holder_tx_holding_cell_htlcs_count : u32 , // dust HTLCs *non*-included
298+ on_holder_tx_included_htlcs : u32 ,
298299}
299300
300301/// An enum gathering stats on commitment transaction, either local or remote.
@@ -413,6 +414,12 @@ pub(crate) const CONCURRENT_INBOUND_HTLC_FEE_BUFFER: u32 = 2;
413414/// transaction (not counting the value of the HTLCs themselves).
414415pub ( crate ) const MIN_AFFORDABLE_HTLC_COUNT : usize = 4 ;
415416
417+ /// If after this value tick periods, the channel feerate isn't satisfying, we auto-close the
418+ /// channel and goes on-chain to avoid unsafe situations where a commitment transaction with
419+ /// time-sensitive outputs won't confirm due to staling feerate too far away from the upper feerate
420+ /// groups of network mempools.
421+ const AUTOCLOSE_TIMEOUT : u16 = 60 ;
422+
416423// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
417424// has been completed, and then turn into a Channel to get compiler-time enforcement of things like
418425// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
@@ -435,6 +442,14 @@ pub(super) struct Channel<Signer: Sign> {
435442
436443 latest_monitor_update_id : u64 ,
437444
445+ // Auto-close timer, if the channel is outbound, we sent a `update_fee`, and we didn't
446+ // receive a RAA from counterparty committing this state after `AUTOCLOSE_TIMEOUT` periods,
447+ // this channel must be force-closed.
448+ // If the channel is inbound, it has been observed the channel feerate should increase,
449+ // and we didn't receive a RAA from counterparty committing an `update_fee` after
450+ // `AUTOCLOSE_TIMEOUT` periods, this channel must be force-closed.
451+ autoclose_timer : u16 ,
452+
438453 holder_signer : Signer ,
439454 shutdown_scriptpubkey : Option < ShutdownScript > ,
440455 destination_script : Script ,
@@ -747,6 +762,8 @@ impl<Signer: Sign> Channel<Signer> {
747762
748763 latest_monitor_update_id : 0 ,
749764
765+ autoclose_timer : 0 ,
766+
750767 holder_signer,
751768 shutdown_scriptpubkey,
752769 destination_script : keys_provider. get_destination_script ( ) ,
@@ -1037,6 +1054,8 @@ impl<Signer: Sign> Channel<Signer> {
10371054
10381055 latest_monitor_update_id : 0 ,
10391056
1057+ autoclose_timer : 0 ,
1058+
10401059 holder_signer,
10411060 shutdown_scriptpubkey,
10421061 destination_script : keys_provider. get_destination_script ( ) ,
@@ -2042,6 +2061,7 @@ impl<Signer: Sign> Channel<Signer> {
20422061 on_holder_tx_dust_exposure_msat : 0 ,
20432062 holding_cell_msat : 0 ,
20442063 on_holder_tx_holding_cell_htlcs_count : 0 ,
2064+ on_holder_tx_included_htlcs : 0 ,
20452065 } ;
20462066
20472067 let counterparty_dust_limit_timeout_sat = ( self . get_dust_buffer_feerate ( outbound_feerate_update) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
@@ -2053,6 +2073,8 @@ impl<Signer: Sign> Channel<Signer> {
20532073 }
20542074 if htlc. amount_msat / 1000 < holder_dust_limit_success_sat {
20552075 stats. on_holder_tx_dust_exposure_msat += htlc. amount_msat ;
2076+ } else {
2077+ stats. on_holder_tx_included_htlcs += 1 ;
20562078 }
20572079 }
20582080 stats
@@ -2067,6 +2089,7 @@ impl<Signer: Sign> Channel<Signer> {
20672089 on_holder_tx_dust_exposure_msat : 0 ,
20682090 holding_cell_msat : 0 ,
20692091 on_holder_tx_holding_cell_htlcs_count : 0 ,
2092+ on_holder_tx_included_htlcs : 0 ,
20702093 } ;
20712094
20722095 let counterparty_dust_limit_success_sat = ( self . get_dust_buffer_feerate ( outbound_feerate_update) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
@@ -2078,6 +2101,8 @@ impl<Signer: Sign> Channel<Signer> {
20782101 }
20792102 if htlc. amount_msat / 1000 < holder_dust_limit_timeout_sat {
20802103 stats. on_holder_tx_dust_exposure_msat += htlc. amount_msat ;
2104+ } else {
2105+ stats. on_holder_tx_included_htlcs += 1 ;
20812106 }
20822107 }
20832108
@@ -2832,13 +2857,33 @@ impl<Signer: Sign> Channel<Signer> {
28322857 }
28332858 }
28342859
2860+ /// Trigger the autoclose timer if it's in the starting position
2861+ pub fn maybe_trigger_autoclose_timer ( & mut self , current_feerate : u32 , new_feerate : u32 ) -> bool {
2862+
2863+ // Verify the new feerate is at least superior by 30% of current feerate before to
2864+ // start a autoclose timer and current feerate has fallen behind background feerate.
2865+ if new_feerate > current_feerate * 1300 / 1000 {
2866+ return false ;
2867+ }
2868+
2869+ // Start an auto-close timer, if the channel feerate doesn't increase before its
2870+ // expiration (i.e this outbound feerate update has been committed on both sides),
2871+ // the channel will be marked as unsafe and force-closed.
2872+ // If a timer is already pending, no-op, as a higher-feerate `update_fee` will
2873+ // implicitly override a lower-feerate `update_fee` part of the same update sequence.
2874+ if self . autoclose_timer == 0 {
2875+ self . autoclose_timer = 1 ;
2876+ return true ;
2877+ }
2878+ return false ;
2879+ }
2880+
28352881 /// Handles receiving a remote's revoke_and_ack. Note that we may return a new
28362882 /// commitment_signed message here in case we had pending outbound HTLCs to add which were
28372883 /// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail,
28382884 /// generating an appropriate error *after* the channel state has been updated based on the
28392885 /// revoke_and_ack message.
2840- pub fn revoke_and_ack < L : Deref > ( & mut self , msg : & msgs:: RevokeAndACK , logger : & L ) -> Result < RAAUpdates , ChannelError >
2841- where L :: Target : Logger ,
2886+ pub fn revoke_and_ack < L : Deref > ( & mut self , msg : & msgs:: RevokeAndACK , logger : & L ) -> Result < RAAUpdates , ChannelError > where L :: Target : Logger
28422887 {
28432888 if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) {
28442889 return Err ( ChannelError :: Close ( "Got revoke/ACK message when channel was not in an operational state" . to_owned ( ) ) ) ;
@@ -2999,6 +3044,7 @@ impl<Signer: Sign> Channel<Signer> {
29993044 log_trace ! ( logger, " ...promoting outbound fee update {} to Committed" , feerate) ;
30003045 self . feerate_per_kw = feerate;
30013046 self . pending_update_fee = None ;
3047+ self . autoclose_timer = 0 ;
30023048 } ,
30033049 FeeUpdateState :: RemoteAnnounced => { debug_assert ! ( !self . is_outbound( ) ) ; } ,
30043050 FeeUpdateState :: AwaitingRemoteRevokeToAnnounce => {
@@ -3007,6 +3053,7 @@ impl<Signer: Sign> Channel<Signer> {
30073053 require_commitment = true ;
30083054 self . feerate_per_kw = feerate;
30093055 self . pending_update_fee = None ;
3056+ self . autoclose_timer = 0 ;
30103057 } ,
30113058 }
30123059 }
@@ -3145,6 +3192,8 @@ impl<Signer: Sign> Channel<Signer> {
31453192 return None ;
31463193 }
31473194
3195+ self . maybe_trigger_autoclose_timer ( self . get_feerate ( ) , feerate_per_kw) ;
3196+
31483197 debug_assert ! ( self . pending_update_fee. is_none( ) ) ;
31493198 self . pending_update_fee = Some ( ( feerate_per_kw, FeeUpdateState :: Outbound ) ) ;
31503199
@@ -3343,6 +3392,33 @@ impl<Signer: Sign> Channel<Signer> {
33433392 Ok ( ( ) )
33443393 }
33453394
3395+ /// If the auto-close timer is reached following the triggering of a auto-close condition
3396+ /// (i.e a non-satisfying feerate to ensure efficient confirmation), we force-close
3397+ /// channel, hopefully narrowing the safety risks for the user funds.
3398+ pub fn check_autoclose ( & mut self , new_feerate : u32 ) -> Result < ( ) , ChannelError > {
3399+ if self . autoclose_timer > 0 && self . autoclose_timer < AUTOCLOSE_TIMEOUT {
3400+ // Again, check at each autoclose tick that mempool feerate hasn't fall back
3401+ // more in-sync to the current channel feerate. Otherwise, reset autoclose
3402+ // timer from scratch.
3403+ if new_feerate < self . get_feerate ( ) * 1300 / 1000 {
3404+ self . autoclose_timer += 1 ;
3405+ } else {
3406+ self . autoclose_timer = 0 ;
3407+ }
3408+ }
3409+ if self . autoclose_timer == AUTOCLOSE_TIMEOUT {
3410+ let inbound_stats = self . get_inbound_pending_htlc_stats ( None ) ;
3411+ let outbound_stats = self . get_outbound_pending_htlc_stats ( None ) ;
3412+ // If the channel has pending *included* HTLCs to claim on-chain and `should_autoclose`=y, close the channel
3413+ if inbound_stats. on_holder_tx_included_htlcs + outbound_stats. on_holder_tx_included_htlcs > 0 && self . config . should_autoclose {
3414+ return Err ( ChannelError :: Close ( "Channel has time-sensitive outputs and the auto-close timer has been reached" . to_owned ( ) ) ) ;
3415+ }
3416+ // Otherwise, do not reset the autoclose timer as a substantial HTLC can be committed
3417+ // at anytime on the still low-feerate channel.
3418+ }
3419+ Ok ( ( ) )
3420+ }
3421+
33463422 fn get_last_revoke_and_ack ( & self ) -> msgs:: RevokeAndACK {
33473423 let next_per_commitment_point = self . holder_signer . get_per_commitment_point ( self . cur_holder_commitment_transaction_number , & self . secp_ctx ) ;
33483424 let per_commitment_secret = self . holder_signer . release_commitment_secret ( self . cur_holder_commitment_transaction_number + 2 ) ;
@@ -3419,7 +3495,8 @@ impl<Signer: Sign> Channel<Signer> {
34193495
34203496 /// May panic if some calls other than message-handling calls (which will all Err immediately)
34213497 /// have been called between remove_uncommitted_htlcs_and_mark_paused and this call.
3422- pub fn channel_reestablish < L : Deref > ( & mut self , msg : & msgs:: ChannelReestablish , logger : & L ) -> Result < ( Option < msgs:: FundingLocked > , Option < msgs:: RevokeAndACK > , Option < msgs:: CommitmentUpdate > , Option < ChannelMonitorUpdate > , RAACommitmentOrder , Vec < ( HTLCSource , PaymentHash ) > , Option < msgs:: Shutdown > ) , ChannelError > where L :: Target : Logger {
3498+ pub fn channel_reestablish < L : Deref > ( & mut self , msg : & msgs:: ChannelReestablish , logger : & L ) -> Result < ( Option < msgs:: FundingLocked > , Option < msgs:: RevokeAndACK > , Option < msgs:: CommitmentUpdate > , Option < ChannelMonitorUpdate > , RAACommitmentOrder , Vec < ( HTLCSource , PaymentHash ) > , Option < msgs:: Shutdown > ) , ChannelError > where L :: Target : Logger ,
3499+ {
34233500 if self . channel_state & ( ChannelState :: PeerDisconnected as u32 ) == 0 {
34243501 // While BOLT 2 doesn't indicate explicitly we should error this channel here, it
34253502 // almost certainly indicates we are going to end up out-of-sync in some way, so we
@@ -4865,6 +4942,7 @@ impl<Signer: Sign> Channel<Signer> {
48654942 log_trace ! ( logger, " ...promoting inbound AwaitingRemoteRevokeToAnnounce fee update {} to Committed" , feerate) ;
48664943 self . feerate_per_kw = feerate;
48674944 self . pending_update_fee = None ;
4945+ self . autoclose_timer = 0 ;
48684946 }
48694947 }
48704948 self . resend_order = RAACommitmentOrder :: RevokeAndACKFirst ;
@@ -5384,6 +5462,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
53845462 ( 9 , self . target_closing_feerate_sats_per_kw, option) ,
53855463 ( 11 , self . monitor_pending_finalized_fulfills, vec_type) ,
53865464 ( 13 , self . channel_creation_height, required) ,
5465+ ( 15 , self . autoclose_timer, required) ,
53875466 } ) ;
53885467
53895468 Ok ( ( ) )
@@ -5623,6 +5702,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
56235702 // only, so we default to that if none was written.
56245703 let mut channel_type = Some ( ChannelTypeFeatures :: only_static_remote_key ( ) ) ;
56255704 let mut channel_creation_height = Some ( serialized_height) ;
5705+ let mut autoclose_timer = 0 ;
56265706 read_tlv_fields ! ( reader, {
56275707 ( 0 , announcement_sigs, option) ,
56285708 ( 1 , minimum_depth, option) ,
@@ -5633,6 +5713,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
56335713 ( 9 , target_closing_feerate_sats_per_kw, option) ,
56345714 ( 11 , monitor_pending_finalized_fulfills, vec_type) ,
56355715 ( 13 , channel_creation_height, option) ,
5716+ ( 15 , autoclose_timer, required) ,
56365717 } ) ;
56375718
56385719 let chan_features = channel_type. as_ref ( ) . unwrap ( ) ;
@@ -5661,6 +5742,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
56615742
56625743 latest_monitor_update_id,
56635744
5745+ autoclose_timer,
5746+
56645747 holder_signer,
56655748 shutdown_scriptpubkey,
56665749 destination_script,
0 commit comments