Skip to content

Commit

Permalink
lightningd: add ordering and pagination to listforwards.
Browse files Browse the repository at this point in the history
Changelog-Added: JSON-RPC: `listforwards` new parameters `index`, `start` and `limit`.
  • Loading branch information
rustyrussell committed Oct 23, 2023
1 parent 4cb3791 commit 1f32dfc
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 54 deletions.
8 changes: 7 additions & 1 deletion doc/lightning-listforwards.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ lightning-listforwards -- Command showing all htlcs and their information
SYNOPSIS
--------

**listforwards** [*status*] [*in\_channel*] [*out\_channel*]
**listforwards** [*status*] [*in\_channel*] [*out\_channel*] [*index* [*start*] [*limit*]]

DESCRIPTION
-----------
Expand All @@ -18,6 +18,12 @@ If *status* is specified, then only the forwards with the given status are retur
If *in\_channel* or *out\_channel* is specified, then only the matching forwards
on the given in/out channel are returned.

If neither *in\_channel* or *out\_channel* is specified,
`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), and `limit`
can be used to specify the maximum number of entries to return.

RETURN VALUE
------------

Expand Down
4 changes: 3 additions & 1 deletion doc/lightning-sql.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,15 @@ The following tables are currently supported:
- `close_cause` (type `string`, sqltype `TEXT`)

- `forwards` indexed by `in_channel and in_htlc_id` (see lightning-listforwards(7))
- `created_index` (type `u64`, sqltype `INTEGER`)
- `in_channel` (type `short_channel_id`, sqltype `TEXT`)
- `in_htlc_id` (type `u64`, sqltype `INTEGER`)
- `in_msat` (type `msat`, sqltype `INTEGER`)
- `status` (type `string`, sqltype `TEXT`)
- `received_time` (type `number`, sqltype `REAL`)
- `out_channel` (type `short_channel_id`, sqltype `TEXT`)
- `out_htlc_id` (type `u64`, sqltype `INTEGER`)
- `updated_index` (type `u64`, sqltype `INTEGER`)
- `style` (type `string`, sqltype `TEXT`)
- `fee_msat` (type `msat`, sqltype `INTEGER`)
- `out_msat` (type `msat`, sqltype `INTEGER`)
Expand Down Expand Up @@ -517,4 +519,4 @@ RESOURCES
---------

Main web site: <https://github.com/ElementsProject/lightning>
[comment]: # ( SHA256STAMP:ff17015e3407e1b9fd71274a4259b943a235c4874bf77be0db4b31dfbab30e69)
[comment]: # ( SHA256STAMP:826897e2d257c12679b9fec7b35d3d20bb0a6e580d166862beec1cc7b8eb375e)
19 changes: 19 additions & 0 deletions doc/schemas/listforwards.request.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@
},
"out_channel": {
"type": "short_channel_id"
},
"index": {
"type": "string",
"added": "v23.11",
"enum": [
"created",
"updated"
],
"description": ""
},
"start": {
"type": "u64",
"added": "v23.11",
"description": ""
},
"limit": {
"type": "u32",
"added": "v23.11",
"description": ""
}
}
}
29 changes: 26 additions & 3 deletions lightningd/forwards.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,14 @@ static void listforwardings_add_forwardings(struct json_stream *response,
struct wallet *wallet,
enum forward_status status,
const struct short_channel_id *chan_in,
const struct short_channel_id *chan_out)
const struct short_channel_id *chan_out,
const enum wait_index *listindex,
u64 liststart,
const u32 *listlimit)
{
const struct forwarding *forwardings;

forwardings = wallet_forwarded_payments_get(wallet, tmpctx, status, chan_in, chan_out);
forwardings = wallet_forwarded_payments_get(wallet, tmpctx, status, chan_in, chan_out, listindex, liststart, listlimit);

json_array_start(response, "forwards");
for (size_t i=0; i<tal_count(forwardings); i++) {
Expand Down Expand Up @@ -188,17 +191,37 @@ static struct command_result *json_listforwards(struct command *cmd,
struct json_stream *response;
struct short_channel_id *chan_in, *chan_out;
enum forward_status *status;
enum wait_index *listindex;
u64 *liststart;
u32 *listlimit;

if (!param(cmd, buffer, params,
p_opt_def("status", param_forward_status, &status,
FORWARD_ANY),
p_opt("in_channel", param_short_channel_id, &chan_in),
p_opt("out_channel", param_short_channel_id, &chan_out),
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();

if (*liststart != 0 && !listindex) {
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}");
}

if ((chan_in || chan_out) && *liststart != 0) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Cannot use start with in_channel or out_channel");
}

response = json_stream_success(cmd);
listforwardings_add_forwardings(response, cmd->ld->wallet, *status, chan_in, chan_out);
listforwardings_add_forwardings(response, cmd->ld->wallet, *status, chan_in, chan_out, listindex, *liststart, listlimit);

return command_success(cmd, response);
}
Expand Down
177 changes: 129 additions & 48 deletions wallet/wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -4825,7 +4825,10 @@ const struct forwarding *wallet_forwarded_payments_get(struct wallet *w,
const tal_t *ctx,
enum forward_status status,
const struct short_channel_id *chan_in,
const struct short_channel_id *chan_out)
const struct short_channel_id *chan_out,
const enum wait_index *listindex,
u64 liststart,
const u32 *listlimit)
{
struct forwarding *results = tal_arr(ctx, struct forwarding, 0);
size_t count = 0;
Expand All @@ -4834,57 +4837,135 @@ const struct forwarding *wallet_forwarded_payments_get(struct wallet *w,
// placeholder for any parameter, the value doesn't matter because it's discarded by sql
const int any = -1;

stmt = db_prepare_v2(
w->db,
SQL("SELECT"
" state"
", in_msatoshi"
", out_msatoshi"
", in_channel_scid"
", out_channel_scid"
", in_htlc_id"
", out_htlc_id"
", received_time"
", resolved_time"
", failcode "
", forward_style "
", id "
", updated_index "
"FROM forwards "
"WHERE (1 = ? OR state = ?) AND "
"(1 = ? OR in_channel_scid = ?) AND "
"(1 = ? OR out_channel_scid = ?)"));

if (status == FORWARD_ANY) {
// any status
db_bind_int(stmt, 1);
db_bind_int(stmt, any);
} else {
// specific forward status
db_bind_int(stmt, 0);
db_bind_int(stmt, status);
}
/* We don't support start/limits with this */
if (chan_in || chan_out) {
stmt = db_prepare_v2(
w->db,
SQL("SELECT"
" state"
", in_msatoshi"
", out_msatoshi"
", in_channel_scid"
", out_channel_scid"
", in_htlc_id"
", out_htlc_id"
", received_time"
", resolved_time"
", failcode "
", forward_style "
", id "
", updated_index "
"FROM forwards "
"WHERE (1 = ? OR state = ?) AND "
"(1 = ? OR in_channel_scid = ?) AND "
"(1 = ? OR out_channel_scid = ?)"));

if (status == FORWARD_ANY) {
// any status
db_bind_int(stmt, 1);
db_bind_int(stmt, any);
} else {
// specific forward status
db_bind_int(stmt, 0);
db_bind_int(stmt, status);
}

if (chan_in) {
// specific in_channel
db_bind_int(stmt, 0);
db_bind_short_channel_id(stmt, chan_in);
} else {
// any in_channel
db_bind_int(stmt, 1);
db_bind_int(stmt, any);
}
if (chan_in) {
// specific in_channel
db_bind_int(stmt, 0);
db_bind_short_channel_id(stmt, chan_in);
} else {
// any in_channel
db_bind_int(stmt, 1);
db_bind_int(stmt, any);
}

if (chan_out) {
// specific out_channel
db_bind_int(stmt, 0);
db_bind_short_channel_id(stmt, chan_out);
if (chan_out) {
// specific out_channel
db_bind_int(stmt, 0);
db_bind_short_channel_id(stmt, chan_out);
} else {
// any out_channel
db_bind_int(stmt, 1);
db_bind_int(stmt, any);
}
} else if (listindex && *listindex == WAIT_INDEX_UPDATED) {
stmt = db_prepare_v2(
w->db,
SQL("SELECT"
" state"
", in_msatoshi"
", out_msatoshi"
", in_channel_scid"
", out_channel_scid"
", in_htlc_id"
", out_htlc_id"
", received_time"
", resolved_time"
", failcode "
", forward_style "
", id "
", updated_index "
"FROM forwards "
" WHERE"
" (1 = ? OR state = ?)"
" AND"
" updated_index >= ?"
" ORDER BY updated_index"
" LIMIT ?;"));
if (status == FORWARD_ANY) {
// any status
db_bind_int(stmt, 1);
db_bind_int(stmt, any);
} else {
// specific forward status
db_bind_int(stmt, 0);
db_bind_int(stmt, status);
}
db_bind_u64(stmt, liststart);
if (listlimit)
db_bind_int(stmt, *listlimit);
else
db_bind_int(stmt, INT_MAX);
} else {
// any out_channel
db_bind_int(stmt, 1);
db_bind_int(stmt, any);
stmt = db_prepare_v2(
w->db,
SQL("SELECT"
" state"
", in_msatoshi"
", out_msatoshi"
", in_channel_scid"
", out_channel_scid"
", in_htlc_id"
", out_htlc_id"
", received_time"
", resolved_time"
", failcode "
", forward_style "
", id "
", updated_index "
"FROM forwards "
" WHERE"
" (1 = ? OR state = ?)"
" AND"
" id >= ?"
" ORDER BY id"
" LIMIT ?;"));
if (status == FORWARD_ANY) {
// any status
db_bind_int(stmt, 1);
db_bind_int(stmt, any);
} else {
// specific forward status
db_bind_int(stmt, 0);
db_bind_int(stmt, status);
}
db_bind_u64(stmt, liststart);
if (listlimit)
db_bind_int(stmt, *listlimit);
else
db_bind_int(stmt, INT_MAX);
}

db_query_prepared(stmt);

for (count=0; db_step(stmt); count++) {
Expand Down
5 changes: 4 additions & 1 deletion wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,10 @@ const struct forwarding *wallet_forwarded_payments_get(struct wallet *w,
const tal_t *ctx,
enum forward_status state,
const struct short_channel_id *chan_in,
const struct short_channel_id *chan_out);
const struct short_channel_id *chan_out,
const enum wait_index *listindex,
u64 liststart,
const u32 *listlimit);

/**
* Delete a particular forward entry
Expand Down

0 comments on commit 1f32dfc

Please sign in to comment.