mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
payalgo: Implement retry_for for pay command.
This commit is contained in:
@@ -21,5 +21,6 @@
|
|||||||
#define PAY_INVOICE_EXPIRED 207
|
#define PAY_INVOICE_EXPIRED 207
|
||||||
#define PAY_NO_SUCH_PAYMENT 208
|
#define PAY_NO_SUCH_PAYMENT 208
|
||||||
#define PAY_UNSPECIFIED_ERROR 209
|
#define PAY_UNSPECIFIED_ERROR 209
|
||||||
|
#define PAY_STOPPED_RETRYING 210
|
||||||
|
|
||||||
#endif /* !defined (LIGHTNING_LIGHTNINGD_JSONRPC_ERRORS_H) */
|
#endif /* !defined (LIGHTNING_LIGHTNINGD_JSONRPC_ERRORS_H) */
|
||||||
|
|||||||
@@ -149,6 +149,9 @@ struct pay {
|
|||||||
|
|
||||||
/* List of failures to pay. */
|
/* List of failures to pay. */
|
||||||
struct list_head pay_failures;
|
struct list_head pay_failures;
|
||||||
|
|
||||||
|
/* Whether we are attempting payment or not. */
|
||||||
|
bool in_sendpay;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct routing_failure *
|
static struct routing_failure *
|
||||||
@@ -237,6 +240,7 @@ static void json_pay_failure(struct pay *pay,
|
|||||||
switch (r->errorcode) {
|
switch (r->errorcode) {
|
||||||
case PAY_IN_PROGRESS:
|
case PAY_IN_PROGRESS:
|
||||||
case PAY_RHASH_ALREADY_USED:
|
case PAY_RHASH_ALREADY_USED:
|
||||||
|
case PAY_STOPPED_RETRYING:
|
||||||
json_object_start(data, NULL);
|
json_object_start(data, NULL);
|
||||||
json_add_num(data, "getroute_tries", pay->getroute_tries);
|
json_add_num(data, "getroute_tries", pay->getroute_tries);
|
||||||
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
|
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
|
||||||
@@ -332,6 +336,8 @@ static void json_pay_sendpay_resolve(const struct sendpay_result *r,
|
|||||||
struct pay *pay = (struct pay *) vpay;
|
struct pay *pay = (struct pay *) vpay;
|
||||||
char const *why;
|
char const *why;
|
||||||
|
|
||||||
|
pay->in_sendpay = false;
|
||||||
|
|
||||||
/* If we succeed, hurray */
|
/* If we succeed, hurray */
|
||||||
if (r->succeeded) {
|
if (r->succeeded) {
|
||||||
log_info(pay->cmd->ld->log, "pay(%p): Success", pay);
|
log_info(pay->cmd->ld->log, "pay(%p): Success", pay);
|
||||||
@@ -486,6 +492,7 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
|
|||||||
pay->route = tal_dup_arr(pay, struct route_hop, route,
|
pay->route = tal_dup_arr(pay, struct route_hop, route,
|
||||||
tal_count(route), 0);
|
tal_count(route), 0);
|
||||||
|
|
||||||
|
pay->in_sendpay = true;
|
||||||
send_payment(pay->try_parent,
|
send_payment(pay->try_parent,
|
||||||
pay->cmd->ld, &pay->payment_hash, route,
|
pay->cmd->ld, &pay->payment_hash, route,
|
||||||
&json_pay_sendpay_resume, pay);
|
&json_pay_sendpay_resume, pay);
|
||||||
@@ -542,16 +549,37 @@ static bool json_pay_try(struct pay *pay)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void json_pay_stop_retrying(struct pay *pay)
|
||||||
|
{
|
||||||
|
struct sendpay_result *sr;
|
||||||
|
sr = tal(pay, struct sendpay_result);
|
||||||
|
sr->succeeded = false;
|
||||||
|
if (pay->in_sendpay) {
|
||||||
|
/* Still in sendpay. Return with PAY_IN_PROGRESS */
|
||||||
|
sr->errorcode = PAY_IN_PROGRESS;
|
||||||
|
sr->details = "Stopped retrying during payment attempt; "
|
||||||
|
"continue monitoring with "
|
||||||
|
"pay or listpayments";
|
||||||
|
} else {
|
||||||
|
/* Outside sendpay, no ongoing payment */
|
||||||
|
sr->errorcode = PAY_STOPPED_RETRYING;
|
||||||
|
sr->details = "Stopped retrying, no ongoing payment";
|
||||||
|
}
|
||||||
|
json_pay_failure(pay, sr);
|
||||||
|
}
|
||||||
|
|
||||||
static void json_pay(struct command *cmd,
|
static void json_pay(struct command *cmd,
|
||||||
const char *buffer, const jsmntok_t *params)
|
const char *buffer, const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
jsmntok_t *bolt11tok, *msatoshitok, *desctok, *riskfactortok, *maxfeetok;
|
jsmntok_t *bolt11tok, *msatoshitok, *desctok, *riskfactortok, *maxfeetok;
|
||||||
|
jsmntok_t *retryfortok;
|
||||||
double riskfactor = 1.0;
|
double riskfactor = 1.0;
|
||||||
double maxfeepercent = 0.5;
|
double maxfeepercent = 0.5;
|
||||||
u64 msatoshi;
|
u64 msatoshi;
|
||||||
struct pay *pay = tal(cmd, struct pay);
|
struct pay *pay = tal(cmd, struct pay);
|
||||||
struct bolt11 *b11;
|
struct bolt11 *b11;
|
||||||
char *fail, *b11str, *desc;
|
char *fail, *b11str, *desc;
|
||||||
|
unsigned int retryfor = 60;
|
||||||
|
|
||||||
if (!json_get_params(cmd, buffer, params,
|
if (!json_get_params(cmd, buffer, params,
|
||||||
"bolt11", &bolt11tok,
|
"bolt11", &bolt11tok,
|
||||||
@@ -559,6 +587,7 @@ static void json_pay(struct command *cmd,
|
|||||||
"?description", &desctok,
|
"?description", &desctok,
|
||||||
"?riskfactor", &riskfactortok,
|
"?riskfactor", &riskfactortok,
|
||||||
"?maxfeepercent", &maxfeetok,
|
"?maxfeepercent", &maxfeetok,
|
||||||
|
"?retry_for", &retryfortok,
|
||||||
NULL)) {
|
NULL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -584,6 +613,13 @@ static void json_pay(struct command *cmd,
|
|||||||
pay->expiry.ts.tv_sec = b11->timestamp + b11->expiry;
|
pay->expiry.ts.tv_sec = b11->timestamp + b11->expiry;
|
||||||
pay->min_final_cltv_expiry = b11->min_final_cltv_expiry;
|
pay->min_final_cltv_expiry = b11->min_final_cltv_expiry;
|
||||||
|
|
||||||
|
if (retryfortok && !json_tok_number(buffer, retryfortok, &retryfor)) {
|
||||||
|
command_fail(cmd, "'%.*s' is not an integer",
|
||||||
|
retryfortok->end - retryfortok->start,
|
||||||
|
buffer + retryfortok->start);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (b11->msatoshi) {
|
if (b11->msatoshi) {
|
||||||
msatoshi = *b11->msatoshi;
|
msatoshi = *b11->msatoshi;
|
||||||
if (msatoshitok) {
|
if (msatoshitok) {
|
||||||
@@ -650,10 +686,17 @@ static void json_pay(struct command *cmd,
|
|||||||
pay->route = NULL;
|
pay->route = NULL;
|
||||||
/* Start with no failures */
|
/* Start with no failures */
|
||||||
list_head_init(&pay->pay_failures);
|
list_head_init(&pay->pay_failures);
|
||||||
|
pay->in_sendpay = false;
|
||||||
|
|
||||||
/* Initiate payment */
|
/* Initiate payment */
|
||||||
if (json_pay_try(pay))
|
if (json_pay_try(pay))
|
||||||
command_still_pending(cmd);
|
command_still_pending(cmd);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Set up timeout. */
|
||||||
|
new_reltimer(&cmd->ld->timers, pay, time_from_sec(retryfor),
|
||||||
|
&json_pay_stop_retrying, pay);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command pay_command = {
|
static const struct json_command pay_command = {
|
||||||
@@ -662,7 +705,8 @@ static const struct json_command pay_command = {
|
|||||||
"Send payment specified by {bolt11} with optional {msatoshi} "
|
"Send payment specified by {bolt11} with optional {msatoshi} "
|
||||||
"(if and only if {bolt11} does not have amount), "
|
"(if and only if {bolt11} does not have amount), "
|
||||||
"{description} (required if {bolt11} uses description hash), "
|
"{description} (required if {bolt11} uses description hash), "
|
||||||
"{riskfactor} (default 1.0), and "
|
"{riskfactor} (default 1.0), "
|
||||||
"{maxfeepercent} (default 0.5) the maximum acceptable fee as a percentage (e.g. 0.5 => 0.5%)"
|
"{maxfeepercent} (default 0.5) the maximum acceptable fee as a percentage (e.g. 0.5 => 0.5%), and "
|
||||||
|
"{retry_for} (default 60) the integer number of seconds before we stop retrying"
|
||||||
};
|
};
|
||||||
AUTODATA(json_command, &pay_command);
|
AUTODATA(json_command, &pay_command);
|
||||||
|
|||||||
Reference in New Issue
Block a user