Skip to content

Commit e1000b2

Browse files
committed
Refactor test utils and add a simple MPP send/claim test.
1 parent e0f3a03 commit e1000b2

File tree

2 files changed

+151
-105
lines changed

2 files changed

+151
-105
lines changed

lightning/src/ln/functional_test_utils.rs

Lines changed: 117 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -776,51 +776,55 @@ 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<[u8; 32]>) {
780-
let mut payment_event = {
781-
origin_node.node.send_payment(route, our_payment_hash, our_payment_secret.as_ref()).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<[u8; 32]>) {
780+
origin_node.node.send_payment(route, our_payment_hash, our_payment_secret.as_ref()).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+
if path_idx == expected_paths.len() - 1 {
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"),
809+
}
810+
} else {
811+
assert!(events_2.is_empty());
812+
}
813+
} else {
814+
let mut events_2 = node.node.get_and_clear_pending_msg_events();
815+
assert_eq!(events_2.len(), 1);
816+
check_added_monitors!(node, 1);
817+
payment_event = SendEvent::from_event(events_2.remove(0));
818+
assert_eq!(payment_event.msgs.len(), 1);
809819
}
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-
}
817820

818-
prev_node = node;
821+
prev_node = node;
822+
}
819823
}
820824
}
821825

822826
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);
827+
send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, None);
824828
}
825829

826830
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 +833,96 @@ pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route
829833
(our_payment_preimage, our_payment_hash)
830834
}
831835

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<[u8; 32]>, 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);
836+
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<[u8; 32]>, expected_amount: u64) {
837+
for path in expected_paths.iter() {
838+
assert_eq!(path.last().unwrap().node.get_our_node_id(), expected_paths[0].last().unwrap().node.get_our_node_id());
839+
}
840+
assert!(expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount));
841+
check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len());
835842

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-
}
843+
macro_rules! msgs_from_ev {
844+
($ev: expr) => {
845+
match $ev {
846+
&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 } } => {
847+
assert!(update_add_htlcs.is_empty());
848+
assert_eq!(update_fulfill_htlcs.len(), 1);
849+
assert!(update_fail_htlcs.is_empty());
850+
assert!(update_fail_malformed_htlcs.is_empty());
851+
assert!(update_fee.is_none());
852+
((update_fulfill_htlcs[0].clone(), commitment_signed.clone()), node_id.clone())
853+
},
854+
_ => panic!("Unexpected event"),
855855
}
856856
}
857857
}
858+
let mut per_path_msgs: Vec<((msgs::UpdateFulfillHTLC, msgs::CommitmentSigned), PublicKey)> = Vec::with_capacity(expected_paths.len());
859+
let events = expected_paths[0].last().unwrap().node.get_and_clear_pending_msg_events();
860+
assert_eq!(events.len(), expected_paths.len());
861+
for ev in events.iter() {
862+
per_path_msgs.push(msgs_from_ev!(ev));
863+
}
858864

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);
865+
for (expected_route, (path_msgs, next_hop)) in expected_paths.iter().zip(per_path_msgs.drain(..)) {
866+
let mut next_msgs = Some(path_msgs);
867+
let mut expected_next_node = next_hop;
868+
869+
macro_rules! last_update_fulfill_dance {
870+
($node: expr, $prev_node: 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, 0);
874+
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
875+
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
876+
}
866877
}
867878
}
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;
879+
macro_rules! mid_update_fulfill_dance {
880+
($node: expr, $prev_node: expr, $new_msgs: expr) => {
881+
{
882+
$node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
883+
check_added_monitors!($node, 1);
884+
let new_next_msgs = if $new_msgs {
885+
let events = $node.node.get_and_clear_pending_msg_events();
886+
assert_eq!(events.len(), 1);
887+
let (res, nexthop) = msgs_from_ev!(&events[0]);
888+
expected_next_node = nexthop;
889+
Some(res)
890+
} else {
891+
assert!($node.node.get_and_clear_pending_msg_events().is_empty());
892+
None
893+
};
894+
commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
895+
next_msgs = new_next_msgs;
896+
}
882897
}
883898
}
884-
}
885899

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-
}
900+
let mut prev_node = expected_route.last().unwrap();
901+
for (idx, node) in expected_route.iter().rev().enumerate().skip(1) {
902+
assert_eq!(expected_next_node, node.node.get_our_node_id());
903+
let update_next_msgs = !skip_last || idx != expected_route.len() - 1;
904+
if next_msgs.is_some() {
905+
mid_update_fulfill_dance!(node, prev_node, update_next_msgs);
906+
} else {
907+
assert!(!update_next_msgs);
908+
assert!(node.node.get_and_clear_pending_msg_events().is_empty());
909+
}
910+
if !skip_last && idx == expected_route.len() - 1 {
911+
assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
912+
}
900913

901-
prev_node = node;
902-
}
914+
prev_node = node;
915+
}
903916

904-
if !skip_last {
905-
last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
906-
expect_payment_sent!(origin_node, our_payment_preimage);
917+
if !skip_last {
918+
last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
919+
expect_payment_sent!(origin_node, our_payment_preimage);
920+
}
907921
}
908922
}
909923

910924
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);
925+
claim_payment_along_route_with_secret(origin_node, &[expected_route], skip_last, our_payment_preimage, None, expected_amount);
912926
}
913927

914928
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
@@ -7367,10 +7367,42 @@ fn test_simple_payment_secret() {
73677367
let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]);
73687368
let (_, payment_secret) = get_payment_preimage_hash!(&nodes[0]);
73697369
let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
7370-
send_along_route_with_secret(&nodes[0], route, &[&nodes[1], &nodes[2]], 100000, payment_hash, Some(payment_secret.0));
7370+
send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2]]], 100000, payment_hash, Some(payment_secret.0));
73717371
// Claiming with all the correct values but the wrong secret should result in nothing...
73727372
assert_eq!(nodes[2].node.claim_funds(payment_preimage, &None, 100_000), false);
73737373
assert_eq!(nodes[2].node.claim_funds(payment_preimage, &Some([42; 32]), 100_000), false);
73747374
// ...but with the right secret we should be able to claim all the way back
7375-
claim_payment_along_route_with_secret(&nodes[0], &[&nodes[1], &nodes[2]], false, payment_preimage, Some(payment_secret.0), 100_000);
7375+
claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage, Some(payment_secret.0), 100_000);
7376+
}
7377+
7378+
#[test]
7379+
fn test_simple_mpp() {
7380+
// Simple test of sending a multi-path payment.
7381+
let chanmon_cfgs = create_chanmon_cfgs(4);
7382+
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
7383+
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
7384+
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
7385+
7386+
let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7387+
let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7388+
let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7389+
let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
7390+
7391+
let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]);
7392+
let (_, payment_secret) = get_payment_preimage_hash!(&nodes[0]);
7393+
let mut route = nodes[0].router.get_route(&nodes[3].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
7394+
let path = route.paths[0].clone();
7395+
route.paths.push(path);
7396+
route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
7397+
route.paths[0][0].short_channel_id = chan_1_id;
7398+
route.paths[0][1].short_channel_id = chan_3_id;
7399+
route.paths[1][0].pubkey = nodes[2].node.get_our_node_id();
7400+
route.paths[1][0].short_channel_id = chan_2_id;
7401+
route.paths[1][1].short_channel_id = chan_4_id;
7402+
send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], 200_000, payment_hash, Some(payment_secret.0));
7403+
// Claiming with all the correct values but the wrong secret should result in nothing...
7404+
assert_eq!(nodes[3].node.claim_funds(payment_preimage, &None, 200_000), false);
7405+
assert_eq!(nodes[3].node.claim_funds(payment_preimage, &Some([42; 32]), 200_000), false);
7406+
// ...but with the right secret we should be able to claim all the way back
7407+
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);
73767408
}

0 commit comments

Comments
 (0)