1
+ #include <common/blindedpath.h>
1
2
#include <common/json_command.h>
2
3
#include <common/json_helpers.h>
3
4
#include <common/json_tok.h>
10
11
#include <lightningd/peer_control.h>
11
12
#include <lightningd/plugin_hook.h>
12
13
#include <lightningd/subd.h>
14
+ #include <sodium/randombytes.h>
13
15
14
16
struct onion_message_hook_payload {
15
17
/* Optional */
@@ -20,6 +22,26 @@ struct onion_message_hook_payload {
20
22
struct tlv_onionmsg_payload * om ;
21
23
};
22
24
25
+ static void json_add_blindedpath (struct json_stream * stream ,
26
+ const char * fieldname ,
27
+ const struct pubkey * blinding ,
28
+ const struct pubkey * first_node_id ,
29
+ struct onionmsg_path * * path )
30
+ {
31
+ json_object_start (stream , fieldname );
32
+ json_add_pubkey (stream , "blinding" , blinding );
33
+ json_add_pubkey (stream , "first_node_id" , first_node_id );
34
+ json_array_start (stream , "hops" );
35
+ for (size_t i = 0 ; i < tal_count (path ); i ++ ) {
36
+ json_object_start (stream , NULL );
37
+ json_add_pubkey (stream , "id" , & path [i ]-> node_id );
38
+ json_add_hex_talarr (stream , "enctlv" , path [i ]-> enctlv );
39
+ json_object_end (stream );
40
+ };
41
+ json_array_end (stream );
42
+ json_object_end (stream );
43
+ }
44
+
23
45
static void onion_message_serialize (struct onion_message_hook_payload * payload ,
24
46
struct json_stream * stream ,
25
47
struct plugin * plugin )
@@ -559,3 +581,103 @@ static const struct json_command sendonionmessage_command = {
559
581
"Send message to {first_id}, using {blinding}, encoded over {hops} (id, tlv)"
560
582
};
561
583
AUTODATA (json_command , & sendonionmessage_command );
584
+
585
+ static struct command_result * param_pubkeys (struct command * cmd ,
586
+ const char * name ,
587
+ const char * buffer ,
588
+ const jsmntok_t * tok ,
589
+ struct pubkey * * pubkeys )
590
+ {
591
+ size_t i ;
592
+ const jsmntok_t * t ;
593
+
594
+ if (tok -> type != JSMN_ARRAY || tok -> size == 0 )
595
+ return command_fail (cmd , JSONRPC2_INVALID_PARAMS ,
596
+ "%s must be an (non-empty) array" , name );
597
+
598
+ * pubkeys = tal_arr (cmd , struct pubkey , tok -> size );
599
+ json_for_each_arr (i , t , tok ) {
600
+ if (!json_to_pubkey (buffer , t , & (* pubkeys )[i ]))
601
+ return command_fail_badparam (cmd , name , buffer , t ,
602
+ "should be a compressed pubkey" );
603
+ }
604
+ return NULL ;
605
+ }
606
+
607
+ static struct command_result * json_blindedpath (struct command * cmd ,
608
+ const char * buffer ,
609
+ const jsmntok_t * obj UNNEEDED ,
610
+ const jsmntok_t * params )
611
+ {
612
+ struct pubkey * ids ;
613
+ struct onionmsg_path * * path ;
614
+ struct privkey blinding_iter ;
615
+ struct pubkey first_blinding , first_node , me ;
616
+ size_t nhops ;
617
+ struct json_stream * response ;
618
+
619
+ if (!param (cmd , buffer , params ,
620
+ p_req ("ids" , param_pubkeys , & ids ),
621
+ NULL ))
622
+ return command_param_failed ();
623
+
624
+ nhops = tal_count (ids );
625
+
626
+ /* Final id should be us! */
627
+ if (!pubkey_from_node_id (& me , & cmd -> ld -> id ))
628
+ fatal ("My id %s is invalid?" ,
629
+ type_to_string (tmpctx , struct node_id , & cmd -> ld -> id ));
630
+
631
+ first_node = ids [0 ];
632
+ if (!pubkey_eq (& ids [nhops - 1 ], & me ))
633
+ return command_fail (cmd , LIGHTNINGD ,
634
+ "Final of ids must be this node (%s), not %s" ,
635
+ type_to_string (tmpctx , struct pubkey , & me ),
636
+ type_to_string (tmpctx , struct pubkey ,
637
+ & ids [nhops - 1 ]));
638
+
639
+ randombytes_buf (& blinding_iter , sizeof (blinding_iter ));
640
+ if (!pubkey_from_privkey (& blinding_iter , & first_blinding ))
641
+ /* Should not happen! */
642
+ return command_fail (cmd , LIGHTNINGD ,
643
+ "Could not convert blinding to pubkey!" );
644
+
645
+ /* We convert ids into aliases as we go. */
646
+ path = tal_arr (cmd , struct onionmsg_path * , nhops );
647
+
648
+ for (size_t i = 0 ; i < nhops - 1 ; i ++ ) {
649
+ path [i ] = tal (path , struct onionmsg_path );
650
+ path [i ]-> enctlv = create_enctlv (path [i ],
651
+ & blinding_iter ,
652
+ & ids [i ],
653
+ & ids [i + 1 ],
654
+ /* FIXME: Pad? */
655
+ 0 ,
656
+ NULL ,
657
+ & blinding_iter ,
658
+ & path [i ]-> node_id );
659
+ }
660
+
661
+ /* FIXME: Add padding! */
662
+ path [nhops - 1 ] = tal (path , struct onionmsg_path );
663
+ path [nhops - 1 ]-> enctlv = create_final_enctlv (path [nhops - 1 ],
664
+ & blinding_iter ,
665
+ & ids [nhops - 1 ],
666
+ /* FIXME: Pad? */
667
+ 0 ,
668
+ & cmd -> ld -> onion_reply_secret ,
669
+ & path [nhops - 1 ]-> node_id );
670
+
671
+ response = json_stream_success (cmd );
672
+ json_add_blindedpath (response , "blindedpath" ,
673
+ & first_blinding , & first_node , path );
674
+ return command_success (cmd , response );
675
+ }
676
+
677
+ static const struct json_command blindedpath_command = {
678
+ "blindedpath" ,
679
+ "utility" ,
680
+ json_blindedpath ,
681
+ "Create blinded path to us along {ids} (pubkey array ending in our id)"
682
+ };
683
+ AUTODATA (json_command , & blindedpath_command );
0 commit comments