4141#define PEER_FD 3
4242#define HSM_FD 4
4343
44+ /* Map public keys to the private key */
45+ struct node {
46+ struct privkey p ;
47+ struct node_id id ;
48+ const char * name ;
49+ };
50+
51+ static const struct node_id * node_key (const struct node * n )
52+ {
53+ return & n -> id ;
54+ }
55+ static bool node_cmp (const struct node * n , const struct node_id * node_id )
56+ {
57+ return node_id_eq (& n -> id , node_id );
58+ }
59+ HTABLE_DEFINE_TYPE (struct node , node_key , node_id_hash , node_cmp , node_map );
60+
4461struct info {
4562 /* To talk to lightningd */
4663 struct daemon_conn * dc ;
4764 /* The actual channel (to make sure we can fit!) */
4865 struct channel * channel ;
49- /* Cache of privkeys which have proven useful */
50- size_t * cached_node_idx ;
66+ /* Peer's privkey */
67+ struct node * peer ;
68+ /* Fast lookup for node ids to get privkeys */
69+ struct node_map * node_map ;
5170 /* Gossip map for lookup up our "channels" */
5271 struct gossmap * gossmap ;
5372 /* To check cltv delays */
@@ -72,7 +91,7 @@ struct info {
7291};
7392
7493/* FIXME: For the ecdh() function called by onion routines */
75- static size_t current_nodeidx ;
94+ static struct node * current_node ;
7695
7796/* Core of an outgoing HTLC: freed by succeed() or fail() */
7897struct fake_htlc {
@@ -106,40 +125,6 @@ struct reservation {
106125 struct amount_msat amount ;
107126};
108127
109- static void make_privkey (size_t idx , struct privkey * pk )
110- {
111- /* pyln-testing uses 'lightning-N' then all zeroes as hsm_secret. */
112- if (idx & 1 ) {
113- u32 salt = 0 ;
114- struct secret hsm_secret ;
115- memset (& hsm_secret , 0 , sizeof (hsm_secret ));
116- snprintf ((char * )& hsm_secret , sizeof (hsm_secret ),
117- "lightning-%zu" , idx >> 1 );
118-
119- /* This maps hsm_secret -> node privkey */
120- hkdf_sha256 (pk , sizeof (* pk ),
121- & salt , sizeof (salt ),
122- & hsm_secret , sizeof (hsm_secret ),
123- "nodeid" , 6 );
124- return ;
125- }
126-
127- /* gossmap-compress uses the node index (size_t, native endian), then all ones */
128- memset (pk , 1 , sizeof (* pk ));
129- idx >>= 1 ;
130- memcpy (pk , & idx , sizeof (idx ));
131-
132- struct pubkey pubkey ;
133- pubkey_from_privkey (pk , & pubkey );
134- }
135-
136- static const char * fmt_nodeidx (const tal_t * ctx , size_t idx )
137- {
138- if (idx & 1 )
139- return tal_fmt (ctx , "lightningd-%zu" , idx >> 1 );
140- return tal_fmt (ctx , "gossmap-node-%zu" , idx >> 1 );
141- }
142-
143128/* Return deterministic value >= min < max for this channel */
144129static u64 channel_range (const struct info * info ,
145130 const struct short_channel_id_dir * scidd ,
@@ -150,10 +135,8 @@ static u64 channel_range(const struct info *info,
150135
151136void ecdh (const struct pubkey * point , struct secret * ss )
152137{
153- struct privkey pk ;
154- make_privkey (current_nodeidx , & pk );
155138 if (secp256k1_ecdh (secp256k1_ctx , ss -> data , & point -> pubkey ,
156- pk .secret .data , NULL , NULL ) != 1 )
139+ current_node -> p .secret .data , NULL , NULL ) != 1 )
157140 abort ();
158141}
159142
@@ -270,15 +253,65 @@ static u8 *get_next_onion(const tal_t *ctx, const struct route_step *rs)
270253 abort ();
271254}
272255
273- /* Sets current_nodeidx, *next_onion_packet, *shared_secret and *me, and decodes */
256+ static struct node * make_peer_node (const tal_t * ctx )
257+ {
258+ struct node * n = tal (ctx , struct node );
259+ u32 salt = 0 ;
260+ struct secret hsm_secret ;
261+ struct pubkey pubkey ;
262+
263+ memset (& hsm_secret , 0 , sizeof (hsm_secret ));
264+ snprintf ((char * )& hsm_secret , sizeof (hsm_secret ),
265+ "lightning-2" );
266+
267+ /* This maps hsm_secret -> node privkey */
268+ hkdf_sha256 (& n -> p , sizeof (n -> p ),
269+ & salt , sizeof (salt ),
270+ & hsm_secret , sizeof (hsm_secret ),
271+ "nodeid" , 6 );
272+ pubkey_from_privkey (& n -> p , & pubkey );
273+ node_id_from_pubkey (& n -> id , & pubkey );
274+ n -> name = tal_fmt (n , "lightningd-2" );
275+
276+ return n ;
277+ }
278+
279+ /* expected_id is NULL for initial node (aka l2) */
280+ static struct node * get_current_node (struct info * info ,
281+ const struct node_id * expected_id )
282+ {
283+ if (!expected_id )
284+ return info -> peer ;
285+
286+ return node_map_get (info -> node_map , expected_id );
287+ }
288+
289+ static void populate_node_map (const struct gossmap * gossmap ,
290+ struct node_map * node_map )
291+ {
292+ for (size_t i = 0 ; i < gossmap_max_node_idx (gossmap ); i ++ ) {
293+ struct node * n = tal (node_map , struct node );
294+ struct pubkey pubkey ;
295+
296+ /* gossmap-compress uses the node index (size_t, native endian), then all ones */
297+ memset (& n -> p , 1 , sizeof (n -> p ));
298+ memcpy (& n -> p , & i , sizeof (i ));
299+ n -> name = tal_fmt (n , "node#%zu" , i );
300+
301+ pubkey_from_privkey (& n -> p , & pubkey );
302+ node_id_from_pubkey (& n -> id , & pubkey );
303+ node_map_add (node_map , n );
304+ }
305+ }
306+
307+ /* Sets current_node, *next_onion_packet, *shared_secret and *me, and decodes */
274308static struct onion_payload * decode_onion (const tal_t * ctx ,
275309 struct info * info ,
276310 const u8 onion_routing_packet [],
277311 const struct pubkey * path_key ,
278312 const struct sha256 * payment_hash ,
279313 struct amount_msat amount ,
280314 u32 cltv ,
281- const struct node_id * expected_id ,
282315 u8 * * next_onion_packet ,
283316 struct secret * shared_secret ,
284317 struct gossmap_node * * me )
@@ -289,9 +322,6 @@ static struct onion_payload *decode_onion(const tal_t *ctx,
289322 struct onion_payload * payload ;
290323 u64 failtlvtype ;
291324 size_t failtlvpos ;
292- struct privkey pk ;
293- struct pubkey current_pubkey ;
294- struct node_id current_node_id ;
295325 const char * explanation ;
296326
297327 op = parse_onionpacket (tmpctx , onion_routing_packet ,
@@ -301,35 +331,13 @@ static struct onion_payload *decode_onion(const tal_t *ctx,
301331 status_failed (STATUS_FAIL_INTERNAL_ERROR ,
302332 "Could not parse onion (failcode %u)" , failcode );
303333
304- /* Try previously-useful keys first */
305- for (size_t i = 0 ; i < tal_count (info -> cached_node_idx ); i ++ ) {
306- current_nodeidx = info -> cached_node_idx [i ];
307- if (!ecdh_maybe_blinding (& op -> ephemeralkey , path_key , shared_secret ))
308- abort ();
309- rs = process_onionpacket (tmpctx , op , shared_secret ,
310- payment_hash -> u .u8 , sizeof (* payment_hash ));
311- if (rs )
312- break ;
313- }
314-
315- if (!rs ) {
316- /* Try a new one */
317- for (current_nodeidx = 0 ; current_nodeidx < 100000 ; current_nodeidx ++ ) {
318- if (!ecdh_maybe_blinding (& op -> ephemeralkey , path_key , shared_secret ))
319- abort ();
320- rs = process_onionpacket (tmpctx , op , shared_secret ,
321- payment_hash -> u .u8 , sizeof (* payment_hash ));
322- if (rs )
323- break ;
324- }
325- if (!rs )
326- status_failed (STATUS_FAIL_INTERNAL_ERROR ,
327- "Could not find privkey for onion" );
328-
329- /* Add to cache */
330- tal_arr_expand (& info -> cached_node_idx , current_nodeidx );
331- }
332-
334+ if (!ecdh_maybe_blinding (& op -> ephemeralkey , path_key , shared_secret ))
335+ abort ();
336+ rs = process_onionpacket (tmpctx , op , shared_secret ,
337+ payment_hash -> u .u8 , sizeof (* payment_hash ));
338+ if (!rs )
339+ status_failed (STATUS_FAIL_INTERNAL_ERROR ,
340+ "Could not decode onion for %s" , current_node -> name );
333341 * next_onion_packet = get_next_onion (ctx , rs );
334342
335343 payload = onion_decode (tmpctx ,
@@ -344,26 +352,14 @@ static struct onion_payload *decode_onion(const tal_t *ctx,
344352 }
345353
346354 /* Find ourselves in the gossmap, so we know our channels */
347- make_privkey (current_nodeidx , & pk );
348- pubkey_from_privkey (& pk , & current_pubkey );
349- node_id_from_pubkey (& current_node_id , & current_pubkey );
350-
351- /* This means pay plugin messed up! */
352- if (expected_id && !node_id_eq (expected_id , & current_node_id ))
353- status_failed (STATUS_FAIL_INTERNAL_ERROR ,
354- "Onion sent to %s, but encrypted to %s" ,
355- fmt_node_id (tmpctx , expected_id ),
356- fmt_node_id (tmpctx , & current_node_id ));
357-
358- * me = gossmap_find_node (info -> gossmap , & current_node_id );
355+ * me = gossmap_find_node (info -> gossmap , & current_node -> id );
359356 if (!* me )
360357 status_failed (STATUS_FAIL_INTERNAL_ERROR ,
361358 "Cannot find %s (%s) in gossmap" ,
362- fmt_nodeidx ( tmpctx , current_nodeidx ) ,
363- fmt_node_id (tmpctx , & current_node_id ));
359+ current_node -> name ,
360+ fmt_node_id (tmpctx , & current_node -> id ));
364361
365- status_debug ("Unpacked onion for %s" ,
366- fmt_nodeidx (tmpctx , current_nodeidx ));
362+ status_debug ("Unpacked onion for %s" , current_node -> name );
367363 return payload ;
368364}
369365
@@ -382,7 +378,7 @@ static void fail(struct info *info,
382378 towire_u16 (& msg , failcode );
383379
384380 status_debug ("Failing payment at %s due to %s" ,
385- fmt_nodeidx (tmpctx , current_nodeidx ),
381+ fmt_node_id (tmpctx , & current_node -> id ),
386382 onion_wire_name (failcode ));
387383
388384 err = channel_fail_htlc (info -> channel ,
@@ -573,8 +569,7 @@ static void add_mpp(struct info *info,
573569 struct preimage preimage ;
574570 struct multi_payment * mp ;
575571
576- status_debug ("Received payment at %s" ,
577- fmt_nodeidx (tmpctx , current_nodeidx ));
572+ status_debug ("Received payment at %s" , current_node -> name );
578573 mp = add_payment_part (info , htlc , payload );
579574 if (!mp )
580575 return ;
@@ -706,14 +701,20 @@ static void forward_htlc(struct info *info,
706701 struct delayed_forward * dfwd ;
707702 unsigned int msec_delay ;
708703
704+ current_node = get_current_node (info , expected );
705+ if (!current_node ) {
706+ status_failed (STATUS_FAIL_INTERNAL_ERROR ,
707+ "Could not find privkey for %s" ,
708+ fmt_node_id (tmpctx , expected ));
709+ }
710+
709711 /* Decode, and figure out who I am */
710712 payload = decode_onion (tmpctx ,
711713 info ,
712714 onion_routing_packet ,
713715 path_key ,
714716 & htlc -> payment_hash ,
715717 amount , cltv_expiry ,
716- expected ,
717718 & next_onion_packet ,
718719 & shared_secret ,
719720 & me );
@@ -1291,7 +1292,10 @@ int main(int argc, char *argv[])
12911292 status_failed (STATUS_FAIL_INTERNAL_ERROR ,
12921293 "Loading gossmap %s" , strerror (errno ));
12931294
1294- info -> cached_node_idx = tal_arr (info , size_t , 0 );
1295+ info -> node_map = tal (info , struct node_map );
1296+ node_map_init (info -> node_map );
1297+ populate_node_map (info -> gossmap , info -> node_map );
1298+ info -> peer = make_peer_node (info );
12951299 info -> multi_payments = tal_arr (info , struct multi_payment * , 0 );
12961300 info -> reservations = tal_arr (info , struct reservation * , 0 );
12971301 timers_init (& info -> timers , time_mono ());
0 commit comments