Skip to content

Commit 991f248

Browse files
committed
Improve prediction of commitment stats in can_send_send_update_fee
`ChannelContext::get_pending_htlc_stats` predicts that the set of HTLCs on the next commitment will be all the HTLCs in `ChannelContext.pending_inbound_htlcs`, and `ChannelContext.pending_outbound_htlcs`, as well as all the outbound HTLC adds in the holding cell. This is an overestimate: * Outbound HTLC removals which have been ACK'ed by the counterparty will certainly not be present in any *next* commitment, even though they remain in `pending_outbound_htlcs` (I refer to states `AwaitingRemoteRevokeToRemove` and `AwaitingRemovedRemoteRevoke`). * Outbound HTLCs in the `RemoteRemoved` state, will not be present in the next *local* commitment. * Inbound HTLCs in the `LocalRemoved` state will not be present in the next *remote* commitment. `ChannelContext::build_commitment_stats(funding, true, true, ..)` makes these errors when predicting the HTLC count on the remote commitment: * Inbound HTLCs in the state `RemoteAnnounced` are not included, but they will be in the next remote commitment transaction if the local ACK's the addition before producing the next remote commitment. * Inbound HTLCs in the state `AwaitingRemoteRevokeToAnnounce` are not included, even though the local has ACK'ed the addition. * Outbound HTLCs in the state `AwaitingRemoteRevokeToRemove` are counted, even though the local party has ACK'ed the removal. This commit replaces these functions in favor of the newly added `ChannelContext::get_next_{local, remote}_commitment_stats` methods, and fixes the issues described above. We now always calculate dust exposure using a buffer from `msg.feerate_per_kw`, and not from `max(feerate_per_kw, self.feerate_per_kw, self.pending_update_fee)`.
1 parent 797cf5b commit 991f248

File tree

1 file changed

+7
-15
lines changed

1 file changed

+7
-15
lines changed

lightning/src/ln/channel.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,8 +1112,6 @@ struct HTLCStats {
11121112
// htlc on the counterparty's commitment transaction.
11131113
extra_nondust_htlc_on_counterparty_tx_dust_exposure_msat: Option<u64>,
11141114
on_holder_tx_dust_exposure_msat: u64,
1115-
outbound_holding_cell_msat: u64,
1116-
on_holder_tx_outbound_holding_cell_htlcs_count: u32, // dust HTLCs *non*-included
11171115
}
11181116

11191117
/// A struct gathering data on a commitment, either local or remote.
@@ -4465,23 +4463,24 @@ where
44654463
let dust_exposure_limiting_feerate = self.get_dust_exposure_limiting_feerate(
44664464
&fee_estimator, funding.get_channel_type(),
44674465
);
4468-
let htlc_stats = self.get_pending_htlc_stats(funding, Some(feerate_per_kw), dust_exposure_limiting_feerate);
4469-
let stats = self.build_commitment_stats(funding, true, true, Some(feerate_per_kw), Some(htlc_stats.on_holder_tx_outbound_holding_cell_htlcs_count as usize + CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize));
4470-
let holder_balance_msat = stats.local_balance_before_fee_msat - htlc_stats.outbound_holding_cell_msat;
4466+
// Include outbound update_add_htlc's in the holding cell, and those which haven't yet been ACK'ed by the counterparty (ie. LocalAnnounced HTLCs)
4467+
let include_counterparty_unknown_htlcs = true;
4468+
let next_remote_commitment_stats = self.get_next_remote_commitment_stats(funding, None, include_counterparty_unknown_htlcs, CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize, feerate_per_kw, dust_exposure_limiting_feerate);
44714469
// Note that `stats.commit_tx_fee_sat` accounts for any HTLCs that transition from non-dust to dust under a higher feerate (in the case where HTLC-transactions pay endogenous fees).
4472-
if holder_balance_msat < stats.commit_tx_fee_sat * 1000 + funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 {
4470+
if next_remote_commitment_stats.holder_balance_msat.unwrap_or(0) < next_remote_commitment_stats.commit_tx_fee_sat * 1000 + funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 {
44734471
//TODO: auto-close after a number of failures?
44744472
log_debug!(logger, "Cannot afford to send new feerate at {}", feerate_per_kw);
44754473
return false;
44764474
}
44774475

44784476
// Note, we evaluate pending htlc "preemptive" trimmed-to-dust threshold at the proposed `feerate_per_kw`.
44794477
let max_dust_htlc_exposure_msat = self.get_max_dust_htlc_exposure_msat(dust_exposure_limiting_feerate);
4480-
if htlc_stats.on_holder_tx_dust_exposure_msat > max_dust_htlc_exposure_msat {
4478+
if next_remote_commitment_stats.dust_exposure_msat > max_dust_htlc_exposure_msat {
44814479
log_debug!(logger, "Cannot afford to send new feerate at {} without infringing max dust htlc exposure", feerate_per_kw);
44824480
return false;
44834481
}
4484-
if htlc_stats.on_counterparty_tx_dust_exposure_msat > max_dust_htlc_exposure_msat {
4482+
4483+
if next_remote_commitment_stats.dust_exposure_msat > max_dust_htlc_exposure_msat {
44854484
log_debug!(logger, "Cannot afford to send new feerate at {} without infringing max dust htlc exposure", feerate_per_kw);
44864485
return false;
44874486
}
@@ -4845,8 +4844,6 @@ where
48454844
}
48464845

48474846
let mut pending_outbound_htlcs_value_msat = 0;
4848-
let mut outbound_holding_cell_msat = 0;
4849-
let mut on_holder_tx_outbound_holding_cell_htlcs_count = 0;
48504847
let mut pending_outbound_htlcs = self.pending_outbound_htlcs.len();
48514848
{
48524849
let counterparty_dust_limit_success_sat = htlc_success_tx_fee_sat + context.counterparty_dust_limit_satoshis;
@@ -4867,16 +4864,13 @@ where
48674864
if let &HTLCUpdateAwaitingACK::AddHTLC { ref amount_msat, .. } = update {
48684865
pending_outbound_htlcs += 1;
48694866
pending_outbound_htlcs_value_msat += amount_msat;
4870-
outbound_holding_cell_msat += amount_msat;
48714867
if *amount_msat / 1000 < counterparty_dust_limit_success_sat {
48724868
on_counterparty_tx_dust_exposure_msat += amount_msat;
48734869
} else {
48744870
on_counterparty_tx_accepted_nondust_htlcs += 1;
48754871
}
48764872
if *amount_msat / 1000 < holder_dust_limit_timeout_sat {
48774873
on_holder_tx_dust_exposure_msat += amount_msat;
4878-
} else {
4879-
on_holder_tx_outbound_holding_cell_htlcs_count += 1;
48804874
}
48814875
}
48824876
}
@@ -4914,8 +4908,6 @@ where
49144908
on_counterparty_tx_dust_exposure_msat,
49154909
extra_nondust_htlc_on_counterparty_tx_dust_exposure_msat,
49164910
on_holder_tx_dust_exposure_msat,
4917-
outbound_holding_cell_msat,
4918-
on_holder_tx_outbound_holding_cell_htlcs_count,
49194911
}
49204912
}
49214913

0 commit comments

Comments
 (0)