From 7c964164f519083e427ee37d01f3f816b4ca241e Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 17 Mar 2020 20:54:41 -0400 Subject: [PATCH] XXX: Incl tx fee when calcing inbound HTLC limits on inbound channels When we receive an inbound HTLC from a peer on an inbound channel, the peer needs to be able to pay for the additional commitment tx fees as well. XXX: Needs tests + a similar limit on outbound. Probably also needs new actions in chanmon_fail_consistency fuzztest for "send 1 msat HTLC" or so. --- lightning/src/ln/channel.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 81762923..aea17ca9 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -1680,14 +1680,28 @@ impl Channel { // Channel state once they will not be present in the next received commitment // transaction). let mut removed_outbound_total_msat = 0; + // When calculating the set of HTLCs which will be included in their next + // commitment_signed, all inbound HTLCs are included (as all states imply it will be + // included) and only committed outbound HTLCs, see below. + let mut their_acked_htlcs = self.pending_inbound_htlcs.len() as u64; for ref htlc in self.pending_outbound_htlcs.iter() { if let OutboundHTLCState::AwaitingRemoteRevokeToRemove(None) = htlc.state { removed_outbound_total_msat += htlc.amount_msat; } else if let OutboundHTLCState::AwaitingRemovedRemoteRevoke(None) = htlc.state { removed_outbound_total_msat += htlc.amount_msat; + } else if let OutboundHTLCState::Committed = htlc.state { + // We only include outbound HTLCs if it will not be included in their next + // commitment_signed, ie if they've responded to us with an RAA after announcement + // and if they haven't yet started removal. + their_acked_htlcs += 1; } } - if htlc_inbound_value_msat + msg.amount_msat + self.value_to_self_msat > (self.channel_value_satoshis - Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis)) * 1000 + removed_outbound_total_msat { + let remote_fee_cost = if !self.channel_outbound { + // Note that we ignore the fact that feerate_per_kw can change at runtime here. That's + // OK, soon enough it won't be the case. + self.feerate_per_kw * (COMMITMENT_TX_BASE_WEIGHT + their_acked_htlcs * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000 + } else { 0 }; + if htlc_inbound_value_msat + msg.amount_msat + self.value_to_self_msat > (self.channel_value_satoshis - Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis) - remote_fee_cost) * 1000 + removed_outbound_total_msat { return Err(ChannelError::Close("Remote HTLC add would put them over their reserve value")); } if self.next_remote_htlc_id != msg.htlc_id { -- 2.30.2