Skip to content

Commit 16c7e2a

Browse files
committed
Refactor test utils and add a simple MPP send/claim test.
1 parent 4275490 commit 16c7e2a

File tree

2 files changed

+153
-105
lines changed

2 files changed

+153
-105
lines changed

lightning/src/ln/functional_test_utils.rs

Lines changed: 119 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -776,51 +776,57 @@ macro_rules! expect_payment_failed {
776776
}
777777
}
778778

779-
pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>) {
780-
let mut payment_event = {
781-
origin_node.node.send_payment(route, our_payment_hash, &our_payment_secret).unwrap();
782-
check_added_monitors!(origin_node, 1);
783-
784-
let mut events = origin_node.node.get_and_clear_pending_msg_events();
785-
assert_eq!(events.len(), 1);
786-
SendEvent::from_event(events.remove(0))
787-
};
788-
let mut prev_node = origin_node;
789-
790-
for (idx, &node) in expected_route.iter().enumerate() {
791-
assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
792-
793-
node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
794-
check_added_monitors!(node, 0);
795-
commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
796-
797-
expect_pending_htlcs_forwardable!(node);
798-
799-
if idx == expected_route.len() - 1 {
800-
let events_2 = node.node.get_and_clear_pending_events();
801-
assert_eq!(events_2.len(), 1);
802-
match events_2[0] {
803-
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
804-
assert_eq!(our_payment_hash, *payment_hash);
805-
assert_eq!(our_payment_secret, *payment_secret);
806-
assert_eq!(amt, recv_value);
807-
},
808-
_ => panic!("Unexpected event"),
779+
pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>) {
780+
origin_node.node.send_payment(route, our_payment_hash, &our_payment_secret).unwrap();
781+
check_added_monitors!(origin_node, expected_paths.len());
782+
783+
let mut events = origin_node.node.get_and_clear_pending_msg_events();
784+
assert_eq!(events.len(), expected_paths.len());
785+
for (path_idx, (ev, expected_route)) in events.drain(..).zip(expected_paths.iter()).enumerate() {
786+
let mut payment_event = SendEvent::from_event(ev);
787+
let mut prev_node = origin_node;
788+
789+
for (idx, &node) in expected_route.iter().enumerate() {
790+
assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
791+
792+
node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
793+
check_added_monitors!(node, 0);
794+
commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
795+
796+
expect_pending_htlcs_forwardable!(node);
797+
798+
if idx == expected_route.len() - 1 {
799+
let events_2 = node.node.get_and_clear_pending_events();
800+
// Once we've gotten through all the HTLCs, the last one should result in a
801+
// PaymentReceived (but each previous one should not!).
802+
if path_idx == expected_paths.len() - 1 {
803+
assert_eq!(events_2.len(), 1);
804+
match events_2[0] {
805+
Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
806+
assert_eq!(our_payment_hash, *payment_hash);
807+
assert_eq!(our_payment_secret, *payment_secret);
808+
assert_eq!(amt, recv_value);
809+
},
810+
_ => panic!("Unexpected event"),
811+
}
812+
} else {
813+
assert!(events_2.is_empty());
814+
}
815+
} else {
816+
let mut events_2 = node.node.get_and_clear_pending_msg_events();
817+
assert_eq!(events_2.len(), 1);
818+
check_added_monitors!(node, 1);
819+
payment_event = SendEvent::from_event(events_2.remove(0));
820+
assert_eq!(payment_event.msgs.len(), 1);
809821
}
810-
} else {
811-
let mut events_2 = node.node.get_and_clear_pending_msg_events();
812-
assert_eq!(events_2.len(), 1);
813-
check_added_monitors!(node, 1);
814-
payment_event = SendEvent::from_event(events_2.remove(0));
815-
assert_eq!(payment_event.msgs.len(), 1);
816-
}
817822

818-
prev_node = node;
823+
prev_node = node;
824+
}
819825
}
820826
}
821827

822828
pub fn send_along_route_with_hash<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash) {
823-
send_along_route_with_secret(origin_node, route, expected_route, recv_value, our_payment_hash, None);
829+
send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, None);
824830
}
825831

826832
pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
@@ -829,86 +835,96 @@ pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route
829835
(our_payment_preimage, our_payment_hash)
830836
}
831837

832-
pub fn claim_payment_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option<PaymentSecret>, expected_amount: u64) {
833-
assert!(expected_route.last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount));
834-
check_added_monitors!(expected_route.last().unwrap(), 1);
838+
pub fn claim_payment_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option<PaymentSecret>, expected_amount: u64) {
839+
for path in expected_paths.iter() {
840+
assert_eq!(path.last().unwrap().node.get_our_node_id(), expected_paths[0].last().unwrap().node.get_our_node_id());
841+
}
842+
assert!(expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount));
843+
check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len());
835844

836-
let mut next_msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)> = None;
837-
let mut expected_next_node = expected_route.last().unwrap().node.get_our_node_id();
838-
macro_rules! get_next_msgs {
839-
($node: expr) => {
840-
{
841-
let events = $node.node.get_and_clear_pending_msg_events();
842-
assert_eq!(events.len(), 1);
843-
match events[0] {
844-
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 } } => {
845-
assert!(update_add_htlcs.is_empty());
846-
assert_eq!(update_fulfill_htlcs.len(), 1);
847-
assert!(update_fail_htlcs.is_empty());
848-
assert!(update_fail_malformed_htlcs.is_empty());
849-
assert!(update_fee.is_none());
850-
expected_next_node = node_id.clone();
851-
Some((update_fulfill_htlcs[0].clone(), commitment_signed.clone()))
852-
},
853-
_ => panic!("Unexpected event"),
854-
}
845+
macro_rules! msgs_from_ev {
846+
($ev: expr) => {
847+
match $ev {
848+
&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 } } => {
849+
assert!(update_add_htlcs.is_empty());
850+
assert_eq!(update_fulfill_htlcs.len(), 1);
851+
assert!(update_fail_htlcs.is_empty());
852+
assert!(update_fail_malformed_htlcs.is_empty());
853+
assert!(update_fee.is_none());
854+
((update_fulfill_htlcs[0].clone(), commitment_signed.clone()), node_id.clone())
855+
},
856+
_ => panic!("Unexpected event"),
855857
}
856858
}
857859
}
860+
let mut per_path_msgs: Vec<((msgs::UpdateFulfillHTLC, msgs::CommitmentSigned), PublicKey)> = Vec::with_capacity(expected_paths.len());
861+
let events = expected_paths[0].last().unwrap().node.get_and_clear_pending_msg_events();
862+
assert_eq!(events.len(), expected_paths.len());
863+
for ev in events.iter() {
864+
per_path_msgs.push(msgs_from_ev!(ev));
865+
}
858866

859-
macro_rules! last_update_fulfill_dance {
860-
($node: expr, $prev_node: expr) => {
861-
{
862-
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
863-
check_added_monitors!($node, 0);
864-
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
865-
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
867+
for (expected_route, (path_msgs, next_hop)) in expected_paths.iter().zip(per_path_msgs.drain(..)) {
868+
let mut next_msgs = Some(path_msgs);
869+
let mut expected_next_node = next_hop;
870+
871+
macro_rules! last_update_fulfill_dance {
872+
($node: expr, $prev_node: expr) => {
873+
{
874+
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
875+
check_added_monitors!($node, 0);
876+
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
877+
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
878+
}
866879
}
867880
}
868-
}
869-
macro_rules! mid_update_fulfill_dance {
870-
($node: expr, $prev_node: expr, $new_msgs: expr) => {
871-
{
872-
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
873-
check_added_monitors!($node, 1);
874-
let new_next_msgs = if $new_msgs {
875-
get_next_msgs!($node)
876-
} else {
877-
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
878-
None
879-
};
880-
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
881-
next_msgs = new_next_msgs;
881+
macro_rules! mid_update_fulfill_dance {
882+
($node: expr, $prev_node: expr, $new_msgs: expr) => {
883+
{
884+
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
885+
check_added_monitors!($node, 1);
886+
let new_next_msgs = if $new_msgs {
887+
let events = $node.node.get_and_clear_pending_msg_events();
888+
assert_eq!(events.len(), 1);
889+
let (res, nexthop) = msgs_from_ev!(&events[0]);
890+
expected_next_node = nexthop;
891+
Some(res)
892+
} else {
893+
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
894+
None
895+
};
896+
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
897+
next_msgs = new_next_msgs;
898+
}
882899
}
883900
}
884-
}
885901

886-
let mut prev_node = expected_route.last().unwrap();
887-
for (idx, node) in expected_route.iter().rev().enumerate() {
888-
assert_eq!(expected_next_node, node.node.get_our_node_id());
889-
let update_next_msgs = !skip_last || idx != expected_route.len() - 1;
890-
if next_msgs.is_some() {
891-
mid_update_fulfill_dance!(node, prev_node, update_next_msgs);
892-
} else if update_next_msgs {
893-
next_msgs = get_next_msgs!(node);
894-
} else {
895-
assert!(node.node.get_and_clear_pending_msg_events().is_empty());
896-
}
897-
if !skip_last && idx == expected_route.len() - 1 {
898-
assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
899-
}
902+
let mut prev_node = expected_route.last().unwrap();
903+
for (idx, node) in expected_route.iter().rev().enumerate().skip(1) {
904+
assert_eq!(expected_next_node, node.node.get_our_node_id());
905+
let update_next_msgs = !skip_last || idx != expected_route.len() - 1;
906+
if next_msgs.is_some() {
907+
mid_update_fulfill_dance!(node, prev_node, update_next_msgs);
908+
} else {
909+
assert!(!update_next_msgs);
910+
assert!(node.node.get_and_clear_pending_msg_events().is_empty());
911+
}
912+
if !skip_last && idx == expected_route.len() - 1 {
913+
assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
914+
}
900915

901-
prev_node = node;
902-
}
916+
prev_node = node;
917+
}
903918

904-
if !skip_last {
905-
last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
906-
expect_payment_sent!(origin_node, our_payment_preimage);
919+
if !skip_last {
920+
last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
921+
expect_payment_sent!(origin_node, our_payment_preimage);
922+
}
907923
}
908924
}
909925

910926
pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], skip_last: bool, our_payment_preimage: PaymentPreimage, expected_amount: u64) {
911-
claim_payment_along_route_with_secret(origin_node, expected_route, skip_last, our_payment_preimage, None, expected_amount);
927+
claim_payment_along_route_with_secret(origin_node, &[expected_route], skip_last, our_payment_preimage, None, expected_amount);
912928
}
913929

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

lightning/src/ln/functional_tests.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7569,10 +7569,42 @@ fn test_simple_payment_secret() {
75697569
let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]);
75707570
let payment_secret = PaymentSecret([0xdb; 32]);
75717571
let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
7572-
send_along_route_with_secret(&nodes[0], route, &[&nodes[1], &nodes[2]], 100000, payment_hash, Some(payment_secret.clone()));
7572+
send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2]]], 100000, payment_hash, Some(payment_secret.clone()));
75737573
// Claiming with all the correct values but the wrong secret should result in nothing...
75747574
assert_eq!(nodes[2].node.claim_funds(payment_preimage, &None, 100_000), false);
75757575
assert_eq!(nodes[2].node.claim_funds(payment_preimage, &Some(PaymentSecret([42; 32])), 100_000), false);
75767576
// ...but with the right secret we should be able to claim all the way back
7577-
claim_payment_along_route_with_secret(&nodes[0], &[&nodes[1], &nodes[2]], false, payment_preimage, Some(payment_secret.clone()), 100_000);
7577+
claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage, Some(payment_secret.clone()), 100_000);
7578+
}
7579+
7580+
#[test]
7581+
fn test_simple_mpp() {
7582+
// Simple test of sending a multi-path payment.
7583+
let chanmon_cfgs = create_chanmon_cfgs(4);
7584+
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
7585+
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
7586+
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
7587+
7588+
let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7589+
let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7590+
let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7591+
let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7592+
7593+
let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]);
7594+
let payment_secret = PaymentSecret([0xdb; 32]);
7595+
let mut route = nodes[0].router.get_route(&nodes[3].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
7596+
let path = route.paths[0].clone();
7597+
route.paths.push(path);
7598+
route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
7599+
route.paths[0][0].short_channel_id = chan_1_id;
7600+
route.paths[0][1].short_channel_id = chan_3_id;
7601+
route.paths[1][0].pubkey = nodes[2].node.get_our_node_id();
7602+
route.paths[1][0].short_channel_id = chan_2_id;
7603+
route.paths[1][1].short_channel_id = chan_4_id;
7604+
send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], 200_000, payment_hash, Some(payment_secret.clone()));
7605+
// Claiming with all the correct values but the wrong secret should result in nothing...
7606+
assert_eq!(nodes[3].node.claim_funds(payment_preimage, &None, 200_000), false);
7607+
assert_eq!(nodes[3].node.claim_funds(payment_preimage, &Some(PaymentSecret([42; 32])), 200_000), false);
7608+
// ...but with the right secret we should be able to claim all the way back
7609+
claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage, Some(payment_secret), 200_000);
75787610
}

0 commit comments

Comments
 (0)