Skip to content

Commit 5eceaa7

Browse files
ZmnSCPxjrustyrussell
authored andcommittedJan 3, 2018
invoice: Modify waitanyinvoice interface to use pay_index.
1 parent 3003b73 commit 5eceaa7

File tree

6 files changed

+86
-88
lines changed

6 files changed

+86
-88
lines changed
 

‎doc/lightning-waitanyinvoice.7

+8-6
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
.\" Title: lightning-waitanyinvoice
33
.\" Author: [see the "AUTHOR" section]
44
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
5-
.\" Date: 01/23/2017
5+
.\" Date: 12/26/2017
66
.\" Manual: \ \&
77
.\" Source: \ \&
88
.\" Language: English
99
.\"
10-
.TH "LIGHTNING\-WAITANYIN" "7" "01/23/2017" "\ \&" "\ \&"
10+
.TH "LIGHTNING\-WAITANYIN" "7" "12/26/2017" "\ \&" "\ \&"
1111
.\" -----------------------------------------------------------------
1212
.\" * Define some portability stuff
1313
.\" -----------------------------------------------------------------
@@ -31,15 +31,17 @@
3131
lightning-waitanyinvoice \- Protocol for waiting for payments\&.
3232
.SH "SYNOPSIS"
3333
.sp
34-
\fBwaitanyinvoice\fR [\fIlastlabel\fR]
34+
\fBwaitanyinvoice\fR [\fIlastpay_index\fR]
3535
.SH "DESCRIPTION"
3636
.sp
37-
The \fBwaitanyinvoice\fR RPC command waits until an invoice is paid, then returns a single entry as per \fBlistinvoice\fR\&. It will not return for any invoices paid prior to or including \fIlastlabel\fR\&.
37+
The \fBwaitanyinvoice\fR RPC command waits until an invoice is paid, then returns a single entry as per \fBlistinvoice\fR\&. It will not return for any invoices paid prior to or including the \fIlastpay_index\fR\&.
3838
.sp
39-
This is usually called iteratively: once with no arguments, then repeatedly with the returned \fIlabel\fR entry\&. This ensures that no paid invoice is missed\&.
39+
This is usually called iteratively: once with no arguments, then repeatedly with the returned \fIpay_index\fR entry\&. This ensures that no paid invoice is missed\&.
40+
.sp
41+
The \fIpay_index\fR is a monotonically\-increasing number assigned to an 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\&.
4042
.SH "RETURN VALUE"
4143
.sp
42-
On success, the \fIrhash\fR, \fIlabel\fR, and \fImsatoshi\fR will be returned\&.
44+
On success, the \fIrhash\fR, \fIlabel\fR, \fIpay_index\fR, and \fImsatoshi\fR will be returned\&.
4345
.SH "AUTHOR"
4446
.sp
4547
Rusty Russell <rusty@rustcorp\&.com\&.au> is mainly responsible\&.

‎doc/lightning-waitanyinvoice.7.txt

+10-4
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,27 @@ lightning-waitanyinvoice - Protocol for waiting for payments.
88

99
SYNOPSIS
1010
--------
11-
*waitanyinvoice* ['lastlabel']
11+
*waitanyinvoice* ['lastpay_index']
1212

1313
DESCRIPTION
1414
-----------
1515
The *waitanyinvoice* RPC command waits until an invoice is paid, then
1616
returns a single entry as per *listinvoice*. It will not return for
17-
any invoices paid prior to or including 'lastlabel'.
17+
any invoices paid prior to or including the 'lastpay_index'.
1818

1919
This is usually called iteratively: once with no arguments, then
20-
repeatedly with the returned 'label' entry. This ensures that no paid
20+
repeatedly with the returned 'pay_index' entry. This ensures that no paid
2121
invoice is missed.
2222

23+
The 'pay_index' is a monotonically-increasing number assigned to an
24+
invoice when it gets paid. The first valid 'pay_index' is 1; specifying
25+
'lastpay_index' of 0 equivalent to not specifying a 'lastpay_index'.
26+
Negative 'lastpay_index' is invalid.
27+
28+
2329
RETURN VALUE
2430
------------
25-
On success, the 'rhash', 'label', and 'msatoshi' will be returned.
31+
On success, the 'rhash', 'label', 'pay_index', and 'msatoshi' will be returned.
2632

2733
//FIXME:Enumerate errors
2834

‎lightningd/invoice.c

+27-23
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ static void tell_waiter(struct command *cmd, const struct invoice *paid)
8383
json_add_hex(response, "rhash", &paid->rhash, sizeof(paid->rhash));
8484
json_add_u64(response, "msatoshi", paid->msatoshi);
8585
json_add_bool(response, "complete", paid->state == PAID);
86+
if (paid->state == PAID)
87+
json_add_u64(response, "pay_index", paid->pay_index);
8688
json_object_end(response);
8789
command_success(cmd, response);
8890
}
@@ -98,7 +100,11 @@ void resolve_invoice(struct lightningd *ld, struct invoice *invoice)
98100

99101
invoice->state = PAID;
100102

101-
/* Tell all the waitanyinvoice waiters about the new paid invoice */
103+
/* wallet_invoice_save updates pay_index member,
104+
* which tell_waiter needs. */
105+
wallet_invoice_save(ld->wallet, invoice);
106+
107+
/* Tell all the waiters about the new paid invoice */
102108
while ((w = list_pop(&invs->invoice_waiters,
103109
struct invoice_waiter,
104110
list)) != NULL)
@@ -109,8 +115,6 @@ void resolve_invoice(struct lightningd *ld, struct invoice *invoice)
109115
list)) != NULL)
110116
tell_waiter(w->cmd, invoice);
111117

112-
wallet_invoice_save(ld->wallet, invoice);
113-
114118
/* Also mark the payment in the history table as complete */
115119
wallet_payment_set_status(ld->wallet, &invoice->rhash, PAYMENT_COMPLETE);
116120
}
@@ -389,51 +393,51 @@ AUTODATA(json_command, &delinvoice_command);
389393
static void json_waitanyinvoice(struct command *cmd,
390394
const char *buffer, const jsmntok_t *params)
391395
{
392-
jsmntok_t *labeltok;
393-
const char *label = NULL;
396+
jsmntok_t *pay_indextok;
397+
u64 pay_index;
394398
struct invoice_waiter *w;
395399
struct invoices *invs = cmd->ld->invoices;
396-
int res;
400+
bool res;
397401
struct wallet *wallet = cmd->ld->wallet;
398402
char* outlabel;
399403
struct sha256 outrhash;
400404
u64 outmsatoshi;
405+
u64 outpay_index;
401406
struct json_result *response;
402407

403408
if (!json_get_params(buffer, params,
404-
"?label", &labeltok,
409+
"?lastpay_index", &pay_indextok,
405410
NULL)) {
406411
command_fail(cmd, "Invalid arguments");
407412
return;
408413
}
409414

410-
if (!labeltok) {
411-
label = NULL;
415+
if (!pay_indextok) {
416+
pay_index = 0;
412417
} else {
413-
label = tal_strndup(cmd, buffer + labeltok->start,
414-
labeltok->end - labeltok->start);
418+
if (!json_tok_u64(buffer, pay_indextok, &pay_index)) {
419+
command_fail(cmd, "'%.*s' is not a valid number",
420+
pay_indextok->end - pay_indextok->start,
421+
buffer + pay_indextok->start);
422+
return;
423+
}
415424
}
416425

417426
/* Find next paid invoice. */
418-
res = wallet_invoice_nextpaid(cmd, wallet, label,
419-
&outlabel, &outrhash, &outmsatoshi);
420-
label = tal_free(label);
421-
422-
/* If we failed to find label, error it. */
423-
if (res == -1) {
424-
command_fail(cmd, "Label not found");
425-
return;
426-
}
427+
res = wallet_invoice_nextpaid(cmd, wallet, pay_index,
428+
&outlabel, &outrhash,
429+
&outmsatoshi, &outpay_index);
427430

428431
/* If we found one, return it. */
429-
if (res == 1) {
432+
if (res) {
430433
response = new_json_result(cmd);
431434

432435
json_object_start(response, NULL);
433436
json_add_string(response, "label", outlabel);
434437
json_add_hex(response, "rhash", &outrhash, sizeof(outrhash));
435438
json_add_u64(response, "msatoshi", outmsatoshi);
436439
json_add_bool(response, "complete", true);
440+
json_add_u64(response, "pay_index", outpay_index);
437441
json_object_end(response);
438442

439443
command_success(cmd, response);
@@ -454,8 +458,8 @@ static void json_waitanyinvoice(struct command *cmd,
454458
static const struct json_command waitanyinvoice_command = {
455459
"waitanyinvoice",
456460
json_waitanyinvoice,
457-
"Wait for the next invoice to be paid, after {label} (if supplied)))",
458-
"Returns {label}, {rhash} and {msatoshi} on success. "
461+
"Wait for the next invoice to be paid, after {lastpay_index} (if supplied)))",
462+
"Returns {label}, {rhash}, {msatoshi}, and {pay_index} on success. "
459463
};
460464
AUTODATA(json_command, &waitanyinvoice_command);
461465

‎tests/test_lightningd.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -2435,20 +2435,22 @@ def test_waitanyinvoice(self):
24352435
l1.rpc.pay(inv2['bolt11'])
24362436
r = f.result(timeout=5)
24372437
assert r['label'] == 'inv1'
2438+
pay_index = r['pay_index']
24382439

24392440
# This one should return immediately with inv2
2440-
r = self.executor.submit(l2.rpc.waitanyinvoice, 'inv1').result(timeout=5)
2441+
r = self.executor.submit(l2.rpc.waitanyinvoice, pay_index).result(timeout=5)
24412442
assert r['label'] == 'inv2'
2443+
pay_index = r['pay_index']
24422444

24432445
# Now spawn the next waiter
2444-
f = self.executor.submit(l2.rpc.waitanyinvoice, 'inv2')
2446+
f = self.executor.submit(l2.rpc.waitanyinvoice, pay_index)
24452447
time.sleep(1)
24462448
assert not f.done()
24472449
l1.rpc.pay(inv3['bolt11'])
24482450
r = f.result(timeout=5)
24492451
assert r['label'] == 'inv3'
24502452

2451-
self.assertRaises(ValueError, l2.rpc.waitanyinvoice, 'doesntexist')
2453+
self.assertRaises(ValueError, l2.rpc.waitanyinvoice, 'non-number')
24522454

24532455

24542456
def test_waitanyinvoice_reversed(self):
@@ -2471,10 +2473,11 @@ def test_waitanyinvoice_reversed(self):
24712473
# Wait - should not block, should return inv2
24722474
r = self.executor.submit(l2.rpc.waitanyinvoice).result(timeout=5)
24732475
assert r['label'] == 'inv2'
2476+
pay_index = r['pay_index']
24742477
# Pay inv1
24752478
l1.rpc.pay(inv1['bolt11'])
24762479
# Wait inv2 - should not block, should return inv1
2477-
r = self.executor.submit(l2.rpc.waitanyinvoice, 'inv2').result(timeout=5)
2480+
r = self.executor.submit(l2.rpc.waitanyinvoice, pay_index).result(timeout=5)
24782481
assert r['label'] == 'inv1'
24792482

24802483
def test_channel_reenable(self):

‎wallet/wallet.c

+18-36
Original file line numberDiff line numberDiff line change
@@ -1125,49 +1125,31 @@ bool wallet_htlcs_reconnect(struct wallet *wallet,
11251125
return true;
11261126
}
11271127

1128-
int wallet_invoice_nextpaid(const tal_t *cxt,
1129-
const struct wallet *wallet,
1130-
const char *labelz,
1131-
char **outlabel,
1132-
struct sha256 *outrhash,
1133-
u64 *outmsatoshi)
1128+
bool wallet_invoice_nextpaid(const tal_t *cxt,
1129+
const struct wallet *wallet,
1130+
u64 pay_index,
1131+
char **outlabel,
1132+
struct sha256 *outrhash,
1133+
u64 *outmsatoshi,
1134+
u64 *outpay_index)
11341135
{
11351136
sqlite3_stmt *stmt;
11361137
int res;
1137-
u64 pay_index;
11381138

11391139
/* Generate query. */
1140-
if (labelz) {
1141-
/* Find label. */
1142-
stmt = db_prepare(wallet->db,
1143-
"SELECT pay_index FROM invoices WHERE label=?;");
1144-
sqlite3_bind_text(stmt, 1, labelz, strlen(labelz), SQLITE_TRANSIENT);
1145-
res = sqlite3_step(stmt);
1146-
if (res != SQLITE_ROW) {
1147-
sqlite3_finalize(stmt);
1148-
return -1;
1149-
}
1150-
pay_index = sqlite3_column_int64(stmt, 0);
1151-
sqlite3_finalize(stmt);
1152-
1153-
stmt = db_prepare(wallet->db,
1154-
"SELECT label, payment_hash, msatoshi FROM invoices"
1155-
" WHERE pay_index NOT NULL"
1156-
" AND pay_index > ?"
1157-
" ORDER BY pay_index ASC LIMIT 1;");
1158-
sqlite3_bind_int64(stmt, 1, pay_index);
1159-
} else {
1160-
stmt = db_prepare(wallet->db,
1161-
"SELECT label, payment_hash, msatoshi FROM invoices"
1162-
" WHERE pay_index NOT NULL"
1163-
" ORDER BY pay_index ASC LIMIT 1;");
1164-
}
1140+
stmt = db_prepare(wallet->db,
1141+
"SELECT label, payment_hash, msatoshi, pay_index"
1142+
" FROM invoices"
1143+
" WHERE pay_index NOT NULL"
1144+
" AND pay_index > ?"
1145+
" ORDER BY pay_index ASC LIMIT 1;");
1146+
sqlite3_bind_int64(stmt, 1, pay_index);
11651147

11661148
res = sqlite3_step(stmt);
11671149
if (res != SQLITE_ROW) {
11681150
/* No paid invoice found. */
11691151
sqlite3_finalize(stmt);
1170-
return 0;
1152+
return false;
11711153
} else {
11721154
/* Paid invoice found, return data. */
11731155
*outlabel = tal_strndup(cxt, sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0));
@@ -1177,11 +1159,11 @@ int wallet_invoice_nextpaid(const tal_t *cxt,
11771159

11781160
*outmsatoshi = sqlite3_column_int64(stmt, 2);
11791161

1162+
*outpay_index = sqlite3_column_int64(stmt, 3);
1163+
11801164
sqlite3_finalize(stmt);
1181-
return 1;
1165+
return true;
11821166
}
1183-
1184-
return -1;
11851167
}
11861168

11871169
/* Acquire the next pay_index. */

‎wallet/wallet.h

+16-15
Original file line numberDiff line numberDiff line change
@@ -333,28 +333,29 @@ bool wallet_htlcs_reconnect(struct wallet *wallet,
333333
/**
334334
* wallet_invoice_nextpaid -- Find a paid invoice.
335335
*
336-
* Get the details (label, rhash, msatoshi) of the next paid
337-
* invoice after the invoice with the given label. If label is
338-
* `NULL`, get the details of the first paid invoice. Return -1
339-
* if label is non-`NULL` and is not found, 0 if no more paid
340-
* invoices after specified invoice (or no paid invoices if label
341-
* is `NULL`), 1 if the next paid invoice was found.
336+
* Get the details (label, rhash, msatoshi, pay_index) of the first paid
337+
* invoice greater than the given pay_index. Return false if no paid
338+
* invoice found, return true if found. The first ever paid invoice will
339+
* have a pay_index of 1 or greater, so giving a pay_index of 0 will get
340+
* the first ever paid invoice if there is one.
342341
*
343342
* @ctx: Context to create the returned label.
344343
* @wallet: Wallet to query
345-
* @labelz: The label to be queried (zero-terminated), or
346-
* `NULL` if first invoice is to be queried.
344+
* @pay_index: The paid invoice returned will have pay_index greater
345+
* than this argument.
347346
* @outlabel: Pointer to label of found paid invoice. Caller
348-
* must free if this function returns 1.
347+
* must free if this function returns true.
349348
* @outrhash: Pointer to struct rhash to be filled.
350349
* @outmsatoshi: Pointer to number of millisatoshis value to pay.
350+
* @outpay_index: Pointer to pay_index of found paid invoice.
351351
*/
352-
int wallet_invoice_nextpaid(const tal_t *cxt,
353-
const struct wallet *wallet,
354-
const char *labelz,
355-
char **outlabel,
356-
struct sha256 *outrhash,
357-
u64 *outmsatoshi);
352+
bool wallet_invoice_nextpaid(const tal_t *cxt,
353+
const struct wallet *wallet,
354+
u64 pay_index,
355+
char **outlabel,
356+
struct sha256 *outrhash,
357+
u64 *outmsatoshi,
358+
u64 *outpay_index);
358359

359360
/**
360361
* wallet_invoice_save -- Save/update an invoice to the wallet

0 commit comments

Comments
 (0)
Please sign in to comment.