11#include "config.h"
22#include <common/json_stream.h>
3+ #include <common/onionreply.h>
4+ #include <common/sphinx.h>
35#include <plugins/renepay/json.h>
46
57/* See if this notification is about one of our flows. */
@@ -72,12 +74,103 @@ struct route *tal_route_from_json(const tal_t *ctx, const char *buf,
7274 return tal_free (route );
7375}
7476
77+ static bool get_data_details_onionreply (struct payment_result * result ,
78+ const char * buffer ,
79+ const jsmntok_t * datatok ,
80+ struct secret * shared_secrets )
81+ {
82+ const tal_t * this_ctx = tal (result , tal_t );
83+ const jsmntok_t * onionreplytok ;
84+ struct onionreply * onionreply , * wonionreply ;
85+ const u8 * replymsg ;
86+ int index ;
87+
88+ onionreplytok = json_get_member (buffer , datatok , "onionreply" );
89+ if (!onionreplytok || !shared_secrets )
90+ goto fail ;
91+ onionreply = new_onionreply (
92+ this_ctx ,
93+ take (json_tok_bin_from_hex (this_ctx , buffer , onionreplytok )));
94+ assert (onionreply );
95+ /* FIXME: It seems that lightningd will unwrap top portion of the
96+ * onionreply for us before serializing it, while unwrap_onionreply will
97+ * try to do the entire unwraping. It would be a better API if either
98+ * lightningd unwraps the entire thing or it doesn't do any unwraping.
99+ * Also it wouldn't hurt if injectpaymentonion accepted the shared
100+ * secrets to allow lightningd do the decoding for us. */
101+ wonionreply = wrap_onionreply (this_ctx , & shared_secrets [0 ], onionreply );
102+ replymsg = unwrap_onionreply (this_ctx , shared_secrets ,
103+ tal_count (shared_secrets ),
104+ wonionreply , & index );
105+ if (replymsg ) {
106+ result -> failcode = tal (result , enum onion_wire );
107+ * result -> failcode = fromwire_peektype (replymsg );
108+
109+ result -> erring_index = tal (result , u32 );
110+ * result -> erring_index = index ;
111+ }
112+ tal_free (this_ctx );
113+ return true;
114+ fail :
115+ tal_free (this_ctx );
116+ return false;
117+ }
118+
119+ static bool get_data_details (struct payment_result * result ,
120+ const char * buffer ,
121+ const jsmntok_t * datatok )
122+ {
123+
124+ const jsmntok_t * erridxtok , * failcodetok , * errnodetok , * errchantok ,
125+ * errdirtok , * rawmsgtok , * failcodenametok ;
126+ erridxtok = json_get_member (buffer , datatok , "erring_index" );
127+ failcodetok = json_get_member (buffer , datatok , "failcode" );
128+
129+ if (!erridxtok || !failcodetok )
130+ return false;
131+ result -> failcode = tal (result , enum onion_wire );
132+ json_to_u32 (buffer , failcodetok , result -> failcode );
133+
134+ result -> erring_index = tal (result , u32 );
135+ json_to_u32 (buffer , erridxtok , result -> erring_index );
136+
137+ // search for other fields
138+ errnodetok = json_get_member (buffer , datatok , "erring_node" );
139+ errchantok = json_get_member (buffer , datatok , "erring_channel" );
140+ errdirtok = json_get_member (buffer , datatok , "erring_direction" );
141+ failcodenametok = json_get_member (buffer , datatok , "failcodename" );
142+ rawmsgtok = json_get_member (buffer , datatok , "raw_message" );
143+
144+ if (errnodetok != NULL ) {
145+ result -> erring_node = tal (result , struct node_id );
146+ json_to_node_id (buffer , errnodetok , result -> erring_node );
147+ }
148+
149+ if (errchantok != NULL ) {
150+ result -> erring_channel = tal (result , struct short_channel_id );
151+ json_to_short_channel_id (buffer , errchantok ,
152+ result -> erring_channel );
153+ }
154+ if (errdirtok != NULL ) {
155+ result -> erring_direction = tal (result , int );
156+ json_to_int (buffer , errdirtok , result -> erring_direction );
157+ }
158+ if (rawmsgtok != NULL )
159+ result -> raw_message =
160+ json_tok_bin_from_hex (result , buffer , rawmsgtok );
161+
162+ if (failcodenametok != NULL )
163+ result -> failcodename =
164+ json_strdup (result , buffer , failcodenametok );
165+
166+ return true;
167+ }
168+
75169struct payment_result * tal_sendpay_result_from_json (const tal_t * ctx ,
76170 const char * buffer ,
77- const jsmntok_t * toks )
171+ const jsmntok_t * toks ,
172+ struct secret * shared_secrets )
78173{
79- // FIXME: we will be getting onionreply try to decode these with
80- // shared_secrets
81174 const jsmntok_t * idtok = json_get_member (buffer , toks , "created_index" );
82175 const jsmntok_t * hashtok =
83176 json_get_member (buffer , toks , "payment_hash" );
@@ -89,8 +182,6 @@ struct payment_result *tal_sendpay_result_from_json(const tal_t *ctx,
89182 const jsmntok_t * codetok = json_get_member (buffer , toks , "code" );
90183 const jsmntok_t * msgtok = json_get_member (buffer , toks , "message" );
91184 const jsmntok_t * datatok = json_get_member (buffer , toks , "data" );
92- const jsmntok_t * erridxtok , * failcodetok , * rawmsgtok ,
93- * failcodenametok , * errchantok , * errnodetok , * errdirtok ;
94185 struct payment_result * result ;
95186
96187 /* Check if we have an error and need to descend into data to get
@@ -110,6 +201,7 @@ struct payment_result *tal_sendpay_result_from_json(const tal_t *ctx,
110201 }
111202
112203 result = tal (ctx , struct payment_result );
204+ memset (result , 0 , sizeof (struct payment_result ));
113205
114206 if (msgtok )
115207 result -> message = json_strdup (result , buffer , msgtok );
@@ -147,77 +239,12 @@ struct payment_result *tal_sendpay_result_from_json(const tal_t *ctx,
147239
148240 /* Now extract the error details if the error code is not 0 */
149241 if (result -> code != 0 && datatok ) {
150- erridxtok = json_get_member (buffer , datatok , "erring_index" );
151- errnodetok = json_get_member (buffer , datatok , "erring_node" );
152- errchantok = json_get_member (buffer , datatok , "erring_channel" );
153- errdirtok =
154- json_get_member (buffer , datatok , "erring_direction" );
155- failcodetok = json_get_member (buffer , datatok , "failcode" );
156- failcodenametok =
157- json_get_member (buffer , datatok , "failcodename" );
158- rawmsgtok = json_get_member (buffer , datatok , "raw_message" );
159- /* check type for sanity */
160- if ((failcodetok != NULL &&
161- failcodetok -> type != JSMN_PRIMITIVE ) ||
162- (failcodenametok != NULL &&
163- failcodenametok -> type != JSMN_STRING ) ||
164- (erridxtok != NULL && erridxtok -> type != JSMN_PRIMITIVE ) ||
165- (errnodetok != NULL && errnodetok -> type != JSMN_STRING ) ||
166- (errchantok != NULL && errchantok -> type != JSMN_STRING ) ||
167- (errdirtok != NULL && errdirtok -> type != JSMN_PRIMITIVE ) ||
168- (rawmsgtok != NULL && rawmsgtok -> type != JSMN_STRING ))
242+ /* try one, then try the other, then fail */
243+ if (!get_data_details (result , buffer , datatok ) &&
244+ !get_data_details_onionreply (result , buffer , datatok ,
245+ shared_secrets ))
169246 goto fail ;
170-
171- if (rawmsgtok != NULL )
172- result -> raw_message =
173- json_tok_bin_from_hex (result , buffer , rawmsgtok );
174- else
175- result -> raw_message = NULL ;
176-
177- if (failcodenametok != NULL )
178- result -> failcodename =
179- json_strdup (result , buffer , failcodenametok );
180- else
181- result -> failcodename = NULL ;
182-
183- if (failcodetok ){
184- result -> failcode = tal (result , enum onion_wire );
185- json_to_u32 (buffer , failcodetok , result -> failcode );
186- }else
187- result -> failcode = NULL ;
188- if (erridxtok != NULL ) {
189- result -> erring_index = tal (result , u32 );
190- json_to_u32 (buffer , erridxtok , result -> erring_index );
191- } else {
192- result -> erring_index = NULL ;
193- }
194-
195- if (errdirtok != NULL ) {
196- result -> erring_direction = tal (result , int );
197- json_to_int (buffer , errdirtok ,
198- result -> erring_direction );
199- } else {
200- result -> erring_direction = NULL ;
201- }
202-
203- if (errnodetok != NULL ) {
204- result -> erring_node = tal (result , struct node_id );
205- json_to_node_id (buffer , errnodetok ,
206- result -> erring_node );
207- } else {
208- result -> erring_node = NULL ;
209- }
210-
211- if (errchantok != NULL ) {
212- result -> erring_channel =
213- tal (result , struct short_channel_id );
214- json_to_short_channel_id (buffer , errchantok ,
215- result -> erring_channel );
216- } else {
217- result -> erring_channel = NULL ;
218- }
219247 }
220-
221248 return result ;
222249fail :
223250 return tal_free (result );
0 commit comments