20
20
#include <sodium.h>
21
21
22
22
static struct gossmap * global_gossmap ;
23
- static struct node_id local_id ;
23
+ static struct pubkey local_id ;
24
24
static bool disable_connect = false;
25
25
static LIST_HEAD (sent_list );
26
26
@@ -33,8 +33,8 @@ struct sent {
33
33
struct command * cmd ;
34
34
/* The offer we are trying to get an invoice/payment for. */
35
35
struct tlv_offer * offer ;
36
- /* Path to use. */
37
- struct node_id * path ;
36
+ /* Path to use (including self) */
37
+ struct pubkey * path ;
38
38
39
39
/* The invreq we sent, OR the invoice we sent */
40
40
struct tlv_invoice_request * invreq ;
@@ -567,18 +567,21 @@ static void node_id_from_pubkey32(struct node_id *nid,
567
567
& node32_id -> pubkey );
568
568
}
569
569
570
- /* Create path to node which can carry onion messages; if it can't find
571
- * one, returns NULL. Fills in nodeid_parity for 33rd nodeid byte. */
572
- static struct node_id * path_to_node (const tal_t * ctx ,
573
- struct gossmap * gossmap ,
574
- const struct pubkey32 * node32_id ,
575
- enum nodeid_parity * parity )
570
+ /* Create path to node which can carry onion messages (including
571
+ * self); if it can't find one, returns NULL. Fills in nodeid_parity
572
+ * for 33rd nodeid byte. */
573
+ static struct pubkey * path_to_node (const tal_t * ctx ,
574
+ struct plugin * plugin ,
575
+ const struct pubkey32 * node32_id ,
576
+ enum nodeid_parity * parity )
576
577
{
577
578
struct route_hop * r ;
578
579
const struct dijkstra * dij ;
579
580
const struct gossmap_node * src ;
580
581
const struct gossmap_node * dst ;
581
- struct node_id * nodes , dstid ;
582
+ struct node_id dstid , local_nodeid ;
583
+ struct pubkey * nodes ;
584
+ struct gossmap * gossmap = get_gossmap (plugin );
582
585
583
586
/* We try both parities. */
584
587
* parity = nodeid_parity_even ;
@@ -597,7 +600,8 @@ static struct node_id *path_to_node(const tal_t *ctx,
597
600
* parity = node_parity (gossmap , dst );
598
601
599
602
/* If we don't exist in gossip, routing can't happen. */
600
- src = gossmap_find_node (gossmap , & local_id );
603
+ node_id_from_pubkey (& local_nodeid , & local_id );
604
+ src = gossmap_find_node (gossmap , & local_nodeid );
601
605
if (!src )
602
606
return NULL ;
603
607
@@ -608,9 +612,15 @@ static struct node_id *path_to_node(const tal_t *ctx,
608
612
if (!r )
609
613
return NULL ;
610
614
611
- nodes = tal_arr (ctx , struct node_id , tal_count (r ));
612
- for (size_t i = 0 ; i < tal_count (r ); i ++ )
613
- nodes [i ] = r [i ].node_id ;
615
+ nodes = tal_arr (ctx , struct pubkey , tal_count (r ) + 1 );
616
+ nodes [0 ] = local_id ;
617
+ for (size_t i = 0 ; i < tal_count (r ); i ++ ) {
618
+ if (!pubkey_from_node_id (& nodes [i + 1 ], & r [i ].node_id )) {
619
+ plugin_err (plugin , "Could not convert nodeid %s" ,
620
+ type_to_string (tmpctx , struct node_id ,
621
+ & r [i ].node_id ));
622
+ }
623
+ }
614
624
return nodes ;
615
625
}
616
626
@@ -631,19 +641,14 @@ static struct command_result *send_message(struct command *cmd,
631
641
struct out_req * req ;
632
642
633
643
/* FIXME: Maybe we should allow this? */
634
- if (tal_bytelen (sent -> path ) == 0 )
644
+ if (tal_count (sent -> path ) == 1 )
635
645
return command_fail (cmd , PAY_ROUTE_NOT_FOUND ,
636
646
"Refusing to talk to ourselves" );
637
647
638
- /* Reverse path is offset by one: we are the final node. */
639
- backwards = tal_arr (tmpctx , struct pubkey , tal_count (sent -> path ));
640
- for (size_t i = 0 ; i < tal_count (sent -> path ) - 1 ; i ++ ) {
641
- if (!pubkey_from_node_id (& backwards [tal_count (sent -> path )- 2 - i ],
642
- & sent -> path [i ]))
643
- abort ();
644
- }
645
- if (!pubkey_from_node_id (& backwards [tal_count (sent -> path )- 1 ], & local_id ))
646
- abort ();
648
+ /* Reverse path is offset by one. */
649
+ backwards = tal_arr (tmpctx , struct pubkey , tal_count (sent -> path ) - 1 );
650
+ for (size_t i = 0 ; i < tal_count (backwards ); i ++ )
651
+ backwards [tal_count (backwards )- 1 - i ] = sent -> path [i ];
647
652
648
653
/* Ok, now make reply for onion_message */
649
654
path = make_blindedpath (tmpctx , backwards , & blinding ,
@@ -654,9 +659,9 @@ static struct command_result *send_message(struct command *cmd,
654
659
forward_error ,
655
660
sent );
656
661
json_array_start (req -> js , "hops" );
657
- for (size_t i = 0 ; i < tal_count (sent -> path ); i ++ ) {
662
+ for (size_t i = 1 ; i < tal_count (sent -> path ); i ++ ) {
658
663
json_object_start (req -> js , NULL );
659
- json_add_node_id (req -> js , "id" , & sent -> path [i ]);
664
+ json_add_pubkey (req -> js , "id" , & sent -> path [i ]);
660
665
if (i == tal_count (sent -> path ) - 1 )
661
666
json_add_hex_talarr (req -> js , msgfield , msgval );
662
667
json_object_end (req -> js );
@@ -757,7 +762,17 @@ static struct command_result *try_other_parity(struct command *cmd,
757
762
758
763
/* Flip parity */
759
764
ca -> node_id .k [0 ] = SECP256K1_TAG_PUBKEY_ODD ;
760
- ca -> sent -> path [0 ] = ca -> node_id ;
765
+ /* Path is us -> them, so they're second entry */
766
+ if (!pubkey_from_node_id (& ca -> sent -> path [1 ], & ca -> node_id )) {
767
+ /* Should not happen!
768
+ * Pieter Wuille points out:
769
+ * y^2 = x^3 + 7 mod p
770
+ * negating y doesn’t change the left hand side
771
+ */
772
+ return command_done_err (cmd , LIGHTNINGD ,
773
+ "Failed: could not convert inverted pubkey?" ,
774
+ NULL );
775
+ }
761
776
req = jsonrpc_request_start (cmd -> plugin , cmd , "connect" , connected ,
762
777
connect_failed , ca );
763
778
json_add_node_id (req -> js , "id" , & ca -> node_id );
@@ -797,8 +812,14 @@ connect_direct(struct command *cmd,
797
812
}
798
813
799
814
/* Make a direct path -> dst. */
800
- sent -> path = tal_arr (sent , struct node_id , 1 );
801
- sent -> path [0 ] = ca -> node_id ;
815
+ sent -> path = tal_arr (sent , struct pubkey , 2 );
816
+ sent -> path [0 ] = local_id ;
817
+ if (!pubkey_from_node_id (& sent -> path [1 ], & ca -> node_id )) {
818
+ /* Should not happen! */
819
+ return command_done_err (cmd , LIGHTNINGD ,
820
+ "Failed: could not convert to pubkey?" ,
821
+ NULL );
822
+ }
802
823
803
824
if (disable_connect ) {
804
825
/* FIXME: This means we will fail if parity is wrong! */
@@ -918,7 +939,7 @@ static struct command_result *invreq_done(struct command *cmd,
918
939
}
919
940
}
920
941
921
- sent -> path = path_to_node (sent , get_gossmap ( cmd -> plugin ) ,
942
+ sent -> path = path_to_node (sent , cmd -> plugin ,
922
943
sent -> offer -> node_id ,
923
944
& parity );
924
945
if (!sent -> path )
@@ -978,7 +999,7 @@ force_payer_secret(struct command *cmd,
978
999
"Failed to sign with payer_secret" );
979
1000
}
980
1001
981
- sent -> path = path_to_node (sent , get_gossmap ( cmd -> plugin ) ,
1002
+ sent -> path = path_to_node (sent , cmd -> plugin ,
982
1003
sent -> offer -> node_id ,
983
1004
& parity );
984
1005
if (!sent -> path )
@@ -1273,7 +1294,7 @@ static struct command_result *createinvoice_done(struct command *cmd,
1273
1294
"Bad createinvoice response %s" , fail );
1274
1295
}
1275
1296
1276
- sent -> path = path_to_node (sent , get_gossmap ( cmd -> plugin ) ,
1297
+ sent -> path = path_to_node (sent , cmd -> plugin ,
1277
1298
sent -> offer -> node_id ,
1278
1299
& parity );
1279
1300
if (!sent -> path )
@@ -1455,9 +1476,13 @@ static struct command_result *json_sendinvoice(struct command *cmd,
1455
1476
* - MUST set `description` the same as the offer.
1456
1477
*/
1457
1478
sent -> inv -> node_id = tal (sent -> inv , struct pubkey32 );
1458
- if (!pubkey32_from_node_id (sent -> inv -> node_id , & local_id ))
1459
- plugin_err (cmd -> plugin , "Invalid local_id %s?" ,
1460
- type_to_string (tmpctx , struct node_id , & local_id ));
1479
+
1480
+ /* This only fails if pubkey is invalid. */
1481
+ if (!secp256k1_xonly_pubkey_from_pubkey (secp256k1_ctx ,
1482
+ & sent -> inv -> node_id -> pubkey ,
1483
+ NULL ,
1484
+ & local_id .pubkey ))
1485
+ abort ();
1461
1486
1462
1487
sent -> inv -> description
1463
1488
= tal_dup_talarr (sent -> inv , char , sent -> offer -> description );
@@ -1633,7 +1658,7 @@ static struct command_result *json_rawrequest(struct command *cmd,
1633
1658
sent -> cmd = cmd ;
1634
1659
sent -> offer = NULL ;
1635
1660
1636
- sent -> path = path_to_node (sent , get_gossmap ( cmd -> plugin ) ,
1661
+ sent -> path = path_to_node (sent , cmd -> plugin ,
1637
1662
& node_id32 ,
1638
1663
& parity );
1639
1664
if (!sent -> path ) {
@@ -1680,7 +1705,7 @@ static const char *init(struct plugin *p, const char *buf UNUSED,
1680
1705
1681
1706
rpc_scan (p , "getinfo" ,
1682
1707
take (json_out_obj (NULL , NULL , NULL )),
1683
- "{id:%}" , JSON_SCAN (json_to_node_id , & local_id ));
1708
+ "{id:%}" , JSON_SCAN (json_to_pubkey , & local_id ));
1684
1709
1685
1710
rpc_scan (p , "listconfigs" ,
1686
1711
take (json_out_obj (NULL , "config" , "experimental-offers" )),
0 commit comments