Skip to content

Commit 26c6dc7

Browse files
Test 0.2 -> 0.3 reload with with forward htlcs present
We have an overarching goal of (mostly) getting rid of ChannelManager persistence and rebuilding the ChannelManager's state from existing ChannelMonitors, due to issues when the two structs are out-of-sync on restart. The main issue that can arise is channel force closure. In the previous commit we started this process by rebuilding ChannelManager::decode_update_add_htlcs, forward_htlcs, and pending_intercepted_htlcs from the Channel data, which will soon be included in the ChannelMonitors as part of a different series of PRs. Here we test that HTLC forwards that were originally received on 0.2 can still be successfully forwarded using the new reload + legacy handling code that will be merged for 0.3.
1 parent a1d327f commit 26c6dc7

File tree

2 files changed

+185
-0
lines changed

2 files changed

+185
-0
lines changed

lightning-tests/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ lightning-types = { path = "../lightning-types", features = ["_test_utils"] }
1515
lightning-invoice = { path = "../lightning-invoice", default-features = false }
1616
lightning-macros = { path = "../lightning-macros" }
1717
lightning = { path = "../lightning", features = ["_test_utils"] }
18+
lightning_0_2 = { package = "lightning", git = "https://github.com/lightningdevkit/rust-lightning.git", branch = "0.2", features = ["_test_utils"] }
1819
lightning_0_1 = { package = "lightning", version = "0.1.7", features = ["_test_utils"] }
1920
lightning_0_0_125 = { package = "lightning", version = "0.0.125", features = ["_test_utils"] }
2021

lightning-tests/src/upgrade_downgrade_tests.rs

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010
//! Tests which test upgrading from previous versions of LDK or downgrading to previous versions of
1111
//! LDK.
1212
13+
use lightning_0_2::commitment_signed_dance as commitment_signed_dance_0_2;
14+
use lightning_0_2::events::Event as Event_0_2;
15+
use lightning_0_2::get_monitor as get_monitor_0_2;
16+
use lightning_0_2::ln::channelmanager::PaymentId as PaymentId_0_2;
17+
use lightning_0_2::ln::channelmanager::RecipientOnionFields as RecipientOnionFields_0_2;
18+
use lightning_0_2::ln::functional_test_utils as lightning_0_2_utils;
19+
use lightning_0_2::ln::msgs::ChannelMessageHandler as _;
20+
use lightning_0_2::routing::router as router_0_2;
21+
use lightning_0_2::util::ser::Writeable as _;
22+
1323
use lightning_0_1::commitment_signed_dance as commitment_signed_dance_0_1;
1424
use lightning_0_1::events::ClosureReason as ClosureReason_0_1;
1525
use lightning_0_1::expect_pending_htlcs_forwardable_ignore as expect_pending_htlcs_forwardable_ignore_0_1;
@@ -498,3 +508,177 @@ fn test_0_1_htlc_forward_after_splice() {
498508
do_test_0_1_htlc_forward_after_splice(true);
499509
do_test_0_1_htlc_forward_after_splice(false);
500510
}
511+
512+
#[test]
513+
fn upgrade_mid_htlc_forward() {
514+
do_upgrade_mid_htlc_forward(false);
515+
}
516+
#[test]
517+
fn upgrade_mid_htlc_intercept_forward() {
518+
do_upgrade_mid_htlc_forward(true);
519+
}
520+
fn do_upgrade_mid_htlc_forward(intercept_htlc: bool) {
521+
// In 0.3, we started reconstructing the `ChannelManager`'s HTLC forwards maps from the HTLCs
522+
// contained in `Channel`s, as part of getting rid of `ChannelManager` persistence. However, HTLC
523+
// forwards can only be reconstructed this way if they were received on 0.3 or higher. Test that
524+
// HTLC forwards that were serialized on <=0.2 will still succeed when read on 0.3+.
525+
let (node_a_ser, node_b_ser, node_c_ser, mon_a_1_ser, mon_b_1_ser, mon_b_2_ser, mon_c_1_ser);
526+
let (node_a_id, node_b_id, node_c_id);
527+
let (payment_secret_bytes, payment_hash_bytes, payment_preimage_bytes);
528+
let (node_a_blocks, node_b_blocks, node_c_blocks);
529+
let chan_id_bytes_b_c;
530+
531+
{
532+
let chanmon_cfgs = lightning_0_2_utils::create_chanmon_cfgs(3);
533+
let node_cfgs = lightning_0_2_utils::create_node_cfgs(3, &chanmon_cfgs);
534+
535+
let mut intercept_cfg = lightning_0_2_utils::test_default_channel_config();
536+
intercept_cfg.accept_intercept_htlcs = true;
537+
let cfgs = &[None, Some(intercept_cfg), None];
538+
let node_chanmgrs = lightning_0_2_utils::create_node_chanmgrs(3, &node_cfgs, cfgs);
539+
let nodes = lightning_0_2_utils::create_network(3, &node_cfgs, &node_chanmgrs);
540+
541+
node_a_id = nodes[0].node.get_our_node_id();
542+
node_b_id = nodes[1].node.get_our_node_id();
543+
node_c_id = nodes[2].node.get_our_node_id();
544+
let chan_id_a = lightning_0_2_utils::create_announced_chan_between_nodes_with_value(
545+
&nodes, 0, 1, 10_000_000, 0,
546+
)
547+
.2;
548+
549+
let chan_id_b = lightning_0_2_utils::create_announced_chan_between_nodes_with_value(
550+
&nodes, 1, 2, 50_000, 0,
551+
)
552+
.2;
553+
chan_id_bytes_b_c = chan_id_b.0;
554+
555+
// Ensure all nodes are at the same initial height.
556+
let node_max_height = nodes.iter().map(|node| node.best_block_info().1).max().unwrap();
557+
for node in &nodes {
558+
let blocks_to_mine = node_max_height - node.best_block_info().1;
559+
if blocks_to_mine > 0 {
560+
lightning_0_2_utils::connect_blocks(node, blocks_to_mine);
561+
}
562+
}
563+
564+
// Initiate an HTLC to be sent over node_a -> node_b -> node_c
565+
let (preimage, hash, secret) =
566+
lightning_0_2_utils::get_payment_preimage_hash(&nodes[2], Some(1_000_000), None);
567+
payment_preimage_bytes = preimage.0;
568+
payment_hash_bytes = hash.0;
569+
payment_secret_bytes = secret.0;
570+
571+
let pay_params = router_0_2::PaymentParameters::from_node_id(
572+
node_c_id,
573+
lightning_0_2_utils::TEST_FINAL_CLTV,
574+
)
575+
.with_bolt11_features(nodes[2].node.bolt11_invoice_features())
576+
.unwrap();
577+
578+
let route_params =
579+
router_0_2::RouteParameters::from_payment_params_and_value(pay_params, 1_000_000);
580+
let mut route = lightning_0_2_utils::get_route(&nodes[0], &route_params).unwrap();
581+
582+
if intercept_htlc {
583+
route.paths[0].hops[1].short_channel_id = nodes[1].node.get_intercept_scid();
584+
}
585+
586+
let onion = RecipientOnionFields_0_2::secret_only(secret);
587+
let id = PaymentId_0_2(hash.0);
588+
nodes[0].node.send_payment_with_route(route, hash, onion, id).unwrap();
589+
590+
lightning_0_2_utils::check_added_monitors(&nodes[0], 1);
591+
let send_event = lightning_0_2_utils::SendEvent::from_node(&nodes[0]);
592+
593+
// Lock in the HTLC on the inbound edge of the forwarding node without initiating the outbound
594+
// edge.
595+
nodes[1].node.handle_update_add_htlc(node_a_id, &send_event.msgs[0]);
596+
commitment_signed_dance_0_2!(nodes[1], nodes[0], send_event.commitment_msg, false);
597+
nodes[1].node.test_process_pending_update_add_htlcs();
598+
let events = nodes[1].node.get_and_clear_pending_events();
599+
assert_eq!(events.len(), 1);
600+
assert!(matches!(events[0], Event_0_2::HTLCIntercepted { .. }));
601+
602+
node_a_ser = nodes[0].node.encode();
603+
node_b_ser = nodes[1].node.encode();
604+
node_c_ser = nodes[2].node.encode();
605+
mon_a_1_ser = get_monitor_0_2!(nodes[0], chan_id_a).encode();
606+
mon_b_1_ser = get_monitor_0_2!(nodes[1], chan_id_a).encode();
607+
mon_b_2_ser = get_monitor_0_2!(nodes[1], chan_id_b).encode();
608+
mon_c_1_ser = get_monitor_0_2!(nodes[2], chan_id_b).encode();
609+
610+
node_a_blocks = Arc::clone(&nodes[0].blocks);
611+
node_b_blocks = Arc::clone(&nodes[1].blocks);
612+
node_c_blocks = Arc::clone(&nodes[2].blocks);
613+
}
614+
615+
// Create a dummy node to reload over with the 0.2 state
616+
let mut chanmon_cfgs = create_chanmon_cfgs(3);
617+
618+
// Our TestChannelSigner will fail as we're jumping ahead, so disable its state-based checks
619+
chanmon_cfgs[0].keys_manager.disable_all_state_policy_checks = true;
620+
chanmon_cfgs[1].keys_manager.disable_all_state_policy_checks = true;
621+
chanmon_cfgs[2].keys_manager.disable_all_state_policy_checks = true;
622+
623+
chanmon_cfgs[0].tx_broadcaster.blocks = node_a_blocks;
624+
chanmon_cfgs[1].tx_broadcaster.blocks = node_b_blocks;
625+
chanmon_cfgs[2].tx_broadcaster.blocks = node_c_blocks;
626+
627+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
628+
let (persister_a, persister_b, persister_c, chain_mon_a, chain_mon_b, chain_mon_c);
629+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
630+
let (node_a, node_b, node_c);
631+
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
632+
633+
let config = test_default_channel_config();
634+
let a_mons = &[&mon_a_1_ser[..]];
635+
reload_node!(nodes[0], config.clone(), &node_a_ser, a_mons, persister_a, chain_mon_a, node_a);
636+
let b_mons = &[&mon_b_1_ser[..], &mon_b_2_ser[..]];
637+
reload_node!(nodes[1], config.clone(), &node_b_ser, b_mons, persister_b, chain_mon_b, node_b);
638+
let c_mons = &[&mon_c_1_ser[..]];
639+
reload_node!(nodes[2], config, &node_c_ser, c_mons, persister_c, chain_mon_c, node_c);
640+
641+
reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1]));
642+
let mut reconnect_b_c_args = ReconnectArgs::new(&nodes[1], &nodes[2]);
643+
reconnect_b_c_args.send_channel_ready = (true, true);
644+
reconnect_b_c_args.send_announcement_sigs = (true, true);
645+
reconnect_nodes(reconnect_b_c_args);
646+
647+
// Now release the HTLC to node c, to be claimed back to node A
648+
nodes[1].node.process_pending_htlc_forwards();
649+
650+
if intercept_htlc {
651+
let events = nodes[1].node.get_and_clear_pending_events();
652+
assert_eq!(events.len(), 1);
653+
let (intercept_id, expected_outbound_amt_msat) = match events[0] {
654+
Event::HTLCIntercepted { intercept_id, expected_outbound_amount_msat, .. } => {
655+
(intercept_id, expected_outbound_amount_msat)
656+
},
657+
_ => panic!(),
658+
};
659+
nodes[1]
660+
.node
661+
.forward_intercepted_htlc(
662+
intercept_id,
663+
&ChannelId(chan_id_bytes_b_c),
664+
nodes[2].node.get_our_node_id(),
665+
expected_outbound_amt_msat,
666+
)
667+
.unwrap();
668+
nodes[1].node.process_pending_htlc_forwards();
669+
}
670+
671+
let pay_secret = PaymentSecret(payment_secret_bytes);
672+
let pay_hash = PaymentHash(payment_hash_bytes);
673+
let pay_preimage = PaymentPreimage(payment_preimage_bytes);
674+
675+
check_added_monitors(&nodes[1], 1);
676+
let forward_event = SendEvent::from_node(&nodes[1]);
677+
nodes[2].node.handle_update_add_htlc(node_b_id, &forward_event.msgs[0]);
678+
let commitment = &forward_event.commitment_msg;
679+
do_commitment_signed_dance(&nodes[2], &nodes[1], commitment, false, false);
680+
681+
expect_and_process_pending_htlcs(&nodes[2], false);
682+
expect_payment_claimable!(nodes[2], pay_hash, pay_secret, 1_000_000);
683+
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], pay_preimage);
684+
}

0 commit comments

Comments
 (0)