mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
libplugin: Introduce payment_abort to terminate a payment
The main responsibility of this new function is to mark a payment process as terminated and set a reasonable error message, that will be displayed to the caller. We also skip the remaining modifiers since they might end up clobbering the message.
This commit is contained in:
committed by
Rusty Russell
parent
2e51afcc50
commit
60af8be5ba
@@ -61,6 +61,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
||||
p->invstring = NULL;
|
||||
p->routetxt = NULL;
|
||||
p->max_htlcs = UINT32_MAX;
|
||||
p->aborterror = NULL;
|
||||
|
||||
/* Copy over the relevant pieces of information. */
|
||||
if (parent != NULL) {
|
||||
@@ -1884,6 +1885,14 @@ static void payment_finished(struct payment *p)
|
||||
|
||||
json_add_string(ret, "status", "complete");
|
||||
|
||||
if (command_finished(cmd, ret)) {/* Ignore result. */}
|
||||
return;
|
||||
} else if (p->aborterror != NULL) {
|
||||
/* We set an explicit toplevel error message,
|
||||
* so let's report that. */
|
||||
ret = jsonrpc_stream_fail(cmd, PAY_STOPPED_RETRYING,
|
||||
p->aborterror);
|
||||
payment_json_add_attempts(ret, "attempts", p);
|
||||
if (command_finished(cmd, ret)) {/* Ignore result. */}
|
||||
return;
|
||||
} else if (result.failure == NULL || result.failure->failcode < NODE) {
|
||||
@@ -2028,6 +2037,32 @@ void payment_continue(struct payment *p)
|
||||
abort();
|
||||
}
|
||||
|
||||
void payment_abort(struct payment *p, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
struct payment *root = payment_root(p);
|
||||
payment_set_step(p, PAYMENT_STEP_FAILED);
|
||||
p->end_time = time_now();
|
||||
|
||||
va_start(ap, fmt);
|
||||
p->failreason = tal_vfmt(p, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
root->abort = true;
|
||||
|
||||
/* Only set the abort error if it's not yet set, otherwise we
|
||||
* might end up clobbering the earliest and decisive failure
|
||||
* with less relevant ones. */
|
||||
if (root->aborterror == NULL)
|
||||
root->aborterror = tal_dup_talarr(root, char, p->failreason);
|
||||
|
||||
paymod_log(p, LOG_INFORM, "%s", p->failreason);
|
||||
|
||||
/* Do not use payment_continue, because that'd continue
|
||||
* applying the modifiers before calling
|
||||
* payment_finished(). */
|
||||
payment_finished(p);
|
||||
}
|
||||
|
||||
void payment_fail(struct payment *p, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -292,6 +292,10 @@ struct payment {
|
||||
* and payment_lower_max_htlcs functions.
|
||||
*/
|
||||
u32 max_htlcs;
|
||||
|
||||
/* A human readable error message that is used as a top-level
|
||||
* explanation if a payment is aborted. */
|
||||
char *aborterror;
|
||||
};
|
||||
|
||||
struct payment_modifier {
|
||||
@@ -436,6 +440,13 @@ 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);
|
||||
|
||||
/* Fails a payment process by setting the root payment to
|
||||
* aborted. This will cause all subpayments to terminate as soon as
|
||||
* they can, and sets the root failreason so we have a sensible error
|
||||
* message. The failreason is overwritten if it is already set, since
|
||||
* we probably know better what happened in the modifier.. */
|
||||
void payment_abort(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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user