Skip to content

Commit 7eebbbb

Browse files
draft implementing the core of the paginator
Signed-off-by: Vincenzo Palazzo <[email protected]>
1 parent e0e967c commit 7eebbbb

File tree

7 files changed

+246
-18
lines changed

7 files changed

+246
-18
lines changed

common/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ COMMON_HEADERS_NOGEN := $(COMMON_SRC_NOGEN:.c=.h) \
109109
common/htlc.h \
110110
common/json_command.h \
111111
common/jsonrpc_errors.h \
112+
common/jsonrpc_paginator.h \
112113
common/overflows.h
113114

114115
COMMON_HEADERS_GEN := common/htlc_state_names_gen.h common/status_wiregen.h common/peer_status_wiregen.h common/scb_wiregen.h

common/json_param.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
#include "ccan/tal/tal.h"
12
#include "config.h"
3+
#include "jsmn.h"
4+
#include <assert.h>
25
#include <bitcoin/address.h>
36
#include <bitcoin/base58.h>
47
#include <bitcoin/feerate.h>
@@ -14,6 +17,8 @@
1417
#include <common/json_command.h>
1518
#include <common/json_param.h>
1619
#include <common/route.h>
20+
#include <stdbool.h>
21+
#include <stddef.h>
1722

1823
struct param {
1924
const char *name;
@@ -352,6 +357,14 @@ bool param(struct command *cmd, const char *buffer,
352357
if (streq(name, "")) {
353358
allow_extra = true;
354359
continue;
360+
} else if (streq(name, "paginator")) {
361+
struct command_result *result;
362+
if ((result = cbx(cmd, name, buffer, NULL, arg)))
363+
return result;
364+
/* we allow extra but we already made a check that are
365+
* paginator keys, so this should be safe! */
366+
allow_extra = true;
367+
continue;
355368
}
356369
if (!param_add(&params, name, style, cbx, arg)) {
357370
/* We really do ignore this return! */
@@ -439,6 +452,37 @@ struct command_result *param_string(struct command *cmd, const char *name,
439452
return NULL;
440453
}
441454

455+
struct command_result *param_arr_str(struct command *cmd, const char *name,
456+
const char *buffer, const jsmntok_t *tok,
457+
const char ***arr)
458+
{
459+
const jsmntok_t *curr;
460+
size_t i;
461+
462+
if (tok->type != JSMN_ARRAY)
463+
return command_fail_badparam(cmd, name, buffer, tok,
464+
"schould be an array of string");
465+
466+
*arr = tal_arr(cmd, const char *, 0);
467+
json_for_each_arr(i, curr, tok) {
468+
struct json_escape *esc;
469+
const char *str;
470+
471+
if (curr->type != JSMN_STRING)
472+
return command_fail_badparam(cmd, name, buffer, tok,
473+
"the item of the array should be a string");
474+
475+
esc = json_escape_string_(cmd, buffer + curr->start,
476+
curr->end - curr->start);
477+
str = json_escape_unescape(cmd, esc);
478+
tal_arr_expand(arr, str);
479+
}
480+
481+
return NULL;
482+
}
483+
484+
485+
442486
struct command_result *param_ignore(struct command *cmd, const char *name,
443487
const char *buffer, const jsmntok_t *tok,
444488
const void *unused)
@@ -1066,3 +1110,24 @@ struct command_result *param_pubkey(struct command *cmd, const char *name,
10661110
"should be a compressed pubkey");
10671111
}
10681112

1113+
struct command_result *param_paginator(struct command *cmd, const char *name,
1114+
const char *buffer, const jsmntok_t *tok)
1115+
{
1116+
/*
1117+
const jsmntok_t *tok_tmp;
1118+
1119+
tok_tmp = json_get_member(buffer, tok, "batch");
1120+
if (tok_tmp)
1121+
return NULL;
1122+
tok_tmp = json_get_member(buffer, tok, "offset");
1123+
if (tok_tmp)
1124+
return NULL;
1125+
1126+
tok_tmp = json_get_member(buffer, tok, "limit");
1127+
if (tok_tmp)
1128+
return NULL;
1129+
1130+
return command_fail_badparam(cmd, name, buffer, tok,
1131+
"paginator request format in the wrong way!");*/
1132+
return NULL;
1133+
}

common/json_param.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
#ifndef LIGHTNING_COMMON_JSON_PARAM_H
33
#define LIGHTNING_COMMON_JSON_PARAM_H
44
#include "config.h"
5+
#include <assert.h>
56
#include <ccan/short_types/short_types.h>
67
#include <common/bolt11.h>
78
#include <common/json_parse.h>
9+
#include <common/jsonrpc_paginator.h>
810
#include <common/lease_rates.h>
911
#include <common/node_id.h>
1012
#include <common/sphinx.h>
@@ -49,6 +51,10 @@ struct command_result;
4951
bool param(struct command *cmd, const char *buffer,
5052
const jsmntok_t params[], ...) LAST_ARG_NULL;
5153

54+
bool param_partial_par(struct command *cmd, const char *buffer,
55+
const jsmntok_t tokens[], ...) LAST_ARG_NULL;
56+
57+
5258
/*
5359
* The callback signature.
5460
*
@@ -80,6 +86,10 @@ enum param_style {
8086
PARAM_OPTIONAL_WITH_DEFAULT,
8187
};
8288

89+
/** Check if this is a valid paginator input */
90+
struct command_result *param_paginator(struct command *cmd, const char *name,
91+
const char *buffer, const jsmntok_t *tok);
92+
8393
/*
8494
* Add a required parameter.
8595
*/
@@ -139,6 +149,9 @@ enum param_style {
139149
/* Special flag for 'check' which allows any parameters. */
140150
#define p_opt_any() "", PARAM_OPTIONAL, NULL, NULL
141151

152+
#define p_paginator() "paginator", PARAM_OPTIONAL, param_paginator, NULL
153+
154+
142155
/* All the helper routines. */
143156
struct amount_msat;
144157
struct amount_sat;
@@ -181,6 +194,11 @@ struct command_result *param_string(struct command *cmd, const char *name,
181194
const char * buffer, const jsmntok_t *tok,
182195
const char **str);
183196

197+
/* Extract an array of strings */
198+
struct command_result *param_arr_str(struct command *cmd, const char *name,
199+
const char *buffer, const jsmntok_t *tok,
200+
const char ***arr);
201+
184202
/* Extract a label. It is either an escaped string or a number. */
185203
struct command_result *param_label(struct command *cmd, const char *name,
186204
const char * buffer, const jsmntok_t *tok,
@@ -340,5 +358,4 @@ struct command_result *param_lease_hex(struct command *cmd,
340358
struct command_result *param_pubkey(struct command *cmd, const char *name,
341359
const char *buffer, const jsmntok_t *tok,
342360
struct pubkey **pubkey);
343-
344361
#endif /* LIGHTNING_COMMON_JSON_PARAM_H */

common/jsonrpc_paginator.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* Welcome in this wanderful experience of writing
3+
* a paginator for the core lightning JSON RPC 2.0 in C!
4+
*
5+
*
6+
* I will try to keep the code as simple as possible,
7+
* so if you had any dout on what I'm trying to do, blame me
8+
* that I was not able to do my job.
9+
*
10+
*
11+
* In short, the goal of this paginator is offer a struct
12+
* that it is used to grep the paginator information by
13+
* pre processin the JSON RPC request.
14+
*
15+
* So let immagine a normal listnode RPC call, where
16+
* cli | rest | grpc -> json_listnodes -> json response {....}
17+
*
18+
* if the paginator will be enbaled on the listnodes, the
19+
* call will be
20+
*
21+
* cli | rest | grpc -> json_paginator_listnodes -> json_listnodes + struct jsonrpc_paginator -> sjon response { .... }
22+
*
23+
* Done, this should be all!
24+
*
25+
*
26+
* Now let see how this is implemented.
27+
* */
28+
#ifndef JSONRPC_PAGINATOR_H
29+
#define JSONRPC_PAGINATOR_H
30+
31+
#include <ccan/tal/tal.h>
32+
#include <ccan/short_types/short_types.h>
33+
34+
/**
35+
* jsonrpc_paginator - core struct where all the paginator information
36+
* are stored,
37+
*
38+
* A developer that want to extend the functionality of the
39+
* paginator must not abuse of this struct to avoid to made the logic
40+
* messy, thanks!
41+
*
42+
* @batch: array string to be able to query a list of things, useful also
43+
* when you deal with reading stuff from file to avoid reaccess to the file
44+
* to search another item.
45+
*
46+
* @offset: a position (u64) that determines the number of element (in SQL row)
47+
* returned by request.
48+
* @limit: a position (u64) that give the number of element in [0,..,offset - 1] to skip skip.
49+
*/
50+
struct jsonrpc_paginator {
51+
/** reall usefult for access to gossip map */
52+
const char **batch;
53+
/** query the database */
54+
const u64 *offset;
55+
const u64 *limit;
56+
/* FIXME: more smarter one? like sort_by = "json key"
57+
* but this required to have a mapping between json_keys and sql keys
58+
* maybe we had already somethings in the sql plugin? */
59+
};
60+
61+
/** new_paginator - helper function to create a new paginator from a list of parameter.
62+
* This is simple enought to be avoided, but write simple code inside the C macros
63+
* is frustating, so let use this insteand.
64+
*
65+
* BTW: I love C Macros, really!
66+
* */
67+
static inline struct jsonrpc_paginator *new_paginator(const tal_t *ctx, const char **batch,
68+
const u64 *limit, const u64 *offset)
69+
{
70+
struct jsonrpc_paginator *paginator = NULL;
71+
if (batch || limit || offset) {
72+
paginator = tal(ctx, struct jsonrpc_paginator);
73+
paginator->batch = batch;
74+
paginator->limit = limit;
75+
paginator->offset = offset;
76+
return paginator;
77+
}
78+
return NULL;
79+
}
80+
81+
#endif // JSONRPC_PAGINATOR_H

lightningd/jsonrpc.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#ifndef LIGHTNING_LIGHTNINGD_JSONRPC_H
22
#define LIGHTNING_LIGHTNINGD_JSONRPC_H
3-
#include "ccan/compiler/compiler.h"
43
#include "config.h"
54
#include <ccan/list/list.h>
65
#include <common/autodata.h>
76
#include <common/json_stream.h>
7+
#include <common/jsonrpc_paginator.h>
88
#include <common/status_levels.h>
99

1010
struct jsonrpc;
@@ -19,10 +19,6 @@ enum command_mode {
1919
CMD_CHECK
2020
};
2121

22-
// FIXME(vincenzopalazzo): The filtering architecture
23-
// desearve an own file.
24-
struct jsonrpc_paginator { };
25-
2622
/* Context for a command (from JSON, but might outlive the connection!). */
2723
/* FIXME: move definition into jsonrpc.c */
2824
struct command {
@@ -49,7 +45,7 @@ struct command {
4945
/* Optional output field filter. */
5046
struct json_filter *filter;
5147
/* Option filtering option */
52-
struct jsonrpc_paginator *paginator;
48+
const struct jsonrpc_paginator *paginator;
5349
};
5450

5551
/**
@@ -279,15 +275,23 @@ struct jsonrpc_request *jsonrpc_request_start_(
279275

280276
void jsonrpc_request_end(struct jsonrpc_request *request);
281277

282-
#define PAGINATOR(callback) \
283-
static struct command_result *callback##_paginator(struct command *cmd, \
278+
AUTODATA_TYPE(json_command, struct json_command);
279+
280+
#define PAGINATOR(callback) \
281+
static struct command_result* callback##_paginator(struct command *cmd, \
284282
const char *buffer, \
285283
const jsmntok_t *obj UNNEEDED, \
286284
const jsmntok_t *params) \
287285
{ \
288-
return callback(cmd, buffer, obj, params); \
286+
const char **batch; \
287+
u64 *limit, *offset; \
288+
if (!param_partial_par(cmd, buffer, params, \
289+
p_opt("batch", param_arr_str, &batch), \
290+
p_opt("limit", param_u64, &limit), \
291+
p_opt("offset", param_u64, &offset), \
292+
NULL)) \
293+
return command_param_failed(); \
294+
cmd->paginator = new_paginator(cmd, batch, limit, offset); \
295+
return callback(cmd, buffer, obj, params); \
289296
}
290-
291-
AUTODATA_TYPE(json_command, struct json_command);
292-
293297
#endif /* LIGHTNING_LIGHTNINGD_JSONRPC_H */

plugins/libplugin.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <common/htlc.h>
1515
#include <common/json_command.h>
1616
#include <common/jsonrpc_errors.h>
17+
#include <common/jsonrpc_paginator.h>
1718
#include <common/node_id.h>
1819
#include <common/status_levels.h>
1920
#include <common/utils.h>
@@ -57,6 +58,8 @@ struct command {
5758
struct plugin *plugin;
5859
/* Optional output field filter. */
5960
struct json_filter *filter;
61+
/* Option filtering option */
62+
struct jsonrpc_paginator *paginator;
6063
};
6164

6265
/* Create an array of these, one for each command you support. */
@@ -485,4 +488,22 @@ const jsmntok_t *jsonrpc_request_sync(const tal_t *ctx, struct plugin *plugin,
485488
const struct json_out *params TAKES,
486489
const char **resp);
487490

491+
#define PAGINATOR(callback) \
492+
static struct command_result* callback##_paginator(struct command *cmd, \
493+
const char *buffer, \
494+
const jsmntok_t *params) \
495+
{ \
496+
const char **batch; \
497+
u64 *limit, *offset; \
498+
if (!param(cmd, buffer, params, \
499+
p_opt("batch", param_arr_str, &batch), \
500+
p_opt("limit", param_u64, &limit), \
501+
p_opt("offset", param_u64, &offset), \
502+
p_opt_any(), \
503+
NULL)) \
504+
return command_param_failed(); \
505+
cmd->paginator = new_paginator(cmd, batch, limit, offset); \
506+
return callback(cmd, buffer, params); \
507+
}
508+
488509
#endif /* LIGHTNING_PLUGINS_LIBPLUGIN_H */

0 commit comments

Comments
 (0)