You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Improve prediction of commitment stats in can_accept_incoming_htlc
`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`.
* Outbound HTLCs in the `RemoteRemoved` state, will not be present in
the next *local* commitment.
* Outbound HTLCs in the `LocalAnnounced` state have no guarantee that
they were yet received by the counterparty.
* Outbound `update_add_htlc`'s in the holding cell are certainly not
known by the counterparty, and we will reevaluate their addition to
the channel when freeing the holding cell.
* Inbound HTLCs in the `LocalRemoved` state will not be present in the
next *remote* commitment.
This commit stops using `get_pending_htlc_stats` in favor of the newly
added `ChannelContext::get_next_{local, remote}_commitment_stats`
methods, and fixes the issues described above.
The value of `remote_balance_before_fee_msat` remains *exactly*
the same.
`ChannelContext::next_remote_commit_tx_fee_msat` counts inbound HTLCs in
the `LocalRemoved` state, as well as outbound HTLCs in the
`LocalAnnounced` state. We now do not count them for the same reasons
described above.
Finally, we now always check holder dust exposure, whereas we previously
would only do it if the incoming HTLC was dust on our own commitment
transaction.
let htlc_stats = self.get_pending_htlc_stats(funding, None, dust_exposure_limiting_feerate);
4497
+
// The fee spike buffer (an additional nondust HTLC) we keep for the remote if the channel
4498
+
// is not zero fee. This deviates from the spec because the fee spike buffer requirement
4499
+
// doesn't exist on the receiver's side, only on the sender's. Note that with anchor
4500
+
// outputs we are no longer as sensitive to fee spikes, so we need to account for them.
4501
+
let fee_spike_buffer_htlc = if funding.get_channel_type().supports_anchor_zero_fee_commitments() {
4502
+
0
4503
+
} else {
4504
+
1
4505
+
};
4506
+
// Do not include outbound update_add_htlc's in the holding cell, or those which haven't yet been ACK'ed by the counterparty (ie. LocalAnnounced HTLCs)
4507
+
let do_not_include_counterparty_unknown_htlcs = false;
4508
+
// A `None` `HTLCCandidate` is used as in this case because we're already accounting for
4509
+
// the incoming HTLC as it has been fully committed by both sides.
4510
+
let next_local_commitment_stats = self.get_next_local_commitment_stats(funding, None, do_not_include_counterparty_unknown_htlcs, fee_spike_buffer_htlc, self.feerate_per_kw, dust_exposure_limiting_feerate);
4511
+
let next_remote_commitment_stats = self.get_next_remote_commitment_stats(funding, None, do_not_include_counterparty_unknown_htlcs, fee_spike_buffer_htlc, self.feerate_per_kw, dust_exposure_limiting_feerate);
4512
+
4498
4513
let max_dust_htlc_exposure_msat = self.get_max_dust_htlc_exposure_msat(dust_exposure_limiting_feerate);
4499
-
let on_counterparty_tx_dust_htlc_exposure_msat = htlc_stats.on_counterparty_tx_dust_exposure_msat;
4500
-
if on_counterparty_tx_dust_htlc_exposure_msat > max_dust_htlc_exposure_msat {
4514
+
if next_remote_commitment_stats.dust_exposure_msat > max_dust_htlc_exposure_msat {
4501
4515
// Note that the total dust exposure includes both the dust HTLCs and the excess mining fees of the counterparty commitment transaction
4502
4516
log_info!(logger, "Cannot accept value that would put our total dust exposure at {} over the limit {} on counterparty commitment tx",
0 commit comments