mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 01:43:36 +01:00
listinvoices: add index and start params.
Now we have defined ordering, we can add a start param. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: JSON-RPC: `listinvoices` has `index` and `start` parameters for listing control.
This commit is contained in:
parent
bbf4f312a4
commit
16c133746b
16
.msggen.json
16
.msggen.json
@ -102,6 +102,10 @@
|
||||
"spent": 2,
|
||||
"unconfirmed": 0
|
||||
},
|
||||
"ListinvoicesIndex": {
|
||||
"created": 0,
|
||||
"updated": 1
|
||||
},
|
||||
"ListinvoicesInvoicesStatus": {
|
||||
"expired": 2,
|
||||
"paid": 1,
|
||||
@ -935,10 +939,12 @@
|
||||
"ListInvoices.invoices[].status": 4
|
||||
},
|
||||
"ListinvoicesRequest": {
|
||||
"ListInvoices.index": 5,
|
||||
"ListInvoices.invstring": 2,
|
||||
"ListInvoices.label": 1,
|
||||
"ListInvoices.offer_id": 4,
|
||||
"ListInvoices.payment_hash": 3
|
||||
"ListInvoices.payment_hash": 3,
|
||||
"ListInvoices.start": 6
|
||||
},
|
||||
"ListinvoicesResponse": {
|
||||
"ListInvoices.invoices[]": 1
|
||||
@ -3548,6 +3554,10 @@
|
||||
"added": "pre-v0.10.1",
|
||||
"deprecated": null
|
||||
},
|
||||
"ListInvoices.index": {
|
||||
"added": "v23.08",
|
||||
"deprecated": false
|
||||
},
|
||||
"ListInvoices.invoices[]": {
|
||||
"added": "pre-v0.10.1",
|
||||
"deprecated": false
|
||||
@ -3624,6 +3634,10 @@
|
||||
"added": "pre-v0.10.1",
|
||||
"deprecated": false
|
||||
},
|
||||
"ListInvoices.start": {
|
||||
"added": "v23.08",
|
||||
"deprecated": false
|
||||
},
|
||||
"ListNodes": {
|
||||
"added": "pre-v0.10.1",
|
||||
"deprecated": null
|
||||
|
BIN
cln-grpc/proto/node.proto
generated
BIN
cln-grpc/proto/node.proto
generated
Binary file not shown.
BIN
cln-grpc/src/convert.rs
generated
BIN
cln-grpc/src/convert.rs
generated
Binary file not shown.
BIN
cln-rpc/src/model.rs
generated
BIN
cln-rpc/src/model.rs
generated
Binary file not shown.
@ -1023,7 +1023,7 @@ class LightningRpc(UnixDomainSocketRpc):
|
||||
"""
|
||||
return self.call("listtransactions")
|
||||
|
||||
def listinvoices(self, label=None, payment_hash=None, invstring=None, offer_id=None):
|
||||
def listinvoices(self, label=None, payment_hash=None, invstring=None, offer_id=None, index=None, start=None):
|
||||
"""Query invoices
|
||||
|
||||
Show invoice matching {label}, {payment_hash}, {invstring} or {offer_id}
|
||||
@ -1035,6 +1035,8 @@ class LightningRpc(UnixDomainSocketRpc):
|
||||
"payment_hash": payment_hash,
|
||||
"invstring": invstring,
|
||||
"offer_id": offer_id,
|
||||
"index": index,
|
||||
"start": start,
|
||||
}
|
||||
return self.call("listinvoices", payload)
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -4,7 +4,7 @@ lightning-listinvoices -- Command for querying invoice status
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
**listinvoices** [*label*] [*invstring*] [*payment\_hash*] [*offer\_id*]
|
||||
**listinvoices** [*label*] [*invstring*] [*payment\_hash*] [*offer\_id*] [*index* [*start*]]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -17,6 +17,10 @@ provided when creating the invoice, the `invstring` string representing
|
||||
the invoice, the `payment_hash` of the invoice, or the local `offer_id`
|
||||
this invoice was issued for. Only one of the query parameters can be used at once.
|
||||
|
||||
`index` controls ordering, by `created` (default) or `updated`. If
|
||||
`index` is specified, `start` may be specified to start from that
|
||||
value, which is generally returned from lightning-wait(7).
|
||||
|
||||
RETURN VALUE
|
||||
------------
|
||||
|
||||
|
@ -27,6 +27,20 @@
|
||||
"offer_id": {
|
||||
"type": "string",
|
||||
"description": ""
|
||||
},
|
||||
"index": {
|
||||
"type": "string",
|
||||
"added": "v23.08",
|
||||
"enum": [
|
||||
"created",
|
||||
"updated"
|
||||
],
|
||||
"description": ""
|
||||
},
|
||||
"start": {
|
||||
"type": "u64",
|
||||
"added": "v23.08",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1222,7 +1222,9 @@ static void json_add_invoices(struct json_stream *response,
|
||||
struct wallet *wallet,
|
||||
const struct json_escape *label,
|
||||
const struct sha256 *payment_hash,
|
||||
const struct sha256 *local_offer_id)
|
||||
const struct sha256 *local_offer_id,
|
||||
const enum wait_index *listindex,
|
||||
u64 liststart)
|
||||
{
|
||||
const struct invoice_details *details;
|
||||
u64 inv_dbid;
|
||||
@ -1244,7 +1246,9 @@ static void json_add_invoices(struct json_stream *response,
|
||||
} else {
|
||||
struct db_stmt *stmt;
|
||||
|
||||
for (stmt = invoices_first(wallet->invoices, &inv_dbid);
|
||||
for (stmt = invoices_first(wallet->invoices,
|
||||
listindex, liststart,
|
||||
&inv_dbid);
|
||||
stmt;
|
||||
stmt = invoices_next(wallet->invoices, stmt, &inv_dbid)) {
|
||||
details = invoices_get_details(tmpctx,
|
||||
@ -1271,6 +1275,8 @@ static struct command_result *json_listinvoices(struct command *cmd,
|
||||
struct wallet *wallet = cmd->ld->wallet;
|
||||
const char *invstring;
|
||||
struct sha256 *payment_hash, *offer_id;
|
||||
enum wait_index *listindex;
|
||||
u64 *liststart;
|
||||
char *fail;
|
||||
|
||||
if (!param(cmd, buffer, params,
|
||||
@ -1278,6 +1284,8 @@ static struct command_result *json_listinvoices(struct command *cmd,
|
||||
p_opt("invstring", param_invstring, &invstring),
|
||||
p_opt("payment_hash", param_sha256, &payment_hash),
|
||||
p_opt("offer_id", param_sha256, &offer_id),
|
||||
p_opt("index", param_index, &listindex),
|
||||
p_opt_def("start", param_u64, &liststart, 0),
|
||||
NULL))
|
||||
return command_param_failed();
|
||||
|
||||
@ -1288,6 +1296,10 @@ static struct command_result *json_listinvoices(struct command *cmd,
|
||||
" {label}, {invstring}, {payment_hash}"
|
||||
" or {offer_id}");
|
||||
}
|
||||
if (*liststart != 0 && !listindex) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Can only specify {start} with {index}");
|
||||
}
|
||||
|
||||
/* Extract the payment_hash from the invoice. */
|
||||
if (invstring != NULL) {
|
||||
@ -1312,7 +1324,8 @@ static struct command_result *json_listinvoices(struct command *cmd,
|
||||
|
||||
response = json_stream_success(cmd);
|
||||
json_array_start(response, "invoices");
|
||||
json_add_invoices(response, wallet, label, payment_hash, offer_id);
|
||||
json_add_invoices(response, wallet, label, payment_hash, offer_id,
|
||||
listindex, *liststart);
|
||||
json_array_end(response);
|
||||
return command_success(cmd, response);
|
||||
}
|
||||
|
@ -399,6 +399,8 @@ bool invoices_find_unpaid(struct invoices *invoices UNNEEDED,
|
||||
{ fprintf(stderr, "invoices_find_unpaid called!\n"); abort(); }
|
||||
/* Generated stub for invoices_first */
|
||||
struct db_stmt *invoices_first(struct invoices *invoices UNNEEDED,
|
||||
const enum wait_index *listindex UNNEEDED,
|
||||
u64 liststart UNNEEDED,
|
||||
u64 *inv_dbid UNNEEDED)
|
||||
{ fprintf(stderr, "invoices_first called!\n"); abort(); }
|
||||
/* Generated stub for invoices_get_details */
|
||||
@ -720,6 +722,12 @@ struct command_result *param_escaped_string(struct command *cmd UNNEEDED,
|
||||
const jsmntok_t *tok UNNEEDED,
|
||||
const char **str UNNEEDED)
|
||||
{ fprintf(stderr, "param_escaped_string called!\n"); abort(); }
|
||||
/* Generated stub for param_index */
|
||||
struct command_result *param_index(struct command *cmd UNNEEDED, const char *name UNNEEDED,
|
||||
const char *buffer UNNEEDED,
|
||||
const jsmntok_t *tok UNNEEDED,
|
||||
enum wait_index **index UNNEEDED)
|
||||
{ fprintf(stderr, "param_index called!\n"); abort(); }
|
||||
/* Generated stub for param_invstring */
|
||||
struct command_result *param_invstring(struct command *cmd UNNEEDED, const char *name UNNEEDED,
|
||||
const char * buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
|
@ -858,3 +858,35 @@ def test_invoice_deschash(node_factory, chainparams):
|
||||
wait_for(lambda: len([ev for ev in l1.rpc.bkpr_listincome()['income_events'] if ev['tag'] == 'invoice']) == 1)
|
||||
inv = only_one([ev for ev in l1.rpc.bkpr_listincome()['income_events'] if ev['tag'] == 'invoice'])
|
||||
assert inv['description'] == b11['description_hash']
|
||||
|
||||
|
||||
def test_listinvoices_index(node_factory, executor):
|
||||
l1, l2 = node_factory.line_graph(2)
|
||||
|
||||
invs = {}
|
||||
for i in range(1, 100):
|
||||
invs[i] = l2.rpc.invoice(i, str(i), "test_listinvoices_index")
|
||||
|
||||
assert [inv['label'] for inv in l2.rpc.listinvoices(index='created')['invoices']] == [str(i) for i in range(1, 100)]
|
||||
assert [inv['label'] for inv in l2.rpc.listinvoices(index='created', start=1)['invoices']] == [str(i) for i in range(1, 100)]
|
||||
assert [inv['label'] for inv in l2.rpc.listinvoices(index='created', start=2)['invoices']] == [str(i) for i in range(2, 100)]
|
||||
assert [inv['label'] for inv in l2.rpc.listinvoices(index='created', start=99)['invoices']] == [str(i) for i in range(99, 100)]
|
||||
assert l2.rpc.listinvoices(index='created', start=100) == {'invoices': []}
|
||||
assert l2.rpc.listinvoices(index='created', start=2100) == {'invoices': []}
|
||||
|
||||
# Pay 10 of them, in reverse order. These will be the last ones in the 'updated' index.
|
||||
for i in range(70, 60, -1):
|
||||
l1.rpc.pay(invs[i]['bolt11'])
|
||||
|
||||
# Make sure it's fully resolved!
|
||||
wait_for(lambda: only_one(l2.rpc.listpeerchannels()['channels'])['htlcs'] == [])
|
||||
|
||||
# They're all still there!
|
||||
assert set([inv['label'] for inv in l2.rpc.listinvoices(index='updated')['invoices']]) == set([str(i) for i in range(1, 100)])
|
||||
|
||||
# Last 10 are in a defined order:
|
||||
assert [inv['label'] for inv in l2.rpc.listinvoices(index='updated', start=1)['invoices']] == [str(i) for i in range(70, 60, -1)]
|
||||
assert [inv['label'] for inv in l2.rpc.listinvoices(index='updated', start=2)['invoices']] == [str(i) for i in range(69, 60, -1)]
|
||||
assert [inv['label'] for inv in l2.rpc.listinvoices(index='updated', start=10)['invoices']] == [str(i) for i in range(61, 60, -1)]
|
||||
assert l2.rpc.listinvoices(index='updated', start=11) == {'invoices': []}
|
||||
assert l2.rpc.listinvoices(index='updated', start=2100) == {'invoices': []}
|
||||
|
@ -964,6 +964,7 @@ static struct migration dbmigrations[] = {
|
||||
{SQL("ALTER TABLE channels ADD ignore_fee_limits INTEGER DEFAULT 0;"), NULL},
|
||||
{NULL, migrate_initialize_wait_indexes},
|
||||
{SQL("ALTER TABLE invoices ADD updated_index BIGINT DEFAULT 0"), NULL},
|
||||
{SQL("CREATE INDEX invoice_update_idx ON invoices (updated_index)"), NULL},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -470,11 +470,24 @@ void invoices_delete_expired(struct invoices *invoices,
|
||||
}
|
||||
|
||||
struct db_stmt *invoices_first(struct invoices *invoices,
|
||||
const enum wait_index *listindex,
|
||||
u64 liststart,
|
||||
u64 *inv_dbid)
|
||||
{
|
||||
struct db_stmt *stmt;
|
||||
|
||||
stmt = db_prepare_v2(invoices->wallet->db, SQL("SELECT id FROM invoices ORDER by id;"));
|
||||
if (listindex && *listindex == WAIT_INDEX_UPDATED) {
|
||||
stmt = db_prepare_v2(invoices->wallet->db,
|
||||
SQL("SELECT id FROM invoices"
|
||||
" WHERE updated_index >= ?"
|
||||
" ORDER BY updated_index;"));
|
||||
} else {
|
||||
stmt = db_prepare_v2(invoices->wallet->db,
|
||||
SQL("SELECT id FROM invoices"
|
||||
" WHERE id >= ?"
|
||||
" ORDER BY id;"));
|
||||
}
|
||||
db_bind_u64(stmt, liststart);
|
||||
db_query_prepared(stmt);
|
||||
|
||||
return invoices_next(invoices, stmt, inv_dbid);
|
||||
|
@ -138,12 +138,16 @@ void invoices_delete_expired(struct invoices *invoices,
|
||||
/**
|
||||
* Iterate through all the invoices.
|
||||
* @invoices: the invoices
|
||||
* @listindex: what index order to use (if you care)
|
||||
* @liststart: first index to return (0 == all).
|
||||
* @inv_dbid: the first invoice dbid (if returns non-NULL)
|
||||
*
|
||||
* Returns pointer to hand as @stmt to invoices_next(), or NULL.
|
||||
* If you choose not to call invoices_next() you must free it!
|
||||
*/
|
||||
struct db_stmt *invoices_first(struct invoices *invoices,
|
||||
const enum wait_index *listindex,
|
||||
u64 liststart,
|
||||
u64 *inv_dbid);
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <lightningd/bitcoind.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/peer_htlcs.h>
|
||||
#include <lightningd/wait.h>
|
||||
|
||||
struct amount_msat;
|
||||
struct invoices;
|
||||
|
Loading…
Reference in New Issue
Block a user