@@ -21,6 +21,7 @@ struct routefail {
2121
2222static struct command_result * update_gossip (struct routefail * r );
2323static struct command_result * handle_failure (struct routefail * r );
24+ static void find_erring_node (struct route * route );
2425
2526struct command_result * routefail_start (const tal_t * ctx , struct route * route ,
2627 struct command * cmd )
@@ -40,9 +41,60 @@ struct command_result *routefail_start(const tal_t *ctx, struct route *route,
4041 r -> route = route ;
4142 r -> cmd = cmd ;
4243 assert (route -> result );
44+ find_erring_node (route );
4345 return update_gossip (r );
4446}
4547
48+ /* The erring_node and erring_channel are necessary fields to handle the error.
49+ * We might not know those values from listsendpays because the payment could
50+ * have been paid with sendonion or similar RPCs, but if we know the route then
51+ * we can deduce them just like lightningd's wallet would with a sendpay
52+ * command. */
53+ static void find_erring_node (struct route * route )
54+ {
55+ struct payment_result * result = route -> result ;
56+ if (result -> erring_node && result -> erring_channel &&
57+ result -> erring_direction )
58+ return ;
59+
60+ /* we need the hops, othewise our assumptions are wrong */
61+ assert (route -> hops );
62+ assert (result -> erring_index );
63+ unsigned int index = * result -> erring_index ;
64+ unsigned int path_len = tal_count (route -> hops );
65+
66+ /* self-pay failure? */
67+ assert (path_len > 0 );
68+ assert (index >= 0 );
69+ assert (path_len >= index );
70+
71+ if (index == path_len - 1 ) {
72+ result -> erring_channel = tal_dup (
73+ result , struct short_channel_id , & route -> hops [index ].scid );
74+ result -> erring_direction =
75+ tal_dup (result , int , & route -> hops [index ].direction );
76+ result -> erring_node = tal_dup (result , struct node_id ,
77+ & route -> hops [index ].node_id );
78+ } else {
79+ result -> erring_channel =
80+ tal_dup (result , struct short_channel_id ,
81+ & route -> hops [index + 1 ].scid );
82+ result -> erring_direction =
83+ tal_dup (result , int , & route -> hops [index + 1 ].direction );
84+
85+ /* If the error is a BADONION, then it's on behalf of the
86+ * following node. */
87+ if (result -> failcode & BADONION )
88+ result -> erring_node =
89+ tal_dup (result , struct node_id ,
90+ & route -> hops [index + 1 ].node_id );
91+ else
92+ result -> erring_node =
93+ tal_dup (result , struct node_id ,
94+ & route -> hops [index ].node_id );
95+ }
96+ }
97+
4698static struct command_result * routefail_end (struct routefail * r TAKES )
4799{
48100 /* Notify the tracker that route has failed and routefail have completed
@@ -188,6 +240,7 @@ static void route_final_error(struct route *route, enum jsonrpc_errcode error,
188240 route -> final_msg = tal_strdup (route , what );
189241}
190242
243+ /* FIXME: do proper error handling for BOLT12 */
191244static struct command_result * handle_failure (struct routefail * r )
192245{
193246 /* BOLT #4:
0 commit comments