Browse Source

lightningd/invoice.c: Add `timeout` parameter to `waitanyinvoice`.

Fixes: #3192

Changelog-Added: `waitanyinvoice` now supports a `timeout` parameter, which when set will cause the command to fail when the timeout is reached; can set this to 0 to fail immediately if no new invoice has been paid yet.
travis-debug
ZmnSCPxj jxPCSnmZ 5 years ago
committed by Christian Decker
parent
commit
67590fc6be
  1. 1
      common/jsonrpc_errors.h
  2. 8
      contrib/pyln-client/pyln/client/lightning.py
  3. 20
      doc/lightning-waitanyinvoice.7
  4. 15
      doc/lightning-waitanyinvoice.7.md
  5. 22
      lightningd/invoice.c

1
common/jsonrpc_errors.h

@ -52,5 +52,6 @@
#define INVOICE_LABEL_ALREADY_EXISTS 900
#define INVOICE_PREIMAGE_ALREADY_EXISTS 901
#define INVOICE_HINTS_GAVE_NO_ROUTES 902
#define INVOICE_WAIT_TIMED_OUT 904
#endif /* LIGHTNING_COMMON_JSONRPC_ERRORS_H */

8
contrib/pyln-client/pyln/client/lightning.py

@ -988,14 +988,18 @@ class LightningRpc(UnixDomainSocketRpc):
"""
return self.call("stop")
def waitanyinvoice(self, lastpay_index=None):
def waitanyinvoice(self, lastpay_index=None, timeout=None, **kwargs):
"""
Wait for the next invoice to be paid, after {lastpay_index}
(if supplied)
Fail after {timeout} seconds has passed without an invoice
being paid.
"""
payload = {
"lastpay_index": lastpay_index
"lastpay_index": lastpay_index,
"timeout": timeout
}
payload.update({k: v for k, v in kwargs.items()})
return self.call("waitanyinvoice", payload)
def waitblockheight(self, blockheight, timeout=None):

20
doc/lightning-waitanyinvoice.7

@ -3,7 +3,7 @@
lightning-waitanyinvoice - Command for waiting for payments
.SH SYNOPSIS
\fBwaitanyinvoice\fR [\fIlastpay_index\fR]
\fBwaitanyinvoice\fR [\fIlastpay_index\fR] [\fItimeout\fR]
.SH DESCRIPTION
@ -22,11 +22,29 @@ invoice when it gets paid\. The first valid \fIpay_index\fR is 1; specifying
\fIlastpay_index\fR of 0 equivalent to not specifying a \fIlastpay_index\fR\.
Negative \fIlastpay_index\fR is invalid\.
If \fItimeout\fR is specified, wait at most that number of seconds, which
must be an integer\.
If the specified \fItimeout\fR is reached, this command will return with an
error\.
You can specify this to 0 so that \fBwaitanyinvoice\fR will return
immediately with an error if no pending invoice is available yet\.
If unspecified, this command will wait indefinitely\.
.SH RETURN VALUE
On success, an invoice description will be returned as per
\fBlightning-listinvoice\fR(7): \fIcomplete\fR will always be \fItrue\fR\.
Possible errors are:
.RS
.IP \[bu]
904\.
The \fItimeout\fR was reached without an invoice being paid\.
.RE
.SH AUTHOR
Rusty Russell \fI<rusty@rustcorp.com.au\fR> is mainly responsible\.

15
doc/lightning-waitanyinvoice.7.md

@ -4,7 +4,7 @@ lightning-waitanyinvoice -- Command for waiting for payments
SYNOPSIS
--------
**waitanyinvoice** \[*lastpay\_index*\]
**waitanyinvoice** \[*lastpay\_index*\] \[*timeout*\]
DESCRIPTION
-----------
@ -22,12 +22,25 @@ invoice when it gets paid. The first valid *pay\_index* is 1; specifying
*lastpay\_index* of 0 equivalent to not specifying a *lastpay\_index*.
Negative *lastpay\_index* is invalid.
If *timeout* is specified, wait at most that number of seconds, which
must be an integer.
If the specified *timeout* is reached, this command will return with an
error.
You can specify this to 0 so that **waitanyinvoice** will return
immediately with an error if no pending invoice is available yet.
If unspecified, this command will wait indefinitely.
RETURN VALUE
------------
On success, an invoice description will be returned as per
lightning-listinvoice(7): *complete* will always be *true*.
Possible errors are:
* 904.
The *timeout* was reached without an invoice being paid.
AUTHOR
------

22
lightningd/invoice.c

@ -16,6 +16,7 @@
#include <common/overflows.h>
#include <common/param.h>
#include <common/pseudorand.h>
#include <common/timeout.h>
#include <common/utils.h>
#include <errno.h>
#include <gossipd/gen_gossip_wire.h>
@ -102,6 +103,12 @@ static void wait_on_invoice(const struct invoice *invoice, void *cmd)
else
tell_waiter_deleted((struct command *) cmd);
}
static void wait_timed_out(struct command *cmd)
{
was_pending(command_fail(cmd, INVOICE_WAIT_TIMED_OUT,
"Timed out while waiting "
"for invoice to be paid"));
}
/* We derive invoice secret using 1-way function from payment_preimage
* (just a different one from the payment_hash!) */
@ -1129,13 +1136,25 @@ static struct command_result *json_waitanyinvoice(struct command *cmd,
const jsmntok_t *params)
{
u64 *pay_index;
u64 *timeout;
struct wallet *wallet = cmd->ld->wallet;
if (!param(cmd, buffer, params,
p_opt_def("lastpay_index", param_u64, &pay_index, 0),
p_opt("timeout", &param_u64, &timeout),
NULL))
return command_param_failed();
/*~ We allocate the timeout and the wallet-waitanyinvoice
* in the cmd context, so whichever one manages to complete
* the command first (and destroy the cmd context)
* auto-cancels the other, is not tal amazing?
*/
if (timeout)
(void) new_reltimer(cmd->ld->timers, cmd,
time_from_sec(*timeout),
&wait_timed_out, cmd);
/* Set command as pending. We do not know if
* wallet_invoice_waitany will return immediately
* or not, so indicating pending is safest. */
@ -1155,7 +1174,8 @@ static const struct json_command waitanyinvoice_command = {
"waitanyinvoice",
"payment",
json_waitanyinvoice,
"Wait for the next invoice to be paid, after {lastpay_index} (if supplied)"
"Wait for the next invoice to be paid, after {lastpay_index} (if supplied). "
"If {timeout} seconds is reached while waiting, fail with an error."
};
AUTODATA(json_command, &waitanyinvoice_command);

Loading…
Cancel
Save