@@ -48,6 +48,7 @@ pub fn find_path<L: Deref, GL: Deref>(
48
48
let network_nodes = graph_lock. nodes ( ) ;
49
49
let our_node_id = NodeId :: from_pubkey ( our_node_pubkey) ;
50
50
let dest_node_id = NodeId :: from_pubkey ( destination) ;
51
+ if our_node_id == dest_node_id { return Err ( Error :: InvalidDestination ) }
51
52
52
53
// Add our start and first-hops to `frontier`.
53
54
let start = NodeId :: from_pubkey ( & our_node_pubkey) ;
@@ -56,6 +57,7 @@ pub fn find_path<L: Deref, GL: Deref>(
56
57
frontier. push ( PathBuildingHop { cost : 0 , node_id : start, parent_node_id : start } ) ;
57
58
if let Some ( first_hops) = first_hops {
58
59
for hop in first_hops {
60
+ if hop. counterparty . node_id == * our_node_pubkey { return Err ( Error :: InvalidFirstHop ) }
59
61
if !hop. counterparty . features . supports_onion_messages ( ) { continue ; }
60
62
let node_id = NodeId :: from_pubkey ( & hop. counterparty . node_id ) ;
61
63
frontier. push ( PathBuildingHop { cost : 1 , node_id, parent_node_id : start } ) ;
@@ -112,6 +114,10 @@ pub enum Error {
112
114
PathNotFound ,
113
115
/// We failed to convert this node id into a [`PublicKey`].
114
116
InvalidNodeId ( secp256k1:: Error ) ,
117
+ /// We attempted to generate a path to ourselves, which is not allowed.
118
+ InvalidDestination ,
119
+ /// First hops cannot have our node id as a counterparty node id.
120
+ InvalidFirstHop ,
115
121
}
116
122
117
123
impl fmt:: Display for Error {
@@ -120,6 +126,8 @@ impl fmt::Display for Error {
120
126
Error :: PathNotFound => write ! ( f, "Failed to find a path to the destination" ) ,
121
127
Error :: InvalidNodeId ( e) =>
122
128
write ! ( f, "Failed to convert a node id into a PublicKey with error: {}" , e) ,
129
+ Error :: InvalidDestination => write ! ( f, "Cannot generate a route to ourselves" ) ,
130
+ Error :: InvalidFirstHop => write ! ( f, "First hops cannot have our node id as a counterparty node id" ) ,
123
131
}
124
132
}
125
133
}
@@ -252,4 +260,21 @@ mod tests {
252
260
assert_eq ! ( path. len( ) , 1 ) ;
253
261
assert_eq ! ( path[ 0 ] , node_pks[ 0 ] ) ;
254
262
}
263
+
264
+ #[ test]
265
+ fn invalid_first_hop ( ) {
266
+ // Check that we can't generate a path if first_hops contains a counterparty node id that
267
+ // is equal to our node id.
268
+ let mut features = InitFeatures :: empty ( ) ;
269
+ features. set_onion_messages_optional ( ) ;
270
+ let ( secp_ctx, network_graph, gossip_sync, _, logger) = build_graph_with_features ( features. to_context ( ) ) ;
271
+ let ( _, our_id, privkeys, node_pks) = get_nodes ( & secp_ctx) ;
272
+
273
+ let bad_first_hop = vec ! [ get_channel_details( Some ( 2 ) , our_id, features, 100000 ) ] ;
274
+ let err = super :: find_path ( & our_id, & node_pks[ 2 ] , & network_graph, Some ( & bad_first_hop. iter ( ) . collect :: < Vec < _ > > ( ) ) , Arc :: clone ( & logger) ) . unwrap_err ( ) ;
275
+ assert_eq ! ( err, super :: Error :: InvalidFirstHop ) ;
276
+
277
+ let path = super :: find_path ( & our_id, & node_pks[ 2 ] , & network_graph, None , Arc :: clone ( & logger) ) . unwrap ( ) ;
278
+ assert_eq ! ( path. len( ) , 2 ) ;
279
+ }
255
280
}
0 commit comments