@@ -126,18 +126,28 @@ static struct command_result *update_gossip_failure(struct command *cmd UNUSED,
126126{
127127 assert (r );
128128 assert (r -> payment );
129+ assert (r -> route -> result -> erring_index );
130+
131+ const int index = * r -> route -> result -> erring_index ;
132+ struct short_channel_id_dir scidd ;
133+
134+ if (r -> route -> result -> erring_channel ) {
135+ scidd .scid = * r -> route -> result -> erring_channel ;
136+ scidd .dir = * r -> route -> result -> erring_direction ;
137+ } else if (r -> route -> hops ) {
138+ assert (index < tal_count (r -> route -> hops ));
139+ const struct route_hop * hop = & r -> route -> hops [index ];
140+ scidd .scid = hop -> scid ;
141+ scidd .dir = hop -> direction ;
142+
143+ } else /* don't have information to disable the erring channel */
144+ goto finish ;
129145
130- /* FIXME it might be too strong assumption that erring_channel should
131- * always be present here, but at least the documentation for
132- * waitsendpay says it is present in the case of error. */
133- assert (r -> route -> result -> erring_channel );
134- struct short_channel_id_dir scidd = {
135- .scid = * r -> route -> result -> erring_channel ,
136- .dir = * r -> route -> result -> erring_direction };
137146 payment_disable_chan (
138- r -> payment , scidd , LOG_INFORM ,
139- "addgossip failed (%.*s)" , json_tok_full_len (result ),
140- json_tok_full (buf , result ));
147+ r -> payment , scidd , LOG_INFORM , "addgossip failed (%.*s)" ,
148+ json_tok_full_len (result ), json_tok_full (buf , result ));
149+
150+ finish :
141151 return update_gossip_done (cmd , method , buf , result , r );
142152}
143153
@@ -188,6 +198,7 @@ static void route_final_error(struct route *route, enum jsonrpc_errcode error,
188198 route -> final_msg = tal_strdup (route , what );
189199}
190200
201+ /* FIXME: do proper error handling for BOLT12 */
191202static struct command_result * handle_failure (struct routefail * r )
192203{
193204 /* BOLT #4:
@@ -242,7 +253,12 @@ static struct command_result *handle_failure(struct routefail *r)
242253 if (route -> hops )
243254 path_len = tal_count (route -> hops );
244255
245- assert (result -> erring_index );
256+ if (!result -> erring_index ) {
257+ payment_note (
258+ payment , LOG_UNUSUAL ,
259+ "The erring_index is unknown we skip error handling" );
260+ goto finish ;
261+ }
246262
247263 enum node_type node_type = UNKNOWN_NODE ;
248264 if (route -> hops ) {
@@ -254,76 +270,128 @@ static struct command_result *handle_failure(struct routefail *r)
254270 node_type = INTERMEDIATE_NODE ;
255271 }
256272
257- assert (result -> erring_node );
258-
259273 switch (result -> failcode ) {
260274 // intermediate only
261275 case WIRE_INVALID_ONION_VERSION :
262276 case WIRE_INVALID_ONION_HMAC :
263277 case WIRE_INVALID_ONION_KEY :
264- if (node_type == FINAL_NODE )
278+ switch (node_type ) {
279+ case FINAL_NODE :
265280 payment_note (payment , LOG_UNUSUAL ,
266- "Final node %s reported strange "
281+ "Final node reported strange "
267282 "error code %04x (%s)" ,
268- fmt_node_id (tmpctx , result -> erring_node ),
269283 result -> failcode ,
270284 onion_wire_name (result -> failcode ));
285+ break ;
286+ case ORIGIN_NODE :
287+ case INTERMEDIATE_NODE :
288+ case UNKNOWN_NODE :
289+ break ;
290+ }
271291
272292 case WIRE_INVALID_ONION_BLINDING :
273- if (node_type == FINAL_NODE ) {
293+ switch (node_type ) {
294+ case FINAL_NODE :
274295 /* these errors from a final node mean a permanent
275296 * failure */
276297 route_final_error (
277298 route , PAY_DESTINATION_PERM_FAIL ,
278299 "Received error code %04x (%s) at final node." ,
279300 result -> failcode ,
280301 onion_wire_name (result -> failcode ));
281- } else if (node_type == INTERMEDIATE_NODE ||
282- node_type == ORIGIN_NODE ) {
302+
303+ break ;
304+ case INTERMEDIATE_NODE :
305+ case ORIGIN_NODE :
306+ if (!route -> hops )
307+ break ;
308+
283309 /* we disable the next node in the hop */
284310 assert (* result -> erring_index < path_len );
285311 payment_disable_node (
286- payment ,
287- route -> hops [* result -> erring_index ].node_id , LOG_DBG ,
288- "received %s from previous hop" ,
312+ payment , route -> hops [* result -> erring_index ].node_id ,
313+ LOG_DBG , "received %s from previous hop" ,
289314 onion_wire_name (result -> failcode ));
315+ break ;
316+ case UNKNOWN_NODE :
317+ break ;
290318 }
291319 break ;
292320
293321 // final only
294322 case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS :
323+ switch (node_type ) {
324+ case FINAL_NODE :
325+ route_final_error (route , PAY_DESTINATION_PERM_FAIL ,
326+ "Unknown invoice or wrong payment "
327+ "details at destination." );
328+ break ;
329+ case ORIGIN_NODE :
330+ route_final_error (
331+ route , PAY_UNSPECIFIED_ERROR ,
332+ "Error code %04x (%s) reported at the origin." ,
333+ failcode ,
334+ onion_wire_name (failcode ));
335+ break ;
336+ case INTERMEDIATE_NODE :
337+ if (!route -> hops )
338+ break ;
339+ payment_disable_node (
340+ payment ,
341+ route -> hops [* result -> erring_index - 1 ].node_id ,
342+ LOG_INFORM , "received error %s" ,
343+ onion_wire_name (failcode ));
344+ break ;
345+ case UNKNOWN_NODE :
346+ break ;
347+ }
348+ break ;
295349 case WIRE_FINAL_INCORRECT_HTLC_AMOUNT :
296350 case WIRE_FINAL_INCORRECT_CLTV_EXPIRY :
297- if (node_type == INTERMEDIATE_NODE )
351+ switch (node_type ) {
352+ case INTERMEDIATE_NODE :
298353 payment_note (payment , LOG_UNUSUAL ,
299- "Intermediate node %s reported strange "
354+ "Intermediate node reported strange "
300355 "error code %04x (%s)" ,
301- fmt_node_id (tmpctx , result -> erring_node ),
302356 result -> failcode ,
303357 onion_wire_name (result -> failcode ));
358+ break ;
359+ case ORIGIN_NODE :
360+ case FINAL_NODE :
361+ case UNKNOWN_NODE :
362+ break ;
363+ }
304364
305365 case WIRE_PERMANENT_NODE_FAILURE :
306366 case WIRE_REQUIRED_NODE_FEATURE_MISSING :
307367 case WIRE_TEMPORARY_NODE_FAILURE :
308368 case WIRE_INVALID_ONION_PAYLOAD :
309-
310- if ( node_type == FINAL_NODE ) {
369+ switch ( node_type ) {
370+ case FINAL_NODE :
311371 route_final_error (
312372 route , PAY_DESTINATION_PERM_FAIL ,
313373 "Received error code %04x (%s) at final node." ,
314374 result -> failcode ,
315375 onion_wire_name (result -> failcode ));
316- } else if (node_type == ORIGIN_NODE ) {
376+ break ;
377+ case ORIGIN_NODE :
317378 route_final_error (
318379 route , PAY_UNSPECIFIED_ERROR ,
319380 "Error code %04x (%s) reported at the origin." ,
320381 result -> failcode ,
321382 onion_wire_name (result -> failcode ));
322- } else {
323- payment_disable_node (payment ,
324- * result -> erring_node , LOG_INFORM ,
325- "received error %s" ,
326- onion_wire_name (result -> failcode ));
383+ break ;
384+ case INTERMEDIATE_NODE :
385+ if (!route -> hops )
386+ break ;
387+ payment_disable_node (
388+ payment ,
389+ route -> hops [* result -> erring_index - 1 ].node_id ,
390+ LOG_INFORM , "received error %s" ,
391+ onion_wire_name (result -> failcode ));
392+ break ;
393+ case UNKNOWN_NODE :
394+ break ;
327395 }
328396 break ;
329397
@@ -333,11 +401,11 @@ static struct command_result *handle_failure(struct routefail *r)
333401 case WIRE_UNKNOWN_NEXT_PEER :
334402 case WIRE_EXPIRY_TOO_FAR :
335403 case WIRE_CHANNEL_DISABLED :
336- if (node_type == FINAL_NODE ) {
404+ switch (node_type ) {
405+ case FINAL_NODE :
337406 payment_note (payment , LOG_UNUSUAL ,
338- "Final node %s reported strange "
407+ "Final node reported strange "
339408 "error code %04x (%s)" ,
340- fmt_node_id (tmpctx , result -> erring_node ),
341409 result -> failcode ,
342410 onion_wire_name (result -> failcode ));
343411
@@ -347,35 +415,56 @@ static struct command_result *handle_failure(struct routefail *r)
347415 result -> failcode ,
348416 onion_wire_name (result -> failcode ));
349417
350- } else {
351- assert (result -> erring_channel );
418+ break ;
419+ case ORIGIN_NODE :
420+ payment_note (payment , LOG_UNUSUAL ,
421+ "First node reported strange "
422+ "error code %04x (%s)" ,
423+ result -> failcode ,
424+ onion_wire_name (result -> failcode ));
425+
426+ break ;
427+ case INTERMEDIATE_NODE :
428+ if (!route -> hops )
429+ break ;
352430 struct short_channel_id_dir scidd = {
353- .scid = * result -> erring_channel ,
354- .dir = * result -> erring_direction };
355- payment_disable_chan (
356- payment , scidd , LOG_INFORM ,
357- "%s" , onion_wire_name (result -> failcode ));
431+ .scid = route -> hops [* result -> erring_index ].scid ,
432+ .dir = route -> hops [* result -> erring_index ].direction };
433+ payment_disable_chan (payment , scidd , LOG_INFORM , "%s" ,
434+ onion_wire_name (result -> failcode ));
435+
436+ break ;
437+ case UNKNOWN_NODE :
438+ break ;
358439 }
359440 break ;
360441 // final only
361442 case WIRE_MPP_TIMEOUT :
362-
363- if ( node_type == INTERMEDIATE_NODE ) {
443+ switch ( node_type ) {
444+ case INTERMEDIATE_NODE :
364445 /* Normally WIRE_MPP_TIMEOUT is raised by the final
365446 * node. If this is not the final node, then something
366447 * wrong is going on. We report it and disable that
367448 * node. */
368449 payment_note (payment , LOG_UNUSUAL ,
369- "Intermediate node %s reported strange "
450+ "Intermediate node reported strange "
370451 "error code %04x (%s)" ,
371- fmt_node_id (tmpctx , result -> erring_node ),
372452 result -> failcode ,
373453 onion_wire_name (result -> failcode ));
374454
375- payment_disable_node (payment ,
376- * result -> erring_node , LOG_INFORM ,
377- "received error %s" ,
378- onion_wire_name (result -> failcode ));
455+ if (!route -> hops )
456+ break ;
457+ payment_disable_node (
458+ payment ,
459+ route -> hops [* result -> erring_index - 1 ].node_id ,
460+ LOG_INFORM , "received error %s" ,
461+ onion_wire_name (result -> failcode ));
462+
463+ break ;
464+ case ORIGIN_NODE :
465+ case FINAL_NODE :
466+ case UNKNOWN_NODE :
467+ break ;
379468 }
380469 break ;
381470
@@ -384,12 +473,11 @@ static struct command_result *handle_failure(struct routefail *r)
384473 case WIRE_INCORRECT_CLTV_EXPIRY :
385474 case WIRE_FEE_INSUFFICIENT :
386475 case WIRE_AMOUNT_BELOW_MINIMUM :
387-
388- if ( node_type == FINAL_NODE ) {
476+ switch ( node_type ) {
477+ case FINAL_NODE :
389478 payment_note (payment , LOG_UNUSUAL ,
390- "Final node %s reported strange "
479+ "Final node reported strange "
391480 "error code %04x (%s)" ,
392- fmt_node_id (tmpctx , result -> erring_node ),
393481 result -> failcode ,
394482 onion_wire_name (result -> failcode ));
395483
@@ -399,33 +487,44 @@ static struct command_result *handle_failure(struct routefail *r)
399487 result -> failcode ,
400488 onion_wire_name (result -> failcode ));
401489
402- } else {
490+ break ;
491+ case ORIGIN_NODE :
492+ payment_note (payment , LOG_UNUSUAL ,
493+ "First node reported strange "
494+ "error code %04x (%s)" ,
495+ result -> failcode ,
496+ onion_wire_name (result -> failcode ));
497+
498+ break ;
499+ case INTERMEDIATE_NODE :
500+ if (!route -> hops )
501+ break ;
403502 /* Usually this means we need to update the channel
404503 * information and try again. To avoid hitting this
405504 * error again with the same channel we flag it. */
406- assert (result -> erring_channel );
407505 struct short_channel_id_dir scidd = {
408- .scid = * result -> erring_channel ,
409- .dir = * result -> erring_direction };
410- payment_warn_chan (payment ,
411- scidd , LOG_INFORM ,
506+ .scid = route -> hops [* result -> erring_index ].scid ,
507+ .dir = route -> hops [* result -> erring_index ].direction };
508+ payment_warn_chan (payment , scidd , LOG_INFORM ,
412509 "received error %s" ,
413510 onion_wire_name (result -> failcode ));
414- }
415511
512+ break ;
513+ case UNKNOWN_NODE :
514+ break ;
515+ }
416516 break ;
417517 // intermediate only
418518 case WIRE_TEMPORARY_CHANNEL_FAILURE :
419-
420- if ( node_type == FINAL_NODE ) {
519+ switch ( node_type ) {
520+ case FINAL_NODE :
421521 /* WIRE_TEMPORARY_CHANNEL_FAILURE could mean that the
422522 * next channel has not enough outbound liquidity or
423523 * cannot add another HTLC. A final node cannot raise
424524 * this error. */
425525 payment_note (payment , LOG_UNUSUAL ,
426- "Final node %s reported strange "
526+ "Final node reported strange "
427527 "error code %04x (%s)" ,
428- fmt_node_id (tmpctx , result -> erring_node ),
429528 result -> failcode ,
430529 onion_wire_name (result -> failcode ));
431530
@@ -434,9 +533,16 @@ static struct command_result *handle_failure(struct routefail *r)
434533 "Received error code %04x (%s) at final node." ,
435534 result -> failcode ,
436535 onion_wire_name (result -> failcode ));
437- }
438536
537+ break ;
538+ case INTERMEDIATE_NODE :
539+ case ORIGIN_NODE :
540+ case UNKNOWN_NODE :
541+ break ;
542+ }
439543 break ;
440544 }
545+
546+ finish :
441547 return routefail_end (take (r ));
442548}
0 commit comments