Skip to content

Commit b2f320b

Browse files
committed
Refactor test utils and add a simple MPP send/claim test.
1 parent 3233d18 commit b2f320b

File tree

2 files changed

+146
-105
lines changed

2 files changed

+146
-105
lines changed

lightning/src/ln/functional_test_utils.rs

Lines changed: 117 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -647,51 +647,55 @@ macro_rules! expect_payment_sent {
647647
}
648648
}
649649

650-
pub fn send_along_route_with_secret(origin_node: &Node, route: Route, expected_route: &[&Node], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<[u8; 32]>) {
651-
let mut payment_event = {
652-
origin_node.node.send_payment(route, our_payment_hash, our_payment_secret.as_ref()).unwrap();
653-
check_added_monitors!(origin_node, 1);
654-
655-
let mut events = origin_node.node.get_and_clear_pending_msg_events();
656-
assert_eq!(events.len(), 1);
657-
SendEvent::from_event(events.remove(0))
658-
};
659-
let mut prev_node = origin_node;
660-
661-
for (idx, &node) in expected_route.iter().enumerate() {
662-
assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
663-
664-
node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
665-
check_added_monitors!(node, 0);
666-
commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
667-
668-
expect_pending_htlcs_forwardable!(node);
669-
670-
if idx == expected_route.len() - 1 {
671-
let events_2 = node.node.get_and_clear_pending_events();
672-
assert_eq!(events_2.len(), 1);
673-
match events_2[0] {
674-
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
675-
assert_eq!(our_payment_hash, *payment_hash);
676-
assert_eq!(our_payment_secret, *payment_secret);
677-
assert_eq!(amt, recv_value);
678-
},
679-
_ => panic!("Unexpected event"),
650+
pub fn send_along_route_with_secret(origin_node: &Node, route: Route, expected_paths: &[&[&Node]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<[u8; 32]>) {
651+
origin_node.node.send_payment(route, our_payment_hash, our_payment_secret.as_ref()).unwrap();
652+
check_added_monitors!(origin_node, expected_paths.len());
653+
654+
let mut events = origin_node.node.get_and_clear_pending_msg_events();
655+
assert_eq!(events.len(), expected_paths.len());
656+
for (path_idx, (ev, expected_route)) in events.drain(..).zip(expected_paths.iter()).enumerate() {
657+
let mut payment_event = SendEvent::from_event(ev);
658+
let mut prev_node = origin_node;
659+
660+
for (idx, &node) in expected_route.iter().enumerate() {
661+
assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
662+
663+
node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
664+
check_added_monitors!(node, 0);
665+
commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
666+
667+
expect_pending_htlcs_forwardable!(node);
668+
669+
if idx == expected_route.len() - 1 {
670+
let events_2 = node.node.get_and_clear_pending_events();
671+
if path_idx == expected_paths.len() - 1 {
672+
assert_eq!(events_2.len(), 1);
673+
match events_2[0] {
674+
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
675+
assert_eq!(our_payment_hash, *payment_hash);
676+
assert_eq!(our_payment_secret, *payment_secret);
677+
assert_eq!(amt, recv_value);
678+
},
679+
_ => panic!("Unexpected event"),
680+
}
681+
} else {
682+
assert!(events_2.is_empty());
683+
}
684+
} else {
685+
let mut events_2 = node.node.get_and_clear_pending_msg_events();
686+
assert_eq!(events_2.len(), 1);
687+
check_added_monitors!(node, 1);
688+
payment_event = SendEvent::from_event(events_2.remove(0));
689+
assert_eq!(payment_event.msgs.len(), 1);
680690
}
681-
} else {
682-
let mut events_2 = node.node.get_and_clear_pending_msg_events();
683-
assert_eq!(events_2.len(), 1);
684-
check_added_monitors!(node, 1);
685-
payment_event = SendEvent::from_event(events_2.remove(0));
686-
assert_eq!(payment_event.msgs.len(), 1);
687-
}
688691

689-
prev_node = node;
692+
prev_node = node;
693+
}
690694
}
691695
}
692696

693697
pub fn send_along_route_with_hash(origin_node: &Node, route: Route, expected_route: &[&Node], recv_value: u64, our_payment_hash: PaymentHash) {
694-
send_along_route_with_secret(origin_node, route, expected_route, recv_value, our_payment_hash, None);
698+
send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, None);
695699
}
696700

697701
pub fn send_along_route(origin_node: &Node, route: Route, expected_route: &[&Node], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
@@ -700,86 +704,96 @@ pub fn send_along_route(origin_node: &Node, route: Route, expected_route: &[&Nod
700704
(our_payment_preimage, our_payment_hash)
701705
}
702706

703-
pub fn claim_payment_along_route_with_secret(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option<[u8; 32]>, expected_amount: u64) {
704-
assert!(expected_route.last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount));
705-
check_added_monitors!(expected_route.last().unwrap(), 1);
707+
pub fn claim_payment_along_route_with_secret(origin_node: &Node, expected_paths: &[&[&Node]], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option<[u8; 32]>, expected_amount: u64) {
708+
for path in expected_paths.iter() {
709+
assert_eq!(path.last().unwrap().node.get_our_node_id(), expected_paths[0].last().unwrap().node.get_our_node_id());
710+
}
711+
assert!(expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount));
712+
check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len());
706713

707-
let mut next_msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)> = None;
708-
let mut expected_next_node = expected_route.last().unwrap().node.get_our_node_id();
709-
macro_rules! get_next_msgs {
710-
($node: expr) => {
711-
{
712-
let events = $node.node.get_and_clear_pending_msg_events();
713-
assert_eq!(events.len(), 1);
714-
match events[0] {
715-
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 } } => {
716-
assert!(update_add_htlcs.is_empty());
717-
assert_eq!(update_fulfill_htlcs.len(), 1);
718-
assert!(update_fail_htlcs.is_empty());
719-
assert!(update_fail_malformed_htlcs.is_empty());
720-
assert!(update_fee.is_none());
721-
expected_next_node = node_id.clone();
722-
Some((update_fulfill_htlcs[0].clone(), commitment_signed.clone()))
723-
},
724-
_ => panic!("Unexpected event"),
725-
}
714+
macro_rules! msgs_from_ev {
715+
($ev: expr) => {
716+
match $ev {
717+
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 } } => {
718+
assert!(update_add_htlcs.is_empty());
719+
assert_eq!(update_fulfill_htlcs.len(), 1);
720+
assert!(update_fail_htlcs.is_empty());
721+
assert!(update_fail_malformed_htlcs.is_empty());
722+
assert!(update_fee.is_none());
723+
((update_fulfill_htlcs[0].clone(), commitment_signed.clone()), node_id.clone())
724+
},
725+
_ => panic!("Unexpected event"),
726726
}
727727
}
728728
}
729+
let mut per_path_msgs: Vec<((msgs::UpdateFulfillHTLC, msgs::CommitmentSigned), PublicKey)> = Vec::with_capacity(expected_paths.len());
730+
let events = expected_paths[0].last().unwrap().node.get_and_clear_pending_msg_events();
731+
assert_eq!(events.len(), expected_paths.len());
732+
for ev in events.iter() {
733+
per_path_msgs.push(msgs_from_ev!(ev));
734+
}
729735

730-
macro_rules! last_update_fulfill_dance {
731-
($node: expr, $prev_node: expr) => {
732-
{
733-
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
734-
check_added_monitors!($node, 0);
735-
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
736-
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
736+
for (expected_route, (path_msgs, next_hop)) in expected_paths.iter().zip(per_path_msgs.drain(..)) {
737+
let mut next_msgs = Some(path_msgs);
738+
let mut expected_next_node = next_hop;
739+
740+
macro_rules! last_update_fulfill_dance {
741+
($node: expr, $prev_node: expr) => {
742+
{
743+
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
744+
check_added_monitors!($node, 0);
745+
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
746+
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
747+
}
737748
}
738749
}
739-
}
740-
macro_rules! mid_update_fulfill_dance {
741-
($node: expr, $prev_node: expr, $new_msgs: expr) => {
742-
{
743-
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
744-
check_added_monitors!($node, 1);
745-
let new_next_msgs = if $new_msgs {
746-
get_next_msgs!($node)
747-
} else {
748-
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
749-
None
750-
};
751-
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
752-
next_msgs = new_next_msgs;
750+
macro_rules! mid_update_fulfill_dance {
751+
($node: expr, $prev_node: expr, $new_msgs: expr) => {
752+
{
753+
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
754+
check_added_monitors!($node, 1);
755+
let new_next_msgs = if $new_msgs {
756+
let events = $node.node.get_and_clear_pending_msg_events();
757+
assert_eq!(events.len(), 1);
758+
let (res, nexthop) = msgs_from_ev!(events[0]);
759+
expected_next_node = nexthop;
760+
Some(res)
761+
} else {
762+
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
763+
None
764+
};
765+
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
766+
next_msgs = new_next_msgs;
767+
}
753768
}
754769
}
755-
}
756770

757-
let mut prev_node = expected_route.last().unwrap();
758-
for (idx, node) in expected_route.iter().rev().enumerate() {
759-
assert_eq!(expected_next_node, node.node.get_our_node_id());
760-
let update_next_msgs = !skip_last || idx != expected_route.len() - 1;
761-
if next_msgs.is_some() {
762-
mid_update_fulfill_dance!(node, prev_node, update_next_msgs);
763-
} else if update_next_msgs {
764-
next_msgs = get_next_msgs!(node);
765-
} else {
766-
assert!(node.node.get_and_clear_pending_msg_events().is_empty());
767-
}
768-
if !skip_last && idx == expected_route.len() - 1 {
769-
assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
770-
}
771+
let mut prev_node = expected_route.last().unwrap();
772+
for (idx, node) in expected_route.iter().rev().enumerate().skip(1) {
773+
assert_eq!(expected_next_node, node.node.get_our_node_id());
774+
let update_next_msgs = !skip_last || idx != expected_route.len() - 1;
775+
if next_msgs.is_some() {
776+
mid_update_fulfill_dance!(node, prev_node, update_next_msgs);
777+
} else {
778+
assert!(!update_next_msgs);
779+
assert!(node.node.get_and_clear_pending_msg_events().is_empty());
780+
}
781+
if !skip_last && idx == expected_route.len() - 1 {
782+
assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
783+
}
771784

772-
prev_node = node;
773-
}
785+
prev_node = node;
786+
}
774787

775-
if !skip_last {
776-
last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
777-
expect_payment_sent!(origin_node, our_payment_preimage);
788+
if !skip_last {
789+
last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
790+
expect_payment_sent!(origin_node, our_payment_preimage);
791+
}
778792
}
779793
}
780794

781795
pub fn claim_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_preimage: PaymentPreimage, expected_amount: u64) {
782-
claim_payment_along_route_with_secret(origin_node, expected_route, skip_last, our_payment_preimage, None, expected_amount);
796+
claim_payment_along_route_with_secret(origin_node, &[expected_route], skip_last, our_payment_preimage, None, expected_amount);
783797
}
784798

785799
pub fn claim_payment(origin_node: &Node, expected_route: &[&Node], our_payment_preimage: PaymentPreimage, expected_amount: u64) {

lightning/src/ln/functional_tests.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6831,10 +6831,37 @@ fn test_simple_payment_secret() {
68316831
let (payment_preimage, payment_hash) = get_payment_preimage_hash!(nodes[0]);
68326832
let (_, payment_secret) = get_payment_preimage_hash!(nodes[0]);
68336833
let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
6834-
send_along_route_with_secret(&nodes[0], route, &[&nodes[1], &nodes[2]], 100000, payment_hash, Some(payment_secret.0));
6834+
send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2]]], 100000, payment_hash, Some(payment_secret.0));
68356835
// Claiming with all the correct values but the wrong secret should result in nothing...
68366836
assert_eq!(nodes[2].node.claim_funds(payment_preimage, &None, 100_000), false);
68376837
assert_eq!(nodes[2].node.claim_funds(payment_preimage, &Some([42; 32]), 100_000), false);
68386838
// ...but with the right secret we should be able to claim all the way back
6839-
claim_payment_along_route_with_secret(&nodes[0], &[&nodes[1], &nodes[2]], false, payment_preimage, Some(payment_secret.0), 100_000);
6839+
claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage, Some(payment_secret.0), 100_000);
6840+
}
6841+
6842+
#[test]
6843+
fn test_simple_mpp() {
6844+
// Simple test of sending a multi-path payment.
6845+
let mut nodes = create_network(4, &[None, None, None, None]);
6846+
let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::our_features(), InitFeatures::our_features()).0.contents.short_channel_id;
6847+
let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::our_features(), InitFeatures::our_features()).0.contents.short_channel_id;
6848+
let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::our_features(), InitFeatures::our_features()).0.contents.short_channel_id;
6849+
let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::our_features(), InitFeatures::our_features()).0.contents.short_channel_id;
6850+
6851+
let (payment_preimage, payment_hash) = get_payment_preimage_hash!(nodes[0]);
6852+
let (_, payment_secret) = get_payment_preimage_hash!(nodes[0]);
6853+
let mut route = nodes[0].router.get_route(&nodes[3].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
6854+
route.paths.push(route.paths[0].clone());
6855+
route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
6856+
route.paths[0][0].short_channel_id = chan_1_id;
6857+
route.paths[0][1].short_channel_id = chan_3_id;
6858+
route.paths[1][0].pubkey = nodes[2].node.get_our_node_id();
6859+
route.paths[1][0].short_channel_id = chan_2_id;
6860+
route.paths[1][1].short_channel_id = chan_4_id;
6861+
send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], 200_000, payment_hash, Some(payment_secret.0));
6862+
// Claiming with all the correct values but the wrong secret should result in nothing...
6863+
assert_eq!(nodes[3].node.claim_funds(payment_preimage, &None, 200_000), false);
6864+
assert_eq!(nodes[3].node.claim_funds(payment_preimage, &Some([42; 32]), 200_000), false);
6865+
// ...but with the right secret we should be able to claim all the way back
6866+
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);
68406867
}

0 commit comments

Comments
 (0)