Skip to content

Commit e7c2a61

Browse files
committed
Increase min CLTV delta and delta before CLTV at which chans close
In the previous commit it was observed that we actually have to run the whole "get a transaction confirmed" process from start to finish twice to claim an HTLC on an anchor channel. This leaves us with only 9 blocks to get each transaction confirmed, which is quite aggressive. Here we double this threshold, force-closing channels which have an expiring HTLC 36 blocks before expiry instead of 18. We also increase the minimum CLTV expiry delta to 48 to ensure we have at least a few blocks after the transactions get confirmed before we need to fail the inbound edge of a forwarded HTLC back. We do not change the default CLTV expiry delta of 72 blocks.
1 parent ccf8d44 commit e7c2a61

File tree

3 files changed

+21
-27
lines changed

3 files changed

+21
-27
lines changed

lightning/src/chain/channelmonitor.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,13 @@ impl_writeable_tlv_based!(HTLCUpdate, {
223223
/// transaction.
224224
pub(crate) const COUNTERPARTY_CLAIMABLE_WITHIN_BLOCKS_PINNABLE: u32 = 12;
225225

226-
/// When we go to force-close a channel because an HTLC is expiring, we should ensure that the
227-
/// HTLC(s) expiring are not considered pinnable, allowing us to aggregate them with other HTLC(s)
228-
/// expiring at the same time.
229-
const _: () = assert!(CLTV_CLAIM_BUFFER > COUNTERPARTY_CLAIMABLE_WITHIN_BLOCKS_PINNABLE);
226+
/// When we go to force-close a channel because an HTLC is expiring, by the time we've gotten the
227+
/// commitment transaction confirmed, we should ensure that the HTLC(s) expiring are not considered
228+
/// pinnable, allowing us to aggregate them with other HTLC(s) expiring at the same time.
229+
const _: () = assert!(MAX_BLOCKS_FOR_CONF > COUNTERPARTY_CLAIMABLE_WITHIN_BLOCKS_PINNABLE);
230230

231231
/// The upper bound on how many blocks we think it can take for us to get a transaction confirmed.
232-
pub(crate) const MAX_BLOCKS_FOR_CONF: u32 = 9;
232+
pub(crate) const MAX_BLOCKS_FOR_CONF: u32 = 18;
233233

234234
/// If an HTLC expires within this many blocks, force-close the channel to broadcast the
235235
/// HTLC-Success transaction.

lightning/src/ln/channelmanager.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2824,7 +2824,7 @@ pub const BREAKDOWN_TIMEOUT: u16 = 6 * 24;
28242824
pub(crate) const MAX_LOCAL_BREAKDOWN_TIMEOUT: u16 = 2 * 6 * 24 * 7;
28252825

28262826
/// The minimum number of blocks between an inbound HTLC's CLTV and the corresponding outbound
2827-
/// HTLC's CLTV. The current default represents roughly seven hours of blocks at six blocks/hour.
2827+
/// HTLC's CLTV. The current default represents roughly eight hours of blocks at six blocks/hour.
28282828
///
28292829
/// This can be increased (but not decreased) through [`ChannelConfig::cltv_expiry_delta`]
28302830
///
@@ -2833,7 +2833,7 @@ pub(crate) const MAX_LOCAL_BREAKDOWN_TIMEOUT: u16 = 2 * 6 * 24 * 7;
28332833
// i.e. the node we forwarded the payment on to should always have enough room to reliably time out
28342834
// the HTLC via a full update_fail_htlc/commitment_signed dance before we hit the
28352835
// CLTV_CLAIM_BUFFER point (we static assert that it's at least 3 blocks more).
2836-
pub const MIN_CLTV_EXPIRY_DELTA: u16 = 6*7;
2836+
pub const MIN_CLTV_EXPIRY_DELTA: u16 = 6*8;
28372837
// This should be long enough to allow a payment path drawn across multiple routing hops with substantial
28382838
// `cltv_expiry_delta`. Indeed, the length of those values is the reaction delay offered to a routing node
28392839
// in case of HTLC on-chain settlement. While appearing less competitive, a node operator could decide to

lightning/src/ln/functional_tests.rs

+14-20
Original file line numberDiff line numberDiff line change
@@ -3500,7 +3500,7 @@ fn do_test_htlc_on_chain_timeout(connect_style: ConnectStyle) {
35003500
let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // 1 timeout tx
35013501
assert_eq!(node_txn.len(), 1);
35023502
check_spends!(node_txn[0], commitment_tx[0]);
3503-
assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
3503+
assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT + 1);
35043504
}
35053505

35063506
#[xtest(feature = "_externalize_tests")]
@@ -9387,25 +9387,19 @@ fn do_test_onchain_htlc_settlement_after_close(broadcast_alice: bool, go_onchain
93879387
// Step (6):
93889388
// Finally, check that Bob broadcasted a preimage-claiming transaction for the HTLC output on the
93899389
// broadcasted commitment transaction.
9390-
{
9391-
let script_weight = match broadcast_alice {
9392-
true => OFFERED_HTLC_SCRIPT_WEIGHT,
9393-
false => ACCEPTED_HTLC_SCRIPT_WEIGHT
9394-
};
9395-
// If Alice force-closed, Bob only broadcasts a HTLC-output-claiming transaction. Otherwise,
9396-
// Bob force-closed and broadcasts the commitment transaction along with a
9397-
// HTLC-output-claiming transaction.
9398-
let mut bob_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
9399-
if broadcast_alice {
9400-
assert_eq!(bob_txn.len(), 1);
9401-
check_spends!(bob_txn[0], txn_to_broadcast[0]);
9402-
assert_eq!(bob_txn[0].input[0].witness.last().unwrap().len(), script_weight);
9403-
} else {
9404-
assert_eq!(bob_txn.len(), if nodes[1].connect_style.borrow().updates_best_block_first() { 3 } else { 2 });
9405-
let htlc_tx = bob_txn.pop().unwrap();
9406-
check_spends!(htlc_tx, txn_to_broadcast[0]);
9407-
assert_eq!(htlc_tx.input[0].witness.last().unwrap().len(), script_weight);
9408-
}
9390+
// If Alice force-closed, Bob only broadcasts a HTLC-output-claiming transaction. Otherwise,
9391+
// Bob force-closed and broadcasts the commitment transaction along with a
9392+
// HTLC-output-claiming transaction.
9393+
let mut bob_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
9394+
if broadcast_alice {
9395+
assert_eq!(bob_txn.len(), 1);
9396+
check_spends!(bob_txn[0], txn_to_broadcast[0]);
9397+
assert_eq!(bob_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
9398+
} else {
9399+
assert_eq!(bob_txn.len(), if nodes[1].connect_style.borrow().updates_best_block_first() { 3 } else { 2 });
9400+
let htlc_tx = bob_txn.pop().unwrap();
9401+
check_spends!(htlc_tx, txn_to_broadcast[0]);
9402+
assert_eq!(htlc_tx.input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT + 1);
94099403
}
94109404
}
94119405

0 commit comments

Comments
 (0)