From 4dd034666136f5541d4e25c55251f4028c14706d Mon Sep 17 00:00:00 2001 From: Jesse de Wit Date: Fri, 9 Aug 2024 10:02:10 +0200 Subject: [PATCH 1/3] trace payment_continue and payment mods --- plugins/libplugin-pay.c | 41 ++++++++++++++++++++++++++++++++++++----- plugins/libplugin-pay.h | 12 ++++++++++++ plugins/renepay/mods.c | 5 +++++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 9d1f7eda8bb8..0844ff135b21 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -10,9 +10,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -2423,12 +2425,17 @@ void payment_continue(struct payment *p) { struct payment_modifier *mod; void *moddata; + + trace_span_start("payment_continue", p); /* If we are in the middle of calling the modifiers, continue calling * them, otherwise we can continue with the payment state-machine. */ p->current_modifier++; mod = p->modifiers[p->current_modifier]; if (mod != NULL) { + char *str = tal_fmt(tmpctx, "%d", p->current_modifier); + trace_span_tag(p, "modifier", str); + trace_span_end(p); /* There is another modifier, so call it. */ moddata = p->modifier_data[p->current_modifier]; return mod->post_step_cb(moddata, p); @@ -2436,6 +2443,8 @@ void payment_continue(struct payment *p) /* There are no more modifiers, so reset the call chain and * proceed to the next state. */ p->current_modifier = -1; + trace_span_tag(p, "step", payment_step_str[p->step]); + trace_span_end(p); switch (p->step) { case PAYMENT_STEP_INITIALIZED: case PAYMENT_STEP_RETRY_GETROUTE: @@ -2462,6 +2471,7 @@ void payment_continue(struct payment *p) return; } } + trace_span_end(p); /* We should never get here, it'd mean one of the state machine called * `payment_continue` after the final state. */ abort(); @@ -2663,7 +2673,7 @@ local_channel_hints_listpeerchannels(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { struct listpeers_channel **chans; - + trace_span_resume(p); chans = json_to_listpeers_channels(tmpctx, buffer, toks); for (size_t i = 0; i < tal_count(chans); i++) { @@ -2713,6 +2723,7 @@ local_channel_hints_listpeerchannels(struct command *cmd, const char *buffer, } } + trace_span_end(p); payment_continue(p); return command_still_pending(cmd); } @@ -2728,6 +2739,8 @@ static void local_channel_hints_cb(void *d UNUSED, struct payment *p) if (p->parent != NULL || p->step != PAYMENT_STEP_INITIALIZED) return payment_continue(p); + trace_span_start("local_channel_hints_cb", p); + trace_span_suspend(p); req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels", local_channel_hints_listpeerchannels, local_channel_hints_listpeerchannels, p); @@ -3281,6 +3294,7 @@ static void exemptfee_cb(struct exemptfee_data *d, struct payment *p) if (p->step != PAYMENT_STEP_INITIALIZED || p->parent != NULL) return payment_continue(p); + trace_span_start("exemptfee_cb", p); if (amount_msat_greater_eq(d->amount, p->constraints.fee_budget)) { paymod_log( p, LOG_INFORM, @@ -3291,6 +3305,8 @@ static void exemptfee_cb(struct exemptfee_data *d, struct payment *p) p->constraints.fee_budget = d->amount; p->start_constraints->fee_budget = d->amount; } + + trace_span_end(p); return payment_continue(p); } @@ -3507,8 +3523,12 @@ static void shadow_route_cb(struct shadow_route_data *d, = amount_msat_div(p->constraints.fee_budget, 4); if (pseudorand(2) == 0) { + trace_span_tag(p, "shadow_route_cb", "pseudorand(2) == 0"); + trace_span_end(p); return payment_continue(p); } else { + trace_span_tag(p, "shadow_route_cb", "pseudorand(2) != 0"); + trace_span_end(p); shadow_route_extend(d, p); } } @@ -3527,8 +3547,11 @@ static void direct_pay_override(struct payment *p) { * anything. */ d = payment_mod_directpay_get_data(root); - if (d->chan == NULL) + if (d->chan == NULL) { + trace_span_tag(p, "direct_pay_override", "d->chan == NULL"); + trace_span_end(p); return payment_continue(p); + } /* If we have a channel we need to make sure that it still has * sufficient capacity. Look it up in the channel_hints. */ @@ -3558,7 +3581,7 @@ static void direct_pay_override(struct payment *p) { payment_set_step(p, PAYMENT_STEP_GOT_ROUTE); } - + trace_span_end(p); payment_continue(p); } @@ -3570,6 +3593,7 @@ static struct command_result *direct_pay_listpeerchannels(struct command *cmd, const jsmntok_t *toks, struct payment *p) { + trace_span_resume(p); struct listpeers_channel **channels = json_to_listpeers_channels(tmpctx, buffer, toks); struct direct_pay_data *d = payment_mod_directpay_get_data(p); @@ -3620,7 +3644,8 @@ static void direct_pay_cb(struct direct_pay_data *d, struct payment *p) return payment_continue(p); - + trace_span_start("direct_pay_cb", p); + trace_span_suspend(p); req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels", direct_pay_listpeerchannels, direct_pay_listpeerchannels, @@ -3876,7 +3901,7 @@ payee_incoming_limit_count(struct command *cmd, { const jsmntok_t *channelstok; size_t num_channels = 0; - + trace_span_start("payee_incoming_limit_count", p); channelstok = json_get_member(buf, result, "channels"); assert(channelstok); @@ -3909,6 +3934,7 @@ payee_incoming_limit_count(struct command *cmd, payment_lower_max_htlcs(p, lim, why); } + trace_span_end(p); payment_continue(p); return command_still_pending(cmd); } @@ -3922,8 +3948,10 @@ static void payee_incoming_limit_step_cb(void *d UNUSED, struct payment *p) || !payment_supports_mpp(p)) return payment_continue(p); + trace_span_start("payee_incoming_limit_step_cb", p); /* Get information on the destination. */ struct out_req *req; + trace_span_end(p); req = jsonrpc_request_start(p->plugin, NULL, "listchannels", &payee_incoming_limit_count, &payment_rpc_failure, p); @@ -3952,6 +3980,8 @@ static void route_exclusions_step_cb(struct route_exclusions_data *d, { if (p->parent) return payment_continue(p); + + trace_span_start("route_exclusions_step_cb", p); struct route_exclusion **exclusions = d->exclusions; for (size_t i = 0; i < tal_count(exclusions); i++) { struct route_exclusion *e = exclusions[i]; @@ -3970,6 +4000,7 @@ static void route_exclusions_step_cb(struct route_exclusions_data *d, tal_arr_expand(&p->excluded_nodes, e->u.node_id); } } + trace_span_end(p); payment_continue(p); } diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index 283c312fa5fe..c0b44de84dcf 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -129,6 +129,18 @@ enum payment_step { PAYMENT_STEP_SUCCESS = 64, }; +const char * const payment_step_str[] = +{ + [PAYMENT_STEP_INITIALIZED] = "PAYMENT_STEP_INITIALIZED", + [PAYMENT_STEP_GOT_ROUTE] = "PAYMENT_STEP_GOT_ROUTE", + [PAYMENT_STEP_RETRY_GETROUTE] = "PAYMENT_STEP_RETRY_GETROUTE", + [PAYMENT_STEP_ONION_PAYLOAD] = "PAYMENT_STEP_ONION_PAYLOAD", + [PAYMENT_STEP_SPLIT] = "PAYMENT_STEP_SPLIT", + [PAYMENT_STEP_RETRY] = "PAYMENT_STEP_RETRY", + [PAYMENT_STEP_FAILED] = "PAYMENT_STEP_FAILED", + [PAYMENT_STEP_SUCCESS] = "PAYMENT_STEP_SUCCESS", +}; + /* Just a container to collect a subtree result so we can summarize all * sub-payments and return a reasonable result to the caller of `pay` */ struct payment_tree_result { diff --git a/plugins/renepay/mods.c b/plugins/renepay/mods.c index 2053aab2750b..ceb7e2929b9a 100644 --- a/plugins/renepay/mods.c +++ b/plugins/renepay/mods.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -569,6 +570,7 @@ static struct command_result *routehints_done(struct command *cmd UNUSED, assert(payment); assert(payment->local_gossmods); + trace_span_start("routehints_done", payment); const struct node_id *destination = &payment->payment_info.destination; const struct route_info **routehints = payment->payment_info.routehints; assert(routehints); @@ -599,13 +601,16 @@ static struct command_result *routehints_done(struct command *cmd UNUSED, "been ignored.", __func__, skipped_count); + trace_span_end(payment); return payment_continue(payment); } static struct command_result *routehints_cb(struct payment *payment) { + trace_span_start("routehints_cb", payment); struct command *cmd = payment_command(payment); assert(cmd); + trace_span_end(payment); struct out_req *req = jsonrpc_request_start( cmd->plugin, cmd, "waitblockheight", routehints_done, payment_rpc_failure, payment); From 3ed0e622a10ff405e38edde7174792b0058fc21e Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 12 Aug 2024 17:00:56 +0200 Subject: [PATCH 2/3] plugin: Add tracing support for `send_outreq` The `send_outreq` function is a good place to suspend and resume traces, since these are usually the places where we hand off control back to the `io_loop`. This assumes that we do not continue doing heavy liftin after we have queued an `outreq` call, but that is most likely the case anyway. This frees us from having to track suspensions whenever we call the RPC from a plugin. --- plugins/bkpr/test/run-bkpr_db.c | 15 +++++++++++++++ plugins/bkpr/test/run-recorder.c | 15 +++++++++++++++ plugins/libplugin-pay.c | 4 ---- plugins/libplugin.c | 16 ++++++++++++++++ plugins/test/run-route-calc.c | 9 +++++++++ plugins/test/run-route-overlong.c | 9 +++++++++ wallet/test/run-wallet.c | 2 +- 7 files changed, 65 insertions(+), 5 deletions(-) diff --git a/plugins/bkpr/test/run-bkpr_db.c b/plugins/bkpr/test/run-bkpr_db.c index 308110548ec1..b2c555bca525 100644 --- a/plugins/bkpr/test/run-bkpr_db.c +++ b/plugins/bkpr/test/run-bkpr_db.c @@ -253,6 +253,21 @@ void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNE /* Generated stub for towire_wirestring */ void towire_wirestring(u8 **pptr UNNEEDED, const char *str UNNEEDED) { fprintf(stderr, "towire_wirestring called!\n"); abort(); } +/* Generated stub for trace_span_end */ +void trace_span_end(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_end called!\n"); abort(); } +/* Generated stub for trace_span_resume */ +void trace_span_resume(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_resume called!\n"); abort(); } +/* Generated stub for trace_span_start */ +void trace_span_start(const char *name UNNEEDED, const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_start called!\n"); abort(); } +/* Generated stub for trace_span_suspend */ +void trace_span_suspend(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_suspend called!\n"); abort(); } +/* Generated stub for trace_span_tag */ +void trace_span_tag(const void *key UNNEEDED, const char *name UNNEEDED, const char *value UNNEEDED) +{ fprintf(stderr, "trace_span_tag called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ static char *tmp_dsn(const tal_t *ctx) diff --git a/plugins/bkpr/test/run-recorder.c b/plugins/bkpr/test/run-recorder.c index 8f805d413873..6d6d1f06b5ba 100644 --- a/plugins/bkpr/test/run-recorder.c +++ b/plugins/bkpr/test/run-recorder.c @@ -259,6 +259,21 @@ void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNE /* Generated stub for towire_wirestring */ void towire_wirestring(u8 **pptr UNNEEDED, const char *str UNNEEDED) { fprintf(stderr, "towire_wirestring called!\n"); abort(); } +/* Generated stub for trace_span_end */ +void trace_span_end(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_end called!\n"); abort(); } +/* Generated stub for trace_span_resume */ +void trace_span_resume(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_resume called!\n"); abort(); } +/* Generated stub for trace_span_start */ +void trace_span_start(const char *name UNNEEDED, const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_start called!\n"); abort(); } +/* Generated stub for trace_span_suspend */ +void trace_span_suspend(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_suspend called!\n"); abort(); } +/* Generated stub for trace_span_tag */ +void trace_span_tag(const void *key UNNEEDED, const char *name UNNEEDED, const char *value UNNEEDED) +{ fprintf(stderr, "trace_span_tag called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ static char *tmp_dsn(const tal_t *ctx) diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 0844ff135b21..2435e81bfc99 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -2673,7 +2673,6 @@ local_channel_hints_listpeerchannels(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { struct listpeers_channel **chans; - trace_span_resume(p); chans = json_to_listpeers_channels(tmpctx, buffer, toks); for (size_t i = 0; i < tal_count(chans); i++) { @@ -2740,7 +2739,6 @@ static void local_channel_hints_cb(void *d UNUSED, struct payment *p) return payment_continue(p); trace_span_start("local_channel_hints_cb", p); - trace_span_suspend(p); req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels", local_channel_hints_listpeerchannels, local_channel_hints_listpeerchannels, p); @@ -3593,7 +3591,6 @@ static struct command_result *direct_pay_listpeerchannels(struct command *cmd, const jsmntok_t *toks, struct payment *p) { - trace_span_resume(p); struct listpeers_channel **channels = json_to_listpeers_channels(tmpctx, buffer, toks); struct direct_pay_data *d = payment_mod_directpay_get_data(p); @@ -3645,7 +3642,6 @@ static void direct_pay_cb(struct direct_pay_data *d, struct payment *p) trace_span_start("direct_pay_cb", p); - trace_span_suspend(p); req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels", direct_pay_listpeerchannels, direct_pay_listpeerchannels, diff --git a/plugins/libplugin.c b/plugins/libplugin.c index 3ba3b85ab688..e6fd9a912966 100644 --- a/plugins/libplugin.c +++ b/plugins/libplugin.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -996,10 +997,18 @@ static void handle_rpc_reply(struct plugin *plugin, const jsmntok_t *toks) if (out->cmd) tal_del_destructor2(out->cmd, disable_request_cb, out); + trace_span_resume(out); + /* We want to free this if callback doesn't. */ tal_steal(tmpctx, out); contenttok = json_get_member(buf, toks, "error"); + + /* Annotate the JSON-RPC span whether it succeeded or failed, + * and then emit it. */ + trace_span_tag(out, "error", contenttok == NULL ? "true" : "false"); + trace_span_end(out); + if (contenttok) { if (out->errcb) res = out->errcb(out->cmd, buf, contenttok, out->arg); @@ -1030,6 +1039,13 @@ send_outreq(struct plugin *plugin, const struct out_req *req) json_object_end(req->js); json_stream_close(req->js, req->cmd); + /* We are about to hand control over to the RPC, so suspend + * the current span. It'll be resumed as soon as we have a + * result to pass to either the error or the success + * callback. */ + trace_span_start("jsonrpc", req); + trace_span_tag(req, "id", req->id); + trace_span_suspend(req); ld_rpc_send(plugin, req->js); if (req->cmd != NULL) diff --git a/plugins/test/run-route-calc.c b/plugins/test/run-route-calc.c index da73c25a9a8b..88d51fa8e2ae 100644 --- a/plugins/test/run-route-calc.c +++ b/plugins/test/run-route-calc.c @@ -295,6 +295,15 @@ void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED) /* Generated stub for towire_channel_id */ void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "towire_channel_id called!\n"); abort(); } +/* Generated stub for trace_span_end */ +void trace_span_end(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_end called!\n"); abort(); } +/* Generated stub for trace_span_start */ +void trace_span_start(const char *name UNNEEDED, const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_start called!\n"); abort(); } +/* Generated stub for trace_span_tag */ +void trace_span_tag(const void *key UNNEEDED, const char *name UNNEEDED, const char *value UNNEEDED) +{ fprintf(stderr, "trace_span_tag called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ #ifndef SUPERVERBOSE diff --git a/plugins/test/run-route-overlong.c b/plugins/test/run-route-overlong.c index 4a7d94b3f7d2..2e97cb2297f8 100644 --- a/plugins/test/run-route-overlong.c +++ b/plugins/test/run-route-overlong.c @@ -292,6 +292,15 @@ void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED) /* Generated stub for towire_channel_id */ void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "towire_channel_id called!\n"); abort(); } +/* Generated stub for trace_span_end */ +void trace_span_end(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_end called!\n"); abort(); } +/* Generated stub for trace_span_start */ +void trace_span_start(const char *name UNNEEDED, const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_start called!\n"); abort(); } +/* Generated stub for trace_span_tag */ +void trace_span_tag(const void *key UNNEEDED, const char *name UNNEEDED, const char *value UNNEEDED) +{ fprintf(stderr, "trace_span_tag called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ #ifndef SUPERVERBOSE diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 8d45c180e53f..b6f0791a9231 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -1002,7 +1002,7 @@ void topology_add_sync_waiter_(const tal_t *ctx UNNEEDED, u8 *towire_announcement_signatures(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, struct short_channel_id short_channel_id UNNEEDED, const secp256k1_ecdsa_signature *node_signature UNNEEDED, const secp256k1_ecdsa_signature *bitcoin_signature UNNEEDED) { fprintf(stderr, "towire_announcement_signatures called!\n"); abort(); } /* Generated stub for towire_channel_reestablish */ -u8 *towire_channel_reestablish(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, u64 next_commitment_number UNNEEDED, u64 next_revocation_number UNNEEDED, const struct secret *your_last_per_commitment_secret UNNEEDED, const struct pubkey *my_current_per_commitment_point UNNEEDED, const struct tlv_channel_reestablish_tlvs *tlvs UNNEEDED) +u8 *towire_channel_reestablish(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, u64 next_commitment_number UNNEEDED, u64 next_revocation_number UNNEEDED, const struct secret *your_last_per_commitment_secret UNNEEDED, const struct pubkey *my_current_per_commitment_point UNNEEDED, const struct tlv_channel_reestablish_tlvs *channel_reestablish UNNEEDED) { fprintf(stderr, "towire_channel_reestablish called!\n"); abort(); } /* Generated stub for towire_channeld_dev_memleak */ u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED) From 76a2c8c7f3ffdd77b5a3b9d048aac0073058e33b Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Wed, 14 Aug 2024 13:07:01 +0200 Subject: [PATCH 3/3] libplugin: Move the step string map to C file Having it in the header means we may end up including it multiple times, so move them into the compilation unit, where it'll only be compiled once, and therefore the linker does not get confused as much. --- plugins/Makefile | 4 ++-- plugins/libplugin-pay.c | 12 ++++++++++++ plugins/libplugin-pay.h | 12 ------------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plugins/Makefile b/plugins/Makefile index a0b2d5efe772..981c5e3ab1c2 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -23,8 +23,8 @@ PLUGIN_COMMANDO_OBJS := $(PLUGIN_COMMANDO_SRC:.c=.o) PLUGIN_KEYSEND_SRC := plugins/keysend.c PLUGIN_KEYSEND_OBJS := $(PLUGIN_KEYSEND_SRC:.c=.o) -PLUGIN_LIB_SRC := plugins/libplugin.c -PLUGIN_LIB_HEADER := plugins/libplugin.h +PLUGIN_LIB_SRC := plugins/libplugin.c common/trace.c +PLUGIN_LIB_HEADER := plugins/libplugin.h common/trace.h PLUGIN_LIB_OBJS := $(PLUGIN_LIB_SRC:.c=.o) PLUGIN_PAY_LIB_SRC := plugins/libplugin-pay.c diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 2435e81bfc99..92644997b24b 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -2411,6 +2411,18 @@ static void payment_finished(struct payment *p) } } +const char * const payment_step_str[] = +{ + [PAYMENT_STEP_INITIALIZED] = "PAYMENT_STEP_INITIALIZED", + [PAYMENT_STEP_GOT_ROUTE] = "PAYMENT_STEP_GOT_ROUTE", + [PAYMENT_STEP_RETRY_GETROUTE] = "PAYMENT_STEP_RETRY_GETROUTE", + [PAYMENT_STEP_ONION_PAYLOAD] = "PAYMENT_STEP_ONION_PAYLOAD", + [PAYMENT_STEP_SPLIT] = "PAYMENT_STEP_SPLIT", + [PAYMENT_STEP_RETRY] = "PAYMENT_STEP_RETRY", + [PAYMENT_STEP_FAILED] = "PAYMENT_STEP_FAILED", + [PAYMENT_STEP_SUCCESS] = "PAYMENT_STEP_SUCCESS", +}; + void payment_set_step(struct payment *p, enum payment_step newstep) { p->current_modifier = -1; diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index c0b44de84dcf..283c312fa5fe 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -129,18 +129,6 @@ enum payment_step { PAYMENT_STEP_SUCCESS = 64, }; -const char * const payment_step_str[] = -{ - [PAYMENT_STEP_INITIALIZED] = "PAYMENT_STEP_INITIALIZED", - [PAYMENT_STEP_GOT_ROUTE] = "PAYMENT_STEP_GOT_ROUTE", - [PAYMENT_STEP_RETRY_GETROUTE] = "PAYMENT_STEP_RETRY_GETROUTE", - [PAYMENT_STEP_ONION_PAYLOAD] = "PAYMENT_STEP_ONION_PAYLOAD", - [PAYMENT_STEP_SPLIT] = "PAYMENT_STEP_SPLIT", - [PAYMENT_STEP_RETRY] = "PAYMENT_STEP_RETRY", - [PAYMENT_STEP_FAILED] = "PAYMENT_STEP_FAILED", - [PAYMENT_STEP_SUCCESS] = "PAYMENT_STEP_SUCCESS", -}; - /* Just a container to collect a subtree result so we can summarize all * sub-payments and return a reasonable result to the caller of `pay` */ struct payment_tree_result {