@@ -355,6 +355,12 @@ pub const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2;
355
355
#[ cfg( not( fuzzing) ) ]
356
356
const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE : u64 = 2 ;
357
357
358
+ /// If after this value tick periods, the channel feerate isn't satisfying, we auto-close the
359
+ /// channel and goes on-chain to avoid unsafe situations where a commitment transaction with
360
+ /// time-sensitive outputs won't confirm due to staling feerate too far away from the upper feerate
361
+ /// groups of network mempools.
362
+ const AUTOCLOSE_TIMEOUT : u16 = 6 ;
363
+
358
364
// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
359
365
// has been completed, and then turn into a Channel to get compiler-time enforcement of things like
360
366
// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
@@ -377,6 +383,11 @@ pub(super) struct Channel<Signer: Sign> {
377
383
378
384
latest_monitor_update_id : u64 ,
379
385
386
+ // Auto-close timer, if the channel is outbound, we sent a `update_fee`, and we didn't
387
+ // receive a RAA from counterparty committing this state after `AUTOCLOSE_TIMEOUT` periods,
388
+ // this channel must be force-closed.
389
+ autoclose_timer : u16 ,
390
+
380
391
holder_signer : Signer ,
381
392
shutdown_scriptpubkey : Option < ShutdownScript > ,
382
393
destination_script : Script ,
@@ -668,6 +679,8 @@ impl<Signer: Sign> Channel<Signer> {
668
679
669
680
latest_monitor_update_id : 0 ,
670
681
682
+ autoclose_timer : 0 ,
683
+
671
684
holder_signer,
672
685
shutdown_scriptpubkey,
673
686
destination_script : keys_provider. get_destination_script ( ) ,
@@ -931,6 +944,8 @@ impl<Signer: Sign> Channel<Signer> {
931
944
932
945
latest_monitor_update_id : 0 ,
933
946
947
+ autoclose_timer : 0 ,
948
+
934
949
holder_signer,
935
950
shutdown_scriptpubkey,
936
951
destination_script : keys_provider. get_destination_script ( ) ,
@@ -2706,6 +2721,18 @@ impl<Signer: Sign> Channel<Signer> {
2706
2721
}
2707
2722
}
2708
2723
2724
+ /// Trigger the autoclose timer if it's in the starting position
2725
+ fn maybe_trigger_autoclose_timer ( & mut self ) {
2726
+ // Start an auto-close timer, if the channel feerate doesn't increase before its
2727
+ // expiration (i.e this outbound feerate update has been committed on both sides),
2728
+ // the channel will be marked as unsafe and force-closed.
2729
+ // If a timer is already pending, no-op, as a higher-feerate `update_fee` will
2730
+ // implicitly override a lower-feerate `update_fee` part of the same update sequence.
2731
+ if self . autoclose_timer == 0 {
2732
+ self . autoclose_timer = 1 ;
2733
+ }
2734
+ }
2735
+
2709
2736
/// Handles receiving a remote's revoke_and_ack. Note that we may return a new
2710
2737
/// commitment_signed message here in case we had pending outbound HTLCs to add which were
2711
2738
/// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail,
@@ -2871,6 +2898,7 @@ impl<Signer: Sign> Channel<Signer> {
2871
2898
log_trace ! ( logger, " ...promoting outbound fee update {} to Committed" , feerate) ;
2872
2899
self . feerate_per_kw = feerate;
2873
2900
self . pending_update_fee = None ;
2901
+ self . autoclose_timer = 0 ;
2874
2902
} ,
2875
2903
FeeUpdateState :: RemoteAnnounced => { debug_assert ! ( !self . is_outbound( ) ) ; } ,
2876
2904
FeeUpdateState :: AwaitingRemoteRevokeToAnnounce => {
@@ -2967,6 +2995,8 @@ impl<Signer: Sign> Channel<Signer> {
2967
2995
return None ;
2968
2996
}
2969
2997
2998
+ self . maybe_trigger_autoclose_timer ( ) ;
2999
+
2970
3000
debug_assert ! ( self . pending_update_fee. is_none( ) ) ;
2971
3001
self . pending_update_fee = Some ( ( feerate_per_kw, FeeUpdateState :: Outbound ) ) ;
2972
3002
@@ -3153,6 +3183,22 @@ impl<Signer: Sign> Channel<Signer> {
3153
3183
Ok ( ( ) )
3154
3184
}
3155
3185
3186
+ /// If the auto-close timer is reached following the triggering of a auto-close condition
3187
+ /// (i.e a non-satisfying feerate to ensure efficient confirmation), we force-close
3188
+ /// channel, hopefully narrowing the safety risks for the user funds.
3189
+ pub fn check_autoclose ( & mut self ) -> Result < ( ) , ChannelError > {
3190
+ if self . autoclose_timer > 0 && self . autoclose_timer < AUTOCLOSE_TIMEOUT {
3191
+ self . autoclose_timer += 1 ;
3192
+ }
3193
+ if self . autoclose_timer == AUTOCLOSE_TIMEOUT {
3194
+ // If the channel doesn't have pending HTLC outputs to claim on-chain
3195
+ if self . pending_inbound_htlcs . len ( ) + self . pending_outbound_htlcs . len ( ) > 0 {
3196
+ return Err ( ChannelError :: Close ( "Channel has time-sensitive outputs and the auto-close timer has been reached" . to_owned ( ) ) ) ;
3197
+ }
3198
+ }
3199
+ Ok ( ( ) )
3200
+ }
3201
+
3156
3202
fn get_last_revoke_and_ack ( & self ) -> msgs:: RevokeAndACK {
3157
3203
let next_per_commitment_point = self . holder_signer . get_per_commitment_point ( self . cur_holder_commitment_transaction_number , & self . secp_ctx ) ;
3158
3204
let per_commitment_secret = self . holder_signer . release_commitment_secret ( self . cur_holder_commitment_transaction_number + 2 ) ;
@@ -5176,6 +5222,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
5176
5222
( 5 , self . config, required) ,
5177
5223
( 7 , self . shutdown_scriptpubkey, option) ,
5178
5224
( 9 , self . target_closing_feerate_sats_per_kw, option) ,
5225
+ ( 11 , self . autoclose_timer, required) ,
5179
5226
} ) ;
5180
5227
5181
5228
Ok ( ( ) )
@@ -5409,13 +5456,15 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
5409
5456
5410
5457
let mut announcement_sigs = None ;
5411
5458
let mut target_closing_feerate_sats_per_kw = None ;
5459
+ let mut autoclose_timer = 0 ;
5412
5460
read_tlv_fields ! ( reader, {
5413
5461
( 0 , announcement_sigs, option) ,
5414
5462
( 1 , minimum_depth, option) ,
5415
5463
( 3 , counterparty_selected_channel_reserve_satoshis, option) ,
5416
5464
( 5 , config, option) , // Note that if none is provided we will *not* overwrite the existing one.
5417
5465
( 7 , shutdown_scriptpubkey, option) ,
5418
5466
( 9 , target_closing_feerate_sats_per_kw, option) ,
5467
+ ( 11 , autoclose_timer, required) ,
5419
5468
} ) ;
5420
5469
5421
5470
let mut secp_ctx = Secp256k1 :: new ( ) ;
@@ -5432,6 +5481,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
5432
5481
5433
5482
latest_monitor_update_id,
5434
5483
5484
+ autoclose_timer,
5485
+
5435
5486
holder_signer,
5436
5487
shutdown_scriptpubkey,
5437
5488
destination_script,
0 commit comments