Skip to content

Commit 0e1ccd8

Browse files
F phantom invoice hints filtering tests
1 parent 2e9c089 commit 0e1ccd8

File tree

1 file changed

+103
-50
lines changed

1 file changed

+103
-50
lines changed

lightning-invoice/src/utils.rs

Lines changed: 103 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -733,14 +733,14 @@ mod test {
733733
nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_2.0);
734734

735735
let mut short_chan_ids = HashSet::new();
736-
short_chan_ids.insert(chan_0_1.0.contents.short_channel_id.clone());
737-
short_chan_ids.insert(chan_0_2.0.contents.short_channel_id.clone());
736+
short_chan_ids.insert(chan_0_1.0.contents.short_channel_id);
737+
short_chan_ids.insert(chan_0_2.0.contents.short_channel_id);
738738

739739
match_multi_node_invoice_routes(
740740
Some(10_000),
741741
&nodes[1],
742742
vec![&nodes[1], &nodes[2],],
743-
short_chan_ids.clone(),
743+
short_chan_ids,
744744
false
745745
);
746746
}
@@ -768,51 +768,92 @@ mod test {
768768
nodes[3].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &chan_1_3.0);
769769

770770
let mut short_chan_ids = HashSet::new();
771-
short_chan_ids.insert(chan_0_2.0.contents.short_channel_id.clone());
772-
short_chan_ids.insert(chan_0_3.0.contents.short_channel_id.clone());
773-
short_chan_ids.insert(chan_1_3.0.contents.short_channel_id.clone());
771+
short_chan_ids.insert(chan_0_2.0.contents.short_channel_id);
772+
short_chan_ids.insert(chan_0_3.0.contents.short_channel_id);
773+
short_chan_ids.insert(chan_1_3.0.contents.short_channel_id);
774774

775775
match_multi_node_invoice_routes(
776776
Some(10_000),
777777
&nodes[2],
778778
vec![&nodes[2], &nodes[3],],
779-
short_chan_ids.clone(),
779+
short_chan_ids,
780780
false
781781
);
782782
}
783783

784784
#[test]
785785
#[cfg(feature = "std")]
786-
fn test_multi_node_with_private_channel_hints_includes_only_phantom_route() {
786+
fn test_multi_node_with_only_private_channels_hints_includes_all_channels() {
787787
let mut chanmon_cfgs = create_chanmon_cfgs(3);
788788
let seed_1 = [42 as u8; 32];
789789
let seed_2 = [43 as u8; 32];
790790
let cross_node_seed = [44 as u8; 32];
791791
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
792792
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
793793
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
794-
let mut nodes_2_priv_channels_conf = UserConfig::default();
795-
nodes_2_priv_channels_conf.channel_options.announced_channel = false;
796-
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, Some(nodes_2_priv_channels_conf)]);
794+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
797795
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
798796
let chan_0_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known());
799797
nodes[0].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &chan_0_1.1);
800798
nodes[1].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_1.0);
801799

802-
let chan_2_0 = create_private_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001, InitFeatures::known(), InitFeatures::known());
800+
let mut private_chan_cfg = UserConfig::default();
801+
private_chan_cfg.channel_options.announced_channel = false;
802+
let chan_2_0 = create_private_chan_between_nodes_with_value(&nodes, 2, 0, 100000, 10001, InitFeatures::known(), InitFeatures::known(), Some(private_chan_cfg));
803803
nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_2_0.1);
804804
nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan_2_0.0);
805805

806-
// Hints should include `chan_0_1` from as `nodes[1]` only have public channels, and no
807-
// channels for `nodes[2]` as it contains private channels.
806+
// Hints should include `chan_0_1` from as `nodes[1]` only have public channels, and also
807+
// `chan_0_2` as `nodes[2]` only has private channels.
808808
let mut short_chan_ids = HashSet::new();
809-
short_chan_ids.insert(chan_0_1.0.contents.short_channel_id.clone());
809+
short_chan_ids.insert(chan_0_1.0.contents.short_channel_id);
810+
short_chan_ids.insert(chan_2_0.0.contents.short_channel_id);
810811

811812
match_multi_node_invoice_routes(
812813
Some(10_000),
813814
&nodes[1],
814815
vec![&nodes[1], &nodes[2],],
815-
short_chan_ids.clone(),
816+
short_chan_ids,
817+
true
818+
);
819+
}
820+
821+
#[test]
822+
#[cfg(feature = "std")]
823+
fn test_multi_node_with_mixed_public_and_private_channel_hints_includes_only_phantom_route() {
824+
let mut chanmon_cfgs = create_chanmon_cfgs(4);
825+
let seed_1 = [42 as u8; 32];
826+
let seed_2 = [43 as u8; 32];
827+
let cross_node_seed = [44 as u8; 32];
828+
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
829+
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
830+
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
831+
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
832+
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
833+
let chan_0_2 = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, InitFeatures::known(), InitFeatures::known());
834+
nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan_0_2.1);
835+
nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_2.0);
836+
837+
let chan_0_3 = create_announced_chan_between_nodes_with_value(&nodes, 0, 3, 100000, 10001, InitFeatures::known(), InitFeatures::known());
838+
nodes[0].node.handle_channel_update(&nodes[3].node.get_our_node_id(), &chan_0_3.1);
839+
nodes[3].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_3.0);
840+
841+
let mut private_chan_cfg = UserConfig::default();
842+
private_chan_cfg.channel_options.announced_channel = false;
843+
let priv_chan_1_3 = create_private_chan_between_nodes_with_value(&nodes, 1, 3, 100000, 10001, InitFeatures::known(), InitFeatures::known(), Some(private_chan_cfg));
844+
nodes[1].node.handle_channel_update(&nodes[3].node.get_our_node_id(), &priv_chan_1_3.1);
845+
nodes[3].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &priv_chan_1_3.0);
846+
847+
// Hints should include `chan_0_2` from as `nodes[2]` only have public channels, and no
848+
// channels for `nodes[3]` as it contains a mix of public and private channels.
849+
let mut short_chan_ids = HashSet::new();
850+
short_chan_ids.insert(chan_0_2.0.contents.short_channel_id);
851+
852+
match_multi_node_invoice_routes(
853+
Some(10_000),
854+
&nodes[2],
855+
vec![&nodes[2], &nodes[3],],
856+
short_chan_ids,
816857
true
817858
);
818859
}
@@ -843,83 +884,95 @@ mod test {
843884
nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_2.0);
844885

845886
let mut short_chan_ids = HashSet::new();
846-
short_chan_ids.insert(chan_0_1_high_inbound_capacity.0.contents.short_channel_id.clone());
847-
short_chan_ids.insert(chan_0_2.0.contents.short_channel_id.clone());
887+
short_chan_ids.insert(chan_0_1_high_inbound_capacity.0.contents.short_channel_id);
888+
short_chan_ids.insert(chan_0_2.0.contents.short_channel_id);
848889

849890
match_multi_node_invoice_routes(
850891
Some(10_000),
851892
&nodes[1],
852893
vec![&nodes[1], &nodes[2],],
853-
short_chan_ids.clone(),
894+
short_chan_ids,
854895
false
855896
);
856897
}
857898

858899
#[test]
859900
#[cfg(feature = "std")]
860-
fn test_multi_node_hints_has_no_channels_with_lower_inbound_capacity_than_invoice_amt() {
861-
let mut chanmon_cfgs = create_chanmon_cfgs(3);
901+
fn test_multi_node_channels_inbound_capacity_lower_than_invoice_amt_filtering() {
902+
let mut chanmon_cfgs = create_chanmon_cfgs(4);
862903
let seed_1 = [42 as u8; 32];
863904
let seed_2 = [43 as u8; 32];
864905
let cross_node_seed = [44 as u8; 32];
865906
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
866907
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
867-
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
868-
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
869-
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
870-
let chan_0_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0, InitFeatures::known(), InitFeatures::known());
871-
nodes[0].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &chan_0_1.1);
872-
nodes[1].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_1.0);
908+
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
909+
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
910+
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
873911
let chan_0_2 = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1_000_000, 0, InitFeatures::known(), InitFeatures::known());
874912
nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan_0_2.1);
875913
nodes[2].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_2.0);
914+
let chan_0_3 = create_announced_chan_between_nodes_with_value(&nodes, 0, 3, 100_000, 0, InitFeatures::known(), InitFeatures::known());
915+
nodes[0].node.handle_channel_update(&nodes[3].node.get_our_node_id(), &chan_0_3.1);
916+
nodes[3].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &chan_0_3.0);
917+
let chan_1_3 = create_announced_chan_between_nodes_with_value(&nodes, 1, 3, 200_000, 0, InitFeatures::known(), InitFeatures::known());
918+
nodes[1].node.handle_channel_update(&nodes[3].node.get_our_node_id(), &chan_1_3.1);
919+
nodes[3].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &chan_1_3.0);
876920

877-
// 1 msat above chan_0_1's inbound capacity
921+
// Since the invoice 1 msat above chan_0_3's inbound capacity, it should be filtered out.
878922
let mut short_chan_ids_99_000_001_msat = HashSet::new();
879-
short_chan_ids_99_000_001_msat.insert(chan_0_2.0.contents.short_channel_id.clone());
923+
short_chan_ids_99_000_001_msat.insert(chan_0_2.0.contents.short_channel_id);
924+
short_chan_ids_99_000_001_msat.insert(chan_1_3.0.contents.short_channel_id);
880925

881926
match_multi_node_invoice_routes(
882927
Some(99_000_001),
883-
&nodes[1],
884-
vec![&nodes[1], &nodes[2],],
885-
short_chan_ids_99_000_001_msat.clone(),
928+
&nodes[2],
929+
vec![&nodes[2], &nodes[3],],
930+
short_chan_ids_99_000_001_msat,
886931
false
887932
);
888933

889-
// Exactly at chan_0_1's inbound capacity
934+
// Since the invoice is exactly at chan_0_3's inbound capacity, it should be included.
890935
let mut short_chan_ids_99_000_000_msat = HashSet::new();
891-
short_chan_ids_99_000_000_msat.insert(chan_0_1.0.contents.short_channel_id.clone());
892-
short_chan_ids_99_000_000_msat.insert(chan_0_2.0.contents.short_channel_id.clone());
936+
short_chan_ids_99_000_000_msat.insert(chan_0_2.0.contents.short_channel_id);
937+
short_chan_ids_99_000_000_msat.insert(chan_0_3.0.contents.short_channel_id);
938+
short_chan_ids_99_000_000_msat.insert(chan_1_3.0.contents.short_channel_id);
893939

894940

895941
match_multi_node_invoice_routes(
896942
Some(99_000_000),
897-
&nodes[1],
898-
vec![&nodes[1], &nodes[2],],
899-
short_chan_ids_99_000_000_msat.clone(),
943+
&nodes[2],
944+
vec![&nodes[2], &nodes[3],],
945+
short_chan_ids_99_000_000_msat,
900946
false
901947
);
902948

903-
// Invoices with a higher amount than any of our channels' inbound capacity should result
904-
// in no hints.
949+
// Since the invoice is above all of `nodes[2]` channels' inbound capacity, all of
950+
// `nodes[2]` them should be included.
951+
let mut short_chan_ids_300_000_000_msat = HashSet::new();
952+
short_chan_ids_300_000_000_msat.insert(chan_0_2.0.contents.short_channel_id);
953+
short_chan_ids_300_000_000_msat.insert(chan_0_3.0.contents.short_channel_id);
954+
short_chan_ids_300_000_000_msat.insert(chan_1_3.0.contents.short_channel_id);
955+
956+
905957
match_multi_node_invoice_routes(
906-
Some(99_000_000_1),
907-
&nodes[1],
908-
vec![&nodes[1], &nodes[2],],
909-
HashSet::new(),
958+
Some(300_000_000),
959+
&nodes[2],
960+
vec![&nodes[2], &nodes[3],],
961+
short_chan_ids_300_000_000_msat,
910962
false
911963
);
912964

913-
// An invoice with no specified amount should include all participating nodes in the hints.
965+
// Since the no specified amount, all channels should included.
914966
let mut short_chan_ids_no_specified_amount = HashSet::new();
915-
short_chan_ids_no_specified_amount.insert(chan_0_1.0.contents.short_channel_id.clone());
916-
short_chan_ids_no_specified_amount.insert(chan_0_2.0.contents.short_channel_id.clone());
967+
short_chan_ids_no_specified_amount.insert(chan_0_2.0.contents.short_channel_id);
968+
short_chan_ids_no_specified_amount.insert(chan_0_3.0.contents.short_channel_id);
969+
short_chan_ids_no_specified_amount.insert(chan_1_3.0.contents.short_channel_id);
917970

918971
match_multi_node_invoice_routes(
919972
None,
920-
&nodes[1],
921-
vec![&nodes[1], &nodes[2],],
922-
short_chan_ids_no_specified_amount.clone(),
973+
&nodes[2],
974+
vec![&nodes[2], &nodes[3],],
975+
short_chan_ids_no_specified_amount,
923976
false
924977
);
925978
}

0 commit comments

Comments
 (0)