Skip to content

Commit 17b77e0

Browse files
committed
Add a test of stale-feerate-force-closure behavior
1 parent 5a1cc28 commit 17b77e0

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

lightning/src/ln/channelmanager.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ const UNACCEPTED_INBOUND_CHANNEL_AGE_LIMIT_TICKS: i32 = 2;
965965
/// The number of blocks of historical feerate estimates we keep around and consider when deciding
966966
/// to force-close a channel for having too-low fees. Also the number of blocks we have to see
967967
/// after startup before we consider force-closing channels for having too-low fees.
968-
const FEERATE_TRACKING_BLOCKS: usize = 144;
968+
pub(super) const FEERATE_TRACKING_BLOCKS: usize = 144;
969969

970970
/// Stores a PaymentSecret and any other data we may need to validate an inbound payment is
971971
/// actually ours and not some duplicate HTLC sent to us by a node along the route.

lightning/src/ln/shutdown_tests.rs

+56
Original file line numberDiff line numberDiff line change
@@ -1464,3 +1464,59 @@ fn batch_funding_failure() {
14641464
check_closed_events(&nodes[0], &close);
14651465
assert_eq!(nodes[0].node.list_channels().len(), 0);
14661466
}
1467+
1468+
#[test]
1469+
fn test_force_closure_on_low_stale_fee() {
1470+
// Check that we force-close channels if they have a low fee and that has gotten stale (without
1471+
// update).
1472+
let chanmon_cfgs = create_chanmon_cfgs(2);
1473+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1474+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
1475+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1476+
1477+
let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
1478+
1479+
// Start by connecting lots of blocks to give LDK some feerate history
1480+
for _ in 0..super::channelmanager::FEERATE_TRACKING_BLOCKS * 2 {
1481+
connect_blocks(&nodes[1], 1);
1482+
}
1483+
1484+
// Now connect a handful of blocks with a "high" feerate
1485+
{
1486+
let mut feerate_lock = chanmon_cfgs[1].fee_estimator.sat_per_kw.lock().unwrap();
1487+
*feerate_lock *= 2;
1488+
}
1489+
for _ in 0..super::channelmanager::FEERATE_TRACKING_BLOCKS - 1 {
1490+
connect_blocks(&nodes[1], 1);
1491+
}
1492+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
1493+
1494+
// Now, note that one more block would cause us to force-close, it won't because we've dropped
1495+
// the feerate
1496+
{
1497+
let mut feerate_lock = chanmon_cfgs[1].fee_estimator.sat_per_kw.lock().unwrap();
1498+
*feerate_lock /= 2;
1499+
}
1500+
connect_blocks(&nodes[1], super::channelmanager::FEERATE_TRACKING_BLOCKS as u32 * 2);
1501+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
1502+
1503+
// Now, connect another FEERATE_TRACKING_BLOCKS - 1 blocks at a high feerate, note that none of
1504+
// these will cause a force-closure because LDK only looks at the minimium feerate over the
1505+
// last FEERATE_TRACKING_BLOCKS blocks.
1506+
{
1507+
let mut feerate_lock = chanmon_cfgs[1].fee_estimator.sat_per_kw.lock().unwrap();
1508+
*feerate_lock *= 2;
1509+
}
1510+
1511+
for _ in 0..super::channelmanager::FEERATE_TRACKING_BLOCKS - 1 {
1512+
connect_blocks(&nodes[1], 1);
1513+
}
1514+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
1515+
1516+
// Finally, connect one more block and check the force-close happened.
1517+
connect_blocks(&nodes[1], 1);
1518+
check_added_monitors!(nodes[1], 1);
1519+
check_closed_broadcast(&nodes[1], 1, true);
1520+
let reason = ClosureReason::PeerFeerateTooLow { peer_feerate_sat_per_kw: 253, required_feerate_sat_per_kw: 253 * 2 };
1521+
check_closed_events(&nodes[1], &[ExpectedCloseEvent::from_id_reason(chan_id, false, reason)]);
1522+
}

0 commit comments

Comments
 (0)