Skip to content

Commit 74002d3

Browse files
committed
Refactor test utils and add a simple MPP send/claim test.
1 parent ba403ad commit 74002d3

File tree

2 files changed

+150
-105
lines changed

2 files changed

+150
-105
lines changed

lightning/src/ln/functional_test_utils.rs

Lines changed: 117 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -659,51 +659,55 @@ macro_rules! expect_payment_sent {
659659
}
660660
}
661661

662-
pub fn send_along_route_with_secret<'a, 'b>(origin_node: &Node<'a, 'b>, route: Route, expected_route: &[&Node<'a, 'b>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<[u8; 32]>) {
663-
let mut payment_event = {
664-
origin_node.node.send_payment(route, our_payment_hash, our_payment_secret.as_ref()).unwrap();
665-
check_added_monitors!(origin_node, 1);
666-
667-
let mut events = origin_node.node.get_and_clear_pending_msg_events();
668-
assert_eq!(events.len(), 1);
669-
SendEvent::from_event(events.remove(0))
670-
};
671-
let mut prev_node = origin_node;
672-
673-
for (idx, &node) in expected_route.iter().enumerate() {
674-
assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
675-
676-
node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
677-
check_added_monitors!(node, 0);
678-
commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
679-
680-
expect_pending_htlcs_forwardable!(node);
681-
682-
if idx == expected_route.len() - 1 {
683-
let events_2 = node.node.get_and_clear_pending_events();
684-
assert_eq!(events_2.len(), 1);
685-
match events_2[0] {
686-
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
687-
assert_eq!(our_payment_hash, *payment_hash);
688-
assert_eq!(our_payment_secret, *payment_secret);
689-
assert_eq!(amt, recv_value);
690-
},
691-
_ => panic!("Unexpected event"),
662+
pub fn send_along_route_with_secret<'a, 'b>(origin_node: &Node<'a, 'b>, route: Route, expected_paths: &[&[&Node<'a, 'b>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<[u8; 32]>) {
663+
origin_node.node.send_payment(route, our_payment_hash, our_payment_secret.as_ref()).unwrap();
664+
check_added_monitors!(origin_node, expected_paths.len());
665+
666+
let mut events = origin_node.node.get_and_clear_pending_msg_events();
667+
assert_eq!(events.len(), expected_paths.len());
668+
for (path_idx, (ev, expected_route)) in events.drain(..).zip(expected_paths.iter()).enumerate() {
669+
let mut payment_event = SendEvent::from_event(ev);
670+
let mut prev_node = origin_node;
671+
672+
for (idx, &node) in expected_route.iter().enumerate() {
673+
assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
674+
675+
node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
676+
check_added_monitors!(node, 0);
677+
commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
678+
679+
expect_pending_htlcs_forwardable!(node);
680+
681+
if idx == expected_route.len() - 1 {
682+
let events_2 = node.node.get_and_clear_pending_events();
683+
if path_idx == expected_paths.len() - 1 {
684+
assert_eq!(events_2.len(), 1);
685+
match events_2[0] {
686+
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
687+
assert_eq!(our_payment_hash, *payment_hash);
688+
assert_eq!(our_payment_secret, *payment_secret);
689+
assert_eq!(amt, recv_value);
690+
},
691+
_ => panic!("Unexpected event"),
692+
}
693+
} else {
694+
assert!(events_2.is_empty());
695+
}
696+
} else {
697+
let mut events_2 = node.node.get_and_clear_pending_msg_events();
698+
assert_eq!(events_2.len(), 1);
699+
check_added_monitors!(node, 1);
700+
payment_event = SendEvent::from_event(events_2.remove(0));
701+
assert_eq!(payment_event.msgs.len(), 1);
692702
}
693-
} else {
694-
let mut events_2 = node.node.get_and_clear_pending_msg_events();
695-
assert_eq!(events_2.len(), 1);
696-
check_added_monitors!(node, 1);
697-
payment_event = SendEvent::from_event(events_2.remove(0));
698-
assert_eq!(payment_event.msgs.len(), 1);
699-
}
700703

701-
prev_node = node;
704+
prev_node = node;
705+
}
702706
}
703707
}
704708

705709
pub fn send_along_route_with_hash<'a, 'b>(origin_node: &Node<'a, 'b>, route: Route, expected_route: &[&Node<'a, 'b>], recv_value: u64, our_payment_hash: PaymentHash) {
706-
send_along_route_with_secret(origin_node, route, expected_route, recv_value, our_payment_hash, None);
710+
send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, None);
707711
}
708712

709713
pub fn send_along_route<'a, 'b>(origin_node: &Node<'a, 'b>, route: Route, expected_route: &[&Node<'a, 'b>], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
@@ -712,86 +716,96 @@ pub fn send_along_route<'a, 'b>(origin_node: &Node<'a, 'b>, route: Route, expect
712716
(our_payment_preimage, our_payment_hash)
713717
}
714718

715-
pub fn claim_payment_along_route_with_secret<'a, 'b>(origin_node: &Node<'a, 'b>, expected_route: &[&Node<'a, 'b>], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option<[u8; 32]>, expected_amount: u64) {
716-
assert!(expected_route.last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount));
717-
check_added_monitors!(expected_route.last().unwrap(), 1);
719+
pub fn claim_payment_along_route_with_secret<'a, 'b>(origin_node: &Node<'a, 'b>, expected_paths: &[&[&Node<'a, 'b>]], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option<[u8; 32]>, expected_amount: u64) {
720+
for path in expected_paths.iter() {
721+
assert_eq!(path.last().unwrap().node.get_our_node_id(), expected_paths[0].last().unwrap().node.get_our_node_id());
722+
}
723+
assert!(expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount));
724+
check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len());
718725

719-
let mut next_msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)> = None;
720-
let mut expected_next_node = expected_route.last().unwrap().node.get_our_node_id();
721-
macro_rules! get_next_msgs {
722-
($node: expr) => {
723-
{
724-
let events = $node.node.get_and_clear_pending_msg_events();
725-
assert_eq!(events.len(), 1);
726-
match events[0] {
727-
MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
728-
assert!(update_add_htlcs.is_empty());
729-
assert_eq!(update_fulfill_htlcs.len(), 1);
730-
assert!(update_fail_htlcs.is_empty());
731-
assert!(update_fail_malformed_htlcs.is_empty());
732-
assert!(update_fee.is_none());
733-
expected_next_node = node_id.clone();
734-
Some((update_fulfill_htlcs[0].clone(), commitment_signed.clone()))
735-
},
736-
_ => panic!("Unexpected event"),
737-
}
726+
macro_rules! msgs_from_ev {
727+
($ev: expr) => {
728+
match $ev {
729+
&MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
730+
assert!(update_add_htlcs.is_empty());
731+
assert_eq!(update_fulfill_htlcs.len(), 1);
732+
assert!(update_fail_htlcs.is_empty());
733+
assert!(update_fail_malformed_htlcs.is_empty());
734+
assert!(update_fee.is_none());
735+
((update_fulfill_htlcs[0].clone(), commitment_signed.clone()), node_id.clone())
736+
},
737+
_ => panic!("Unexpected event"),
738738
}
739739
}
740740
}
741+
let mut per_path_msgs: Vec<((msgs::UpdateFulfillHTLC, msgs::CommitmentSigned), PublicKey)> = Vec::with_capacity(expected_paths.len());
742+
let events = expected_paths[0].last().unwrap().node.get_and_clear_pending_msg_events();
743+
assert_eq!(events.len(), expected_paths.len());
744+
for ev in events.iter() {
745+
per_path_msgs.push(msgs_from_ev!(ev));
746+
}
741747

742-
macro_rules! last_update_fulfill_dance {
743-
($node: expr, $prev_node: expr) => {
744-
{
745-
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
746-
check_added_monitors!($node, 0);
747-
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
748-
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
748+
for (expected_route, (path_msgs, next_hop)) in expected_paths.iter().zip(per_path_msgs.drain(..)) {
749+
let mut next_msgs = Some(path_msgs);
750+
let mut expected_next_node = next_hop;
751+
752+
macro_rules! last_update_fulfill_dance {
753+
($node: expr, $prev_node: expr) => {
754+
{
755+
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
756+
check_added_monitors!($node, 0);
757+
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
758+
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
759+
}
749760
}
750761
}
751-
}
752-
macro_rules! mid_update_fulfill_dance {
753-
($node: expr, $prev_node: expr, $new_msgs: expr) => {
754-
{
755-
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
756-
check_added_monitors!($node, 1);
757-
let new_next_msgs = if $new_msgs {
758-
get_next_msgs!($node)
759-
} else {
760-
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
761-
None
762-
};
763-
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
764-
next_msgs = new_next_msgs;
762+
macro_rules! mid_update_fulfill_dance {
763+
($node: expr, $prev_node: expr, $new_msgs: expr) => {
764+
{
765+
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
766+
check_added_monitors!($node, 1);
767+
let new_next_msgs = if $new_msgs {
768+
let events = $node.node.get_and_clear_pending_msg_events();
769+
assert_eq!(events.len(), 1);
770+
let (res, nexthop) = msgs_from_ev!(&events[0]);
771+
expected_next_node = nexthop;
772+
Some(res)
773+
} else {
774+
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
775+
None
776+
};
777+
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
778+
next_msgs = new_next_msgs;
779+
}
765780
}
766781
}
767-
}
768782

769-
let mut prev_node = expected_route.last().unwrap();
770-
for (idx, node) in expected_route.iter().rev().enumerate() {
771-
assert_eq!(expected_next_node, node.node.get_our_node_id());
772-
let update_next_msgs = !skip_last || idx != expected_route.len() - 1;
773-
if next_msgs.is_some() {
774-
mid_update_fulfill_dance!(node, prev_node, update_next_msgs);
775-
} else if update_next_msgs {
776-
next_msgs = get_next_msgs!(node);
777-
} else {
778-
assert!(node.node.get_and_clear_pending_msg_events().is_empty());
779-
}
780-
if !skip_last && idx == expected_route.len() - 1 {
781-
assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
782-
}
783+
let mut prev_node = expected_route.last().unwrap();
784+
for (idx, node) in expected_route.iter().rev().enumerate().skip(1) {
785+
assert_eq!(expected_next_node, node.node.get_our_node_id());
786+
let update_next_msgs = !skip_last || idx != expected_route.len() - 1;
787+
if next_msgs.is_some() {
788+
mid_update_fulfill_dance!(node, prev_node, update_next_msgs);
789+
} else {
790+
assert!(!update_next_msgs);
791+
assert!(node.node.get_and_clear_pending_msg_events().is_empty());
792+
}
793+
if !skip_last && idx == expected_route.len() - 1 {
794+
assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
795+
}
783796

784-
prev_node = node;
785-
}
797+
prev_node = node;
798+
}
786799

787-
if !skip_last {
788-
last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
789-
expect_payment_sent!(origin_node, our_payment_preimage);
800+
if !skip_last {
801+
last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
802+
expect_payment_sent!(origin_node, our_payment_preimage);
803+
}
790804
}
791805
}
792806

793807
pub fn claim_payment_along_route<'a, 'b>(origin_node: &Node<'a, 'b>, expected_route: &[&Node<'a, 'b>], skip_last: bool, our_payment_preimage: PaymentPreimage, expected_amount: u64) {
794-
claim_payment_along_route_with_secret(origin_node, expected_route, skip_last, our_payment_preimage, None, expected_amount);
808+
claim_payment_along_route_with_secret(origin_node, &[expected_route], skip_last, our_payment_preimage, None, expected_amount);
795809
}
796810

797811
pub fn claim_payment<'a, 'b>(origin_node: &Node<'a, 'b>, expected_route: &[&Node<'a, 'b>], our_payment_preimage: PaymentPreimage, expected_amount: u64) {

lightning/src/ln/functional_tests.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7094,10 +7094,41 @@ fn test_simple_payment_secret() {
70947094
let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]);
70957095
let (_, payment_secret) = get_payment_preimage_hash!(&nodes[0]);
70967096
let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
7097-
send_along_route_with_secret(&nodes[0], route, &[&nodes[1], &nodes[2]], 100000, payment_hash, Some(payment_secret.0));
7097+
send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2]]], 100000, payment_hash, Some(payment_secret.0));
70987098
// Claiming with all the correct values but the wrong secret should result in nothing...
70997099
assert_eq!(nodes[2].node.claim_funds(payment_preimage, &None, 100_000), false);
71007100
assert_eq!(nodes[2].node.claim_funds(payment_preimage, &Some([42; 32]), 100_000), false);
71017101
// ...but with the right secret we should be able to claim all the way back
7102-
claim_payment_along_route_with_secret(&nodes[0], &[&nodes[1], &nodes[2]], false, payment_preimage, Some(payment_secret.0), 100_000);
7102+
claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage, Some(payment_secret.0), 100_000);
7103+
}
7104+
7105+
#[test]
7106+
fn test_simple_mpp() {
7107+
// Simple test of sending a multi-path payment.
7108+
let node_cfgs = create_node_cfgs(4);
7109+
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
7110+
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
7111+
7112+
let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7113+
let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7114+
let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7115+
let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7116+
7117+
let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]);
7118+
let (_, payment_secret) = get_payment_preimage_hash!(&nodes[0]);
7119+
let mut route = nodes[0].router.get_route(&nodes[3].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
7120+
let path = route.paths[0].clone();
7121+
route.paths.push(path);
7122+
route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
7123+
route.paths[0][0].short_channel_id = chan_1_id;
7124+
route.paths[0][1].short_channel_id = chan_3_id;
7125+
route.paths[1][0].pubkey = nodes[2].node.get_our_node_id();
7126+
route.paths[1][0].short_channel_id = chan_2_id;
7127+
route.paths[1][1].short_channel_id = chan_4_id;
7128+
send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], 200_000, payment_hash, Some(payment_secret.0));
7129+
// Claiming with all the correct values but the wrong secret should result in nothing...
7130+
assert_eq!(nodes[3].node.claim_funds(payment_preimage, &None, 200_000), false);
7131+
assert_eq!(nodes[3].node.claim_funds(payment_preimage, &Some([42; 32]), 200_000), false);
7132+
// ...but with the right secret we should be able to claim all the way back
7133+
claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage, Some(payment_secret.0), 200_000);
71037134
}

0 commit comments

Comments
 (0)