Skip to content

Commit afd83d4

Browse files
committed
f test remote commitment HTLC timeout claim balances as well
1 parent 11b528b commit afd83d4

File tree

1 file changed

+83
-15
lines changed

1 file changed

+83
-15
lines changed

lightning/src/ln/monitor_tests.rs

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
//! Further functional tests which test blockchain reorganizations.
1111
12-
use chain::channelmonitor::{ANTI_REORG_DELAY, ClaimableBalance};
12+
use chain::channelmonitor::{ANTI_REORG_DELAY, ClaimableBalance, HTLC_FAIL_BACK_BUFFER};
1313
use chain::transaction::OutPoint;
1414
use ln::{channel, PaymentPreimage, PaymentHash};
1515
use ln::channelmanager::BREAKDOWN_TIMEOUT;
@@ -197,7 +197,10 @@ fn test_claim_value_force_close() {
197197
let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
198198
assert_eq!(funding_outpoint.to_channel_id(), chan_id);
199199

200+
// This HTLC is immediately claimed, giving node B the preimage
200201
let payment_preimage = route_payment(&nodes[0], &[&nodes[1]], 3_000_000).0;
202+
// This HTLC is allowed to time out, letting A claim it.
203+
let timeout_payment_hash = route_payment(&nodes[0], &[&nodes[1]], 4_000_000).1;
201204
// This HTLC will be dust, and not be claimable at all:
202205
let (dust_payment_preimage, dust_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 3_000);
203206

@@ -207,13 +210,16 @@ fn test_claim_value_force_close() {
207210

208211
let remote_txn = get_local_commitment_txn!(nodes[1], chan_id);
209212
// Before B receives the payment preimage, it only suggests the push_msat value of 1_000 sats
210-
// as claimable. A lists both its to-self balance and the (possibly-claimable) HTLC.
213+
// as claimable. A lists both its to-self balance and the (possibly-claimable) HTLCs.
211214
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableOnChannelClose {
212-
claimable_amount_satoshis: 1_000_000 - 3_000 - 1_000 - 3 - chan_feerate *
213-
(channel::COMMITMENT_TX_BASE_WEIGHT + channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
215+
claimable_amount_satoshis: 1_000_000 - 3_000 - 4_000 - 1_000 - 3 - chan_feerate *
216+
(channel::COMMITMENT_TX_BASE_WEIGHT + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
214217
}, ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
215218
claimable_amount_satoshis: 3_000,
216219
claimable_height: htlc_cltv_timeout,
220+
}, ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
221+
claimable_amount_satoshis: 4_000,
222+
claimable_height: htlc_cltv_timeout,
217223
}]),
218224
sorted_vec(nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
219225
assert_eq!(vec![ClaimableBalance::ClaimableOnChannelClose {
@@ -233,23 +239,27 @@ fn test_claim_value_force_close() {
233239
// "claimable if you were to close the channel" balance.
234240
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableOnChannelClose {
235241
claimable_amount_satoshis: 1_000_000 - // Channel funding value in satoshis
236-
3_000 - // The larger HTLC value in satoshis
242+
4_000 - // The to-be-failed HTLC value in satoshis
243+
3_000 - // The claimed HTLC value in satoshis
237244
1_000 - // The push_msat value in satoshis
238245
3 - // The dust HTLC value in satoshis
239-
// The commitment transaction fee with one HTLC output:
240-
chan_feerate * (channel::COMMITMENT_TX_BASE_WEIGHT + channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
246+
// The commitment transaction fee with two HTLC outputs:
247+
chan_feerate * (channel::COMMITMENT_TX_BASE_WEIGHT + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
241248
}, ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
242249
claimable_amount_satoshis: 3_000,
243250
claimable_height: htlc_cltv_timeout,
251+
}, ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
252+
claimable_amount_satoshis: 4_000,
253+
claimable_height: htlc_cltv_timeout,
244254
}]),
245255
sorted_vec(nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
246256
assert_eq!(vec![ClaimableBalance::ClaimableOnChannelClose {
247257
claimable_amount_satoshis: 1_000 + 3_000,
248258
}],
249259
nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
250260

251-
// Broadcast the closing transaction (which has the pending HTLC in it) and get B's broadcasted
252-
// HTLC claim transaction with preimage.
261+
// Broadcast the closing transaction (which has both pending HTLCs in it) and get B's
262+
// broadcasted HTLC claim transaction with preimage.
253263
let node_b_commitment_claimable = nodes[1].best_block_info().1 + BREAKDOWN_TIMEOUT as u32;
254264
mine_transaction(&nodes[0], &remote_txn[0]);
255265
mine_transaction(&nodes[1], &remote_txn[0]);
@@ -280,12 +290,15 @@ fn test_claim_value_force_close() {
280290
assert!(nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
281291

282292
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableAwaitingConfirmations {
283-
claimable_amount_satoshis: 1_000_000 - 3_000 - 1_000 - 3 - chan_feerate *
284-
(channel::COMMITMENT_TX_BASE_WEIGHT + channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
293+
claimable_amount_satoshis: 1_000_000 - 3_000 - 4_000 - 1_000 - 3 - chan_feerate *
294+
(channel::COMMITMENT_TX_BASE_WEIGHT + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
285295
confirmation_height: nodes[0].best_block_info().1 + ANTI_REORG_DELAY - 1,
286296
}, ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
287297
claimable_amount_satoshis: 3_000,
288298
claimable_height: htlc_cltv_timeout,
299+
}, ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
300+
claimable_amount_satoshis: 4_000,
301+
claimable_height: htlc_cltv_timeout,
289302
}]),
290303
sorted_vec(nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
291304
// The main non-HTLC balance is just awaiting confirmations, but the claimable height is the
@@ -308,11 +321,14 @@ fn test_claim_value_force_close() {
308321

309322
// After ANTI_REORG_DELAY, A will consider its balance fully spendable and generate a
310323
// `SpendableOutputs` event. However, B still has to wait for the CSV delay.
311-
assert_eq!(vec![ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
324+
assert_eq!(sorted_vec(vec![ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
312325
claimable_amount_satoshis: 3_000,
313326
claimable_height: htlc_cltv_timeout,
314-
}],
315-
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
327+
}, ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
328+
claimable_amount_satoshis: 4_000,
329+
claimable_height: htlc_cltv_timeout,
330+
}]),
331+
sorted_vec(nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
316332
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableAwaitingConfirmations {
317333
claimable_amount_satoshis: 1_000,
318334
confirmation_height: node_b_commitment_claimable,
@@ -337,14 +353,60 @@ fn test_claim_value_force_close() {
337353
// possibly-claimable up to ANTI_REORG_DELAY, at which point it will drop it.
338354
mine_transaction(&nodes[0], &b_broadcast_txn[0]);
339355
expect_payment_sent!(nodes[0], payment_preimage);
340-
assert_eq!(vec![ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
356+
assert_eq!(sorted_vec(vec![ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
341357
claimable_amount_satoshis: 3_000,
342358
claimable_height: htlc_cltv_timeout,
359+
}, ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
360+
claimable_amount_satoshis: 4_000,
361+
claimable_height: htlc_cltv_timeout,
362+
}]),
363+
sorted_vec(nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
364+
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
365+
assert_eq!(vec![ClaimableBalance::MaybeClaimableHTLCAwaitingTimeout {
366+
claimable_amount_satoshis: 4_000,
367+
claimable_height: htlc_cltv_timeout,
343368
}],
344369
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
370+
371+
// When the HTLC timeout output is spendable in the next block, A should broadcast it
372+
connect_blocks(&nodes[0], htlc_cltv_timeout - nodes[0].best_block_info().1 - 1);
373+
let a_broadcast_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
374+
assert_eq!(a_broadcast_txn.len(), 3);
375+
check_spends!(a_broadcast_txn[0], funding_tx);
376+
assert_eq!(a_broadcast_txn[1].input.len(), 1);
377+
check_spends!(a_broadcast_txn[1], remote_txn[0]);
378+
assert_eq!(a_broadcast_txn[2].input.len(), 1);
379+
check_spends!(a_broadcast_txn[2], remote_txn[0]);
380+
assert_ne!(a_broadcast_txn[1].input[0].previous_output.vout,
381+
a_broadcast_txn[2].input[0].previous_output.vout);
382+
// a_broadcast_txn [1] and [2] should spend the HTLC outputs of the commitment tx
383+
assert_eq!(remote_txn[0].output[a_broadcast_txn[1].input[0].previous_output.vout as usize].value, 3_000);
384+
assert_eq!(remote_txn[0].output[a_broadcast_txn[2].input[0].previous_output.vout as usize].value, 4_000);
385+
386+
// Once the HTLC-Timeout transaction confirms, A will no longer consider the HTLC
387+
// "MaybeClaimable", but instead move it to "AwaitingConfirmations".
388+
mine_transaction(&nodes[0], &a_broadcast_txn[2]);
389+
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
390+
assert_eq!(vec![ClaimableBalance::ClaimableAwaitingConfirmations {
391+
claimable_amount_satoshis: 4_000,
392+
confirmation_height: nodes[0].best_block_info().1 + ANTI_REORG_DELAY - 1,
393+
}],
394+
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
395+
// After ANTI_REORG_DELAY, A will generate a SpendableOutputs event and drop the claimable
396+
// balance entry.
345397
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
346398
assert_eq!(Vec::<ClaimableBalance>::new(),
347399
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
400+
expect_payment_failed!(nodes[0], timeout_payment_hash, true);
401+
402+
let mut node_a_spendable = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
403+
assert_eq!(node_a_spendable.len(), 1);
404+
if let Event::SpendableOutputs { outputs } = node_a_spendable.pop().unwrap() {
405+
assert_eq!(outputs.len(), 1);
406+
let spend_tx = nodes[0].keys_manager.backing.spend_spendable_outputs(&[&outputs[0]], Vec::new(),
407+
Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(), 253, &Secp256k1::new()).unwrap();
408+
check_spends!(spend_tx, a_broadcast_txn[2]);
409+
} else { panic!(); }
348410

349411
// Node B will no longer consider the HTLC "contentious" after the HTLC claim transaction
350412
// confirms, and consider it simply "awaiting confirmations". Note that it has to wait for the
@@ -361,6 +423,12 @@ fn test_claim_value_force_close() {
361423
}]),
362424
sorted_vec(nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
363425

426+
// nodes[1] will generate an event to fail-back the to-time-out HTLC at HTLC_FAIL_BACK_BUFFER
427+
// blocks before it times out, though since the channel has already hit the chain no action
428+
// will be taken.
429+
connect_blocks(&nodes[1], node_b_htlc_claimable - HTLC_FAIL_BACK_BUFFER - nodes[1].best_block_info().1);
430+
expect_pending_htlcs_forwardable!(nodes[1]);
431+
364432
// After reaching the commitment output CSV, we'll get a SpendableOutputs event for it and have
365433
// only the HTLC claimable on node B.
366434
connect_blocks(&nodes[1], node_b_commitment_claimable - nodes[1].best_block_info().1);

0 commit comments

Comments
 (0)