From 030633bb28dded66c37e92b28023f1acdc796353 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Tue, 9 Jun 2020 15:38:16 +0200 Subject: [PATCH] paymod: Add a human readable failreason to payments This makes it easier to stash a human readable failure message in an attempt. --- plugins/libplugin-pay.c | 40 +++++++++++++++++++++++----------------- plugins/libplugin-pay.h | 6 +++++- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index a09f2d3f3..74acdf025 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -22,6 +22,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd, p->why = NULL; p->getroute = tal(p, struct getroute_request); p->label = NULL; + p->failreason = NULL; /* Copy over the relevant pieces of information. */ if (parent != NULL) { @@ -75,11 +76,9 @@ static struct command_result *payment_rpc_failure(struct command *cmd, const jsmntok_t *toks, struct payment *p) { - plugin_log(p->plugin, LOG_DBG, - "Failing a partial payment due to a failed RPC call: %.*s", - toks->end - toks->start, buffer + toks->start); - - payment_fail(p); + payment_fail(p, + "Failing a partial payment due to a failed RPC call: %.*s", + toks->end - toks->start, buffer + toks->start); return command_still_pending(cmd); } @@ -365,21 +364,19 @@ static struct command_result *payment_getroute_result(struct command *cmd, /* Ensure that our fee and CLTV budgets are respected. */ if (amount_msat_greater(fee, p->constraints.fee_budget)) { - plugin_log(p->plugin, LOG_INFORM, - "Fee exceeds our fee budget: %s > %s, discarding route", - type_to_string(tmpctx, struct amount_msat, &fee), - type_to_string(tmpctx, struct amount_msat, &p->constraints.fee_budget)); payment_exclude_most_expensive(p); - payment_fail(p); + payment_fail( + p, "Fee exceeds our fee budget: %s > %s, discarding route", + type_to_string(tmpctx, struct amount_msat, &fee), + type_to_string(tmpctx, struct amount_msat, + &p->constraints.fee_budget)); return command_still_pending(cmd); } if (p->route[0].delay > p->constraints.cltv_budget) { - plugin_log(p->plugin, LOG_INFORM, - "CLTV delay exceeds our CLTV budget: %d > %d", - p->route[0].delay, p->constraints.cltv_budget); payment_exclude_longest_delay(p); - payment_fail(p); + payment_fail(p, "CLTV delay exceeds our CLTV budget: %d > %d", + p->route[0].delay, p->constraints.cltv_budget); return command_still_pending(cmd); } @@ -403,8 +400,16 @@ static struct command_result *payment_getroute_error(struct command *cmd, const jsmntok_t *toks, struct payment *p) { + int code; + const jsmntok_t *codetok = json_get_member(buffer, toks, "code"), + *msgtok = json_get_member(buffer, toks, "message"); + json_to_int(buffer, codetok, &code); p->route = NULL; - payment_fail(p); + + payment_fail( + p, "Error computing a route to %s: %.*s (%d)", + type_to_string(tmpctx, struct node_id, p->getroute->destination), + json_tok_full_len(msgtok), json_tok_full(buffer, msgtok), code); /* Let payment_finished_ handle this, so we mark it as pending */ return command_still_pending(cmd); @@ -804,7 +809,7 @@ payment_waitsendpay_finished(struct command *cmd, const char *buffer, break; } - payment_fail(p); + payment_fail(p, "%s", p->result->message); return command_still_pending(cmd); } @@ -1234,10 +1239,11 @@ void payment_continue(struct payment *p) abort(); } -void payment_fail(struct payment *p) +void payment_fail(struct payment *p, const char *fmt, ...) { p->end_time = time_now(); p->step = PAYMENT_STEP_FAILED; + p->failreason = tal_steal(p, reason); payment_continue(p); } diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index 43cf17cd6..717e1d2c5 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -258,6 +258,9 @@ struct payment { const char *why; const char *label; + + /* Human readable explanation of why this payment failed. */ + const char *failreason; }; struct payment_modifier { @@ -342,7 +345,8 @@ void payment_start(struct payment *p); void payment_continue(struct payment *p); /* Fails a partial payment and continues with the core flow. */ -void payment_fail(struct payment *p); +void payment_fail(struct payment *p, const char *fmt, ...) PRINTF_FMT(2,3); + struct payment *payment_root(struct payment *p); struct payment_tree_result payment_collect_result(struct payment *p);