Skip to content

Commit a1404aa

Browse files
committed
Accept feerate increases even if they aren't high enough for us
LND nodes have very broken fee estimators, causing them to suggest feerates that don't even meet a current mempool minimum feerate when fees go up over the course of hours. This can cause us to reject their feerate estimates as they're not high enough, even though their new feerate is higher than what we had already (which is the feerate we'll use to broadcast a closing transaction). This implies we force-close the channel and broadcast something with a feerate lower than our counterparty was offering. Here we simply accept such feerates as they are better than what we had. We really should also close the channel, but only after we get their signature on the new feerate. That should happen by checking channel feerates every time we see a new block so is orthogonal to this code. Ultimately the fix is anchor outputs plus package-based relay in Bitcoin Core, however we're still quite some ways from that, so worth needlessly closing channels for now.
1 parent 838d486 commit a1404aa

File tree

3 files changed

+96
-8
lines changed

3 files changed

+96
-8
lines changed

lightning/src/ln/channel.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -1075,8 +1075,9 @@ impl<Signer: Sign> Channel<Signer> {
10751075
})
10761076
}
10771077

1078-
fn check_remote_fee<F: Deref>(fee_estimator: &LowerBoundedFeeEstimator<F>, feerate_per_kw: u32) -> Result<(), ChannelError>
1079-
where F::Target: FeeEstimator
1078+
fn check_remote_fee<F: Deref, L: Deref>(fee_estimator: &LowerBoundedFeeEstimator<F>,
1079+
feerate_per_kw: u32, cur_feerate_per_kw: Option<u32>, logger: &L)
1080+
-> Result<(), ChannelError> where F::Target: FeeEstimator, L::Target: Logger,
10801081
{
10811082
// We only bound the fee updates on the upper side to prevent completely absurd feerates,
10821083
// always accepting up to 25 sat/vByte or 10x our fee estimator's "High Priority" fee.
@@ -1093,6 +1094,14 @@ impl<Signer: Sign> Channel<Signer> {
10931094
// of 1.1 sat/vbyte and a receiver that wants 1.1 rounded up to 2. Thus, we always add 250
10941095
// sat/kw before the comparison here.
10951096
if feerate_per_kw + 250 < lower_limit {
1097+
if let Some(cur_feerate) = cur_feerate_per_kw {
1098+
if feerate_per_kw > cur_feerate {
1099+
log_warn!(logger,
1100+
"Accepting feerate that may prevent us from closing this channel because it's higher than what we have now. Had {} s/kW, now {} s/kW.",
1101+
cur_feerate, feerate_per_kw);
1102+
return Ok(());
1103+
}
1104+
}
10961105
return Err(ChannelError::Close(format!("Peer's feerate much too low. Actual: {}. Our expected lower limit: {} (- 250)", feerate_per_kw, lower_limit)));
10971106
}
10981107
Ok(())
@@ -1179,7 +1188,7 @@ impl<Signer: Sign> Channel<Signer> {
11791188
if msg.htlc_minimum_msat >= full_channel_value_msat {
11801189
return Err(ChannelError::Close(format!("Minimum htlc value ({}) was larger than full channel value ({})", msg.htlc_minimum_msat, full_channel_value_msat)));
11811190
}
1182-
Channel::<Signer>::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
1191+
Channel::<Signer>::check_remote_fee(fee_estimator, msg.feerate_per_kw, None, logger)?;
11831192

11841193
let max_counterparty_selected_contest_delay = u16::min(config.channel_handshake_limits.their_to_self_delay, MAX_LOCAL_BREAKDOWN_TIMEOUT);
11851194
if msg.to_self_delay > max_counterparty_selected_contest_delay {
@@ -3762,16 +3771,16 @@ impl<Signer: Sign> Channel<Signer> {
37623771
}
37633772
}
37643773

3765-
pub fn update_fee<F: Deref>(&mut self, fee_estimator: &LowerBoundedFeeEstimator<F>, msg: &msgs::UpdateFee) -> Result<(), ChannelError>
3766-
where F::Target: FeeEstimator
3774+
pub fn update_fee<F: Deref, L: Deref>(&mut self, fee_estimator: &LowerBoundedFeeEstimator<F>, msg: &msgs::UpdateFee, logger: &L) -> Result<(), ChannelError>
3775+
where F::Target: FeeEstimator, L::Target: Logger
37673776
{
37683777
if self.is_outbound() {
37693778
return Err(ChannelError::Close("Non-funding remote tried to update channel fee".to_owned()));
37703779
}
37713780
if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
37723781
return Err(ChannelError::Close("Peer sent update_fee when we needed a channel_reestablish".to_owned()));
37733782
}
3774-
Channel::<Signer>::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
3783+
Channel::<Signer>::check_remote_fee(fee_estimator, msg.feerate_per_kw, Some(self.feerate_per_kw), logger)?;
37753784
let feerate_over_dust_buffer = msg.feerate_per_kw > self.get_dust_buffer_feerate(None);
37763785

37773786
self.pending_update_fee = Some((msg.feerate_per_kw, FeeUpdateState::RemoteAnnounced));
@@ -6765,7 +6774,8 @@ mod tests {
67656774
// arithmetic, causing a panic with debug assertions enabled.
67666775
let fee_est = TestFeeEstimator { fee_est: 42 };
67676776
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_est);
6768-
assert!(Channel::<InMemorySigner>::check_remote_fee(&bounded_fee_estimator, u32::max_value()).is_err());
6777+
assert!(Channel::<InMemorySigner>::check_remote_fee(&bounded_fee_estimator,
6778+
u32::max_value(), None, &&test_utils::TestLogger::new()).is_err());
67696779
}
67706780

67716781
struct Keys {

lightning/src/ln/channelmanager.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5189,7 +5189,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
51895189
if chan.get().get_counterparty_node_id() != *counterparty_node_id {
51905190
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
51915191
}
5192-
try_chan_entry!(self, chan.get_mut().update_fee(&self.fee_estimator, &msg), chan);
5192+
try_chan_entry!(self, chan.get_mut().update_fee(&self.fee_estimator, &msg, &self.logger), chan);
51935193
},
51945194
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
51955195
}

lightning/src/ln/functional_tests.rs

+78
Original file line numberDiff line numberDiff line change
@@ -10490,3 +10490,81 @@ fn test_non_final_funding_tx() {
1049010490
assert!(nodes[0].node.funding_transaction_generated(&temp_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).is_ok());
1049110491
get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
1049210492
}
10493+
10494+
#[test]
10495+
fn accept_busted_but_better_fee() {
10496+
// If a peer sends us a fee update that is too low, but higher than our previous channel
10497+
// feerate, we should accept it. In the future we may want to consider closing the channel
10498+
// later, but for now we only accept the update.
10499+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
10500+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
10501+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
10502+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
10503+
10504+
create_chan_between_nodes(&nodes[0], &nodes[1], channelmanager::provided_init_features(), channelmanager::provided_init_features());
10505+
10506+
// Set nodes[1] to expect 5,000 sat/kW.
10507+
{
10508+
let mut feerate_lock = chanmon_cfgs[1].fee_estimator.sat_per_kw.lock().unwrap();
10509+
*feerate_lock = 5000;
10510+
}
10511+
10512+
// If nodes[0] increases their feerate, even if its not enough, nodes[1] should accept it.
10513+
{
10514+
let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
10515+
*feerate_lock = 1000;
10516+
}
10517+
nodes[0].node.timer_tick_occurred();
10518+
check_added_monitors!(nodes[0], 1);
10519+
10520+
let events = nodes[0].node.get_and_clear_pending_msg_events();
10521+
assert_eq!(events.len(), 1);
10522+
match events[0] {
10523+
MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, ref commitment_signed, .. }, .. } => {
10524+
nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_fee.as_ref().unwrap());
10525+
commitment_signed_dance!(nodes[1], nodes[0], commitment_signed, false);
10526+
},
10527+
_ => panic!("Unexpected event"),
10528+
};
10529+
10530+
// If nodes[0] increases their feerate further, even if its not enough, nodes[1] should accept
10531+
// it.
10532+
{
10533+
let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
10534+
*feerate_lock = 2000;
10535+
}
10536+
nodes[0].node.timer_tick_occurred();
10537+
check_added_monitors!(nodes[0], 1);
10538+
10539+
let events = nodes[0].node.get_and_clear_pending_msg_events();
10540+
assert_eq!(events.len(), 1);
10541+
match events[0] {
10542+
MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, ref commitment_signed, .. }, .. } => {
10543+
nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_fee.as_ref().unwrap());
10544+
commitment_signed_dance!(nodes[1], nodes[0], commitment_signed, false);
10545+
},
10546+
_ => panic!("Unexpected event"),
10547+
};
10548+
10549+
// However, if nodes[0] decreases their feerate, nodes[1] should reject it and close the
10550+
// channel.
10551+
{
10552+
let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
10553+
*feerate_lock = 1000;
10554+
}
10555+
nodes[0].node.timer_tick_occurred();
10556+
check_added_monitors!(nodes[0], 1);
10557+
10558+
let events = nodes[0].node.get_and_clear_pending_msg_events();
10559+
assert_eq!(events.len(), 1);
10560+
match events[0] {
10561+
MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, .. }, .. } => {
10562+
nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_fee.as_ref().unwrap());
10563+
check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError {
10564+
err: "Peer's feerate much too low. Actual: 1000. Our expected lower limit: 5000 (- 250)".to_owned() });
10565+
check_closed_broadcast!(nodes[1], true);
10566+
check_added_monitors!(nodes[1], 1);
10567+
},
10568+
_ => panic!("Unexpected event"),
10569+
};
10570+
}

0 commit comments

Comments
 (0)