diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index cb06f4149eb..31c12dd2361 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -3328,42 +3328,10 @@ impl ChannelContext where SP::Target: SignerProvider { } } - macro_rules! add_htlc_output { - ($htlc: expr, $outbound: expr, $source: expr, $state_name: expr) => { - if $outbound == local { // "offered HTLC output" - let htlc_in_tx = get_htlc_in_commitment!($htlc, true); - let htlc_tx_fee = if self.get_channel_type().supports_anchors_zero_fee_htlc_tx() { - 0 - } else { - feerate_per_kw as u64 * htlc_timeout_tx_weight(self.get_channel_type()) / 1000 - }; - if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + htlc_tx_fee { - log_trace!(logger, " ...including {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat); - included_non_dust_htlcs.push((htlc_in_tx, $source)); - } else { - log_trace!(logger, " ...including {} {} dust HTLC {} (hash {}) with value {} due to dust limit", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat); - included_dust_htlcs.push((htlc_in_tx, $source)); - } - } else { - let htlc_in_tx = get_htlc_in_commitment!($htlc, false); - let htlc_tx_fee = if self.get_channel_type().supports_anchors_zero_fee_htlc_tx() { - 0 - } else { - feerate_per_kw as u64 * htlc_success_tx_weight(self.get_channel_type()) / 1000 - }; - if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + htlc_tx_fee { - log_trace!(logger, " ...including {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat); - included_non_dust_htlcs.push((htlc_in_tx, $source)); - } else { - log_trace!(logger, " ...including {} {} dust HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat); - included_dust_htlcs.push((htlc_in_tx, $source)); - } - } - } - } - let mut inbound_htlc_preimages: Vec = Vec::new(); + let mut htlcs_in_tx = Vec::new(); + for ref htlc in self.pending_inbound_htlcs.iter() { let (include, state_name) = match htlc.state { InboundHTLCState::RemoteAnnounced(_) => (!generated_by_local, "RemoteAnnounced"), @@ -3374,8 +3342,8 @@ impl ChannelContext where SP::Target: SignerProvider { }; if include { - add_htlc_output!(htlc, false, None, state_name); - remote_htlc_total_msat += htlc.amount_msat; + let htlc_in_tx = get_htlc_in_commitment!(htlc, !local); + htlcs_in_tx.push((htlc_in_tx, None)); } else { log_trace!(logger, " ...not including inbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, state_name); match &htlc.state { @@ -3416,8 +3384,8 @@ impl ChannelContext where SP::Target: SignerProvider { } if include { - add_htlc_output!(htlc, true, Some(&htlc.source), state_name); - local_htlc_total_msat += htlc.amount_msat; + let htlc_in_tx = get_htlc_in_commitment!(htlc, local); + htlcs_in_tx.push((htlc_in_tx, Some(&htlc.source))); } else { log_trace!(logger, " ...not including outbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, state_name); match htlc.state { @@ -3433,15 +3401,49 @@ impl ChannelContext where SP::Target: SignerProvider { } } } + let mut value_to_self_msat: i64 = self.value_to_self_msat as i64 + value_to_self_msat_offset; + + for (htlc, source) in htlcs_in_tx { + if htlc.offered { // "offered HTLC output" + if local { + local_htlc_total_msat += htlc.amount_msat; + } else { + remote_htlc_total_msat += htlc.amount_msat + } + let htlc_in_tx = get_htlc_in_commitment!(htlc, true); + let htlc_tx_fee = if self.get_channel_type().supports_anchors_zero_fee_htlc_tx() { + 0 + } else { + feerate_per_kw as u64 * htlc_timeout_tx_weight(self.get_channel_type()) / 1000 + }; + if htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + htlc_tx_fee { + included_non_dust_htlcs.push((htlc_in_tx, source)); + } else { + included_dust_htlcs.push((htlc_in_tx, source)); + } + } else { + if local { + remote_htlc_total_msat += htlc.amount_msat + } else { + local_htlc_total_msat += htlc.amount_msat; + } + let htlc_in_tx = get_htlc_in_commitment!(htlc, false); + let htlc_tx_fee = if self.get_channel_type().supports_anchors_zero_fee_htlc_tx() { + 0 + } else { + feerate_per_kw as u64 * htlc_success_tx_weight(self.get_channel_type()) / 1000 + }; + if htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + htlc_tx_fee { + included_non_dust_htlcs.push((htlc_in_tx, source)); + } else { + included_dust_htlcs.push((htlc_in_tx, source)); + } + } + } - let value_to_self_msat: i64 = (self.value_to_self_msat - local_htlc_total_msat) as i64 + value_to_self_msat_offset; - assert!(value_to_self_msat >= 0); - // Note that in case they have several just-awaiting-last-RAA fulfills in-progress (ie - // AwaitingRemoteRevokeToRemove or AwaitingRemovedRemoteRevoke) we may have allowed them to - // "violate" their reserve value by couting those against it. Thus, we have to convert - // everything to i64 before subtracting as otherwise we can overflow. - let value_to_remote_msat: i64 = (self.channel_value_satoshis * 1000) as i64 - (self.value_to_self_msat as i64) - (remote_htlc_total_msat as i64) - value_to_self_msat_offset; - assert!(value_to_remote_msat >= 0); + let mut value_to_remote_msat: i64 = (self.channel_value_satoshis * 1000) as i64 - value_to_self_msat; + value_to_self_msat -= local_htlc_total_msat as i64; + value_to_remote_msat -= remote_htlc_total_msat as i64; #[cfg(debug_assertions)] {