Skip to content

Commit 087c0bd

Browse files
authored
Merge pull request #1852 from TheBlueMatt/2022-11-accept-bad-but-better-fee-updates
Accept feerate increases even if they aren't high enough for us
2 parents 8d93dba + a1404aa commit 087c0bd

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));
@@ -6786,7 +6795,8 @@ mod tests {
67866795
// arithmetic, causing a panic with debug assertions enabled.
67876796
let fee_est = TestFeeEstimator { fee_est: 42 };
67886797
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_est);
6789-
assert!(Channel::<InMemorySigner>::check_remote_fee(&bounded_fee_estimator, u32::max_value()).is_err());
6798+
assert!(Channel::<InMemorySigner>::check_remote_fee(&bounded_fee_estimator,
6799+
u32::max_value(), None, &&test_utils::TestLogger::new()).is_err());
67906800
}
67916801

67926802
struct Keys {

lightning/src/ln/channelmanager.rs

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

lightning/src/ln/functional_tests.rs

+78
Original file line numberDiff line numberDiff line change
@@ -9458,3 +9458,81 @@ fn test_non_final_funding_tx() {
94589458
assert!(nodes[0].node.funding_transaction_generated(&temp_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).is_ok());
94599459
get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
94609460
}
9461+
9462+
#[test]
9463+
fn accept_busted_but_better_fee() {
9464+
// If a peer sends us a fee update that is too low, but higher than our previous channel
9465+
// feerate, we should accept it. In the future we may want to consider closing the channel
9466+
// later, but for now we only accept the update.
9467+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
9468+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
9469+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
9470+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
9471+
9472+
create_chan_between_nodes(&nodes[0], &nodes[1], channelmanager::provided_init_features(), channelmanager::provided_init_features());
9473+
9474+
// Set nodes[1] to expect 5,000 sat/kW.
9475+
{
9476+
let mut feerate_lock = chanmon_cfgs[1].fee_estimator.sat_per_kw.lock().unwrap();
9477+
*feerate_lock = 5000;
9478+
}
9479+
9480+
// If nodes[0] increases their feerate, even if its not enough, nodes[1] should accept it.
9481+
{
9482+
let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
9483+
*feerate_lock = 1000;
9484+
}
9485+
nodes[0].node.timer_tick_occurred();
9486+
check_added_monitors!(nodes[0], 1);
9487+
9488+
let events = nodes[0].node.get_and_clear_pending_msg_events();
9489+
assert_eq!(events.len(), 1);
9490+
match events[0] {
9491+
MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, ref commitment_signed, .. }, .. } => {
9492+
nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_fee.as_ref().unwrap());
9493+
commitment_signed_dance!(nodes[1], nodes[0], commitment_signed, false);
9494+
},
9495+
_ => panic!("Unexpected event"),
9496+
};
9497+
9498+
// If nodes[0] increases their feerate further, even if its not enough, nodes[1] should accept
9499+
// it.
9500+
{
9501+
let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
9502+
*feerate_lock = 2000;
9503+
}
9504+
nodes[0].node.timer_tick_occurred();
9505+
check_added_monitors!(nodes[0], 1);
9506+
9507+
let events = nodes[0].node.get_and_clear_pending_msg_events();
9508+
assert_eq!(events.len(), 1);
9509+
match events[0] {
9510+
MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, ref commitment_signed, .. }, .. } => {
9511+
nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_fee.as_ref().unwrap());
9512+
commitment_signed_dance!(nodes[1], nodes[0], commitment_signed, false);
9513+
},
9514+
_ => panic!("Unexpected event"),
9515+
};
9516+
9517+
// However, if nodes[0] decreases their feerate, nodes[1] should reject it and close the
9518+
// channel.
9519+
{
9520+
let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
9521+
*feerate_lock = 1000;
9522+
}
9523+
nodes[0].node.timer_tick_occurred();
9524+
check_added_monitors!(nodes[0], 1);
9525+
9526+
let events = nodes[0].node.get_and_clear_pending_msg_events();
9527+
assert_eq!(events.len(), 1);
9528+
match events[0] {
9529+
MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, .. }, .. } => {
9530+
nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_fee.as_ref().unwrap());
9531+
check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError {
9532+
err: "Peer's feerate much too low. Actual: 1000. Our expected lower limit: 5000 (- 250)".to_owned() });
9533+
check_closed_broadcast!(nodes[1], true);
9534+
check_added_monitors!(nodes[1], 1);
9535+
},
9536+
_ => panic!("Unexpected event"),
9537+
};
9538+
}

0 commit comments

Comments
 (0)