@@ -45,14 +45,16 @@ use crate::blinded_path::BlindedPath;
45
45
use crate :: events:: { Event , MessageSendEventsProvider , PaymentPurpose } ;
46
46
use crate :: ln:: channelmanager:: { PaymentId , RecentPaymentDetails , Retry , self } ;
47
47
use crate :: ln:: functional_test_utils:: * ;
48
- use crate :: ln:: msgs:: { ChannelMessageHandler , Init , OnionMessage , OnionMessageHandler } ;
48
+ use crate :: ln:: msgs:: { ChannelMessageHandler , Init , NodeAnnouncement , OnionMessage , OnionMessageHandler , RoutingMessageHandler , SocketAddress , UnsignedGossipMessage , UnsignedNodeAnnouncement } ;
49
49
use crate :: offers:: invoice:: Bolt12Invoice ;
50
50
use crate :: offers:: invoice_error:: InvoiceError ;
51
51
use crate :: offers:: invoice_request:: InvoiceRequest ;
52
52
use crate :: offers:: parse:: Bolt12SemanticError ;
53
53
use crate :: onion_message:: messenger:: PeeledOnion ;
54
54
use crate :: onion_message:: offers:: OffersMessage ;
55
55
use crate :: onion_message:: packet:: ParsedOnionMessageContents ;
56
+ use crate :: routing:: gossip:: { NodeAlias , NodeId } ;
57
+ use crate :: sign:: { NodeSigner , Recipient } ;
56
58
57
59
use crate :: prelude:: * ;
58
60
@@ -98,6 +100,37 @@ fn disconnect_peers<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, peers: &[&Node<'a, 'b
98
100
}
99
101
}
100
102
103
+ fn announce_node_address < ' a , ' b , ' c > (
104
+ node : & Node < ' a , ' b , ' c > , peers : & [ & Node < ' a , ' b , ' c > ] , address : SocketAddress ,
105
+ ) {
106
+ let features = node. onion_messenger . provided_node_features ( )
107
+ | node. gossip_sync . provided_node_features ( ) ;
108
+ let rgb = [ 0u8 ; 3 ] ;
109
+ let announcement = UnsignedNodeAnnouncement {
110
+ features,
111
+ timestamp : 1000 ,
112
+ node_id : NodeId :: from_pubkey ( & node. keys_manager . get_node_id ( Recipient :: Node ) . unwrap ( ) ) ,
113
+ rgb,
114
+ alias : NodeAlias ( [ 0u8 ; 32 ] ) ,
115
+ addresses : vec ! [ address] ,
116
+ excess_address_data : Vec :: new ( ) ,
117
+ excess_data : Vec :: new ( ) ,
118
+ } ;
119
+ let signature = node. keys_manager . sign_gossip_message (
120
+ UnsignedGossipMessage :: NodeAnnouncement ( & announcement)
121
+ ) . unwrap ( ) ;
122
+
123
+ let msg = NodeAnnouncement {
124
+ signature,
125
+ contents : announcement
126
+ } ;
127
+
128
+ node. gossip_sync . handle_node_announcement ( & msg) . unwrap ( ) ;
129
+ for peer in peers {
130
+ peer. gossip_sync . handle_node_announcement ( & msg) . unwrap ( ) ;
131
+ }
132
+ }
133
+
101
134
fn route_bolt12_payment < ' a , ' b , ' c > (
102
135
node : & Node < ' a , ' b , ' c > , path : & [ & Node < ' a , ' b , ' c > ] , invoice : & Bolt12Invoice
103
136
) {
@@ -178,6 +211,58 @@ fn extract_invoice_error<'a, 'b, 'c>(
178
211
}
179
212
}
180
213
214
+ /// Checks that blinded paths without Tor-only nodes are preferred when constructing an offer.
215
+ #[ test]
216
+ fn prefers_non_tor_nodes_in_blinded_paths ( ) {
217
+ let mut accept_forward_cfg = test_default_channel_config ( ) ;
218
+ accept_forward_cfg. accept_forwards_to_priv_channels = true ;
219
+
220
+ let mut features = channelmanager:: provided_init_features ( & accept_forward_cfg) ;
221
+ features. set_onion_messages_optional ( ) ;
222
+ features. set_route_blinding_optional ( ) ;
223
+
224
+ let chanmon_cfgs = create_chanmon_cfgs ( 6 ) ;
225
+ let node_cfgs = create_node_cfgs ( 6 , & chanmon_cfgs) ;
226
+
227
+ * node_cfgs[ 1 ] . override_init_features . borrow_mut ( ) = Some ( features) ;
228
+
229
+ let node_chanmgrs = create_node_chanmgrs (
230
+ 6 , & node_cfgs, & [ None , Some ( accept_forward_cfg) , None , None , None , None ]
231
+ ) ;
232
+ let nodes = create_network ( 6 , & node_cfgs, & node_chanmgrs) ;
233
+
234
+ create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000_000 ) ;
235
+ create_unannounced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 10_000_000 , 1_000_000_000 ) ;
236
+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 10_000_000 , 1_000_000_000 ) ;
237
+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 4 , 10_000_000 , 1_000_000_000 ) ;
238
+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 5 , 10_000_000 , 1_000_000_000 ) ;
239
+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 4 , 10_000_000 , 1_000_000_000 ) ;
240
+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 5 , 10_000_000 , 1_000_000_000 ) ;
241
+
242
+ // Add an extra channel so that more than one of Bob's peers have MIN_PEER_CHANNELS.
243
+ create_announced_chan_between_nodes_with_value ( & nodes, 4 , 5 , 10_000_000 , 1_000_000_000 ) ;
244
+
245
+ let ( alice, bob, charlie, david) = ( & nodes[ 0 ] , & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ) ;
246
+ let bob_id = bob. node . get_our_node_id ( ) ;
247
+ let charlie_id = charlie. node . get_our_node_id ( ) ;
248
+
249
+ disconnect_peers ( alice, & [ charlie, david, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
250
+ disconnect_peers ( david, & [ bob, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
251
+
252
+ let tor = SocketAddress :: OnionV2 ( [ 255 , 254 , 253 , 252 , 251 , 250 , 249 , 248 , 247 , 246 , 38 , 7 ] ) ;
253
+ announce_node_address ( charlie, & [ alice, bob, david, & nodes[ 4 ] , & nodes[ 5 ] ] , tor) ;
254
+
255
+ let offer = bob. node
256
+ . create_offer_builder ( "coffee" . to_string ( ) ) . unwrap ( )
257
+ . amount_msats ( 10_000_000 )
258
+ . build ( ) . unwrap ( ) ;
259
+ assert_ne ! ( offer. signing_pubkey( ) , bob_id) ;
260
+ assert ! ( !offer. paths( ) . is_empty( ) ) ;
261
+ for path in offer. paths ( ) {
262
+ assert_ne ! ( path. introduction_node_id, charlie_id) ;
263
+ }
264
+ }
265
+
181
266
/// Checks that an offer can be paid through blinded paths and that ephemeral pubkeys are used
182
267
/// rather than exposing a node's pubkey.
183
268
#[ test]
0 commit comments