Skip to content

Commit ce899fa

Browse files
committed
f - add test cases for RAA commitment order upon reestablish and monitor restored
1 parent 3340a73 commit ce899fa

File tree

1 file changed

+126
-10
lines changed

1 file changed

+126
-10
lines changed

lightning/src/ln/async_signer_tests.rs

+126-10
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,125 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
287287
assert_eq!(nodes[1].node.list_usable_channels().len(), 1);
288288
}
289289

290+
#[derive(PartialEq)]
291+
enum UnblockSignerAcrossDisconnectCase {
292+
AtEnd,
293+
BeforeMonitorRestored,
294+
BeforeReestablish,
295+
}
296+
297+
#[test]
298+
fn test_async_raa_peer_disconnect() {
299+
do_test_async_raa_peer_disconnect(UnblockSignerAcrossDisconnectCase::AtEnd);
300+
do_test_async_raa_peer_disconnect(UnblockSignerAcrossDisconnectCase::BeforeMonitorRestored);
301+
do_test_async_raa_peer_disconnect(UnblockSignerAcrossDisconnectCase::BeforeReestablish);
302+
}
303+
304+
fn do_test_async_raa_peer_disconnect(test_case: UnblockSignerAcrossDisconnectCase) {
305+
let chanmon_cfgs = create_chanmon_cfgs(2);
306+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
307+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
308+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
309+
let (_, _, chan_id, _) = create_announced_chan_between_nodes(&nodes, 0, 1);
310+
311+
// Send a payment.
312+
let src = &nodes[0];
313+
let dst = &nodes[1];
314+
let (route, our_payment_hash, _our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(src, dst, 8000000);
315+
src.node.send_payment_with_route(&route, our_payment_hash,
316+
RecipientOnionFields::secret_only(our_payment_secret), PaymentId(our_payment_hash.0)).unwrap();
317+
check_added_monitors!(src, 1);
318+
319+
// Pass the payment along the route.
320+
let payment_event = {
321+
let mut events = src.node.get_and_clear_pending_msg_events();
322+
assert_eq!(events.len(), 1);
323+
SendEvent::from_event(events.remove(0))
324+
};
325+
assert_eq!(payment_event.node_id, dst.node.get_our_node_id());
326+
assert_eq!(payment_event.msgs.len(), 1);
327+
328+
dst.node.handle_update_add_htlc(&src.node.get_our_node_id(), &payment_event.msgs[0]);
329+
330+
if test_case == UnblockSignerAcrossDisconnectCase::BeforeMonitorRestored {
331+
// Fail to persist the monitor update when handling the commitment_signed.
332+
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
333+
}
334+
335+
// Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
336+
// `commitment_signed` of its own to offer, it should publish a `revoke_and_ack`.
337+
dst.disable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::GetPerCommitmentPoint);
338+
dst.node.handle_commitment_signed(&src.node.get_our_node_id(), &payment_event.commitment_msg);
339+
check_added_monitors(dst, 1);
340+
341+
let events = dst.node.get_and_clear_pending_msg_events();
342+
assert!(events.is_empty(), "expected no message, got {}", events.len());
343+
344+
// Now disconnect and reconnect the peers.
345+
src.node.peer_disconnected(&dst.node.get_our_node_id());
346+
dst.node.peer_disconnected(&src.node.get_our_node_id());
347+
348+
// do reestablish stuff
349+
src.node.peer_connected(&dst.node.get_our_node_id(), &msgs::Init {
350+
features: dst.node.init_features(), networks: None, remote_network_address: None
351+
}, true).unwrap();
352+
let reestablish_1 = get_chan_reestablish_msgs!(src, dst);
353+
assert_eq!(reestablish_1.len(), 1);
354+
dst.node.peer_connected(&src.node.get_our_node_id(), &msgs::Init {
355+
features: src.node.init_features(), networks: None, remote_network_address: None
356+
}, false).unwrap();
357+
let reestablish_2 = get_chan_reestablish_msgs!(dst, src);
358+
assert_eq!(reestablish_2.len(), 1);
359+
360+
if test_case == UnblockSignerAcrossDisconnectCase::BeforeReestablish {
361+
// Reenable the signer before the reestablish.
362+
dst.enable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::GetPerCommitmentPoint);
363+
}
364+
365+
dst.node.handle_channel_reestablish(&src.node.get_our_node_id(), &reestablish_1[0]);
366+
367+
if test_case == UnblockSignerAcrossDisconnectCase::BeforeMonitorRestored {
368+
dst.enable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::GetPerCommitmentPoint);
369+
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
370+
let (outpoint, latest_update, _) = dst.chain_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_id).unwrap().clone();
371+
dst.chain_monitor.chain_monitor.force_channel_monitor_updated(outpoint, latest_update);
372+
check_added_monitors!(dst, 0);
373+
}
374+
375+
// Expect the RAA
376+
let (_, revoke_and_ack, commitment_signed, resend_order) = handle_chan_reestablish_msgs!(dst, src);
377+
if test_case == UnblockSignerAcrossDisconnectCase::AtEnd {
378+
assert!(revoke_and_ack.is_none());
379+
assert!(commitment_signed.is_none());
380+
} else {
381+
assert!(revoke_and_ack.is_some());
382+
assert!(commitment_signed.is_some());
383+
assert!(resend_order == RAACommitmentOrder::RevokeAndACKFirst);
384+
}
385+
386+
// Mark dst's signer as available and retry: we now expect to see dst's RAA + CS.
387+
dst.enable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::GetPerCommitmentPoint);
388+
dst.node.signer_unblocked(Some((src.node.get_our_node_id(), chan_id)));
389+
390+
if test_case == UnblockSignerAcrossDisconnectCase::AtEnd {
391+
let (_, revoke_and_ack, commitment_signed, resend_order) = handle_chan_reestablish_msgs!(dst, src);
392+
assert!(revoke_and_ack.is_some());
393+
assert!(commitment_signed.is_some());
394+
assert!(resend_order == RAACommitmentOrder::RevokeAndACKFirst);
395+
} else {
396+
// Make sure we don't double send the RAA.
397+
let (_, revoke_and_ack, commitment_signed, _) = handle_chan_reestablish_msgs!(dst, src);
398+
assert!(revoke_and_ack.is_none());
399+
assert!(commitment_signed.is_none());
400+
}
401+
}
402+
403+
290404
#[test]
291405
fn test_async_commitment_signature_peer_disconnect() {
292-
do_test_async_commitment_signature_peer_disconnect(0);
406+
// This tests that if our signer is blocked and gets unblocked
407+
// after a peer disconnect + channel reestablish, we'll send the right messages.
408+
do_test_async_commitment_signature_peer_disconnect(UnblockSignerAcrossDisconnectCase::AtEnd);
293409
}
294410

295411
#[test]
@@ -298,18 +414,18 @@ fn test_async_commitment_signature_peer_disconnect_signer_restored_before_monito
298414
// and needed to send a CS, that if our signer becomes available before the monitor
299415
// update completes, then we don't send duplicate messages upon calling `signer_unblocked`
300416
// after the monitor update completes.
301-
do_test_async_commitment_signature_peer_disconnect(1);
417+
do_test_async_commitment_signature_peer_disconnect(UnblockSignerAcrossDisconnectCase::BeforeMonitorRestored);
302418
}
303419

304420
#[test]
305421
fn test_async_commitment_signature_peer_disconnect_signer_restored_before_reestablish() {
306422
// This tests that if we tried to send a commitment_signed, but our signer was blocked,
307423
// if we disconnect, reconnect, the signer becomes available, then handle channel_reestablish,
308424
// that we don't send duplicate messages upon calling `signer_unblocked`.
309-
do_test_async_commitment_signature_peer_disconnect(2);
425+
do_test_async_commitment_signature_peer_disconnect(UnblockSignerAcrossDisconnectCase::BeforeReestablish);
310426
}
311427

312-
fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
428+
fn do_test_async_commitment_signature_peer_disconnect(test_case: UnblockSignerAcrossDisconnectCase) {
313429
let chanmon_cfgs = create_chanmon_cfgs(2);
314430
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
315431
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
@@ -335,7 +451,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
335451

336452
dst.node.handle_update_add_htlc(&src.node.get_our_node_id(), &payment_event.msgs[0]);
337453

338-
if test_case == 1 {
454+
if test_case == UnblockSignerAcrossDisconnectCase::BeforeMonitorRestored {
339455
// Fail to persist the monitor update when handling the commitment_signed.
340456
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
341457
}
@@ -346,7 +462,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
346462
dst.node.handle_commitment_signed(&src.node.get_our_node_id(), &payment_event.commitment_msg);
347463
check_added_monitors(dst, 1);
348464

349-
if test_case != 1 {
465+
if test_case != UnblockSignerAcrossDisconnectCase::BeforeMonitorRestored {
350466
get_event_msg!(dst, MessageSendEvent::SendRevokeAndACK, src.node.get_our_node_id());
351467
}
352468

@@ -366,14 +482,14 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
366482
let reestablish_2 = get_chan_reestablish_msgs!(dst, src);
367483
assert_eq!(reestablish_2.len(), 1);
368484

369-
if test_case == 2 {
485+
if test_case == UnblockSignerAcrossDisconnectCase::BeforeReestablish {
370486
// Reenable the signer before the reestablish.
371487
dst.enable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::SignCounterpartyCommitment);
372488
}
373489

374490
dst.node.handle_channel_reestablish(&src.node.get_our_node_id(), &reestablish_1[0]);
375491

376-
if test_case == 1 {
492+
if test_case == UnblockSignerAcrossDisconnectCase::BeforeMonitorRestored {
377493
dst.enable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::SignCounterpartyCommitment);
378494
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
379495
let (outpoint, latest_update, _) = dst.chain_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_id).unwrap().clone();
@@ -384,7 +500,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
384500
// Expect the RAA
385501
let (_, revoke_and_ack, commitment_signed, _) = handle_chan_reestablish_msgs!(dst, src);
386502
assert!(revoke_and_ack.is_some());
387-
if test_case == 0 {
503+
if test_case == UnblockSignerAcrossDisconnectCase::AtEnd {
388504
assert!(commitment_signed.is_none());
389505
} else {
390506
assert!(commitment_signed.is_some());
@@ -394,7 +510,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
394510
dst.enable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::SignCounterpartyCommitment);
395511
dst.node.signer_unblocked(Some((src.node.get_our_node_id(), chan_id)));
396512

397-
if test_case == 0 {
513+
if test_case == UnblockSignerAcrossDisconnectCase::AtEnd {
398514
let (_, _, commitment_signed, _) = handle_chan_reestablish_msgs!(dst, src);
399515
assert!(commitment_signed.is_some());
400516
} else {

0 commit comments

Comments
 (0)