listinvoices: add limit param.

Changelog-Added: JSON-RPC: `listinvoices` has `limit` parameter for listing control.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-07-22 19:29:15 +09:30
parent 16c133746b
commit 284262d006
13 changed files with 321 additions and 278 deletions

View file

@ -942,6 +942,7 @@
"ListInvoices.index": 5,
"ListInvoices.invstring": 2,
"ListInvoices.label": 1,
"ListInvoices.limit": 7,
"ListInvoices.offer_id": 4,
"ListInvoices.payment_hash": 3,
"ListInvoices.start": 6
@ -3626,6 +3627,10 @@
"added": "pre-v0.10.1",
"deprecated": false
},
"ListInvoices.limit": {
"added": "v23.08",
"deprecated": false
},
"ListInvoices.offer_id": {
"added": "pre-v0.10.1",
"deprecated": false

View file

@ -638,6 +638,7 @@ message ListinvoicesRequest {
optional string offer_id = 4;
optional ListinvoicesIndex index = 5;
optional uint64 start = 6;
optional uint32 limit = 7;
}
message ListinvoicesResponse {

View file

@ -1825,6 +1825,7 @@ impl From<requests::ListinvoicesRequest> for pb::ListinvoicesRequest {
offer_id: c.offer_id, // Rule #2 for type string?
index: c.index.map(|v| v as i32),
start: c.start, // Rule #2 for type u64?
limit: c.limit, // Rule #2 for type u32?
}
}
}
@ -2503,6 +2504,7 @@ impl From<pb::ListinvoicesRequest> for requests::ListinvoicesRequest {
offer_id: c.offer_id, // Rule #1 for type string?
index: c.index.map(|v| v.try_into().unwrap()),
start: c.start, // Rule #1 for type u64?
limit: c.limit, // Rule #1 for type u32?
}
}
}

2
cln-rpc/src/model.rs generated
View file

@ -625,6 +625,8 @@ pub mod requests {
pub index: Option<ListinvoicesIndex>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
impl From<ListinvoicesRequest> for Request {

View file

@ -1023,7 +1023,7 @@ class LightningRpc(UnixDomainSocketRpc):
"""
return self.call("listtransactions")
def listinvoices(self, label=None, payment_hash=None, invstring=None, offer_id=None, index=None, start=None):
def listinvoices(self, label=None, payment_hash=None, invstring=None, offer_id=None, index=None, start=None, limit=None):
"""Query invoices
Show invoice matching {label}, {payment_hash}, {invstring} or {offer_id}
@ -1037,6 +1037,7 @@ class LightningRpc(UnixDomainSocketRpc):
"offer_id": offer_id,
"index": index,
"start": start,
"limit": limit,
}
return self.call("listinvoices", payload)

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,7 @@ lightning-listinvoices -- Command for querying invoice status
SYNOPSIS
--------
**listinvoices** [*label*] [*invstring*] [*payment\_hash*] [*offer\_id*] [*index* [*start*]]
**listinvoices** [*label*] [*invstring*] [*payment\_hash*] [*offer\_id*] [*index* [*start*] [*limit*]]
DESCRIPTION
-----------
@ -19,7 +19,8 @@ this invoice was issued for. Only one of the query parameters can be used at onc
`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).
value, which is generally returned from lightning-wait(7), and `limit`
can be used to specify the maximum number of entries to return.
RETURN VALUE
------------

View file

@ -41,6 +41,11 @@
"type": "u64",
"added": "v23.08",
"description": ""
},
"limit": {
"type": "u32",
"added": "v23.08",
"description": ""
}
}
}

View file

@ -1224,7 +1224,8 @@ static void json_add_invoices(struct json_stream *response,
const struct sha256 *payment_hash,
const struct sha256 *local_offer_id,
const enum wait_index *listindex,
u64 liststart)
u64 liststart,
const u32 *listlimit)
{
const struct invoice_details *details;
u64 inv_dbid;
@ -1247,7 +1248,7 @@ static void json_add_invoices(struct json_stream *response,
struct db_stmt *stmt;
for (stmt = invoices_first(wallet->invoices,
listindex, liststart,
listindex, liststart, listlimit,
&inv_dbid);
stmt;
stmt = invoices_next(wallet->invoices, stmt, &inv_dbid)) {
@ -1277,6 +1278,7 @@ static struct command_result *json_listinvoices(struct command *cmd,
struct sha256 *payment_hash, *offer_id;
enum wait_index *listindex;
u64 *liststart;
u32 *listlimit;
char *fail;
if (!param(cmd, buffer, params,
@ -1286,6 +1288,7 @@ static struct command_result *json_listinvoices(struct command *cmd,
p_opt("offer_id", param_sha256, &offer_id),
p_opt("index", param_index, &listindex),
p_opt_def("start", param_u64, &liststart, 0),
p_opt("limit", param_u32, &listlimit),
NULL))
return command_param_failed();
@ -1300,6 +1303,10 @@ static struct command_result *json_listinvoices(struct command *cmd,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Can only specify {start} with {index}");
}
if (listlimit && !listindex) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Can only specify {limit} with {index}");
}
/* Extract the payment_hash from the invoice. */
if (invstring != NULL) {
@ -1325,7 +1332,7 @@ 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,
listindex, *liststart);
listindex, *liststart, listlimit);
json_array_end(response);
return command_success(cmd, response);
}

View file

@ -401,6 +401,7 @@ bool invoices_find_unpaid(struct invoices *invoices UNNEEDED,
struct db_stmt *invoices_first(struct invoices *invoices UNNEEDED,
const enum wait_index *listindex UNNEEDED,
u64 liststart UNNEEDED,
const u32 *listlimit UNNEEDED,
u64 *inv_dbid UNNEEDED)
{ fprintf(stderr, "invoices_first called!\n"); abort(); }
/* Generated stub for invoices_get_details */
@ -779,6 +780,11 @@ struct command_result *param_string(struct command *cmd UNNEEDED, const char *na
const char * buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
const char **str UNNEEDED)
{ fprintf(stderr, "param_string called!\n"); abort(); }
/* Generated stub for param_u32 */
struct command_result *param_u32(struct command *cmd UNNEEDED, const char *name UNNEEDED,
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
uint32_t **num UNNEEDED)
{ fprintf(stderr, "param_u32 called!\n"); abort(); }
/* Generated stub for param_u64 */
struct command_result *param_u64(struct command *cmd UNNEEDED, const char *name UNNEEDED,
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,

View file

@ -890,3 +890,7 @@ def test_listinvoices_index(node_factory, executor):
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': []}
# limit should work!
for i in range(1, 10):
assert only_one(l2.rpc.listinvoices(index='updated', start=i, limit=1)['invoices'])['label'] == str(70 + 1 - i)

View file

@ -472,6 +472,7 @@ void invoices_delete_expired(struct invoices *invoices,
struct db_stmt *invoices_first(struct invoices *invoices,
const enum wait_index *listindex,
u64 liststart,
const u32 *listlimit,
u64 *inv_dbid)
{
struct db_stmt *stmt;
@ -480,14 +481,20 @@ struct db_stmt *invoices_first(struct invoices *invoices,
stmt = db_prepare_v2(invoices->wallet->db,
SQL("SELECT id FROM invoices"
" WHERE updated_index >= ?"
" ORDER BY updated_index;"));
" ORDER BY updated_index"
" LIMIT ?;"));
} else {
stmt = db_prepare_v2(invoices->wallet->db,
SQL("SELECT id FROM invoices"
" WHERE id >= ?"
" ORDER BY id;"));
" ORDER BY id"
" LIMIT ?;"));
}
db_bind_u64(stmt, liststart);
if (listlimit)
db_bind_int(stmt, *listlimit);
else
db_bind_int(stmt, INT_MAX);
db_query_prepared(stmt);
return invoices_next(invoices, stmt, inv_dbid);

View file

@ -140,6 +140,7 @@ void invoices_delete_expired(struct invoices *invoices,
* @invoices: the invoices
* @listindex: what index order to use (if you care)
* @liststart: first index to return (0 == all).
* @listlimit: limit on number of entries to return (NULL == no limit).
* @inv_dbid: the first invoice dbid (if returns non-NULL)
*
* Returns pointer to hand as @stmt to invoices_next(), or NULL.
@ -148,6 +149,7 @@ void invoices_delete_expired(struct invoices *invoices,
struct db_stmt *invoices_first(struct invoices *invoices,
const enum wait_index *listindex,
u64 liststart,
const u32 *listlimit,
u64 *inv_dbid);
/**