diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 4183709e7..5275df90e 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -731,7 +731,7 @@ payment_waitsendpay_finished(struct command *cmd, const char *buffer, json_tok_full_len(toks), json_tok_full(buffer, toks)); if (p->result->state == PAYMENT_COMPLETE) { - p->step = PAYMENT_STEP_SUCCESS; + payment_set_step(p, PAYMENT_STEP_SUCCESS); p->end_time = time_now(); payment_continue(p); return command_still_pending(cmd); @@ -1230,6 +1230,12 @@ static void payment_finished(struct payment *p) } } +void payment_set_step(struct payment *p, enum payment_step newstep) +{ + p->current_modifier = -1; + p->step = newstep; +} + void payment_continue(struct payment *p) { struct payment_modifier *mod; @@ -1279,9 +1285,15 @@ void payment_continue(struct payment *p) void payment_fail(struct payment *p, const char *fmt, ...) { + va_list ap; p->end_time = time_now(); - p->step = PAYMENT_STEP_FAILED; - p->failreason = tal_steal(p, reason); + payment_set_step(p, PAYMENT_STEP_FAILED); + va_start(ap, fmt); + p->failreason = tal_vfmt(p, fmt, ap); + va_end(ap); + + plugin_log(p->plugin, LOG_INFORM, "%s", p->failreason); + payment_continue(p); } @@ -1398,7 +1410,7 @@ static inline void retry_step_cb(struct retry_mod_data *rd, if (rdata->retries > 0) { subpayment = payment_new(p, NULL, p, p->modifiers); payment_start(subpayment); - p->step = PAYMENT_STEP_RETRY; + payment_set_step(p, PAYMENT_STEP_RETRY); subpayment->why = tal_fmt(subpayment, "Still have %d attempts left", rdata->retries - 1); diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index 717e1d2c5..8089f605f 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -344,6 +344,16 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd, void payment_start(struct payment *p); void payment_continue(struct payment *p); +/** + * Set the payment to the current step. + * + * This must be used by modifiers if they want to skip to a specific step. It + * ensures that the internal state is reset correctly and that all modifier + * callbacks are called once `payment_continue` is called again. + */ +void payment_set_step(struct payment *p, enum payment_step newstep); + + /* Fails a partial payment and continues with the core flow. */ void payment_fail(struct payment *p, const char *fmt, ...) PRINTF_FMT(2,3);