From 38535fc36c9e1061266d6fadc555ee995a75057d Mon Sep 17 00:00:00 2001 From: ZmnSCPxj Date: Sat, 17 Feb 2018 07:34:31 +0000 Subject: [PATCH] payalgo: Create a new failure for paying expired invoice. --- doc/lightning-pay.7 | 21 +++++++++++++++++++-- doc/lightning-pay.7.txt | 5 +++++ lightningd/jsonrpc_errors.h | 1 + lightningd/payalgo.c | 35 ++++++++++++++++++++++------------- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/doc/lightning-pay.7 b/doc/lightning-pay.7 index c64c94114..c0cbfc099 100644 --- a/doc/lightning-pay.7 +++ b/doc/lightning-pay.7 @@ -2,12 +2,12 @@ .\" Title: lightning-pay .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 02/11/2018 +.\" Date: 02/17/2018 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "LIGHTNING\-PAY" "7" "02/11/2018" "\ \&" "\ \&" +.TH "LIGHTNING\-PAY" "7" "02/17/2018" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -155,6 +155,23 @@ as well as the percentage that the fee has of the destination payment amount\&. .RE .sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +207\&. Invoice expired\&. Payment took too long before expiration, or already expired at the time you initiated payment\&. The +\fIdata\fR +field of the error indicates +\fInow\fR +(the current time) and +\fIexpiry\fR +(the invoice expiration) as UNIX epoch time in seconds\&. +.RE +.sp A routing failure object has the fields below: .sp .RS 4 diff --git a/doc/lightning-pay.7.txt b/doc/lightning-pay.7.txt index 405bc04d3..a9b019c39 100644 --- a/doc/lightning-pay.7.txt +++ b/doc/lightning-pay.7.txt @@ -60,6 +60,11 @@ The following error codes may occur: indicate the actual 'fee' as well as the 'feepercent' percentage that the fee has of the destination payment amount. +* 207. Invoice expired. Payment took too long before expiration, + or already expired at the time you initiated payment. + The 'data' field of the error indicates 'now' (the current time) + and 'expiry' (the invoice expiration) as UNIX epoch time in + seconds. A routing failure object has the fields below: diff --git a/lightningd/jsonrpc_errors.h b/lightningd/jsonrpc_errors.h index 8e0a27387..060cb90ec 100644 --- a/lightningd/jsonrpc_errors.h +++ b/lightningd/jsonrpc_errors.h @@ -18,5 +18,6 @@ #define PAY_TRY_OTHER_ROUTE 204 #define PAY_ROUTE_NOT_FOUND 205 #define PAY_ROUTE_TOO_EXPENSIVE 206 +#define PAY_INVOICE_EXPIRED 207 #endif /* !defined (LIGHTNING_LIGHTNINGD_JSONRPC_ERRORS_H) */ diff --git a/lightningd/payalgo.c b/lightningd/payalgo.c index b109099c0..83e2c72d8 100644 --- a/lightningd/payalgo.c +++ b/lightningd/payalgo.c @@ -113,14 +113,13 @@ static void json_pay_failure(struct command *cmd, } /* Start a payment attempt. */ -static void json_pay_try(struct pay *pay); +static bool json_pay_try(struct pay *pay); /* Call when sendpay returns to us. */ static void json_pay_sendpay_resolve(const struct sendpay_result *r, void *vpay) { struct pay *pay = (struct pay *) vpay; - struct timeabs now = time_now(); /* If we succeed, hurray */ if (r->succeeded) { @@ -136,13 +135,6 @@ static void json_pay_sendpay_resolve(const struct sendpay_result *r, return; } - /* If too late anyway, fail now. */ - if (time_after(now, pay->expiry)) { - /* FIXME: maybe another error kind? */ - json_pay_failure(pay->cmd, r); - return; - } - json_pay_try(pay); } @@ -199,11 +191,26 @@ static void json_pay_getroute_reply(struct subd *gossip, &json_pay_sendpay_resolve, pay); } -/* Start a payment attempt */ -static void json_pay_try(struct pay *pay) +/* Start a payment attempt. Return true if deferred, + * false if resolved now. */ +static bool json_pay_try(struct pay *pay) { u8 *req; struct command *cmd = pay->cmd; + struct timeabs now = time_now(); + struct json_result *data; + + /* If too late anyway, fail now. */ + if (time_after(now, pay->expiry)) { + data = new_json_result(cmd); + json_object_start(data, NULL); + json_add_num(data, "now", now.ts.tv_sec); + json_add_num(data, "expiry", pay->expiry.ts.tv_sec); + json_object_end(data); + command_fail_detailed(cmd, PAY_INVOICE_EXPIRED, data, + "Invoice expired"); + return false; + } /* Clear previous sendpay. */ pay->sendpay_parent = tal_free(pay->sendpay_parent); @@ -218,6 +225,8 @@ static void json_pay_try(struct pay *pay) pay->riskfactor, pay->min_final_cltv_expiry); subd_req(pay, cmd->ld->gossip, req, -1, 0, json_pay_getroute_reply, pay); + + return true; } static void json_pay(struct command *cmd, @@ -316,8 +325,8 @@ static void json_pay(struct command *cmd, pay->sendpay_parent = NULL; /* Initiate payment */ - json_pay_try(pay); - command_still_pending(cmd); + if (json_pay_try(pay)) + command_still_pending(cmd); } static const struct json_command pay_command = {