@@ -1904,16 +1904,16 @@ impl<Signer: Sign> Channel<Signer> {
1904
1904
}
1905
1905
1906
1906
/// Returns a HTLCStats about inbound pending htlcs
1907
- fn get_inbound_pending_htlc_stats ( & self ) -> HTLCStats {
1907
+ fn get_inbound_pending_htlc_stats ( & self , outbound_feerate_update : Option < u32 > ) -> HTLCStats {
1908
1908
let mut stats = HTLCStats {
1909
1909
pending_htlcs : self . pending_inbound_htlcs . len ( ) as u32 ,
1910
1910
pending_htlcs_value_msat : 0 ,
1911
1911
on_counterparty_tx_dust_exposure_msat : 0 ,
1912
1912
on_holder_tx_dust_exposure_msat : 0 ,
1913
1913
} ;
1914
1914
1915
- let counterparty_dust_limit_timeout_sat = ( self . get_dust_buffer_feerate ( ) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
1916
- let holder_dust_limit_success_sat = ( self . get_dust_buffer_feerate ( ) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
1915
+ 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 ;
1916
+ let holder_dust_limit_success_sat = ( self . get_dust_buffer_feerate ( outbound_feerate_update ) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
1917
1917
for ref htlc in self . pending_inbound_htlcs . iter ( ) {
1918
1918
stats. pending_htlcs_value_msat += htlc. amount_msat ;
1919
1919
if htlc. amount_msat / 1000 < counterparty_dust_limit_timeout_sat {
@@ -1927,16 +1927,16 @@ impl<Signer: Sign> Channel<Signer> {
1927
1927
}
1928
1928
1929
1929
/// Returns a HTLCStats about pending outbound htlcs, *including* pending adds in our holding cell.
1930
- fn get_outbound_pending_htlc_stats ( & self ) -> HTLCStats {
1930
+ fn get_outbound_pending_htlc_stats ( & self , outbound_feerate_update : Option < u32 > ) -> HTLCStats {
1931
1931
let mut stats = HTLCStats {
1932
1932
pending_htlcs : self . pending_outbound_htlcs . len ( ) as u32 ,
1933
1933
pending_htlcs_value_msat : 0 ,
1934
1934
on_counterparty_tx_dust_exposure_msat : 0 ,
1935
1935
on_holder_tx_dust_exposure_msat : 0 ,
1936
1936
} ;
1937
1937
1938
- let counterparty_dust_limit_success_sat = ( self . get_dust_buffer_feerate ( ) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
1939
- let holder_dust_limit_timeout_sat = ( self . get_dust_buffer_feerate ( ) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
1938
+ 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 ;
1939
+ let holder_dust_limit_timeout_sat = ( self . get_dust_buffer_feerate ( outbound_feerate_update ) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
1940
1940
for ref htlc in self . pending_outbound_htlcs . iter ( ) {
1941
1941
stats. pending_htlcs_value_msat += htlc. amount_msat ;
1942
1942
if htlc. amount_msat / 1000 < counterparty_dust_limit_success_sat {
@@ -1971,11 +1971,11 @@ impl<Signer: Sign> Channel<Signer> {
1971
1971
(
1972
1972
cmp:: max ( self . channel_value_satoshis as i64 * 1000
1973
1973
- self . value_to_self_msat as i64
1974
- - self . get_inbound_pending_htlc_stats ( ) . pending_htlcs_value_msat as i64
1974
+ - self . get_inbound_pending_htlc_stats ( None ) . pending_htlcs_value_msat as i64
1975
1975
- Self :: get_holder_selected_channel_reserve_satoshis ( self . channel_value_satoshis ) as i64 * 1000 ,
1976
1976
0 ) as u64 ,
1977
1977
cmp:: max ( self . value_to_self_msat as i64
1978
- - self . get_outbound_pending_htlc_stats ( ) . pending_htlcs_value_msat as i64
1978
+ - self . get_outbound_pending_htlc_stats ( None ) . pending_htlcs_value_msat as i64
1979
1979
- self . counterparty_selected_channel_reserve_satoshis . unwrap_or ( 0 ) as i64 * 1000 ,
1980
1980
0 ) as u64
1981
1981
)
@@ -2187,8 +2187,8 @@ impl<Signer: Sign> Channel<Signer> {
2187
2187
return Err ( ChannelError :: Close ( format ! ( "Remote side tried to send less than our minimum HTLC value. Lower limit: ({}). Actual: ({})" , self . holder_htlc_minimum_msat, msg. amount_msat) ) ) ;
2188
2188
}
2189
2189
2190
- let inbound_stats = self . get_inbound_pending_htlc_stats ( ) ;
2191
- let outbound_stats = self . get_outbound_pending_htlc_stats ( ) ;
2190
+ let inbound_stats = self . get_inbound_pending_htlc_stats ( None ) ;
2191
+ let outbound_stats = self . get_outbound_pending_htlc_stats ( None ) ;
2192
2192
if inbound_stats. pending_htlcs + 1 > OUR_MAX_HTLCS as u32 {
2193
2193
return Err ( ChannelError :: Close ( format ! ( "Remote tried to push more than our max accepted HTLCs ({})" , OUR_MAX_HTLCS ) ) ) ;
2194
2194
}
@@ -2217,7 +2217,7 @@ impl<Signer: Sign> Channel<Signer> {
2217
2217
}
2218
2218
}
2219
2219
2220
- let exposure_dust_limit_timeout_sats = ( self . get_dust_buffer_feerate ( ) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
2220
+ let exposure_dust_limit_timeout_sats = ( self . get_dust_buffer_feerate ( None ) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
2221
2221
if msg. amount_msat / 1000 < exposure_dust_limit_timeout_sats {
2222
2222
let on_counterparty_tx_dust_htlc_exposure_msat = inbound_stats. on_counterparty_tx_dust_exposure_msat + outbound_stats. on_counterparty_tx_dust_exposure_msat + msg. amount_msat ;
2223
2223
if on_counterparty_tx_dust_htlc_exposure_msat > self . get_max_dust_htlc_exposure_msat ( ) {
@@ -2227,7 +2227,7 @@ impl<Signer: Sign> Channel<Signer> {
2227
2227
}
2228
2228
}
2229
2229
2230
- let exposure_dust_limit_success_sats = ( self . get_dust_buffer_feerate ( ) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
2230
+ let exposure_dust_limit_success_sats = ( self . get_dust_buffer_feerate ( None ) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
2231
2231
if msg. amount_msat / 1000 < exposure_dust_limit_success_sats {
2232
2232
let on_holder_tx_dust_htlc_exposure_msat = inbound_stats. on_holder_tx_dust_exposure_msat + outbound_stats. on_holder_tx_dust_exposure_msat + msg. amount_msat ;
2233
2233
if on_holder_tx_dust_htlc_exposure_msat > self . get_max_dust_htlc_exposure_msat ( ) {
@@ -2963,6 +2963,20 @@ impl<Signer: Sign> Channel<Signer> {
2963
2963
}
2964
2964
}
2965
2965
2966
+ if feerate_per_kw > self . get_dust_buffer_feerate ( None ) {
2967
+ // Note, we evaluate pending htlc "preemptive" trimmed-to-dust threshold at the proposed `feerate_per_kw`.
2968
+ let inbound_stats = self . get_inbound_pending_htlc_stats ( Some ( feerate_per_kw) ) ;
2969
+ let outbound_stats = self . get_outbound_pending_htlc_stats ( Some ( feerate_per_kw) ) ;
2970
+ let holder_tx_dust_exposure = inbound_stats. on_holder_tx_dust_exposure_msat + outbound_stats. on_holder_tx_dust_exposure_msat ;
2971
+ let counterparty_tx_dust_exposure = inbound_stats. on_counterparty_tx_dust_exposure_msat + outbound_stats. on_counterparty_tx_dust_exposure_msat ;
2972
+ if holder_tx_dust_exposure > self . get_max_dust_htlc_exposure_msat ( ) {
2973
+ return None ;
2974
+ }
2975
+ if counterparty_tx_dust_exposure > self . get_max_dust_htlc_exposure_msat ( ) {
2976
+ return None ;
2977
+ }
2978
+ }
2979
+
2966
2980
if ( self . channel_state & ( ChannelState :: AwaitingRemoteRevoke as u32 | ChannelState :: MonitorUpdateFailed as u32 ) ) != 0 {
2967
2981
self . holding_cell_update_fee = Some ( feerate_per_kw) ;
2968
2982
return None ;
@@ -3130,16 +3144,16 @@ impl<Signer: Sign> Channel<Signer> {
3130
3144
return Err ( ChannelError :: Close ( "Peer sent update_fee when we needed a channel_reestablish" . to_owned ( ) ) ) ;
3131
3145
}
3132
3146
Channel :: < Signer > :: check_remote_fee ( fee_estimator, msg. feerate_per_kw ) ?;
3133
- let feerate_over_dust_buffer = msg. feerate_per_kw > self . get_dust_buffer_feerate ( ) ;
3147
+ let feerate_over_dust_buffer = msg. feerate_per_kw > self . get_dust_buffer_feerate ( None ) ;
3134
3148
3135
3149
self . pending_update_fee = Some ( ( msg. feerate_per_kw , FeeUpdateState :: RemoteAnnounced ) ) ;
3136
3150
self . update_time_counter += 1 ;
3137
3151
// If the feerate has increased over the previous dust buffer (note that
3138
3152
// `get_dust_buffer_feerate` considers the `pending_update_fee` status), check that we
3139
3153
// won't be pushed over our dust exposure limit by the feerate increase.
3140
3154
if feerate_over_dust_buffer {
3141
- let inbound_stats = self . get_inbound_pending_htlc_stats ( ) ;
3142
- let outbound_stats = self . get_outbound_pending_htlc_stats ( ) ;
3155
+ let inbound_stats = self . get_inbound_pending_htlc_stats ( None ) ;
3156
+ let outbound_stats = self . get_outbound_pending_htlc_stats ( None ) ;
3143
3157
let holder_tx_dust_exposure = inbound_stats. on_holder_tx_dust_exposure_msat + outbound_stats. on_holder_tx_dust_exposure_msat ;
3144
3158
let counterparty_tx_dust_exposure = inbound_stats. on_counterparty_tx_dust_exposure_msat + outbound_stats. on_counterparty_tx_dust_exposure_msat ;
3145
3159
if holder_tx_dust_exposure > self . get_max_dust_htlc_exposure_msat ( ) {
@@ -3840,7 +3854,7 @@ impl<Signer: Sign> Channel<Signer> {
3840
3854
self . feerate_per_kw
3841
3855
}
3842
3856
3843
- pub fn get_dust_buffer_feerate ( & self ) -> u32 {
3857
+ pub fn get_dust_buffer_feerate ( & self , outbound_feerate_update : Option < u32 > ) -> u32 {
3844
3858
// When calculating our exposure to dust HTLCs, we assume that the channel feerate
3845
3859
// may, at any point, increase by at least 10 sat/vB (i.e 2530 sat/kWU) or 25%,
3846
3860
// whichever is higher. This ensures that we aren't suddenly exposed to significantly
@@ -3852,6 +3866,9 @@ impl<Signer: Sign> Channel<Signer> {
3852
3866
if let Some ( ( feerate, _) ) = self . pending_update_fee {
3853
3867
feerate_per_kw = cmp:: max ( feerate_per_kw, feerate) ;
3854
3868
}
3869
+ if let Some ( feerate) = outbound_feerate_update {
3870
+ feerate_per_kw = cmp:: max ( feerate_per_kw, feerate) ;
3871
+ }
3855
3872
cmp:: max ( 2530 , feerate_per_kw * 1250 / 1000 )
3856
3873
}
3857
3874
@@ -4509,8 +4526,8 @@ impl<Signer: Sign> Channel<Signer> {
4509
4526
return Err ( ChannelError :: Ignore ( "Cannot send an HTLC while disconnected from channel counterparty" . to_owned ( ) ) ) ;
4510
4527
}
4511
4528
4512
- let inbound_stats = self . get_inbound_pending_htlc_stats ( ) ;
4513
- let outbound_stats = self . get_outbound_pending_htlc_stats ( ) ;
4529
+ let inbound_stats = self . get_inbound_pending_htlc_stats ( None ) ;
4530
+ let outbound_stats = self . get_outbound_pending_htlc_stats ( None ) ;
4514
4531
if outbound_stats. pending_htlcs + 1 > self . counterparty_max_accepted_htlcs as u32 {
4515
4532
return Err ( ChannelError :: Ignore ( format ! ( "Cannot push more than their max accepted HTLCs ({})" , self . counterparty_max_accepted_htlcs) ) ) ;
4516
4533
}
@@ -4530,7 +4547,7 @@ impl<Signer: Sign> Channel<Signer> {
4530
4547
}
4531
4548
}
4532
4549
4533
- let exposure_dust_limit_success_sats = ( self . get_dust_buffer_feerate ( ) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
4550
+ let exposure_dust_limit_success_sats = ( self . get_dust_buffer_feerate ( None ) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 ) + self . counterparty_dust_limit_satoshis ;
4534
4551
if amount_msat / 1000 < exposure_dust_limit_success_sats {
4535
4552
let on_counterparty_dust_htlc_exposure_msat = inbound_stats. on_counterparty_tx_dust_exposure_msat + outbound_stats. on_counterparty_tx_dust_exposure_msat + amount_msat;
4536
4553
if on_counterparty_dust_htlc_exposure_msat > self . get_max_dust_htlc_exposure_msat ( ) {
@@ -4539,7 +4556,7 @@ impl<Signer: Sign> Channel<Signer> {
4539
4556
}
4540
4557
}
4541
4558
4542
- let exposure_dust_limit_timeout_sats = ( self . get_dust_buffer_feerate ( ) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
4559
+ let exposure_dust_limit_timeout_sats = ( self . get_dust_buffer_feerate ( None ) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000 ) + self . holder_dust_limit_satoshis ;
4543
4560
if amount_msat / 1000 < exposure_dust_limit_timeout_sats {
4544
4561
let on_holder_dust_htlc_exposure_msat = inbound_stats. on_holder_tx_dust_exposure_msat + outbound_stats. on_holder_tx_dust_exposure_msat + amount_msat;
4545
4562
if on_holder_dust_htlc_exposure_msat > self . get_max_dust_htlc_exposure_msat ( ) {
0 commit comments