- /// Calculates and returns our minimum and maximum closing transaction fee amounts, in whole
- /// satoshis. The amounts remain consistent unless a peer disconnects/reconnects or we restart,
- /// at which point they will be recalculated.
- fn calculate_closing_fee_limits<F: Deref>(&mut self, fee_estimator: &LowerBoundedFeeEstimator<F>)
- -> (u64, u64)
- where F::Target: FeeEstimator
- {
- if let Some((min, max)) = self.context.closing_fee_limits { return (min, max); }
-
- // Propose a range from our current Background feerate to our Normal feerate plus our
- // force_close_avoidance_max_fee_satoshis.
- // If we fail to come to consensus, we'll have to force-close.
- let mut proposed_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Background);
- let normal_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal);
- let mut proposed_max_feerate = if self.context.is_outbound() { normal_feerate } else { u32::max_value() };
-
- // The spec requires that (when the channel does not have anchors) we only send absolute
- // channel fees no greater than the absolute channel fee on the current commitment
- // transaction. It's unclear *which* commitment transaction this refers to, and there isn't
- // very good reason to apply such a limit in any case. We don't bother doing so, risking
- // some force-closure by old nodes, but we wanted to close the channel anyway.
-
- if let Some(target_feerate) = self.context.target_closing_feerate_sats_per_kw {
- let min_feerate = if self.context.is_outbound() { target_feerate } else { cmp::min(self.context.feerate_per_kw, target_feerate) };
- proposed_feerate = cmp::max(proposed_feerate, min_feerate);
- proposed_max_feerate = cmp::max(proposed_max_feerate, min_feerate);
- }
-
- // Note that technically we could end up with a lower minimum fee if one sides' balance is
- // below our dust limit, causing the output to disappear. We don't bother handling this
- // case, however, as this should only happen if a channel is closed before any (material)
- // payments have been made on it. This may cause slight fee overpayment and/or failure to
- // come to consensus with our counterparty on appropriate fees, however it should be a
- // relatively rare case. We can revisit this later, though note that in order to determine
- // if the funders' output is dust we have to know the absolute fee we're going to use.
- let tx_weight = self.get_closing_transaction_weight(Some(&self.get_closing_scriptpubkey()), Some(self.context.counterparty_shutdown_scriptpubkey.as_ref().unwrap()));
- let proposed_total_fee_satoshis = proposed_feerate as u64 * tx_weight / 1000;
- let proposed_max_total_fee_satoshis = if self.context.is_outbound() {
- // We always add force_close_avoidance_max_fee_satoshis to our normal
- // feerate-calculated fee, but allow the max to be overridden if we're using a
- // target feerate-calculated fee.
- cmp::max(normal_feerate as u64 * tx_weight / 1000 + self.context.config.options.force_close_avoidance_max_fee_satoshis,
- proposed_max_feerate as u64 * tx_weight / 1000)
- } else {
- self.context.channel_value_satoshis - (self.context.value_to_self_msat + 999) / 1000
- };
-
- self.context.closing_fee_limits = Some((proposed_total_fee_satoshis, proposed_max_total_fee_satoshis));
- self.context.closing_fee_limits.clone().unwrap()
- }
-
- /// Returns true if we're ready to commence the closing_signed negotiation phase. This is true
- /// after both sides have exchanged a `shutdown` message and all HTLCs have been drained. At
- /// this point if we're the funder we should send the initial closing_signed, and in any case
- /// shutdown should complete within a reasonable timeframe.
- fn closing_negotiation_ready(&self) -> bool {
- self.context.pending_inbound_htlcs.is_empty() && self.context.pending_outbound_htlcs.is_empty() &&
- self.context.channel_state &
- (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::AwaitingRemoteRevoke as u32 |
- ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)
- == BOTH_SIDES_SHUTDOWN_MASK &&
- self.context.pending_update_fee.is_none()
- }
-
- /// Checks if the closing_signed negotiation is making appropriate progress, possibly returning
- /// an Err if no progress is being made and the channel should be force-closed instead.
- /// Should be called on a one-minute timer.
- pub fn timer_check_closing_negotiation_progress(&mut self) -> Result<(), ChannelError> {
- if self.closing_negotiation_ready() {
- if self.context.closing_signed_in_flight {
- return Err(ChannelError::Close("closing_signed negotiation failed to finish within two timer ticks".to_owned()));
- } else {
- self.context.closing_signed_in_flight = true;
- }
- }
- Ok(())
- }
-
- pub fn maybe_propose_closing_signed<F: Deref, L: Deref>(
- &mut self, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L)
- -> Result<(Option<msgs::ClosingSigned>, Option<Transaction>), ChannelError>
- where F::Target: FeeEstimator, L::Target: Logger
+ /// Adds a pending outbound HTLC to this channel, and builds a new remote commitment
+ /// transaction and generates the corresponding [`ChannelMonitorUpdate`] in one go.
+ ///
+ /// Shorthand for calling [`Self::send_htlc`] followed by a commitment update, see docs on
+ /// [`Self::send_htlc`] and [`Self::build_commitment_no_state_update`] for more info.
+ pub fn send_htlc_and_commit<F: Deref, L: Deref>(
+ &mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32,
+ source: HTLCSource, onion_routing_packet: msgs::OnionPacket, skimmed_fee_msat: Option<u64>,
+ fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L
+ ) -> Result<Option<ChannelMonitorUpdate>, ChannelError>
+ where F::Target: FeeEstimator, L::Target: Logger