When communicating the maximum fee we're willing to accept on a
cooperative closing transaction to our peer, we currently tell them
we'll accept `u64::max_value()` if they're the ones who have to pay
it. Spec-wise this is fine - they aren't allowed to try to claim
our balance, and we don't care how much of their own funds they
want to spend on transaction fees.
However, the Eclair folks prefer to check all values on the wire
do not exceed 21 million BTC, which seems like generally good
practice to avoid overflows and such issues. Thus, our close
messages are rejected by Eclair.
Here we simply relax our stated maximum to be the real value - our
counterparty's current balance in satoshis.
Fixes #1071
/// closing_signed message and handling it in `maybe_propose_closing_signed`.
pending_counterparty_closing_signed: Option<msgs::ClosingSigned>,
/// closing_signed message and handling it in `maybe_propose_closing_signed`.
pending_counterparty_closing_signed: Option<msgs::ClosingSigned>,
- /// The minimum and maximum absolute fee we are willing to place on the closing transaction.
- /// These are set once we reach `closing_negotiation_ready`.
+ /// The minimum and maximum absolute fee, in satoshis, we are willing to place on the closing
+ /// transaction. These are set once we reach `closing_negotiation_ready`.
#[cfg(test)]
pub(crate) closing_fee_limits: Option<(u64, u64)>,
#[cfg(not(test))]
#[cfg(test)]
pub(crate) closing_fee_limits: Option<(u64, u64)>,
#[cfg(not(test))]
cmp::max(normal_feerate as u64 * tx_weight / 1000 + self.config.force_close_avoidance_max_fee_satoshis,
proposed_max_feerate as u64 * tx_weight / 1000)
} else {
cmp::max(normal_feerate as u64 * tx_weight / 1000 + self.config.force_close_avoidance_max_fee_satoshis,
proposed_max_feerate as u64 * tx_weight / 1000)
} else {
+ self.channel_value_satoshis - (self.value_to_self_msat + 999) / 1000
};
self.closing_fee_limits = Some((proposed_total_fee_satoshis, proposed_max_total_fee_satoshis));
};
self.closing_fee_limits = Some((proposed_total_fee_satoshis, proposed_max_total_fee_satoshis));
if !self.is_outbound() {
// They have to pay, so pick the highest fee in the overlapping range.
if !self.is_outbound() {
// They have to pay, so pick the highest fee in the overlapping range.
- debug_assert_eq!(our_max_fee, u64::max_value()); // We should never set an upper bound
+ // We should never set an upper bound aside from their full balance
+ debug_assert_eq!(our_max_fee, self.channel_value_satoshis - (self.value_to_self_msat + 999) / 1000);
propose_fee!(cmp::min(max_fee_satoshis, our_max_fee));
} else {
if msg.fee_satoshis < our_min_fee || msg.fee_satoshis > our_max_fee {
propose_fee!(cmp::min(max_fee_satoshis, our_max_fee));
} else {
if msg.fee_satoshis < our_min_fee || msg.fee_satoshis > our_max_fee {