Skip to content

Commit 8b320be

Browse files
committed
Add a test of stale-feerate-force-closure behavior
1 parent c276b0a commit 8b320be

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

0 commit comments

Comments
 (0)