mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
common: clean up json routine locations.
We have them split over common/param.c, common/json.c, common/json_helpers.c, common/json_tok.c and common/json_stream.c. Change that to: * common/json_parse (all the json_to_xxx routines) * common/json_parse_simple (simplest the json parsing routines, for cli too) * common/json_stream (all the json_add_xxx routines) * common/json_param (all the param and param_xxx routines) Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
neil saitug
parent
f12f0d6929
commit
401f1debc5
@@ -8,8 +8,7 @@ ALL_PROGRAMS += cli/lightning-cli
|
||||
LIGHTNING_CLI_COMMON_OBJS := \
|
||||
bitcoin/chainparams.o \
|
||||
common/configdir.o \
|
||||
common/json.o \
|
||||
common/json_stream.o \
|
||||
common/json_parse_simple.o \
|
||||
common/status_levels.o \
|
||||
common/utils.o \
|
||||
common/version.o
|
||||
|
||||
@@ -12,7 +12,7 @@ CLI_TEST_COMMON_OBJS := \
|
||||
common/configdir.o \
|
||||
common/daemon_conn.o \
|
||||
common/htlc_state.o \
|
||||
common/json.o \
|
||||
common/json_parse_simple.o \
|
||||
common/pseudorand.o \
|
||||
common/memleak.o \
|
||||
common/msg_queue.o \
|
||||
|
||||
@@ -78,16 +78,6 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
/* Generated stub for fromwire_node_id */
|
||||
void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for log_level_name */
|
||||
const char *log_level_name(enum log_level level UNNEEDED)
|
||||
{ fprintf(stderr, "log_level_name called!\n"); abort(); }
|
||||
|
||||
@@ -78,16 +78,6 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
/* Generated stub for fromwire_node_id */
|
||||
void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for log_level_name */
|
||||
const char *log_level_name(enum log_level level UNNEEDED)
|
||||
{ fprintf(stderr, "log_level_name called!\n"); abort(); }
|
||||
|
||||
@@ -81,16 +81,6 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
/* Generated stub for fromwire_node_id */
|
||||
void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for log_level_name */
|
||||
const char *log_level_name(enum log_level level UNNEEDED)
|
||||
{ fprintf(stderr, "log_level_name called!\n"); abort(); }
|
||||
|
||||
@@ -46,10 +46,10 @@ COMMON_SRC_NOGEN := \
|
||||
common/initial_channel.c \
|
||||
common/initial_commit_tx.c \
|
||||
common/iso4217.c \
|
||||
common/json.c \
|
||||
common/json_helpers.c \
|
||||
common/json_param.c \
|
||||
common/json_parse.c \
|
||||
common/json_parse_simple.c \
|
||||
common/json_stream.c \
|
||||
common/json_tok.c \
|
||||
common/key_derive.c \
|
||||
common/keyset.c \
|
||||
common/lease_rates.c \
|
||||
@@ -58,7 +58,6 @@ COMMON_SRC_NOGEN := \
|
||||
common/node_id.c \
|
||||
common/onion.c \
|
||||
common/onionreply.c \
|
||||
common/param.c \
|
||||
common/peer_billboard.c \
|
||||
common/peer_failed.c \
|
||||
common/peer_io.c \
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <common/bech32.h>
|
||||
#include <common/bolt11.h>
|
||||
#include <common/bolt11_json.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_stream.h>
|
||||
|
||||
static void json_add_fallback(struct json_stream *response,
|
||||
|
||||
1185
common/json.c
1185
common/json.c
File diff suppressed because it is too large
Load Diff
259
common/json.h
259
common/json.h
@@ -1,259 +0,0 @@
|
||||
#ifndef LIGHTNING_COMMON_JSON_H
|
||||
#define LIGHTNING_COMMON_JSON_H
|
||||
#include "config.h"
|
||||
#include <ccan/crypto/sha256/sha256.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <common/errcode.h>
|
||||
|
||||
#define JSMN_STRICT 1
|
||||
# include <external/jsmn/jsmn.h>
|
||||
|
||||
struct json_escape;
|
||||
struct json_stream;
|
||||
struct timeabs;
|
||||
struct timespec;
|
||||
|
||||
/* Include " if it's a string. */
|
||||
const char *json_tok_full(const char *buffer, const jsmntok_t *t);
|
||||
|
||||
/* Include " if it's a string. */
|
||||
int json_tok_full_len(const jsmntok_t *t);
|
||||
|
||||
/* Is this a string equal to str? */
|
||||
bool json_tok_streq(const char *buffer, const jsmntok_t *tok, const char *str);
|
||||
|
||||
/* Is this a string equal to str of length len? */
|
||||
bool json_tok_strneq(const char *buffer, const jsmntok_t *tok,
|
||||
const char *str, size_t len);
|
||||
|
||||
/* Does this string token start with prefix? */
|
||||
bool json_tok_startswith(const char *buffer, const jsmntok_t *tok,
|
||||
const char *prefix);
|
||||
|
||||
/* Does this string token end with suffix? */
|
||||
bool json_tok_endswith(const char *buffer, const jsmntok_t *tok,
|
||||
const char *suffix);
|
||||
|
||||
/* Allocate a tal string copy */
|
||||
char *json_strdup(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Decode a hex-encoded binary */
|
||||
u8 *json_tok_bin_from_hex(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Extract number from this (may be a string, or a number literal) */
|
||||
bool json_to_number(const char *buffer, const jsmntok_t *tok,
|
||||
unsigned int *num);
|
||||
|
||||
/* Extract number from this (may be a string, or a number literal) */
|
||||
bool json_to_u64(const char *buffer, const jsmntok_t *tok,
|
||||
uint64_t *num);
|
||||
|
||||
/* Extract signed 64 bit integer from this (may be a string, or a number literal) */
|
||||
bool json_to_s64(const char *buffer, const jsmntok_t *tok, s64 *num);
|
||||
|
||||
/* Extract number from this (may be a string, or a number literal) */
|
||||
bool json_to_u32(const char *buffer, const jsmntok_t *tok,
|
||||
uint32_t *num);
|
||||
|
||||
/* Extract number from this (may be a string, or a number literal) */
|
||||
bool json_to_u16(const char *buffer, const jsmntok_t *tok,
|
||||
uint16_t *num);
|
||||
|
||||
bool json_to_sha256(const char *buffer, const jsmntok_t *tok, struct sha256 *dest);
|
||||
/*
|
||||
* Extract a non-negative (either 0 or positive) floating-point number from this
|
||||
* (must be a number literal), multiply it by 1 million and return it as an
|
||||
* integer. Any fraction smaller than 0.000001 is ignored.
|
||||
*/
|
||||
bool json_to_millionths(const char *buffer, const jsmntok_t *tok,
|
||||
u64 *millionths);
|
||||
|
||||
/* Extract signed integer from this (may be a string, or a number literal) */
|
||||
bool json_to_int(const char *buffer, const jsmntok_t *tok, int *num);
|
||||
|
||||
/* Extract an error code from this (may be a string, or a number literal) */
|
||||
bool json_to_errcode(const char *buffer, const jsmntok_t *tok, errcode_t *errcode);
|
||||
|
||||
/* Extract boolean from this */
|
||||
bool json_to_bool(const char *buffer, const jsmntok_t *tok, bool *b);
|
||||
|
||||
/* Is this a number? [0..9]+ */
|
||||
bool json_tok_is_num(const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Is this the null primitive? */
|
||||
bool json_tok_is_null(const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Returns next token with same parent (WARNING: slow!). */
|
||||
const jsmntok_t *json_next(const jsmntok_t *tok);
|
||||
|
||||
/* Get top-level member. */
|
||||
const jsmntok_t *json_get_member(const char *buffer, const jsmntok_t tok[],
|
||||
const char *label);
|
||||
|
||||
/* Get index'th array member. */
|
||||
const jsmntok_t *json_get_arr(const jsmntok_t tok[], size_t index);
|
||||
|
||||
/* Allocate a starter array of tokens for json_parse_input */
|
||||
jsmntok_t *toks_alloc(const tal_t *ctx);
|
||||
|
||||
/* Reset a token array to reuse it. */
|
||||
void toks_reset(jsmntok_t *toks);
|
||||
|
||||
/**
|
||||
* json_parse_input: parse and validate JSON.
|
||||
* @parser: parser initialized with jsmn_init.
|
||||
* @toks: tallocated array from toks_alloc()
|
||||
* @input, @len: input string.
|
||||
* @complete: set to true if the valid JSON is complete, or NULL if must be.
|
||||
*
|
||||
* This returns false if the JSON is invalid, true otherwise.
|
||||
* If it returns true, *@complete indicates that (*@toks)[0] points to a
|
||||
* valid, complete JSON element. If @complete is NULL, then incomplete
|
||||
* JSON returns false (i.e. is considered invalid).
|
||||
*
|
||||
* *@toks is resized to the complete set of tokens, with a dummy
|
||||
* terminator (type == -1) at the end.
|
||||
*
|
||||
* If it returns true, and *@complete is false, you can append more
|
||||
* data to @input and call it again (with the same perser) and the parser
|
||||
* will continue where it left off.
|
||||
*/
|
||||
bool json_parse_input(jsmn_parser *parser,
|
||||
jsmntok_t **toks,
|
||||
const char *input, int len,
|
||||
bool *complete);
|
||||
|
||||
/* Simplified version of above which parses only a complete, valid
|
||||
* JSON string */
|
||||
jsmntok_t *json_parse_simple(const tal_t *ctx, const char *input, int len);
|
||||
|
||||
/* Convert a jsmntype_t enum to a human readable string. */
|
||||
const char *jsmntype_to_string(jsmntype_t t);
|
||||
|
||||
/* Return a copy of a json value as an array. */
|
||||
jsmntok_t *json_tok_copy(const tal_t *ctx, const jsmntok_t *tok);
|
||||
|
||||
/*
|
||||
* Remove @num json values from a json array or object @obj. @tok points
|
||||
* to the first value to remove. The array @tokens will be resized.
|
||||
*/
|
||||
void json_tok_remove(jsmntok_t **tokens,
|
||||
jsmntok_t *obj_or_array, const jsmntok_t *tok, size_t num);
|
||||
|
||||
/* Guide is % for a token: each must be followed by JSON_SCAN().
|
||||
* Returns NULL on error (asserts() on bad guide). */
|
||||
const char *json_scan(const tal_t *ctx,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char *guide,
|
||||
...);
|
||||
|
||||
/* eg. JSON_SCAN(json_to_bool, &boolvar) */
|
||||
#define JSON_SCAN(fmt, var) \
|
||||
json_scan, \
|
||||
stringify(fmt), \
|
||||
((var) + 0*sizeof(fmt((const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, var) == true)), \
|
||||
(fmt)
|
||||
|
||||
/* eg. JSON_SCAN_TAL(tmpctx, json_strdup, &charvar) */
|
||||
#define JSON_SCAN_TAL(ctx, fmt, var) \
|
||||
(ctx), \
|
||||
stringify(fmt), \
|
||||
((var) + 0*sizeof((*var) = fmt((ctx), \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL))), \
|
||||
(fmt)
|
||||
|
||||
/* Already-have-varargs version */
|
||||
const char *json_scanv(const tal_t *ctx,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char *guide,
|
||||
va_list ap);
|
||||
|
||||
/* Iterator macro for array: i is counter, t is token ptr, arr is JSMN_ARRAY */
|
||||
#define json_for_each_arr(i, t, arr) \
|
||||
for (i = 0, t = (arr) + 1; i < (arr)->size; t = json_next(t), i++)
|
||||
|
||||
/* Iterator macro for object: i is counter, t is token ptr (t+1 is
|
||||
* contents of obj member), obj is JSMN_OBJECT */
|
||||
#define json_for_each_obj(i, t, obj) \
|
||||
for (i = 0, t = (obj) + 1; i < (obj)->size; t = json_next(t+1), i++)
|
||||
|
||||
|
||||
/* '"fieldname" : "value"' or '"value"' if fieldname is NULL. Turns
|
||||
* any non-printable chars into JSON escapes, but leaves existing escapes alone.
|
||||
*/
|
||||
void json_add_string(struct json_stream *result, const char *fieldname, const char *value TAKES);
|
||||
|
||||
/* '"fieldname" : "value[:value_len]"' or '"value[:value_len]"' if
|
||||
* fieldname is NULL. Turns any non-printable chars into JSON
|
||||
* escapes, but leaves existing escapes alone.
|
||||
*/
|
||||
void json_add_stringn(struct json_stream *result, const char *fieldname,
|
||||
const char *value TAKES, size_t value_len);
|
||||
|
||||
/* '"fieldname" : "value"' or '"value"' if fieldname is NULL. String must
|
||||
* already be JSON escaped as necessary. */
|
||||
void json_add_escaped_string(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const struct json_escape *esc TAKES);
|
||||
|
||||
/* '"fieldname" : literal' or 'literal' if fieldname is NULL*/
|
||||
void json_add_literal(struct json_stream *result, const char *fieldname,
|
||||
const char *literal, int len);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_num(struct json_stream *result, const char *fieldname,
|
||||
unsigned int value);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_u64(struct json_stream *result, const char *fieldname,
|
||||
uint64_t value);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_s64(struct json_stream *result, const char *fieldname,
|
||||
int64_t value);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_u32(struct json_stream *result, const char *fieldname,
|
||||
uint32_t value);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_s32(struct json_stream *result, const char *fieldname,
|
||||
int32_t value);
|
||||
/* '"fieldname" : true|false' or 'true|false' if fieldname is NULL */
|
||||
void json_add_bool(struct json_stream *result, const char *fieldname,
|
||||
bool value);
|
||||
|
||||
/* '"fieldname" : null' or 'null' if fieldname is NULL */
|
||||
void json_add_null(struct json_stream *stream, const char *fieldname);
|
||||
|
||||
/* '"fieldname" : "0189abcdef..."' or "0189abcdef..." if fieldname is NULL */
|
||||
void json_add_hex(struct json_stream *result, const char *fieldname,
|
||||
const void *data, size_t len);
|
||||
/* '"fieldname" : "0189abcdef..."' or "0189abcdef..." if fieldname is NULL */
|
||||
void json_add_hex_talarr(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const tal_t *data);
|
||||
|
||||
void json_add_timeabs(struct json_stream *result, const char *fieldname,
|
||||
struct timeabs t);
|
||||
|
||||
/* used in log.c and notification.c*/
|
||||
void json_add_time(struct json_stream *result, const char *fieldname,
|
||||
struct timespec ts);
|
||||
|
||||
/* Add ISO_8601 timestamp string, i.e. "2019-09-07T15:50+01:00" */
|
||||
void json_add_timeiso(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
struct timeabs *time);
|
||||
|
||||
/* Add any json token */
|
||||
void json_add_tok(struct json_stream *result, const char *fieldname,
|
||||
const jsmntok_t *tok, const char *buffer);
|
||||
|
||||
/* Add an error code */
|
||||
void json_add_errcode(struct json_stream *result, const char *fieldname,
|
||||
errcode_t code);
|
||||
|
||||
/* Add "bolt11" or "bolt12" field, depending on invstring. */
|
||||
void json_add_invstring(struct json_stream *result, const char *invstring);
|
||||
|
||||
#endif /* LIGHTNING_COMMON_JSON_H */
|
||||
@@ -4,7 +4,7 @@
|
||||
#define LIGHTNING_COMMON_JSON_COMMAND_H
|
||||
#include "config.h"
|
||||
#include <ccan/compiler/compiler.h>
|
||||
#include <common/json.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/jsonrpc_errors.h>
|
||||
|
||||
struct command;
|
||||
|
||||
@@ -1,495 +0,0 @@
|
||||
#include "config.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <bitcoin/psbt.h>
|
||||
#include <ccan/ccan/str/hex/hex.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <common/wireaddr.h>
|
||||
#include <errno.h>
|
||||
#include <wire/onion_wire.h>
|
||||
#include <wire/peer_wire.h>
|
||||
|
||||
bool json_to_bitcoin_amount(const char *buffer, const jsmntok_t *tok,
|
||||
uint64_t *satoshi)
|
||||
{
|
||||
char *end;
|
||||
unsigned long btc, sat;
|
||||
|
||||
btc = strtoul(buffer + tok->start, &end, 10);
|
||||
if (btc == ULONG_MAX && errno == ERANGE)
|
||||
return false;
|
||||
if (end != buffer + tok->end) {
|
||||
/* Expect always 8 decimal places. */
|
||||
if (*end != '.' || buffer + tok->end - end != 9)
|
||||
return false;
|
||||
sat = strtoul(end+1, &end, 10);
|
||||
if (sat == ULONG_MAX && errno == ERANGE)
|
||||
return false;
|
||||
if (end != buffer + tok->end)
|
||||
return false;
|
||||
} else
|
||||
sat = 0;
|
||||
|
||||
*satoshi = btc * (uint64_t)100000000 + sat;
|
||||
if (*satoshi != btc * (uint64_t)100000000 + sat)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_node_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct node_id *id)
|
||||
{
|
||||
return node_id_from_hexstr(buffer + tok->start,
|
||||
tok->end - tok->start, id);
|
||||
}
|
||||
|
||||
bool json_to_pubkey(const char *buffer, const jsmntok_t *tok,
|
||||
struct pubkey *pubkey)
|
||||
{
|
||||
return pubkey_from_hexstr(buffer + tok->start,
|
||||
tok->end - tok->start, pubkey);
|
||||
}
|
||||
|
||||
bool json_to_msat(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_msat *msat)
|
||||
{
|
||||
return parse_amount_msat(msat,
|
||||
buffer + tok->start, tok->end - tok->start);
|
||||
}
|
||||
|
||||
bool json_to_sat(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_sat *sat)
|
||||
{
|
||||
return parse_amount_sat(sat, buffer + tok->start, tok->end - tok->start);
|
||||
}
|
||||
|
||||
bool json_to_sat_or_all(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_sat *sat)
|
||||
{
|
||||
if (json_tok_streq(buffer, tok, "all")) {
|
||||
*sat = AMOUNT_SAT(-1ULL);
|
||||
return true;
|
||||
}
|
||||
return json_to_sat(buffer, tok, sat);
|
||||
}
|
||||
|
||||
bool json_to_short_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct short_channel_id *scid)
|
||||
{
|
||||
return (short_channel_id_from_str(buffer + tok->start,
|
||||
tok->end - tok->start, scid));
|
||||
}
|
||||
|
||||
bool json_to_txid(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_txid *txid)
|
||||
{
|
||||
return bitcoin_txid_from_hex(buffer + tok->start,
|
||||
tok->end - tok->start, txid);
|
||||
}
|
||||
|
||||
bool json_to_outpoint(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_outpoint *op)
|
||||
{
|
||||
jsmntok_t t1, t2;
|
||||
|
||||
if (!split_tok(buffer, tok, ':', &t1, &t2))
|
||||
return false;
|
||||
|
||||
return json_to_txid(buffer, &t1, &op->txid)
|
||||
&& json_to_u32(buffer, &t2, &op->n);
|
||||
}
|
||||
|
||||
bool json_to_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct channel_id *cid)
|
||||
{
|
||||
return hex_decode(buffer + tok->start, tok->end - tok->start,
|
||||
cid, sizeof(*cid));
|
||||
}
|
||||
|
||||
|
||||
bool json_to_coin_mvt_tag(const char *buffer, const jsmntok_t *tok,
|
||||
enum mvt_tag *tag)
|
||||
{
|
||||
enum mvt_tag i_tag;
|
||||
for (size_t i = 0; i < NUM_MVT_TAGS; i++) {
|
||||
i_tag = (enum mvt_tag) i;
|
||||
if (json_tok_streq(buffer, tok, mvt_tag_str(i_tag))) {
|
||||
*tag = i_tag;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool split_tok(const char *buffer, const jsmntok_t *tok,
|
||||
char split,
|
||||
jsmntok_t *a,
|
||||
jsmntok_t *b)
|
||||
{
|
||||
const char *p = memchr(buffer + tok->start, split, tok->end - tok->start);
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
*a = *b = *tok;
|
||||
a->end = p - buffer;
|
||||
b->start = p + 1 - buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_secret(const char *buffer, const jsmntok_t *tok, struct secret *dest)
|
||||
{
|
||||
return hex_decode(buffer + tok->start, tok->end - tok->start,
|
||||
dest->data, sizeof(struct secret));
|
||||
}
|
||||
|
||||
bool json_to_preimage(const char *buffer, const jsmntok_t *tok, struct preimage *preimage)
|
||||
{
|
||||
size_t hexlen = tok->end - tok->start;
|
||||
return hex_decode(buffer + tok->start, hexlen, preimage->r, sizeof(preimage->r));
|
||||
}
|
||||
|
||||
struct wally_psbt *json_to_psbt(const tal_t *ctx, const char *buffer,
|
||||
const jsmntok_t *tok)
|
||||
{
|
||||
return psbt_from_b64(ctx, buffer + tok->start, tok->end - tok->start);
|
||||
}
|
||||
|
||||
struct tlv_obs2_onionmsg_payload_reply_path *
|
||||
json_to_obs2_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok)
|
||||
{
|
||||
struct tlv_obs2_onionmsg_payload_reply_path *rpath;
|
||||
const jsmntok_t *hops, *t;
|
||||
size_t i;
|
||||
const char *err;
|
||||
|
||||
rpath = tal(ctx, struct tlv_obs2_onionmsg_payload_reply_path);
|
||||
err = json_scan(tmpctx, buffer, tok, "{blinding:%,first_node_id:%}",
|
||||
JSON_SCAN(json_to_pubkey, &rpath->blinding),
|
||||
JSON_SCAN(json_to_pubkey, &rpath->first_node_id),
|
||||
NULL);
|
||||
if (err)
|
||||
return tal_free(rpath);
|
||||
|
||||
hops = json_get_member(buffer, tok, "hops");
|
||||
if (!hops || hops->size < 1)
|
||||
return tal_free(rpath);
|
||||
|
||||
rpath->path = tal_arr(rpath, struct onionmsg_path *, hops->size);
|
||||
json_for_each_arr(i, t, hops) {
|
||||
rpath->path[i] = tal(rpath->path, struct onionmsg_path);
|
||||
err = json_scan(tmpctx, buffer, t, "{id:%,encrypted_recipient_data:%}",
|
||||
JSON_SCAN(json_to_pubkey,
|
||||
&rpath->path[i]->node_id),
|
||||
JSON_SCAN_TAL(rpath->path[i],
|
||||
json_tok_bin_from_hex,
|
||||
&rpath->path[i]->encrypted_recipient_data));
|
||||
if (err)
|
||||
return tal_free(rpath);
|
||||
}
|
||||
|
||||
return rpath;
|
||||
}
|
||||
|
||||
struct tlv_onionmsg_payload_reply_path *
|
||||
json_to_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok)
|
||||
{
|
||||
struct tlv_onionmsg_payload_reply_path *rpath;
|
||||
const jsmntok_t *hops, *t;
|
||||
size_t i;
|
||||
const char *err;
|
||||
|
||||
rpath = tal(ctx, struct tlv_onionmsg_payload_reply_path);
|
||||
err = json_scan(tmpctx, buffer, tok, "{blinding:%,first_node_id:%}",
|
||||
JSON_SCAN(json_to_pubkey, &rpath->blinding),
|
||||
JSON_SCAN(json_to_pubkey, &rpath->first_node_id),
|
||||
NULL);
|
||||
if (err)
|
||||
return tal_free(rpath);
|
||||
|
||||
hops = json_get_member(buffer, tok, "hops");
|
||||
if (!hops || hops->size < 1)
|
||||
return tal_free(rpath);
|
||||
|
||||
rpath->path = tal_arr(rpath, struct onionmsg_path *, hops->size);
|
||||
json_for_each_arr(i, t, hops) {
|
||||
rpath->path[i] = tal(rpath->path, struct onionmsg_path);
|
||||
err = json_scan(tmpctx, buffer, t, "{id:%,encrypted_recipient_data:%}",
|
||||
JSON_SCAN(json_to_pubkey,
|
||||
&rpath->path[i]->node_id),
|
||||
JSON_SCAN_TAL(rpath->path[i],
|
||||
json_tok_bin_from_hex,
|
||||
&rpath->path[i]->encrypted_recipient_data));
|
||||
if (err)
|
||||
return tal_free(rpath);
|
||||
}
|
||||
|
||||
return rpath;
|
||||
}
|
||||
|
||||
void json_add_node_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct node_id *id)
|
||||
{
|
||||
json_add_hex(response, fieldname, id->k, sizeof(id->k));
|
||||
}
|
||||
|
||||
void json_add_channel_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct channel_id *cid)
|
||||
{
|
||||
json_add_hex(response, fieldname, cid->id, sizeof(cid->id));
|
||||
}
|
||||
|
||||
void json_add_pubkey(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
u8 der[PUBKEY_CMPR_LEN];
|
||||
|
||||
pubkey_to_der(der, key);
|
||||
json_add_hex(response, fieldname, der, sizeof(der));
|
||||
}
|
||||
|
||||
void json_add_point32(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct point32 *key)
|
||||
{
|
||||
u8 output[32];
|
||||
|
||||
secp256k1_xonly_pubkey_serialize(secp256k1_ctx, output, &key->pubkey);
|
||||
json_add_hex(response, fieldname, output, sizeof(output));
|
||||
}
|
||||
|
||||
void json_add_bip340sig(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct bip340sig *sig)
|
||||
{
|
||||
json_add_hex(response, fieldname, sig->u8, sizeof(sig->u8));
|
||||
}
|
||||
|
||||
void json_add_txid(struct json_stream *result, const char *fieldname,
|
||||
const struct bitcoin_txid *txid)
|
||||
{
|
||||
char hex[hex_str_size(sizeof(*txid))];
|
||||
|
||||
bitcoin_txid_to_hex(txid, hex, sizeof(hex));
|
||||
json_add_string(result, fieldname, hex);
|
||||
}
|
||||
|
||||
void json_add_outpoint(struct json_stream *result, const char *fieldname,
|
||||
const struct bitcoin_outpoint *out)
|
||||
{
|
||||
char hex[hex_str_size(sizeof(out->txid))];
|
||||
bitcoin_txid_to_hex(&out->txid, hex, sizeof(hex));
|
||||
json_add_member(result, fieldname, true, "%s:%d", hex, out->n);
|
||||
}
|
||||
|
||||
void json_add_short_channel_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct short_channel_id *scid)
|
||||
{
|
||||
json_add_member(response, fieldname, true, "%dx%dx%d",
|
||||
short_channel_id_blocknum(scid),
|
||||
short_channel_id_txnum(scid),
|
||||
short_channel_id_outnum(scid));
|
||||
}
|
||||
|
||||
void json_add_address(struct json_stream *response, const char *fieldname,
|
||||
const struct wireaddr *addr)
|
||||
{
|
||||
json_object_start(response, fieldname);
|
||||
if (addr->type == ADDR_TYPE_IPV4) {
|
||||
char addrstr[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, addr->addr, addrstr, INET_ADDRSTRLEN);
|
||||
json_add_string(response, "type", "ipv4");
|
||||
json_add_string(response, "address", addrstr);
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_IPV6) {
|
||||
char addrstr[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, addr->addr, addrstr, INET6_ADDRSTRLEN);
|
||||
json_add_string(response, "type", "ipv6");
|
||||
json_add_string(response, "address", addrstr);
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_TOR_V2_REMOVED) {
|
||||
json_add_string(response, "type", "torv2");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_TOR_V3) {
|
||||
json_add_string(response, "type", "torv3");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_DNS) {
|
||||
json_add_string(response, "type", "dns");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_WEBSOCKET) {
|
||||
json_add_string(response, "type", "websocket");
|
||||
json_add_num(response, "port", addr->port);
|
||||
}
|
||||
json_object_end(response);
|
||||
}
|
||||
|
||||
void json_add_address_internal(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct wireaddr_internal *addr)
|
||||
{
|
||||
switch (addr->itype) {
|
||||
case ADDR_INTERNAL_SOCKNAME:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "local socket");
|
||||
json_add_string(response, "socket", addr->u.sockname);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "any protocol");
|
||||
json_add_num(response, "port", addr->u.port);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_AUTOTOR:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "Tor generated address");
|
||||
json_add_address(response, "service", &addr->u.torservice.address);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_STATICTOR:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "Tor from blob generated static address");
|
||||
json_add_address(response, "service", &addr->u.torservice.address);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "unresolved");
|
||||
json_add_string(response, "name", addr->u.unresolved.name);
|
||||
json_add_num(response, "port", addr->u.unresolved.port);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
json_add_address(response, fieldname, &addr->u.wireaddr);
|
||||
return;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
void json_add_tx(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const struct bitcoin_tx *tx)
|
||||
{
|
||||
json_add_hex_talarr(result, fieldname, linearize_tx(tmpctx, tx));
|
||||
}
|
||||
|
||||
void json_add_psbt(struct json_stream *stream,
|
||||
const char *fieldname,
|
||||
const struct wally_psbt *psbt TAKES)
|
||||
{
|
||||
const char *psbt_b64;
|
||||
psbt_b64 = psbt_to_b64(NULL, psbt);
|
||||
json_add_string(stream, fieldname, take(psbt_b64));
|
||||
if (taken(psbt))
|
||||
tal_free(psbt);
|
||||
}
|
||||
|
||||
void json_add_amount_msat_compat(struct json_stream *result,
|
||||
struct amount_msat msat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
{
|
||||
if (deprecated_apis)
|
||||
json_add_u64(result, rawfieldname, msat.millisatoshis); /* Raw: low-level helper */
|
||||
json_add_amount_msat_only(result, msatfieldname, msat);
|
||||
}
|
||||
|
||||
void json_add_amount_msat_only(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_msat msat)
|
||||
{
|
||||
if (!deprecated_apis)
|
||||
assert(strends(msatfieldname, "_msat"));
|
||||
if (deprecated_apis)
|
||||
json_add_string(result, msatfieldname,
|
||||
type_to_string(tmpctx, struct amount_msat, &msat));
|
||||
else
|
||||
json_add_u64(result, msatfieldname, msat.millisatoshis); /* Raw: low-level helper */
|
||||
}
|
||||
|
||||
void json_add_amount_sat_compat(struct json_stream *result,
|
||||
struct amount_sat sat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
{
|
||||
if (deprecated_apis)
|
||||
json_add_u64(result, rawfieldname, sat.satoshis); /* Raw: low-level helper */
|
||||
json_add_amount_sat_msat(result, msatfieldname, sat);
|
||||
}
|
||||
|
||||
void json_add_amount_sat_msat(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
{
|
||||
struct amount_msat msat;
|
||||
assert(strends(msatfieldname, "_msat"));
|
||||
if (amount_sat_to_msat(&msat, sat))
|
||||
json_add_amount_msat_only(result, msatfieldname, msat);
|
||||
}
|
||||
|
||||
/* When I noticed that we were adding "XXXmsat" fields *not* ending in _msat */
|
||||
void json_add_amount_sats_deprecated(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
{
|
||||
if (deprecated_apis) {
|
||||
struct amount_msat msat;
|
||||
assert(!strends(fieldname, "_msat"));
|
||||
if (amount_sat_to_msat(&msat, sat))
|
||||
json_add_string(result, fieldname,
|
||||
take(fmt_amount_msat(NULL, msat)));
|
||||
}
|
||||
json_add_amount_sat_msat(result, msatfieldname, sat);
|
||||
}
|
||||
|
||||
void json_add_sats(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
struct amount_sat sat)
|
||||
{
|
||||
json_add_string(result, fieldname, take(fmt_amount_sat(NULL, sat)));
|
||||
}
|
||||
|
||||
void json_add_secret(struct json_stream *response, const char *fieldname,
|
||||
const struct secret *secret)
|
||||
{
|
||||
json_add_hex(response, fieldname, secret, sizeof(struct secret));
|
||||
}
|
||||
|
||||
void json_add_sha256(struct json_stream *result, const char *fieldname,
|
||||
const struct sha256 *hash)
|
||||
{
|
||||
json_add_hex(result, fieldname, hash, sizeof(*hash));
|
||||
}
|
||||
|
||||
void json_add_preimage(struct json_stream *result, const char *fieldname,
|
||||
const struct preimage *preimage)
|
||||
{
|
||||
json_add_hex(result, fieldname, preimage, sizeof(*preimage));
|
||||
}
|
||||
|
||||
void json_add_lease_rates(struct json_stream *result,
|
||||
const struct lease_rates *rates)
|
||||
{
|
||||
json_add_amount_sat_msat(result, "lease_fee_base_msat",
|
||||
amount_sat(rates->lease_fee_base_sat));
|
||||
json_add_num(result, "lease_fee_basis", rates->lease_fee_basis);
|
||||
json_add_num(result, "funding_weight", rates->funding_weight);
|
||||
json_add_amount_msat_only(result,
|
||||
"channel_fee_max_base_msat",
|
||||
amount_msat(rates->channel_fee_max_base_msat));
|
||||
json_add_num(result, "channel_fee_max_proportional_thousandths",
|
||||
rates->channel_fee_max_proportional_thousandths);
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
/* More specialized (bitcoin, lightning-specific) JSON helpers. */
|
||||
#ifndef LIGHTNING_COMMON_JSON_HELPERS_H
|
||||
#define LIGHTNING_COMMON_JSON_HELPERS_H
|
||||
#include "config.h"
|
||||
#include <bitcoin/tx.h>
|
||||
#include <common/coin_mvt.h>
|
||||
#include <common/json.h>
|
||||
#include <wire/wire.h>
|
||||
|
||||
struct amount_msat;
|
||||
struct amount_sat;
|
||||
struct bip340sig;
|
||||
struct channel_id;
|
||||
struct lease_rates;
|
||||
struct node_id;
|
||||
struct preimage;
|
||||
struct pubkey;
|
||||
struct point32;
|
||||
struct secret;
|
||||
struct short_channel_id;
|
||||
struct short_channel_id_dir;
|
||||
struct wireaddr;
|
||||
struct wireaddr_internal;
|
||||
struct wally_psbt;
|
||||
|
||||
/* Decode a hex-encoded payment preimage */
|
||||
bool json_to_preimage(const char *buffer, const jsmntok_t *tok, struct preimage *preimage);
|
||||
|
||||
/* Extract a secret from this. */
|
||||
bool json_to_secret(const char *buffer, const jsmntok_t *tok, struct secret *dest);
|
||||
|
||||
/* Extract a psbt from this. */
|
||||
struct wally_psbt *json_to_psbt(const tal_t *ctx, const char *buffer,
|
||||
const jsmntok_t *tok);
|
||||
|
||||
/* Extract a pubkey from this */
|
||||
bool json_to_pubkey(const char *buffer, const jsmntok_t *tok,
|
||||
struct pubkey *pubkey);
|
||||
|
||||
/* Extract node_id from this: makes sure *id is valid! */
|
||||
bool json_to_node_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct node_id *id);
|
||||
|
||||
/* Extract satoshis from this (may be a string, or a decimal number literal) */
|
||||
bool json_to_bitcoin_amount(const char *buffer, const jsmntok_t *tok,
|
||||
uint64_t *satoshi);
|
||||
|
||||
/* Extract a short_channel_id from this */
|
||||
bool json_to_short_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct short_channel_id *scid);
|
||||
|
||||
/* Extract a satoshis amount from this */
|
||||
bool json_to_sat(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_sat *sat);
|
||||
|
||||
/* Extract a satoshis amount from this */
|
||||
/* If the string is "all", set amonut as AMOUNT_SAT(-1ULL). */
|
||||
bool json_to_sat_or_all(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_sat *sat);
|
||||
|
||||
/* Extract a millisatoshis amount from this */
|
||||
bool json_to_msat(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_msat *msat);
|
||||
|
||||
/* Extract a bitcoin txid from this */
|
||||
bool json_to_txid(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_txid *txid);
|
||||
|
||||
/* Extract a bitcoin outpoint from this */
|
||||
bool json_to_outpoint(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_outpoint *op);
|
||||
|
||||
/* Extract a channel id from this */
|
||||
bool json_to_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct channel_id *cid);
|
||||
|
||||
/* Extract a coin movement 'tag' from this */
|
||||
bool json_to_coin_mvt_tag(const char *buffer, const jsmntok_t *tok,
|
||||
enum mvt_tag *tag);
|
||||
|
||||
/* Split a json token into 2 tokens given a splitting character */
|
||||
bool split_tok(const char *buffer, const jsmntok_t *tok,
|
||||
char split,
|
||||
jsmntok_t *a,
|
||||
jsmntok_t *b);
|
||||
|
||||
/* Extract reply path from this JSON */
|
||||
struct tlv_onionmsg_payload_reply_path *
|
||||
json_to_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Obsolete version! */
|
||||
struct tlv_obs2_onionmsg_payload_reply_path *
|
||||
json_to_obs2_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Helpers for outputting JSON results */
|
||||
|
||||
/* '"fieldname" : "0289abcdef..."' or "0289abcdef..." if fieldname is NULL */
|
||||
void json_add_pubkey(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct pubkey *key);
|
||||
|
||||
/* '"fieldname" : "89abcdef..."' or "89abcdef..." if fieldname is NULL */
|
||||
void json_add_point32(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct point32 *key);
|
||||
|
||||
/* '"fieldname" : "89abcdef..."' or "89abcdef..." if fieldname is NULL */
|
||||
void json_add_bip340sig(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct bip340sig *sig);
|
||||
|
||||
/* '"fieldname" : "89abcdef..."' or "89abcdef..." if fieldname is NULL */
|
||||
void json_add_secret(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct secret *secret);
|
||||
|
||||
/* '"fieldname" : "0289abcdef..."' or "0289abcdef..." if fieldname is NULL */
|
||||
void json_add_node_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct node_id *id);
|
||||
|
||||
/* '"fieldname" : "0289abcdef..."' or "0289abcdef..." if fieldname is NULL */
|
||||
void json_add_channel_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct channel_id *cid);
|
||||
|
||||
/* '"fieldname" : <hexrev>' or "<hexrev>" if fieldname is NULL */
|
||||
void json_add_txid(struct json_stream *result, const char *fieldname,
|
||||
const struct bitcoin_txid *txid);
|
||||
|
||||
/* '"fieldname" : "txid:n" */
|
||||
void json_add_outpoint(struct json_stream *result, const char *fieldname,
|
||||
const struct bitcoin_outpoint *out);
|
||||
|
||||
/* '"fieldname" : "1234:5:6"' */
|
||||
void json_add_short_channel_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct short_channel_id *id);
|
||||
|
||||
/* JSON serialize a network address for a node */
|
||||
void json_add_address(struct json_stream *response, const char *fieldname,
|
||||
const struct wireaddr *addr);
|
||||
|
||||
/* JSON serialize a network address for a node. */
|
||||
void json_add_address_internal(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct wireaddr_internal *addr);
|
||||
|
||||
/* Adds both a 'raw' number field and an 'amount_msat' field */
|
||||
void json_add_amount_msat_compat(struct json_stream *result,
|
||||
struct amount_msat msat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds both a 'raw' number field and an 'amount_msat' field */
|
||||
void json_add_amount_sat_compat(struct json_stream *result,
|
||||
struct amount_sat sat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field */
|
||||
void json_add_amount_msat_only(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_msat msat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field */
|
||||
void json_add_amount_sat_msat(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field, and an older deprecated field. */
|
||||
void json_add_amount_sats_deprecated(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* This is used to create requests, *never* for output (output is always
|
||||
* msat!) */
|
||||
void json_add_sats(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
struct amount_sat sat);
|
||||
|
||||
void json_add_sha256(struct json_stream *result, const char *fieldname,
|
||||
const struct sha256 *hash);
|
||||
|
||||
void json_add_preimage(struct json_stream *result, const char *fieldname,
|
||||
const struct preimage *preimage);
|
||||
|
||||
/* '"fieldname" : "010000000001..."' or "010000000001..." if fieldname is NULL */
|
||||
void json_add_tx(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const struct bitcoin_tx *tx);
|
||||
|
||||
/* '"fieldname" : "cHNidP8BAJoCAAAAAljo..." or "cHNidP8BAJoCAAAAAljo..." if fieldname is NULL */
|
||||
void json_add_psbt(struct json_stream *stream,
|
||||
const char *fieldname,
|
||||
const struct wally_psbt *psbt);
|
||||
|
||||
/* Add fields from the lease_rates to a json stream.
|
||||
* Note that field names are set */
|
||||
void json_add_lease_rates(struct json_stream *result,
|
||||
const struct lease_rates *rates);
|
||||
#endif /* LIGHTNING_COMMON_JSON_HELPERS_H */
|
||||
@@ -4,15 +4,378 @@
|
||||
#include <bitcoin/feerate.h>
|
||||
#include <bitcoin/psbt.h>
|
||||
#include <bitcoin/script.h>
|
||||
#include <ccan/asort/asort.h>
|
||||
#include <ccan/json_escape/json_escape.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/bech32.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/route.h>
|
||||
|
||||
struct param {
|
||||
const char *name;
|
||||
bool is_set;
|
||||
enum param_style style;
|
||||
param_cbx cbx;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static bool param_add(struct param **params,
|
||||
const char *name,
|
||||
enum param_style style,
|
||||
param_cbx cbx, void *arg)
|
||||
{
|
||||
#if DEVELOPER
|
||||
if (!(name && cbx && arg))
|
||||
return false;
|
||||
#endif
|
||||
struct param last;
|
||||
|
||||
last.is_set = false;
|
||||
last.name = name;
|
||||
last.style = style;
|
||||
last.cbx = cbx;
|
||||
last.arg = arg;
|
||||
|
||||
tal_arr_expand(params, last);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* FIXME: To support the deprecated p_req_dup_ok */
|
||||
static bool is_required(enum param_style style)
|
||||
{
|
||||
return style == PARAM_REQUIRED || style == PARAM_REQUIRED_ALLOW_DUPS;
|
||||
}
|
||||
|
||||
static struct command_result *make_callback(struct command *cmd,
|
||||
struct param *def,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok)
|
||||
{
|
||||
/* If it had a default, free that now to avoid leak */
|
||||
if (def->style == PARAM_OPTIONAL_WITH_DEFAULT && !def->is_set)
|
||||
tal_free(*(void **)def->arg);
|
||||
|
||||
def->is_set = true;
|
||||
|
||||
return def->cbx(cmd, def->name, buffer, tok, def->arg);
|
||||
}
|
||||
|
||||
static struct command_result *post_check(struct command *cmd,
|
||||
struct param *params)
|
||||
{
|
||||
struct param *first = params;
|
||||
struct param *last = first + tal_count(params);
|
||||
|
||||
/* Make sure required params were provided. */
|
||||
while (first != last && is_required(first->style)) {
|
||||
if (!first->is_set) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"missing required parameter: %s",
|
||||
first->name);
|
||||
}
|
||||
first++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct command_result *parse_by_position(struct command *cmd,
|
||||
struct param *params,
|
||||
const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
bool allow_extra)
|
||||
{
|
||||
struct command_result *res;
|
||||
const jsmntok_t *tok;
|
||||
size_t i;
|
||||
|
||||
json_for_each_arr(i, tok, tokens) {
|
||||
/* check for unexpected trailing params */
|
||||
if (i == tal_count(params)) {
|
||||
if (!allow_extra) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"too many parameters:"
|
||||
" got %u, expected %zu",
|
||||
tokens->size,
|
||||
tal_count(params));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!json_tok_is_null(buffer, tok)) {
|
||||
res = make_callback(cmd, params+i, buffer, tok);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return post_check(cmd, params);
|
||||
}
|
||||
|
||||
static struct param *find_param(struct param *params, const char *start,
|
||||
size_t n)
|
||||
{
|
||||
struct param *first = params;
|
||||
struct param *last = first + tal_count(params);
|
||||
|
||||
while (first != last) {
|
||||
size_t arglen = strcspn(first->name, "|");
|
||||
if (memeq(first->name, arglen, start, n))
|
||||
return first;
|
||||
if (deprecated_apis
|
||||
&& first->name[arglen]
|
||||
&& memeq(first->name + arglen + 1,
|
||||
strlen(first->name + arglen + 1),
|
||||
start, n))
|
||||
return first;
|
||||
first++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct command_result *parse_by_name(struct command *cmd,
|
||||
struct param *params,
|
||||
const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
bool allow_extra)
|
||||
{
|
||||
size_t i;
|
||||
const jsmntok_t *t;
|
||||
|
||||
json_for_each_obj(i, t, tokens) {
|
||||
struct param *p = find_param(params, buffer + t->start,
|
||||
t->end - t->start);
|
||||
if (!p) {
|
||||
if (!allow_extra) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"unknown parameter: %.*s, this may be caused by a failure to autodetect key=value-style parameters. Please try using the -k flag and explicit key=value pairs of parameters.",
|
||||
t->end - t->start,
|
||||
buffer + t->start);
|
||||
}
|
||||
} else {
|
||||
struct command_result *res;
|
||||
|
||||
if (p->is_set) {
|
||||
if (p->style == PARAM_REQUIRED_ALLOW_DUPS)
|
||||
continue;
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"duplicate json names: %s",
|
||||
p->name);
|
||||
}
|
||||
|
||||
res = make_callback(cmd, p, buffer, t + 1);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return post_check(cmd, params);
|
||||
}
|
||||
|
||||
#if DEVELOPER
|
||||
static int comp_by_name(const struct param *a, const struct param *b,
|
||||
void *unused)
|
||||
{
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
static int comp_by_arg(const struct param *a, const struct param *b,
|
||||
void *unused)
|
||||
{
|
||||
/* size_t could be larger than int: don't turn a 4bn difference into 0 */
|
||||
if (a->arg > b->arg)
|
||||
return 1;
|
||||
else if (a->arg < b->arg)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This comparator is a bit different, but works well.
|
||||
* Return 0 if @a is optional and @b is required. Otherwise return 1.
|
||||
*/
|
||||
static int comp_req_order(const struct param *a, const struct param *b,
|
||||
void *unused)
|
||||
{
|
||||
if (!is_required(a->style) && is_required(b->style))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure 2 sequential items in @params are not equal (based on
|
||||
* provided comparator).
|
||||
*/
|
||||
static bool check_distinct(struct param *params,
|
||||
int (*compar) (const struct param *a,
|
||||
const struct param *b, void *unused))
|
||||
{
|
||||
struct param *first = params;
|
||||
struct param *last = first + tal_count(params);
|
||||
first++;
|
||||
while (first != last) {
|
||||
if (compar(first - 1, first, NULL) == 0)
|
||||
return false;
|
||||
first++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check_unique(struct param *copy,
|
||||
int (*compar) (const struct param *a,
|
||||
const struct param *b, void *unused))
|
||||
{
|
||||
asort(copy, tal_count(copy), compar, NULL);
|
||||
return check_distinct(copy, compar);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify consistent internal state.
|
||||
*/
|
||||
static bool check_params(struct param *params)
|
||||
{
|
||||
if (tal_count(params) < 2)
|
||||
return true;
|
||||
|
||||
/* make sure there are no required params following optional */
|
||||
if (!check_distinct(params, comp_req_order))
|
||||
return false;
|
||||
|
||||
/* duplicate so we can sort */
|
||||
struct param *copy = tal_dup_talarr(params, struct param, params);
|
||||
|
||||
/* check for repeated names and args */
|
||||
if (!check_unique(copy, comp_by_name))
|
||||
return false;
|
||||
if (!check_unique(copy, comp_by_arg))
|
||||
return false;
|
||||
|
||||
tal_free(copy);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *param_usage(const tal_t *ctx,
|
||||
const struct param *params)
|
||||
{
|
||||
char *usage = tal_strdup(ctx, "");
|
||||
for (size_t i = 0; i < tal_count(params); i++) {
|
||||
/* Don't print |deprecated part! */
|
||||
int len = strcspn(params[i].name, "|");
|
||||
if (i != 0)
|
||||
tal_append_fmt(&usage, " ");
|
||||
if (is_required(params[i].style))
|
||||
tal_append_fmt(&usage, "%.*s", len, params[i].name);
|
||||
else
|
||||
tal_append_fmt(&usage, "[%.*s]", len, params[i].name);
|
||||
}
|
||||
return usage;
|
||||
}
|
||||
|
||||
static struct command_result *param_arr(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
struct param *params,
|
||||
bool allow_extra)
|
||||
{
|
||||
#if DEVELOPER
|
||||
if (!check_params(params)) {
|
||||
return command_fail(cmd, PARAM_DEV_ERROR,
|
||||
"developer error: check_params");
|
||||
}
|
||||
#endif
|
||||
if (tokens->type == JSMN_ARRAY)
|
||||
return parse_by_position(cmd, params, buffer, tokens, allow_extra);
|
||||
else if (tokens->type == JSMN_OBJECT)
|
||||
return parse_by_name(cmd, params, buffer, tokens, allow_extra);
|
||||
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Expected array or object for params");
|
||||
}
|
||||
|
||||
const char *param_subcommand(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
const char *name, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct param *params = tal_arr(cmd, struct param, 0);
|
||||
const char *arg, **names = tal_arr(tmpctx, const char *, 1);
|
||||
const char *subcmd;
|
||||
|
||||
param_add(¶ms, "subcommand", PARAM_REQUIRED, (void *)param_string, &subcmd);
|
||||
names[0] = name;
|
||||
va_start(ap, name);
|
||||
while ((arg = va_arg(ap, const char *)) != NULL)
|
||||
tal_arr_expand(&names, arg);
|
||||
va_end(ap);
|
||||
|
||||
if (command_usage_only(cmd)) {
|
||||
char *usage = tal_strdup(cmd, "subcommand");
|
||||
for (size_t i = 0; i < tal_count(names); i++)
|
||||
tal_append_fmt(&usage, "%c%s",
|
||||
i == 0 ? '=' : '|', names[i]);
|
||||
command_set_usage(cmd, usage);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check it's valid */
|
||||
if (param_arr(cmd, buffer, tokens, params, true) != NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check it's one of the known ones. */
|
||||
for (size_t i = 0; i < tal_count(names); i++)
|
||||
if (streq(subcmd, names[i]))
|
||||
return subcmd;
|
||||
|
||||
/* We really do ignore this. */
|
||||
struct command_result *ignore;
|
||||
ignore = command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Unknown subcommand '%s'", subcmd);
|
||||
assert(ignore);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool param(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t tokens[], ...)
|
||||
{
|
||||
struct param *params = tal_arr(tmpctx, struct param, 0);
|
||||
const char *name;
|
||||
va_list ap;
|
||||
bool allow_extra = false;
|
||||
|
||||
va_start(ap, tokens);
|
||||
while ((name = va_arg(ap, const char *)) != NULL) {
|
||||
enum param_style style = va_arg(ap, enum param_style);
|
||||
param_cbx cbx = va_arg(ap, param_cbx);
|
||||
void *arg = va_arg(ap, void *);
|
||||
if (streq(name, "")) {
|
||||
allow_extra = true;
|
||||
continue;
|
||||
}
|
||||
if (!param_add(¶ms, name, style, cbx, arg)) {
|
||||
/* We really do ignore this return! */
|
||||
struct command_result *ignore;
|
||||
ignore = command_fail(cmd, PARAM_DEV_ERROR,
|
||||
"developer error: param_add %s", name);
|
||||
assert(ignore);
|
||||
va_end(ap);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
if (command_usage_only(cmd)) {
|
||||
command_set_usage(cmd, param_usage(cmd, params));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Always return false if we're simply checking command parameters;
|
||||
* normally this returns true if all parameters are valid. */
|
||||
return param_arr(cmd, buffer, tokens, params, allow_extra) == NULL
|
||||
&& !command_check_only(cmd);
|
||||
}
|
||||
|
||||
struct command_result *param_array(struct command *cmd, const char *name,
|
||||
const char *buffer, const jsmntok_t *tok,
|
||||
const jsmntok_t **arr)
|
||||
@@ -1,22 +1,152 @@
|
||||
/* Helpers for use with param parsing. */
|
||||
#ifndef LIGHTNING_COMMON_JSON_TOK_H
|
||||
#define LIGHTNING_COMMON_JSON_TOK_H
|
||||
#ifndef LIGHTNING_COMMON_JSON_PARAM_H
|
||||
#define LIGHTNING_COMMON_JSON_PARAM_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <common/bolt11.h>
|
||||
#include <common/json.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/lease_rates.h>
|
||||
#include <common/node_id.h>
|
||||
#include <common/sphinx.h>
|
||||
#include <wire/wire.h>
|
||||
|
||||
/*~ Greetings adventurer!
|
||||
*
|
||||
* Do you want to automatically validate json input and unmarshal it into
|
||||
* local variables, all using typesafe callbacks? And on error,
|
||||
* call command_fail with a proper error message? Then you've come to the
|
||||
* right place!
|
||||
*
|
||||
* Here is a simple example of using the system:
|
||||
*
|
||||
* unsigned *cltv;
|
||||
* u64 *msatoshi;
|
||||
* const jsmntok_t *note;
|
||||
* u64 *expiry;
|
||||
*
|
||||
* if (!param(cmd, buffer, params,
|
||||
* p_req("cltv", json_tok_number, &cltv),
|
||||
* p_opt("msatoshi", json_tok_u64, &msatoshi),
|
||||
* p_opt("note", json_tok_tok, ¬e),
|
||||
* p_opt_def("expiry", json_tok_u64, &expiry, 3600),
|
||||
* NULL))
|
||||
* return;
|
||||
*
|
||||
* If param() returns true then you're good to go.
|
||||
*
|
||||
* All the command handlers throughout the code use this system.
|
||||
* json_invoice() is a great example. The common callbacks can be found in
|
||||
* common/json_tok.c. Use them directly or feel free to write your own.
|
||||
*/
|
||||
struct command;
|
||||
|
||||
/* A dummy type returned by command_ functions, to ensure you return them
|
||||
* immediately */
|
||||
struct command_result;
|
||||
|
||||
/*
|
||||
* Parse the json tokens. @params can be an array of values or an object
|
||||
* of named values.
|
||||
*/
|
||||
bool param(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t params[], ...) LAST_ARG_NULL;
|
||||
|
||||
/*
|
||||
* The callback signature.
|
||||
*
|
||||
* Callbacks must return NULL on success. On failure they
|
||||
* must return command_fail(...).
|
||||
*/
|
||||
typedef struct command_result *(*param_cbx)(struct command *cmd,
|
||||
const char *name,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
void **arg);
|
||||
|
||||
/**
|
||||
* Parse the first json value.
|
||||
*
|
||||
* name...: NULL-terminated array of valid values.
|
||||
*
|
||||
* Returns subcommand: if it returns NULL if you should return
|
||||
* command_param_failed() immediately.
|
||||
*/
|
||||
const char *param_subcommand(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
const char *name, ...) LAST_ARG_NULL;
|
||||
|
||||
enum param_style {
|
||||
PARAM_REQUIRED,
|
||||
PARAM_REQUIRED_ALLOW_DUPS,
|
||||
PARAM_OPTIONAL,
|
||||
PARAM_OPTIONAL_WITH_DEFAULT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Add a required parameter.
|
||||
*/
|
||||
#define p_req(name, cbx, arg) \
|
||||
name"", \
|
||||
PARAM_REQUIRED, \
|
||||
(param_cbx)(cbx), \
|
||||
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, \
|
||||
(arg)) == (struct command_result *)NULL)
|
||||
|
||||
/*
|
||||
* Add an optional parameter. *arg is set to NULL if it isn't found.
|
||||
*/
|
||||
#define p_opt(name, cbx, arg) \
|
||||
name"", \
|
||||
PARAM_OPTIONAL, \
|
||||
(param_cbx)(cbx), \
|
||||
({ *arg = NULL; \
|
||||
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, \
|
||||
(arg)) == (struct command_result *)NULL); })
|
||||
|
||||
/*
|
||||
* Add an required parameter, like p_req, but ignore duplicates.
|
||||
*/
|
||||
#define p_req_dup_ok(name, cbx, arg) \
|
||||
name"", \
|
||||
PARAM_REQUIRED_ALLOW_DUPS, \
|
||||
(param_cbx)(cbx), \
|
||||
({ *arg = NULL; \
|
||||
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, \
|
||||
(arg)) == (struct command_result *)NULL); })
|
||||
|
||||
/*
|
||||
* Add an optional parameter. *arg is set to @def if it isn't found.
|
||||
*/
|
||||
#define p_opt_def(name, cbx, arg, def) \
|
||||
name"", \
|
||||
PARAM_OPTIONAL_WITH_DEFAULT, \
|
||||
(param_cbx)(cbx), \
|
||||
({ (*arg) = tal((cmd), typeof(**arg)); \
|
||||
(**arg) = (def); \
|
||||
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, \
|
||||
(arg)) == (struct command_result *)NULL); })
|
||||
|
||||
/* Special flag for 'check' which allows any parameters. */
|
||||
#define p_opt_any() "", PARAM_OPTIONAL, NULL, NULL
|
||||
|
||||
/* All the helper routines. */
|
||||
struct amount_msat;
|
||||
struct amount_sat;
|
||||
struct bitcoin_txid;
|
||||
struct bitcoin_outpoint;
|
||||
struct channel_id;
|
||||
struct command;
|
||||
struct command_result;
|
||||
struct json_escape;
|
||||
struct route_exclusion;
|
||||
struct sha256;
|
||||
@@ -213,4 +343,4 @@ struct command_result *param_lease_hex(struct command *cmd,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
struct lease_rates **rates);
|
||||
#endif /* LIGHTNING_COMMON_JSON_TOK_H */
|
||||
#endif /* LIGHTNING_COMMON_JSON_PARAM_H */
|
||||
719
common/json_parse.c
Normal file
719
common/json_parse.c
Normal file
@@ -0,0 +1,719 @@
|
||||
/* JSON core and helpers */
|
||||
#include "config.h"
|
||||
#include <assert.h>
|
||||
#include <bitcoin/preimage.h>
|
||||
#include <bitcoin/privkey.h>
|
||||
#include <bitcoin/psbt.h>
|
||||
#include <bitcoin/pubkey.h>
|
||||
#include <bitcoin/short_channel_id.h>
|
||||
#include <bitcoin/tx.h>
|
||||
#include <ccan/json_escape/json_escape.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <ccan/time/time.h>
|
||||
#include <common/amount.h>
|
||||
#include <common/channel_id.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/node_id.h>
|
||||
#include <common/overflows.h>
|
||||
#include <common/utils.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <wire/onion_wire.h>
|
||||
|
||||
bool json_to_s64(const char *buffer, const jsmntok_t *tok, s64 *num)
|
||||
{
|
||||
char *end;
|
||||
long long l;
|
||||
|
||||
l = strtoll(buffer + tok->start, &end, 0);
|
||||
if (end != buffer + tok->end)
|
||||
return false;
|
||||
|
||||
BUILD_ASSERT(sizeof(l) >= sizeof(*num));
|
||||
*num = l;
|
||||
|
||||
/* Check for overflow/underflow */
|
||||
if ((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE)
|
||||
return false;
|
||||
|
||||
/* Check if the number did not fit in `s64` (in case `long long`
|
||||
is a bigger type). */
|
||||
if (*num != l)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_millionths(const char *buffer, const jsmntok_t *tok,
|
||||
u64 *millionths)
|
||||
{
|
||||
int decimal_places = -1;
|
||||
bool has_digits = 0;
|
||||
|
||||
*millionths = 0;
|
||||
for (int i = tok->start; i < tok->end; i++) {
|
||||
if (isdigit(buffer[i])) {
|
||||
has_digits = true;
|
||||
/* Ignore too much precision */
|
||||
if (decimal_places >= 0 && ++decimal_places > 6)
|
||||
continue;
|
||||
if (mul_overflows_u64(*millionths, 10))
|
||||
return false;
|
||||
*millionths *= 10;
|
||||
if (add_overflows_u64(*millionths, buffer[i] - '0'))
|
||||
return false;
|
||||
*millionths += buffer[i] - '0';
|
||||
} else if (buffer[i] == '.') {
|
||||
if (decimal_places != -1)
|
||||
return false;
|
||||
decimal_places = 0;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!has_digits)
|
||||
return false;
|
||||
|
||||
if (decimal_places == -1)
|
||||
decimal_places = 0;
|
||||
|
||||
while (decimal_places < 6) {
|
||||
if (mul_overflows_u64(*millionths, 10))
|
||||
return false;
|
||||
*millionths *= 10;
|
||||
decimal_places++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_number(const char *buffer, const jsmntok_t *tok,
|
||||
unsigned int *num)
|
||||
{
|
||||
uint64_t u64;
|
||||
|
||||
if (!json_to_u64(buffer, tok, &u64))
|
||||
return false;
|
||||
*num = u64;
|
||||
|
||||
/* Just in case it doesn't fit. */
|
||||
if (*num != u64)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_u16(const char *buffer, const jsmntok_t *tok,
|
||||
short unsigned int *num)
|
||||
{
|
||||
uint64_t u64;
|
||||
|
||||
if (!json_to_u64(buffer, tok, &u64))
|
||||
return false;
|
||||
*num = u64;
|
||||
|
||||
/* Just in case it doesn't fit. */
|
||||
if (*num != u64)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_int(const char *buffer, const jsmntok_t *tok, int *num)
|
||||
{
|
||||
s64 tmp;
|
||||
|
||||
if (!json_to_s64(buffer, tok, &tmp))
|
||||
return false;
|
||||
*num = tmp;
|
||||
|
||||
/* Just in case it doesn't fit. */
|
||||
if (*num != tmp)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_errcode(const char *buffer, const jsmntok_t *tok, errcode_t *errcode)
|
||||
{
|
||||
s64 tmp;
|
||||
|
||||
if (!json_to_s64(buffer, tok, &tmp))
|
||||
return false;
|
||||
*errcode = tmp;
|
||||
|
||||
/* Just in case it doesn't fit. */
|
||||
if (*errcode != tmp)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_sha256(const char *buffer, const jsmntok_t *tok, struct sha256 *dest)
|
||||
{
|
||||
if (tok->type != JSMN_STRING)
|
||||
return false;
|
||||
|
||||
return hex_decode(buffer + tok->start, tok->end - tok->start, dest,
|
||||
sizeof(struct sha256));
|
||||
}
|
||||
|
||||
u8 *json_tok_bin_from_hex(const tal_t *ctx, const char *buffer, const jsmntok_t *tok)
|
||||
{
|
||||
u8 *result;
|
||||
size_t hexlen, rawlen;
|
||||
hexlen = tok->end - tok->start;
|
||||
rawlen = hex_data_size(hexlen);
|
||||
|
||||
result = tal_arr(ctx, u8, rawlen);
|
||||
if (!hex_decode(buffer + tok->start, hexlen, result, rawlen))
|
||||
return tal_free(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* talfmt take a ctx pointer and return NULL or a valid pointer.
|
||||
* fmt takes the argument, and returns a bool.
|
||||
*
|
||||
* This function returns NULL on success, or errmsg on failure.
|
||||
*/
|
||||
static const char *handle_percent(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
va_list *ap)
|
||||
{
|
||||
void *ctx;
|
||||
const char *fmtname;
|
||||
|
||||
/* This is set to (dummy) json_scan if it's a non-tal fmt */
|
||||
ctx = va_arg(*ap, void *);
|
||||
fmtname = va_arg(*ap, const char *);
|
||||
if (ctx != json_scan) {
|
||||
void *(*talfmt)(void *, const char *, const jsmntok_t *);
|
||||
void **p;
|
||||
p = va_arg(*ap, void **);
|
||||
talfmt = va_arg(*ap, void *(*)(void *, const char *, const jsmntok_t *));
|
||||
*p = talfmt(ctx, buffer, tok);
|
||||
if (*p != NULL)
|
||||
return NULL;
|
||||
} else {
|
||||
bool (*fmt)(const char *, const jsmntok_t *, void *);
|
||||
void *p;
|
||||
|
||||
p = va_arg(*ap, void *);
|
||||
fmt = va_arg(*ap, bool (*)(const char *, const jsmntok_t *, void *));
|
||||
if (fmt(buffer, tok, p))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tal_fmt(tmpctx, "%s could not parse %.*s",
|
||||
fmtname,
|
||||
json_tok_full_len(tok),
|
||||
json_tok_full(buffer, tok));
|
||||
}
|
||||
|
||||
/* GUIDE := OBJ | ARRAY | '%'
|
||||
* OBJ := '{' FIELDLIST '}'
|
||||
* FIELDLIST := FIELD [',' FIELD]*
|
||||
* FIELD := LITERAL ':' FIELDVAL
|
||||
* FIELDVAL := OBJ | ARRAY | LITERAL | '%'
|
||||
* ARRAY := '[' ARRLIST ']'
|
||||
* ARRLIST := ARRELEM [',' ARRELEM]*
|
||||
* ARRELEM := NUMBER ':' FIELDVAL
|
||||
*/
|
||||
|
||||
static void parse_literal(const char **guide,
|
||||
const char **literal,
|
||||
size_t *len)
|
||||
{
|
||||
*literal = *guide;
|
||||
*len = strspn(*guide,
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789"
|
||||
"_-");
|
||||
*guide += *len;
|
||||
}
|
||||
|
||||
static void parse_number(const char **guide, u32 *number)
|
||||
{
|
||||
char *endp;
|
||||
long int l;
|
||||
|
||||
l = strtol(*guide, &endp, 10);
|
||||
assert(endp != *guide);
|
||||
assert(errno != ERANGE);
|
||||
|
||||
/* Test for overflow */
|
||||
*number = l;
|
||||
assert(*number == l);
|
||||
|
||||
*guide = endp;
|
||||
}
|
||||
|
||||
static char guide_consume_one(const char **guide)
|
||||
{
|
||||
char c = **guide;
|
||||
(*guide)++;
|
||||
return c;
|
||||
}
|
||||
|
||||
static void guide_must_be(const char **guide, char c)
|
||||
{
|
||||
char actual = guide_consume_one(guide);
|
||||
assert(actual == c);
|
||||
}
|
||||
|
||||
/* Recursion: return NULL on success, errmsg on fail */
|
||||
static const char *parse_obj(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap);
|
||||
|
||||
static const char *parse_arr(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap);
|
||||
|
||||
static const char *parse_guide(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap)
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
if (**guide == '{') {
|
||||
errmsg = parse_obj(buffer, tok, guide, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
} else if (**guide == '[') {
|
||||
errmsg = parse_arr(buffer, tok, guide, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
} else {
|
||||
guide_must_be(guide, '%');
|
||||
errmsg = handle_percent(buffer, tok, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *parse_fieldval(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap)
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
if (**guide == '{') {
|
||||
errmsg = parse_obj(buffer, tok, guide, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
} else if (**guide == '[') {
|
||||
errmsg = parse_arr(buffer, tok, guide, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
} else if (**guide == '%') {
|
||||
guide_consume_one(guide);
|
||||
errmsg = handle_percent(buffer, tok, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
} else {
|
||||
const char *literal;
|
||||
size_t len;
|
||||
|
||||
/* Literal must match exactly (modulo quotes for strings) */
|
||||
parse_literal(guide, &literal, &len);
|
||||
if (!memeq(buffer + tok->start, tok->end - tok->start,
|
||||
literal, len)) {
|
||||
return tal_fmt(tmpctx,
|
||||
"%.*s does not match expected %.*s",
|
||||
json_tok_full_len(tok),
|
||||
json_tok_full(buffer, tok),
|
||||
(int)len, literal);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *parse_field(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap)
|
||||
{
|
||||
const jsmntok_t *member;
|
||||
size_t len;
|
||||
const char *memname;
|
||||
|
||||
parse_literal(guide, &memname, &len);
|
||||
guide_must_be(guide, ':');
|
||||
|
||||
member = json_get_membern(buffer, tok, memname, len);
|
||||
if (!member) {
|
||||
return tal_fmt(tmpctx, "object does not have member %.*s",
|
||||
(int)len, memname);
|
||||
}
|
||||
|
||||
return parse_fieldval(buffer, member, guide, ap);
|
||||
}
|
||||
|
||||
static const char *parse_fieldlist(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap)
|
||||
{
|
||||
for (;;) {
|
||||
const char *errmsg;
|
||||
|
||||
errmsg = parse_field(buffer, tok, guide, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
if (**guide != ',')
|
||||
break;
|
||||
guide_consume_one(guide);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *parse_obj(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap)
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
guide_must_be(guide, '{');
|
||||
|
||||
if (tok->type != JSMN_OBJECT) {
|
||||
return tal_fmt(tmpctx, "token is not an object: %.*s",
|
||||
json_tok_full_len(tok),
|
||||
json_tok_full(buffer, tok));
|
||||
}
|
||||
|
||||
errmsg = parse_fieldlist(buffer, tok, guide, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
|
||||
guide_must_be(guide, '}');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *parse_arrelem(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap)
|
||||
{
|
||||
const jsmntok_t *member;
|
||||
u32 idx;
|
||||
|
||||
parse_number(guide, &idx);
|
||||
guide_must_be(guide, ':');
|
||||
|
||||
member = json_get_arr(tok, idx);
|
||||
if (!member) {
|
||||
return tal_fmt(tmpctx, "token has no index %u: %.*s",
|
||||
idx,
|
||||
json_tok_full_len(tok),
|
||||
json_tok_full(buffer, tok));
|
||||
}
|
||||
|
||||
return parse_fieldval(buffer, member, guide, ap);
|
||||
}
|
||||
|
||||
static const char *parse_arrlist(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap)
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
for (;;) {
|
||||
errmsg = parse_arrelem(buffer, tok, guide, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
if (**guide != ',')
|
||||
break;
|
||||
guide_consume_one(guide);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *parse_arr(const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char **guide,
|
||||
va_list *ap)
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
guide_must_be(guide, '[');
|
||||
|
||||
if (tok->type != JSMN_ARRAY) {
|
||||
return tal_fmt(tmpctx, "token is not an array: %.*s",
|
||||
json_tok_full_len(tok),
|
||||
json_tok_full(buffer, tok));
|
||||
}
|
||||
|
||||
errmsg = parse_arrlist(buffer, tok, guide, ap);
|
||||
if (errmsg)
|
||||
return errmsg;
|
||||
|
||||
guide_must_be(guide, ']');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *json_scanv(const tal_t *ctx,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char *guide,
|
||||
va_list ap)
|
||||
{
|
||||
va_list cpy;
|
||||
const char *orig_guide = guide, *errmsg;
|
||||
|
||||
/* We need this, since &ap doesn't work on some platforms... */
|
||||
va_copy(cpy, ap);
|
||||
errmsg = parse_guide(buffer, tok, &guide, &cpy);
|
||||
va_end(cpy);
|
||||
|
||||
if (errmsg) {
|
||||
return tal_fmt(ctx, "Parsing '%.*s': %s",
|
||||
(int)(guide - orig_guide), orig_guide,
|
||||
errmsg);
|
||||
}
|
||||
assert(guide[0] == '\0');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *json_scan(const tal_t *ctx,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char *guide,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *ret;
|
||||
|
||||
va_start(ap, guide);
|
||||
ret = json_scanv(ctx, buffer, tok, guide, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool json_to_bitcoin_amount(const char *buffer, const jsmntok_t *tok,
|
||||
uint64_t *satoshi)
|
||||
{
|
||||
char *end;
|
||||
unsigned long btc, sat;
|
||||
|
||||
btc = strtoul(buffer + tok->start, &end, 10);
|
||||
if (btc == ULONG_MAX && errno == ERANGE)
|
||||
return false;
|
||||
if (end != buffer + tok->end) {
|
||||
/* Expect always 8 decimal places. */
|
||||
if (*end != '.' || buffer + tok->end - end != 9)
|
||||
return false;
|
||||
sat = strtoul(end+1, &end, 10);
|
||||
if (sat == ULONG_MAX && errno == ERANGE)
|
||||
return false;
|
||||
if (end != buffer + tok->end)
|
||||
return false;
|
||||
} else
|
||||
sat = 0;
|
||||
|
||||
*satoshi = btc * (uint64_t)100000000 + sat;
|
||||
if (*satoshi != btc * (uint64_t)100000000 + sat)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_node_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct node_id *id)
|
||||
{
|
||||
return node_id_from_hexstr(buffer + tok->start,
|
||||
tok->end - tok->start, id);
|
||||
}
|
||||
|
||||
bool json_to_pubkey(const char *buffer, const jsmntok_t *tok,
|
||||
struct pubkey *pubkey)
|
||||
{
|
||||
return pubkey_from_hexstr(buffer + tok->start,
|
||||
tok->end - tok->start, pubkey);
|
||||
}
|
||||
|
||||
bool json_to_msat(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_msat *msat)
|
||||
{
|
||||
return parse_amount_msat(msat,
|
||||
buffer + tok->start, tok->end - tok->start);
|
||||
}
|
||||
|
||||
bool json_to_sat(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_sat *sat)
|
||||
{
|
||||
return parse_amount_sat(sat, buffer + tok->start, tok->end - tok->start);
|
||||
}
|
||||
|
||||
bool json_to_sat_or_all(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_sat *sat)
|
||||
{
|
||||
if (json_tok_streq(buffer, tok, "all")) {
|
||||
*sat = AMOUNT_SAT(-1ULL);
|
||||
return true;
|
||||
}
|
||||
return json_to_sat(buffer, tok, sat);
|
||||
}
|
||||
|
||||
bool json_to_short_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct short_channel_id *scid)
|
||||
{
|
||||
return (short_channel_id_from_str(buffer + tok->start,
|
||||
tok->end - tok->start, scid));
|
||||
}
|
||||
|
||||
bool json_to_txid(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_txid *txid)
|
||||
{
|
||||
return bitcoin_txid_from_hex(buffer + tok->start,
|
||||
tok->end - tok->start, txid);
|
||||
}
|
||||
|
||||
bool json_to_outpoint(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_outpoint *op)
|
||||
{
|
||||
jsmntok_t t1, t2;
|
||||
|
||||
if (!split_tok(buffer, tok, ':', &t1, &t2))
|
||||
return false;
|
||||
|
||||
return json_to_txid(buffer, &t1, &op->txid)
|
||||
&& json_to_u32(buffer, &t2, &op->n);
|
||||
}
|
||||
|
||||
bool json_to_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct channel_id *cid)
|
||||
{
|
||||
return hex_decode(buffer + tok->start, tok->end - tok->start,
|
||||
cid, sizeof(*cid));
|
||||
}
|
||||
|
||||
bool json_to_coin_mvt_tag(const char *buffer, const jsmntok_t *tok,
|
||||
enum mvt_tag *tag)
|
||||
{
|
||||
enum mvt_tag i_tag;
|
||||
for (size_t i = 0; i < NUM_MVT_TAGS; i++) {
|
||||
i_tag = (enum mvt_tag) i;
|
||||
if (json_tok_streq(buffer, tok, mvt_tag_str(i_tag))) {
|
||||
*tag = i_tag;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool split_tok(const char *buffer, const jsmntok_t *tok,
|
||||
char split,
|
||||
jsmntok_t *a,
|
||||
jsmntok_t *b)
|
||||
{
|
||||
const char *p = memchr(buffer + tok->start, split, tok->end - tok->start);
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
*a = *b = *tok;
|
||||
a->end = p - buffer;
|
||||
b->start = p + 1 - buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_secret(const char *buffer, const jsmntok_t *tok, struct secret *dest)
|
||||
{
|
||||
return hex_decode(buffer + tok->start, tok->end - tok->start,
|
||||
dest->data, sizeof(struct secret));
|
||||
}
|
||||
|
||||
bool json_to_preimage(const char *buffer, const jsmntok_t *tok, struct preimage *preimage)
|
||||
{
|
||||
size_t hexlen = tok->end - tok->start;
|
||||
return hex_decode(buffer + tok->start, hexlen, preimage->r, sizeof(preimage->r));
|
||||
}
|
||||
|
||||
struct wally_psbt *json_to_psbt(const tal_t *ctx, const char *buffer,
|
||||
const jsmntok_t *tok)
|
||||
{
|
||||
return psbt_from_b64(ctx, buffer + tok->start, tok->end - tok->start);
|
||||
}
|
||||
|
||||
struct tlv_obs2_onionmsg_payload_reply_path *
|
||||
json_to_obs2_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok)
|
||||
{
|
||||
struct tlv_obs2_onionmsg_payload_reply_path *rpath;
|
||||
const jsmntok_t *hops, *t;
|
||||
size_t i;
|
||||
const char *err;
|
||||
|
||||
rpath = tal(ctx, struct tlv_obs2_onionmsg_payload_reply_path);
|
||||
err = json_scan(tmpctx, buffer, tok, "{blinding:%,first_node_id:%}",
|
||||
JSON_SCAN(json_to_pubkey, &rpath->blinding),
|
||||
JSON_SCAN(json_to_pubkey, &rpath->first_node_id),
|
||||
NULL);
|
||||
if (err)
|
||||
return tal_free(rpath);
|
||||
|
||||
hops = json_get_member(buffer, tok, "hops");
|
||||
if (!hops || hops->size < 1)
|
||||
return tal_free(rpath);
|
||||
|
||||
rpath->path = tal_arr(rpath, struct onionmsg_path *, hops->size);
|
||||
json_for_each_arr(i, t, hops) {
|
||||
rpath->path[i] = tal(rpath->path, struct onionmsg_path);
|
||||
err = json_scan(tmpctx, buffer, t, "{id:%,encrypted_recipient_data:%}",
|
||||
JSON_SCAN(json_to_pubkey,
|
||||
&rpath->path[i]->node_id),
|
||||
JSON_SCAN_TAL(rpath->path[i],
|
||||
json_tok_bin_from_hex,
|
||||
&rpath->path[i]->encrypted_recipient_data));
|
||||
if (err)
|
||||
return tal_free(rpath);
|
||||
}
|
||||
|
||||
return rpath;
|
||||
}
|
||||
|
||||
struct tlv_onionmsg_payload_reply_path *
|
||||
json_to_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok)
|
||||
{
|
||||
struct tlv_onionmsg_payload_reply_path *rpath;
|
||||
const jsmntok_t *hops, *t;
|
||||
size_t i;
|
||||
const char *err;
|
||||
|
||||
rpath = tal(ctx, struct tlv_onionmsg_payload_reply_path);
|
||||
err = json_scan(tmpctx, buffer, tok, "{blinding:%,first_node_id:%}",
|
||||
JSON_SCAN(json_to_pubkey, &rpath->blinding),
|
||||
JSON_SCAN(json_to_pubkey, &rpath->first_node_id),
|
||||
NULL);
|
||||
if (err)
|
||||
return tal_free(rpath);
|
||||
|
||||
hops = json_get_member(buffer, tok, "hops");
|
||||
if (!hops || hops->size < 1)
|
||||
return tal_free(rpath);
|
||||
|
||||
rpath->path = tal_arr(rpath, struct onionmsg_path *, hops->size);
|
||||
json_for_each_arr(i, t, hops) {
|
||||
rpath->path[i] = tal(rpath->path, struct onionmsg_path);
|
||||
err = json_scan(tmpctx, buffer, t, "{id:%,encrypted_recipient_data:%}",
|
||||
JSON_SCAN(json_to_pubkey,
|
||||
&rpath->path[i]->node_id),
|
||||
JSON_SCAN_TAL(rpath->path[i],
|
||||
json_tok_bin_from_hex,
|
||||
&rpath->path[i]->encrypted_recipient_data));
|
||||
if (err)
|
||||
return tal_free(rpath);
|
||||
}
|
||||
|
||||
return rpath;
|
||||
}
|
||||
156
common/json_parse.h
Normal file
156
common/json_parse.h
Normal file
@@ -0,0 +1,156 @@
|
||||
#ifndef LIGHTNING_COMMON_JSON_PARSE_H
|
||||
#define LIGHTNING_COMMON_JSON_PARSE_H
|
||||
#include "config.h"
|
||||
#include <ccan/crypto/sha256/sha256.h>
|
||||
#include <common/coin_mvt.h>
|
||||
#include <common/errcode.h>
|
||||
/* Simple helpers are here: this file contains heavier ones */
|
||||
#include <common/json_parse_simple.h>
|
||||
|
||||
struct json_escape;
|
||||
struct json_stream;
|
||||
struct timeabs;
|
||||
struct timespec;
|
||||
struct preimage;
|
||||
struct secret;
|
||||
struct pubkey;
|
||||
struct node_id;
|
||||
struct short_channel_id;
|
||||
struct amount_sat;
|
||||
struct amount_msat;
|
||||
struct bitcoin_txid;
|
||||
struct bitcoin_outpoint;
|
||||
struct channel_id;
|
||||
|
||||
/* Decode a hex-encoded binary */
|
||||
u8 *json_tok_bin_from_hex(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Extract number from this (may be a string, or a number literal) */
|
||||
bool json_to_number(const char *buffer, const jsmntok_t *tok,
|
||||
unsigned int *num);
|
||||
|
||||
/* Extract signed 64 bit integer from this (may be a string, or a number literal) */
|
||||
bool json_to_s64(const char *buffer, const jsmntok_t *tok, s64 *num);
|
||||
|
||||
/* Extract number from this (may be a string, or a number literal) */
|
||||
bool json_to_u16(const char *buffer, const jsmntok_t *tok,
|
||||
uint16_t *num);
|
||||
|
||||
bool json_to_sha256(const char *buffer, const jsmntok_t *tok, struct sha256 *dest);
|
||||
/*
|
||||
* Extract a non-negative (either 0 or positive) floating-point number from this
|
||||
* (must be a number literal), multiply it by 1 million and return it as an
|
||||
* integer. Any fraction smaller than 0.000001 is ignored.
|
||||
*/
|
||||
bool json_to_millionths(const char *buffer, const jsmntok_t *tok,
|
||||
u64 *millionths);
|
||||
|
||||
/* Extract signed integer from this (may be a string, or a number literal) */
|
||||
bool json_to_int(const char *buffer, const jsmntok_t *tok, int *num);
|
||||
|
||||
/* Extract an error code from this (may be a string, or a number literal) */
|
||||
bool json_to_errcode(const char *buffer, const jsmntok_t *tok, errcode_t *errcode);
|
||||
|
||||
/* Split a json token into 2 tokens given a splitting character */
|
||||
bool split_tok(const char *buffer, const jsmntok_t *tok,
|
||||
char split,
|
||||
jsmntok_t *a,
|
||||
jsmntok_t *b);
|
||||
|
||||
/* Decode a hex-encoded payment preimage */
|
||||
bool json_to_preimage(const char *buffer, const jsmntok_t *tok, struct preimage *preimage);
|
||||
|
||||
/* Extract a secret from this. */
|
||||
bool json_to_secret(const char *buffer, const jsmntok_t *tok, struct secret *dest);
|
||||
|
||||
/* Extract a psbt from this. */
|
||||
struct wally_psbt *json_to_psbt(const tal_t *ctx, const char *buffer,
|
||||
const jsmntok_t *tok);
|
||||
|
||||
/* Extract a pubkey from this */
|
||||
bool json_to_pubkey(const char *buffer, const jsmntok_t *tok,
|
||||
struct pubkey *pubkey);
|
||||
|
||||
/* Extract node_id from this: makes sure *id is valid! */
|
||||
bool json_to_node_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct node_id *id);
|
||||
|
||||
/* Extract satoshis from this (may be a string, or a decimal number literal) */
|
||||
bool json_to_bitcoin_amount(const char *buffer, const jsmntok_t *tok,
|
||||
uint64_t *satoshi);
|
||||
|
||||
/* Extract a short_channel_id from this */
|
||||
bool json_to_short_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct short_channel_id *scid);
|
||||
|
||||
/* Extract a satoshis amount from this */
|
||||
bool json_to_sat(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_sat *sat);
|
||||
|
||||
/* Extract a satoshis amount from this */
|
||||
/* If the string is "all", set amonut as AMOUNT_SAT(-1ULL). */
|
||||
bool json_to_sat_or_all(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_sat *sat);
|
||||
|
||||
/* Extract a millisatoshis amount from this */
|
||||
bool json_to_msat(const char *buffer, const jsmntok_t *tok,
|
||||
struct amount_msat *msat);
|
||||
|
||||
/* Extract a bitcoin txid from this */
|
||||
bool json_to_txid(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_txid *txid);
|
||||
|
||||
/* Extract a bitcoin outpoint from this */
|
||||
bool json_to_outpoint(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_outpoint *op);
|
||||
|
||||
/* Extract a channel id from this */
|
||||
bool json_to_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct channel_id *cid);
|
||||
|
||||
/* Extract a coin movement 'tag' from this */
|
||||
bool json_to_coin_mvt_tag(const char *buffer, const jsmntok_t *tok,
|
||||
enum mvt_tag *tag);
|
||||
|
||||
/* Extract reply path from this JSON */
|
||||
struct tlv_onionmsg_payload_reply_path *
|
||||
json_to_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Obsolete version! */
|
||||
struct tlv_obs2_onionmsg_payload_reply_path *
|
||||
json_to_obs2_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
|
||||
/* Guide is % for a token: each must be followed by JSON_SCAN().
|
||||
* Returns NULL on error (asserts() on bad guide). */
|
||||
const char *json_scan(const tal_t *ctx,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char *guide,
|
||||
...);
|
||||
|
||||
/* eg. JSON_SCAN(json_to_bool, &boolvar) */
|
||||
#define JSON_SCAN(fmt, var) \
|
||||
json_scan, \
|
||||
stringify(fmt), \
|
||||
((var) + 0*sizeof(fmt((const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, var) == true)), \
|
||||
(fmt)
|
||||
|
||||
/* eg. JSON_SCAN_TAL(tmpctx, json_strdup, &charvar) */
|
||||
#define JSON_SCAN_TAL(ctx, fmt, var) \
|
||||
(ctx), \
|
||||
stringify(fmt), \
|
||||
((var) + 0*sizeof((*var) = fmt((ctx), \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL))), \
|
||||
(fmt)
|
||||
|
||||
/* Already-have-varargs version */
|
||||
const char *json_scanv(const tal_t *ctx,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
const char *guide,
|
||||
va_list ap);
|
||||
|
||||
#endif /* LIGHTNING_COMMON_JSON_PARSE_H */
|
||||
552
common/json_parse_simple.c
Normal file
552
common/json_parse_simple.c
Normal file
@@ -0,0 +1,552 @@
|
||||
/* JSON core and helpers */
|
||||
#include "config.h"
|
||||
#include <assert.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_parse_simple.h>
|
||||
#include <common/utils.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <wire/onion_wire.h>
|
||||
|
||||
const char *json_tok_full(const char *buffer, const jsmntok_t *t)
|
||||
{
|
||||
if (t->type == JSMN_STRING)
|
||||
return buffer + t->start - 1;
|
||||
return buffer + t->start;
|
||||
}
|
||||
|
||||
/* Include " if it's a string. */
|
||||
int json_tok_full_len(const jsmntok_t *t)
|
||||
{
|
||||
if (t->type == JSMN_STRING)
|
||||
return t->end - t->start + 2;
|
||||
return t->end - t->start;
|
||||
}
|
||||
|
||||
bool json_tok_strneq(const char *buffer, const jsmntok_t *tok,
|
||||
const char *str, size_t len)
|
||||
{
|
||||
if (tok->type != JSMN_STRING)
|
||||
return false;
|
||||
return memeq(buffer + tok->start, tok->end - tok->start, str, len);
|
||||
}
|
||||
|
||||
bool json_tok_streq(const char *buffer, const jsmntok_t *tok, const char *str)
|
||||
{
|
||||
return json_tok_strneq(buffer, tok, str, strlen(str));
|
||||
}
|
||||
|
||||
bool json_tok_startswith(const char *buffer, const jsmntok_t *tok,
|
||||
const char *prefix)
|
||||
{
|
||||
if (tok->type != JSMN_STRING)
|
||||
return false;
|
||||
if (tok->end - tok->start < strlen(prefix))
|
||||
return false;
|
||||
return memcmp(buffer + tok->start,
|
||||
prefix, strlen(prefix)) == 0;
|
||||
}
|
||||
|
||||
bool json_tok_endswith(const char *buffer, const jsmntok_t *tok,
|
||||
const char *suffix)
|
||||
{
|
||||
if (tok->type != JSMN_STRING)
|
||||
return false;
|
||||
if (tok->end - tok->start < strlen(suffix))
|
||||
return false;
|
||||
return memcmp(buffer + tok->end - strlen(suffix),
|
||||
suffix, strlen(suffix)) == 0;
|
||||
}
|
||||
|
||||
char *json_strdup(const tal_t *ctx, const char *buffer, const jsmntok_t *tok)
|
||||
{
|
||||
return tal_strndup(ctx, buffer + tok->start, tok->end - tok->start);
|
||||
}
|
||||
|
||||
|
||||
bool json_to_u64(const char *buffer, const jsmntok_t *tok, u64 *num)
|
||||
{
|
||||
char *end;
|
||||
unsigned long long l;
|
||||
|
||||
l = strtoull(buffer + tok->start, &end, 0);
|
||||
if (end != buffer + tok->end)
|
||||
return false;
|
||||
|
||||
BUILD_ASSERT(sizeof(l) >= sizeof(*num));
|
||||
*num = l;
|
||||
|
||||
/* Check for overflow */
|
||||
if (l == ULLONG_MAX && errno == ERANGE)
|
||||
return false;
|
||||
|
||||
if (*num != l)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_u32(const char *buffer, const jsmntok_t *tok, u32 *num)
|
||||
{
|
||||
uint64_t u64;
|
||||
|
||||
if (!json_to_u64(buffer, tok, &u64))
|
||||
return false;
|
||||
*num = u64;
|
||||
|
||||
/* Just in case it doesn't fit. */
|
||||
if (*num != u64)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_bool(const char *buffer, const jsmntok_t *tok, bool *b)
|
||||
{
|
||||
if (tok->type != JSMN_PRIMITIVE)
|
||||
return false;
|
||||
if (memeqstr(buffer + tok->start, tok->end - tok->start, "true")) {
|
||||
*b = true;
|
||||
return true;
|
||||
}
|
||||
if (memeqstr(buffer + tok->start, tok->end - tok->start, "false")) {
|
||||
*b = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool json_tok_is_num(const char *buffer, const jsmntok_t *tok)
|
||||
{
|
||||
if (tok->type != JSMN_PRIMITIVE)
|
||||
return false;
|
||||
|
||||
for (int i = tok->start; i < tok->end; i++)
|
||||
if (!cisdigit(buffer[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_tok_is_null(const char *buffer, const jsmntok_t *tok)
|
||||
{
|
||||
if (tok->type != JSMN_PRIMITIVE)
|
||||
return false;
|
||||
return buffer[tok->start] == 'n';
|
||||
}
|
||||
|
||||
const jsmntok_t *json_next(const jsmntok_t *tok)
|
||||
{
|
||||
const jsmntok_t *t;
|
||||
size_t i;
|
||||
|
||||
for (t = tok + 1, i = 0; i < tok->size; i++)
|
||||
t = json_next(t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
const jsmntok_t *json_get_membern(const char *buffer,
|
||||
const jsmntok_t tok[],
|
||||
const char *label, size_t len)
|
||||
{
|
||||
const jsmntok_t *t;
|
||||
size_t i;
|
||||
|
||||
if (tok->type != JSMN_OBJECT)
|
||||
return NULL;
|
||||
|
||||
json_for_each_obj(i, t, tok)
|
||||
if (json_tok_strneq(buffer, t, label, len))
|
||||
return t + 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const jsmntok_t *json_get_member(const char *buffer, const jsmntok_t tok[],
|
||||
const char *label)
|
||||
{
|
||||
return json_get_membern(buffer, tok, label, strlen(label));
|
||||
}
|
||||
|
||||
const jsmntok_t *json_get_arr(const jsmntok_t tok[], size_t index)
|
||||
{
|
||||
const jsmntok_t *t;
|
||||
size_t i;
|
||||
|
||||
if (tok->type != JSMN_ARRAY)
|
||||
return NULL;
|
||||
|
||||
json_for_each_arr(i, t, tok) {
|
||||
if (index == 0)
|
||||
return t;
|
||||
index--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
JSMN Result Validation Starts
|
||||
-----------------------------------------------------------------------------*/
|
||||
/*~ LIBJSMN is a fast, small JSON parsing library.
|
||||
*
|
||||
* "Fast, small" means it does not, in fact, do a
|
||||
* lot of checking for invalid JSON.
|
||||
*
|
||||
* For example, by itself it would accept the strings
|
||||
* `{"1" "2" "3" "4"}` and `["key": 1 2 3 4]` as valid.
|
||||
* Obviously those are not in any way valid JSON.
|
||||
*
|
||||
* This part of the code performs some filtering so
|
||||
* that at least some of the invalid JSON that
|
||||
* LIBJSMN accepts, will be rejected by
|
||||
* json_parse_input. It also checks that strings are valid UTF-8.
|
||||
*/
|
||||
|
||||
/*~ These functions are used in JSMN validation.
|
||||
*
|
||||
* The calling convention is that the "current" token
|
||||
* is passed in as the first argument, and after the
|
||||
* validator, is returned from the function.
|
||||
*
|
||||
* p = validate_jsmn_datum(p, end, valid);
|
||||
*
|
||||
* The reason has to do with typical C ABIs.
|
||||
* Usually, the first few arguments are passed in via
|
||||
* register, and the return value is also returned
|
||||
* via register.
|
||||
* This calling convention generally ensures that
|
||||
* the current token pointer `p` is always in a
|
||||
* register and is never forced into memory by the
|
||||
* compiler.
|
||||
*
|
||||
* These functions are pre-declared here as they
|
||||
* are interrecursive.
|
||||
* Note that despite the recursion, `p` is only ever
|
||||
* advanced, and there is only ever one `p` value,
|
||||
* thus the overall algorithm is strict O(n)
|
||||
* (*not* amortized) in time.
|
||||
* The recursion does mean the algorithm is O(d)
|
||||
* in memory (specifically stack frames), where d
|
||||
* is the nestedness of objects in the input.
|
||||
* This may become an issue later if we are in a
|
||||
* stack-limited environment, such as if we actually
|
||||
* went and used threads.
|
||||
*/
|
||||
/* Validate a *single* datum. */
|
||||
static const jsmntok_t *
|
||||
validate_jsmn_datum(const char *buf,
|
||||
const jsmntok_t *p,
|
||||
const jsmntok_t *end,
|
||||
bool *valid);
|
||||
/*~ Validate a key-value pair.
|
||||
*
|
||||
* In JSMN, objects are not dictionaries.
|
||||
* Instead, they are a sequence of datums.
|
||||
*
|
||||
* In fact, objects and arrays in JSMN are "the same",
|
||||
* they only differ in delimiter characters.
|
||||
*
|
||||
* Of course, in "real" JSON, an object is a dictionary
|
||||
* of key-value pairs.
|
||||
*
|
||||
* So what JSMN does is that the syntax "key": "value"
|
||||
* is considered a *single* datum, a string "key"
|
||||
* that contains a value "value".
|
||||
*
|
||||
* Indeed, JSMN accepts `["key": "value"]` as well as
|
||||
* `{"item1", "item2"}`.
|
||||
* The entire point of the validate_jsmn_result function
|
||||
* is to reject such improper arrays and objects.
|
||||
*/
|
||||
static const jsmntok_t *
|
||||
validate_jsmn_keyvalue(const char *buf,
|
||||
const jsmntok_t *p,
|
||||
const jsmntok_t *end,
|
||||
bool *valid);
|
||||
|
||||
static const jsmntok_t *
|
||||
validate_jsmn_datum(const char *buf,
|
||||
const jsmntok_t *p,
|
||||
const jsmntok_t *end,
|
||||
bool *valid)
|
||||
{
|
||||
int i;
|
||||
int sz;
|
||||
|
||||
if (p >= end) {
|
||||
*valid = false;
|
||||
return p;
|
||||
}
|
||||
|
||||
switch (p->type) {
|
||||
case JSMN_STRING:
|
||||
if (!utf8_check(buf + p->start, p->end - p->start))
|
||||
*valid = false;
|
||||
/* Fall thru */
|
||||
case JSMN_UNDEFINED:
|
||||
case JSMN_PRIMITIVE:
|
||||
/* These types should not have sub-datums. */
|
||||
if (p->size != 0)
|
||||
*valid = false;
|
||||
else
|
||||
++p;
|
||||
break;
|
||||
|
||||
case JSMN_ARRAY:
|
||||
/* Save the array size; we will advance p. */
|
||||
sz = p->size;
|
||||
++p;
|
||||
for (i = 0; i < sz; ++i) {
|
||||
/* Arrays should only contain standard JSON datums. */
|
||||
p = validate_jsmn_datum(buf, p, end, valid);
|
||||
if (!*valid)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case JSMN_OBJECT:
|
||||
/* Save the object size; we will advance p. */
|
||||
sz = p->size;
|
||||
++p;
|
||||
for (i = 0; i < sz; ++i) {
|
||||
/* Objects should only contain key-value pairs. */
|
||||
p = validate_jsmn_keyvalue(buf, p, end, valid);
|
||||
if (!*valid)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
/* Key-value pairs *must* be strings with size 1. */
|
||||
static inline const jsmntok_t *
|
||||
validate_jsmn_keyvalue(const char *buf,
|
||||
const jsmntok_t *p,
|
||||
const jsmntok_t *end,
|
||||
bool *valid)
|
||||
{
|
||||
if (p >= end) {
|
||||
*valid = false;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Check key.
|
||||
*
|
||||
* JSMN parses the syntax `"key": "value"` as a
|
||||
* JSMN_STRING of size 1, containing the value
|
||||
* datum as a sub-datum.
|
||||
*
|
||||
* Thus, keys in JSON objects are really strings
|
||||
* that "contain" the value, thus we check if
|
||||
* the size is 1.
|
||||
*
|
||||
* JSMN supports a non-standard syntax such as
|
||||
* `"key": 1 2 3 4`, which it considers as a
|
||||
* string object that contains a sequence of
|
||||
* sub-datums 1 2 3 4.
|
||||
* The check below that p->size == 1 also
|
||||
* incidentally rejects that non-standard
|
||||
* JSON.
|
||||
*/
|
||||
if (p->type != JSMN_STRING || p->size != 1
|
||||
|| !utf8_check(buf + p->start, p->end - p->start)) {
|
||||
*valid = false;
|
||||
return p;
|
||||
}
|
||||
|
||||
++p;
|
||||
return validate_jsmn_datum(buf, p, end, valid);
|
||||
}
|
||||
|
||||
/** validate_jsmn_parse_output
|
||||
*
|
||||
* @brief Validates the result of jsmn_parse.
|
||||
*
|
||||
* @desc LIBJMSN is a small fast library, not a
|
||||
* comprehensive library.
|
||||
*
|
||||
* This simply means that LIBJSMN will accept a
|
||||
* *lot* of very strange text that is technically
|
||||
* not JSON.
|
||||
*
|
||||
* For example, LIBJSMN would accept the strings
|
||||
* `{"1" "2" "3" "4"}` and `["key": 1 2 3 4]` as valid.
|
||||
*
|
||||
* This can lead to strange sequences of jsmntok_t
|
||||
* objects.
|
||||
* Unfortunately, most of our code assumes that
|
||||
* the data fed into our JSON-RPC interface is
|
||||
* valid JSON, and in particular is not invalid
|
||||
* JSON that tickles LIBJSMN into emitting
|
||||
* strange sequences of `jsmntok_t`.
|
||||
*
|
||||
* This function detects such possible problems
|
||||
* and returns false if such an issue is found.
|
||||
* If so, it is probably unsafe to pass the
|
||||
* `jsmntok_t` generated by LIBJSMN to any other
|
||||
* parts of our code.
|
||||
*
|
||||
* @param p - The first jsmntok_t token to process.
|
||||
* This function does not assume that semantically
|
||||
* only one JSON datum is processed; it does expect
|
||||
* a sequence of complete JSON datums (which is
|
||||
* what LIBJSMN *should* output).
|
||||
* @param end - One past the end of jsmntok_t.
|
||||
* Basically, this function is assured to read tokens
|
||||
* starting at p up to end - 1.
|
||||
* If p >= end, this will not validate anything and
|
||||
* trivially return true.
|
||||
*
|
||||
* @return true if there appears to be no problem
|
||||
* with the jsmntok_t sequence outputted by
|
||||
* `jsmn_parse`, false otherwise.
|
||||
*/
|
||||
static bool
|
||||
validate_jsmn_parse_output(const char *buf,
|
||||
const jsmntok_t *p, const jsmntok_t *end)
|
||||
{
|
||||
bool valid = true;
|
||||
|
||||
while (p < end && valid)
|
||||
p = validate_jsmn_datum(buf, p, end, &valid);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
JSMN Result Validation Ends
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void toks_reset(jsmntok_t *toks)
|
||||
{
|
||||
assert(tal_count(toks) >= 1);
|
||||
toks[0].type = JSMN_UNDEFINED;
|
||||
}
|
||||
|
||||
jsmntok_t *toks_alloc(const tal_t *ctx)
|
||||
{
|
||||
jsmntok_t *toks = tal_arr(ctx, jsmntok_t, 10);
|
||||
toks_reset(toks);
|
||||
return toks;
|
||||
}
|
||||
|
||||
bool json_parse_input(jsmn_parser *parser,
|
||||
jsmntok_t **toks,
|
||||
const char *input, int len,
|
||||
bool *complete)
|
||||
{
|
||||
int ret;
|
||||
|
||||
again:
|
||||
ret = jsmn_parse(parser, input, len, *toks, tal_count(*toks) - 1);
|
||||
|
||||
switch (ret) {
|
||||
case JSMN_ERROR_INVAL:
|
||||
return false;
|
||||
case JSMN_ERROR_NOMEM:
|
||||
tal_resize(toks, tal_count(*toks) * 2);
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* Check whether we read at least one full root element, i.e., root
|
||||
* element has its end set. */
|
||||
if ((*toks)[0].type == JSMN_UNDEFINED || (*toks)[0].end == -1) {
|
||||
*complete = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If we read a partial element at the end of the stream we'll get a
|
||||
* ret=JSMN_ERROR_PART, but due to the previous check we know we read at
|
||||
* least one full element, so count tokens that are part of this root
|
||||
* element. */
|
||||
ret = json_next(*toks) - *toks;
|
||||
|
||||
if (!validate_jsmn_parse_output(input, *toks, *toks + ret))
|
||||
return false;
|
||||
|
||||
/* Cut to length and return. */
|
||||
tal_resize(toks, ret + 1);
|
||||
/* Make sure last one is always referenceable. */
|
||||
(*toks)[ret].type = -1;
|
||||
(*toks)[ret].start = (*toks)[ret].end = (*toks)[ret].size = 0;
|
||||
|
||||
*complete = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
jsmntok_t *json_parse_simple(const tal_t *ctx, const char *input, int len)
|
||||
{
|
||||
bool complete;
|
||||
jsmn_parser parser;
|
||||
jsmntok_t *toks = toks_alloc(ctx);
|
||||
|
||||
jsmn_init(&parser);
|
||||
|
||||
if (!json_parse_input(&parser, &toks, input, len, &complete)
|
||||
|| !complete)
|
||||
return tal_free(toks);
|
||||
return toks;
|
||||
}
|
||||
|
||||
const char *jsmntype_to_string(jsmntype_t t)
|
||||
{
|
||||
switch (t) {
|
||||
case JSMN_UNDEFINED :
|
||||
return "UNDEFINED";
|
||||
case JSMN_OBJECT :
|
||||
return "OBJECT";
|
||||
case JSMN_ARRAY :
|
||||
return "ARRAY";
|
||||
case JSMN_STRING :
|
||||
return "STRING";
|
||||
case JSMN_PRIMITIVE :
|
||||
return "PRIMITIVE";
|
||||
}
|
||||
return "INVALID";
|
||||
}
|
||||
|
||||
jsmntok_t *json_tok_copy(const tal_t *ctx, const jsmntok_t *tok)
|
||||
{
|
||||
return tal_dup_arr(ctx, jsmntok_t, tok, json_next(tok) - tok, 0);
|
||||
}
|
||||
|
||||
void json_tok_remove(jsmntok_t **tokens,
|
||||
jsmntok_t *obj_or_array, const jsmntok_t *tok, size_t num)
|
||||
{
|
||||
const jsmntok_t *src = tok;
|
||||
const jsmntok_t *end = json_next(*tokens);
|
||||
jsmntok_t *dest = *tokens + (tok - *tokens);
|
||||
int remove_count;
|
||||
|
||||
assert(*tokens);
|
||||
assert(obj_or_array->type == JSMN_ARRAY
|
||||
|| obj_or_array->type == JSMN_OBJECT);
|
||||
/* obj_or_array must be inside tokens, and tok must be inside
|
||||
* obj_or_array */
|
||||
assert(obj_or_array >= *tokens
|
||||
&& obj_or_array < *tokens + tal_count(*tokens));
|
||||
assert(tok >= obj_or_array
|
||||
&& tok < *tokens + tal_count(*tokens));
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
src = json_next(src);
|
||||
|
||||
/* Don't give us a num which goes over end of obj_or_array. */
|
||||
assert(src <= json_next(obj_or_array));
|
||||
|
||||
remove_count = src - tok;
|
||||
|
||||
memmove(dest, src, sizeof(jsmntok_t) * (end - src));
|
||||
|
||||
/* Subtract first: this ptr may move after tal_resize! */
|
||||
obj_or_array->size -= num;
|
||||
tal_resize(tokens, tal_count(*tokens) - remove_count);
|
||||
}
|
||||
122
common/json_parse_simple.h
Normal file
122
common/json_parse_simple.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/* Very simple core JSON parse helpers: used by lightning-cli too */
|
||||
#ifndef LIGHTNING_COMMON_JSON_PARSE_SIMPLE_H
|
||||
#define LIGHTNING_COMMON_JSON_PARSE_SIMPLE_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
|
||||
#define JSMN_STRICT 1
|
||||
# include <external/jsmn/jsmn.h>
|
||||
|
||||
/* Include " if it's a string. */
|
||||
const char *json_tok_full(const char *buffer, const jsmntok_t *t);
|
||||
|
||||
/* Include " if it's a string. */
|
||||
int json_tok_full_len(const jsmntok_t *t);
|
||||
|
||||
/* Is this a string equal to str? */
|
||||
bool json_tok_streq(const char *buffer, const jsmntok_t *tok, const char *str);
|
||||
|
||||
/* Is this a string equal to str of length len? */
|
||||
bool json_tok_strneq(const char *buffer, const jsmntok_t *tok,
|
||||
const char *str, size_t len);
|
||||
|
||||
/* Does this string token start with prefix? */
|
||||
bool json_tok_startswith(const char *buffer, const jsmntok_t *tok,
|
||||
const char *prefix);
|
||||
|
||||
/* Does this string token end with suffix? */
|
||||
bool json_tok_endswith(const char *buffer, const jsmntok_t *tok,
|
||||
const char *suffix);
|
||||
|
||||
/* Allocate a tal string copy */
|
||||
char *json_strdup(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Extract number from this (may be a string, or a number literal) */
|
||||
bool json_to_u64(const char *buffer, const jsmntok_t *tok, u64 *num);
|
||||
|
||||
/* Extract number from this (may be a string, or a number literal) */
|
||||
bool json_to_u32(const char *buffer, const jsmntok_t *tok, u32 *num);
|
||||
|
||||
/* Extract boolean from this */
|
||||
bool json_to_bool(const char *buffer, const jsmntok_t *tok, bool *b);
|
||||
|
||||
/* Is this a number? [0..9]+ */
|
||||
bool json_tok_is_num(const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Is this the null primitive? */
|
||||
bool json_tok_is_null(const char *buffer, const jsmntok_t *tok);
|
||||
|
||||
/* Returns next token with same parent (WARNING: slow!). */
|
||||
const jsmntok_t *json_next(const jsmntok_t *tok);
|
||||
|
||||
/* Get top-level member with explicit label len */
|
||||
const jsmntok_t *json_get_membern(const char *buffer,
|
||||
const jsmntok_t tok[],
|
||||
const char *label, size_t len);
|
||||
|
||||
/* Get top-level member. */
|
||||
const jsmntok_t *json_get_member(const char *buffer, const jsmntok_t tok[],
|
||||
const char *label);
|
||||
|
||||
/* Get index'th array member. */
|
||||
const jsmntok_t *json_get_arr(const jsmntok_t tok[], size_t index);
|
||||
|
||||
/* Allocate a starter array of tokens for json_parse_input */
|
||||
jsmntok_t *toks_alloc(const tal_t *ctx);
|
||||
|
||||
/* Reset a token array to reuse it. */
|
||||
void toks_reset(jsmntok_t *toks);
|
||||
|
||||
/**
|
||||
* json_parse_input: parse and validate JSON.
|
||||
* @parser: parser initialized with jsmn_init.
|
||||
* @toks: tallocated array from toks_alloc()
|
||||
* @input, @len: input string.
|
||||
* @complete: set to true if the valid JSON is complete, or NULL if must be.
|
||||
*
|
||||
* This returns false if the JSON is invalid, true otherwise.
|
||||
* If it returns true, *@complete indicates that (*@toks)[0] points to a
|
||||
* valid, complete JSON element. If @complete is NULL, then incomplete
|
||||
* JSON returns false (i.e. is considered invalid).
|
||||
*
|
||||
* *@toks is resized to the complete set of tokens, with a dummy
|
||||
* terminator (type == -1) at the end.
|
||||
*
|
||||
* If it returns true, and *@complete is false, you can append more
|
||||
* data to @input and call it again (with the same perser) and the parser
|
||||
* will continue where it left off.
|
||||
*/
|
||||
bool json_parse_input(jsmn_parser *parser,
|
||||
jsmntok_t **toks,
|
||||
const char *input, int len,
|
||||
bool *complete);
|
||||
|
||||
/* Simplified version of above which parses only a complete, valid
|
||||
* JSON string */
|
||||
jsmntok_t *json_parse_simple(const tal_t *ctx, const char *input, int len);
|
||||
|
||||
/* Convert a jsmntype_t enum to a human readable string. */
|
||||
const char *jsmntype_to_string(jsmntype_t t);
|
||||
|
||||
/* Return a copy of a json value as an array. */
|
||||
jsmntok_t *json_tok_copy(const tal_t *ctx, const jsmntok_t *tok);
|
||||
|
||||
/*
|
||||
* Remove @num json values from a json array or object @obj. @tok points
|
||||
* to the first value to remove. The array @tokens will be resized.
|
||||
*/
|
||||
void json_tok_remove(jsmntok_t **tokens,
|
||||
jsmntok_t *obj_or_array, const jsmntok_t *tok, size_t num);
|
||||
|
||||
|
||||
/* Iterator macro for array: i is counter, t is token ptr, arr is JSMN_ARRAY */
|
||||
#define json_for_each_arr(i, t, arr) \
|
||||
for (i = 0, t = (arr) + 1; i < (arr)->size; t = json_next(t), i++)
|
||||
|
||||
/* Iterator macro for object: i is counter, t is token ptr (t+1 is
|
||||
* contents of obj member), obj is JSMN_OBJECT */
|
||||
#define json_for_each_obj(i, t, obj) \
|
||||
for (i = 0, t = (obj) + 1; i < (obj)->size; t = json_next(t+1), i++)
|
||||
|
||||
#endif /* LIGHTNING_COMMON_JSON_PARSE_SIMPLE_H */
|
||||
@@ -1,10 +1,28 @@
|
||||
#include "config.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <bitcoin/preimage.h>
|
||||
#include <bitcoin/privkey.h>
|
||||
#include <bitcoin/psbt.h>
|
||||
#include <bitcoin/short_channel_id.h>
|
||||
#include <bitcoin/signature.h>
|
||||
#include <bitcoin/tx.h>
|
||||
#include <ccan/io/io.h>
|
||||
/* To reach into io_plan: not a public header! */
|
||||
#include <ccan/io/backend.h>
|
||||
#include <ccan/json_escape/json_escape.h>
|
||||
#include <ccan/json_out/json_out.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
#include <common/channel_id.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/json_stream.h>
|
||||
|
||||
#include <common/node_id.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <common/utils.h>
|
||||
#include <common/wireaddr.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <wire/peer_wire.h>
|
||||
|
||||
static void adjust_io_write(struct json_out *jout,
|
||||
ptrdiff_t delta,
|
||||
@@ -204,3 +222,419 @@ struct io_plan *json_stream_output_(struct json_stream *js,
|
||||
js->len_read = 0;
|
||||
return json_stream_output_write(conn, js);
|
||||
}
|
||||
|
||||
void json_add_num(struct json_stream *result, const char *fieldname, unsigned int value)
|
||||
{
|
||||
json_add_member(result, fieldname, false, "%u", value);
|
||||
}
|
||||
|
||||
void json_add_u64(struct json_stream *result, const char *fieldname,
|
||||
uint64_t value)
|
||||
{
|
||||
json_add_member(result, fieldname, false, "%"PRIu64, value);
|
||||
}
|
||||
|
||||
void json_add_s64(struct json_stream *result, const char *fieldname,
|
||||
int64_t value)
|
||||
{
|
||||
json_add_member(result, fieldname, false, "%"PRIi64, value);
|
||||
}
|
||||
|
||||
void json_add_u32(struct json_stream *result, const char *fieldname,
|
||||
uint32_t value)
|
||||
{
|
||||
json_add_member(result, fieldname, false, "%u", value);
|
||||
}
|
||||
|
||||
void json_add_s32(struct json_stream *result, const char *fieldname,
|
||||
int32_t value)
|
||||
{
|
||||
json_add_member(result, fieldname, false, "%d", value);
|
||||
}
|
||||
|
||||
void json_add_literal(struct json_stream *result, const char *fieldname,
|
||||
const char *literal, int len)
|
||||
{
|
||||
/* Literal may contain quotes, so bypass normal checks */
|
||||
char *dest = json_member_direct(result, fieldname, len);
|
||||
memcpy(dest, literal, len);
|
||||
}
|
||||
|
||||
void json_add_stringn(struct json_stream *result, const char *fieldname,
|
||||
const char *value TAKES, size_t value_len)
|
||||
{
|
||||
json_add_member(result, fieldname, true, "%.*s", (int)value_len, value);
|
||||
if (taken(value))
|
||||
tal_free(value);
|
||||
}
|
||||
|
||||
void json_add_string(struct json_stream *result, const char *fieldname, const char *value TAKES)
|
||||
{
|
||||
json_add_stringn(result, fieldname, value, strlen(value));
|
||||
}
|
||||
|
||||
void json_add_bool(struct json_stream *result, const char *fieldname, bool value)
|
||||
{
|
||||
json_add_member(result, fieldname, false, value ? "true" : "false");
|
||||
}
|
||||
|
||||
void json_add_null(struct json_stream *stream, const char *fieldname)
|
||||
{
|
||||
json_add_member(stream, fieldname, false, "null");
|
||||
}
|
||||
|
||||
void json_add_hex(struct json_stream *js, const char *fieldname,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
/* Size without NUL term */
|
||||
size_t hexlen = hex_str_size(len) - 1;
|
||||
char *dest;
|
||||
|
||||
dest = json_member_direct(js, fieldname, 1 + hexlen + 1);
|
||||
dest[0] = '"';
|
||||
if (!hex_encode(data, len, dest + 1, hexlen + 1))
|
||||
abort();
|
||||
dest[1+hexlen] = '"';
|
||||
}
|
||||
|
||||
void json_add_hex_talarr(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const tal_t *data)
|
||||
{
|
||||
json_add_hex(result, fieldname, data, tal_bytelen(data));
|
||||
}
|
||||
|
||||
void json_add_escaped_string(struct json_stream *result, const char *fieldname,
|
||||
const struct json_escape *esc TAKES)
|
||||
{
|
||||
/* Already escaped, don't re-escape! */
|
||||
char *dest = json_member_direct(result, fieldname,
|
||||
1 + strlen(esc->s) + 1);
|
||||
|
||||
dest[0] = '"';
|
||||
memcpy(dest + 1, esc->s, strlen(esc->s));
|
||||
dest[1+strlen(esc->s)] = '"';
|
||||
if (taken(esc))
|
||||
tal_free(esc);
|
||||
}
|
||||
|
||||
void json_add_timeabs(struct json_stream *result, const char *fieldname,
|
||||
struct timeabs t)
|
||||
{
|
||||
json_add_member(result, fieldname, false, "%" PRIu64 ".%03" PRIu64,
|
||||
(u64)t.ts.tv_sec, (u64)t.ts.tv_nsec / 1000000);
|
||||
}
|
||||
|
||||
void json_add_time(struct json_stream *result, const char *fieldname,
|
||||
struct timespec ts)
|
||||
{
|
||||
char timebuf[100];
|
||||
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu.%09u",
|
||||
(unsigned long)ts.tv_sec,
|
||||
(unsigned)ts.tv_nsec);
|
||||
json_add_string(result, fieldname, timebuf);
|
||||
}
|
||||
|
||||
void json_add_timeiso(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
struct timeabs *time)
|
||||
{
|
||||
char iso8601_msec_fmt[sizeof("YYYY-mm-ddTHH:MM:SS.%03dZ")];
|
||||
char iso8601_s[sizeof("YYYY-mm-ddTHH:MM:SS.nnnZ")];
|
||||
|
||||
strftime(iso8601_msec_fmt, sizeof(iso8601_msec_fmt),
|
||||
"%FT%T.%%03dZ", gmtime(&time->ts.tv_sec));
|
||||
snprintf(iso8601_s, sizeof(iso8601_s),
|
||||
iso8601_msec_fmt, (int) time->ts.tv_nsec / 1000000);
|
||||
|
||||
json_add_string(result, fieldname, iso8601_s);
|
||||
}
|
||||
|
||||
|
||||
void json_add_tok(struct json_stream *result, const char *fieldname,
|
||||
const jsmntok_t *tok, const char *buffer)
|
||||
{
|
||||
char *space;
|
||||
assert(tok->type != JSMN_UNDEFINED);
|
||||
|
||||
space = json_member_direct(result, fieldname, json_tok_full_len(tok));
|
||||
memcpy(space, json_tok_full(buffer, tok), json_tok_full_len(tok));
|
||||
}
|
||||
|
||||
void json_add_errcode(struct json_stream *result, const char *fieldname,
|
||||
errcode_t code)
|
||||
{
|
||||
json_add_member(result, fieldname, false, "%"PRIerrcode, code);
|
||||
}
|
||||
|
||||
void json_add_invstring(struct json_stream *result, const char *invstring)
|
||||
{
|
||||
if (strstarts(invstring, "lni"))
|
||||
json_add_string(result, "bolt12", invstring);
|
||||
else
|
||||
json_add_string(result, "bolt11", invstring);
|
||||
}
|
||||
|
||||
void json_add_node_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct node_id *id)
|
||||
{
|
||||
json_add_hex(response, fieldname, id->k, sizeof(id->k));
|
||||
}
|
||||
|
||||
void json_add_channel_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct channel_id *cid)
|
||||
{
|
||||
json_add_hex(response, fieldname, cid->id, sizeof(cid->id));
|
||||
}
|
||||
|
||||
void json_add_pubkey(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
u8 der[PUBKEY_CMPR_LEN];
|
||||
|
||||
pubkey_to_der(der, key);
|
||||
json_add_hex(response, fieldname, der, sizeof(der));
|
||||
}
|
||||
|
||||
void json_add_point32(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct point32 *key)
|
||||
{
|
||||
u8 output[32];
|
||||
|
||||
secp256k1_xonly_pubkey_serialize(secp256k1_ctx, output, &key->pubkey);
|
||||
json_add_hex(response, fieldname, output, sizeof(output));
|
||||
}
|
||||
|
||||
void json_add_bip340sig(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct bip340sig *sig)
|
||||
{
|
||||
json_add_hex(response, fieldname, sig->u8, sizeof(sig->u8));
|
||||
}
|
||||
|
||||
void json_add_txid(struct json_stream *result, const char *fieldname,
|
||||
const struct bitcoin_txid *txid)
|
||||
{
|
||||
char hex[hex_str_size(sizeof(*txid))];
|
||||
|
||||
bitcoin_txid_to_hex(txid, hex, sizeof(hex));
|
||||
json_add_string(result, fieldname, hex);
|
||||
}
|
||||
|
||||
void json_add_outpoint(struct json_stream *result, const char *fieldname,
|
||||
const struct bitcoin_outpoint *out)
|
||||
{
|
||||
char hex[hex_str_size(sizeof(out->txid))];
|
||||
bitcoin_txid_to_hex(&out->txid, hex, sizeof(hex));
|
||||
json_add_member(result, fieldname, true, "%s:%d", hex, out->n);
|
||||
}
|
||||
|
||||
void json_add_short_channel_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct short_channel_id *scid)
|
||||
{
|
||||
json_add_member(response, fieldname, true, "%dx%dx%d",
|
||||
short_channel_id_blocknum(scid),
|
||||
short_channel_id_txnum(scid),
|
||||
short_channel_id_outnum(scid));
|
||||
}
|
||||
|
||||
void json_add_address(struct json_stream *response, const char *fieldname,
|
||||
const struct wireaddr *addr)
|
||||
{
|
||||
json_object_start(response, fieldname);
|
||||
if (addr->type == ADDR_TYPE_IPV4) {
|
||||
char addrstr[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, addr->addr, addrstr, INET_ADDRSTRLEN);
|
||||
json_add_string(response, "type", "ipv4");
|
||||
json_add_string(response, "address", addrstr);
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_IPV6) {
|
||||
char addrstr[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, addr->addr, addrstr, INET6_ADDRSTRLEN);
|
||||
json_add_string(response, "type", "ipv6");
|
||||
json_add_string(response, "address", addrstr);
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_TOR_V2_REMOVED) {
|
||||
json_add_string(response, "type", "torv2");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_TOR_V3) {
|
||||
json_add_string(response, "type", "torv3");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_DNS) {
|
||||
json_add_string(response, "type", "dns");
|
||||
json_add_string(response, "address", fmt_wireaddr_without_port(tmpctx, addr));
|
||||
json_add_num(response, "port", addr->port);
|
||||
} else if (addr->type == ADDR_TYPE_WEBSOCKET) {
|
||||
json_add_string(response, "type", "websocket");
|
||||
json_add_num(response, "port", addr->port);
|
||||
}
|
||||
json_object_end(response);
|
||||
}
|
||||
|
||||
void json_add_address_internal(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct wireaddr_internal *addr)
|
||||
{
|
||||
switch (addr->itype) {
|
||||
case ADDR_INTERNAL_SOCKNAME:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "local socket");
|
||||
json_add_string(response, "socket", addr->u.sockname);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "any protocol");
|
||||
json_add_num(response, "port", addr->u.port);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_AUTOTOR:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "Tor generated address");
|
||||
json_add_address(response, "service", &addr->u.torservice.address);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_STATICTOR:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "Tor from blob generated static address");
|
||||
json_add_address(response, "service", &addr->u.torservice.address);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "unresolved");
|
||||
json_add_string(response, "name", addr->u.unresolved.name);
|
||||
json_add_num(response, "port", addr->u.unresolved.port);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
json_add_address(response, fieldname, &addr->u.wireaddr);
|
||||
return;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
void json_add_tx(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const struct bitcoin_tx *tx)
|
||||
{
|
||||
json_add_hex_talarr(result, fieldname, linearize_tx(tmpctx, tx));
|
||||
}
|
||||
|
||||
void json_add_psbt(struct json_stream *stream,
|
||||
const char *fieldname,
|
||||
const struct wally_psbt *psbt TAKES)
|
||||
{
|
||||
const char *psbt_b64;
|
||||
psbt_b64 = psbt_to_b64(NULL, psbt);
|
||||
json_add_string(stream, fieldname, take(psbt_b64));
|
||||
if (taken(psbt))
|
||||
tal_free(psbt);
|
||||
}
|
||||
|
||||
void json_add_amount_msat_compat(struct json_stream *result,
|
||||
struct amount_msat msat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
{
|
||||
if (deprecated_apis)
|
||||
json_add_u64(result, rawfieldname, msat.millisatoshis); /* Raw: low-level helper */
|
||||
json_add_amount_msat_only(result, msatfieldname, msat);
|
||||
}
|
||||
|
||||
void json_add_amount_msat_only(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_msat msat)
|
||||
{
|
||||
if (!deprecated_apis)
|
||||
assert(strends(msatfieldname, "_msat"));
|
||||
if (deprecated_apis)
|
||||
json_add_string(result, msatfieldname,
|
||||
type_to_string(tmpctx, struct amount_msat, &msat));
|
||||
else
|
||||
json_add_u64(result, msatfieldname, msat.millisatoshis); /* Raw: low-level helper */
|
||||
}
|
||||
|
||||
void json_add_amount_sat_compat(struct json_stream *result,
|
||||
struct amount_sat sat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
{
|
||||
if (deprecated_apis)
|
||||
json_add_u64(result, rawfieldname, sat.satoshis); /* Raw: low-level helper */
|
||||
json_add_amount_sat_msat(result, msatfieldname, sat);
|
||||
}
|
||||
|
||||
void json_add_amount_sat_msat(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
{
|
||||
struct amount_msat msat;
|
||||
assert(strends(msatfieldname, "_msat"));
|
||||
if (amount_sat_to_msat(&msat, sat))
|
||||
json_add_amount_msat_only(result, msatfieldname, msat);
|
||||
}
|
||||
|
||||
/* When I noticed that we were adding "XXXmsat" fields *not* ending in _msat */
|
||||
void json_add_amount_sats_deprecated(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
{
|
||||
if (deprecated_apis) {
|
||||
struct amount_msat msat;
|
||||
assert(!strends(fieldname, "_msat"));
|
||||
if (amount_sat_to_msat(&msat, sat))
|
||||
json_add_string(result, fieldname,
|
||||
take(fmt_amount_msat(NULL, msat)));
|
||||
}
|
||||
json_add_amount_sat_msat(result, msatfieldname, sat);
|
||||
}
|
||||
|
||||
void json_add_sats(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
struct amount_sat sat)
|
||||
{
|
||||
json_add_string(result, fieldname, take(fmt_amount_sat(NULL, sat)));
|
||||
}
|
||||
|
||||
void json_add_secret(struct json_stream *response, const char *fieldname,
|
||||
const struct secret *secret)
|
||||
{
|
||||
json_add_hex(response, fieldname, secret, sizeof(struct secret));
|
||||
}
|
||||
|
||||
void json_add_sha256(struct json_stream *result, const char *fieldname,
|
||||
const struct sha256 *hash)
|
||||
{
|
||||
json_add_hex(result, fieldname, hash, sizeof(*hash));
|
||||
}
|
||||
|
||||
void json_add_preimage(struct json_stream *result, const char *fieldname,
|
||||
const struct preimage *preimage)
|
||||
{
|
||||
json_add_hex(result, fieldname, preimage, sizeof(*preimage));
|
||||
}
|
||||
|
||||
void json_add_lease_rates(struct json_stream *result,
|
||||
const struct lease_rates *rates)
|
||||
{
|
||||
json_add_amount_sat_msat(result, "lease_fee_base_msat",
|
||||
amount_sat(rates->lease_fee_base_sat));
|
||||
json_add_num(result, "lease_fee_basis", rates->lease_fee_basis);
|
||||
json_add_num(result, "funding_weight", rates->funding_weight);
|
||||
json_add_amount_msat_only(result,
|
||||
"channel_fee_max_base_msat",
|
||||
amount_msat(rates->channel_fee_max_base_msat));
|
||||
json_add_num(result, "channel_fee_max_proportional_thousandths",
|
||||
rates->channel_fee_max_proportional_thousandths);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,36 @@
|
||||
#ifndef LIGHTNING_COMMON_JSON_STREAM_H
|
||||
#define LIGHTNING_COMMON_JSON_STREAM_H
|
||||
#include "config.h"
|
||||
|
||||
#define JSMN_STRICT 1
|
||||
# include <external/jsmn/jsmn.h>
|
||||
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <ccan/time/time.h>
|
||||
#include <common/amount.h>
|
||||
#include <common/errcode.h>
|
||||
|
||||
struct command;
|
||||
struct io_conn;
|
||||
struct log;
|
||||
struct json_escape;
|
||||
struct pubkey;
|
||||
struct point32;
|
||||
struct bip340sig;
|
||||
struct secret;
|
||||
struct node_id;
|
||||
struct channel_id;
|
||||
struct bitcoin_txid;
|
||||
struct bitcoin_outpoint;
|
||||
struct short_channel_id;
|
||||
struct sha256;
|
||||
struct preimage;
|
||||
struct bitcoin_tx;
|
||||
struct wally_psbt;
|
||||
struct lease_rates;
|
||||
struct wireaddr;
|
||||
struct wireaddr_internal;
|
||||
|
||||
struct json_stream {
|
||||
struct json_out *jout;
|
||||
@@ -146,4 +171,196 @@ struct io_plan *json_stream_output_(struct json_stream *js,
|
||||
void json_stream_double_cr(struct json_stream *js);
|
||||
void json_stream_flush(struct json_stream *js);
|
||||
|
||||
/* '"fieldname" : "value"' or '"value"' if fieldname is NULL. Turns
|
||||
* any non-printable chars into JSON escapes, but leaves existing escapes alone.
|
||||
*/
|
||||
void json_add_string(struct json_stream *result, const char *fieldname, const char *value);
|
||||
|
||||
/* '"fieldname" : "value[:value_len]"' or '"value[:value_len]"' if
|
||||
* fieldname is NULL. Turns any non-printable chars into JSON
|
||||
* escapes, but leaves existing escapes alone.
|
||||
*/
|
||||
void json_add_stringn(struct json_stream *result, const char *fieldname,
|
||||
const char *value TAKES, size_t value_len);
|
||||
|
||||
/* '"fieldname" : "value"' or '"value"' if fieldname is NULL. String must
|
||||
* already be JSON escaped as necessary. */
|
||||
void json_add_escaped_string(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const struct json_escape *esc TAKES);
|
||||
|
||||
/* '"fieldname" : literal' or 'literal' if fieldname is NULL*/
|
||||
void json_add_literal(struct json_stream *result, const char *fieldname,
|
||||
const char *literal, int len);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_num(struct json_stream *result, const char *fieldname,
|
||||
unsigned int value);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_u64(struct json_stream *result, const char *fieldname,
|
||||
uint64_t value);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_s64(struct json_stream *result, const char *fieldname,
|
||||
int64_t value);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_u32(struct json_stream *result, const char *fieldname,
|
||||
uint32_t value);
|
||||
/* '"fieldname" : value' or 'value' if fieldname is NULL */
|
||||
void json_add_s32(struct json_stream *result, const char *fieldname,
|
||||
int32_t value);
|
||||
/* '"fieldname" : true|false' or 'true|false' if fieldname is NULL */
|
||||
void json_add_bool(struct json_stream *result, const char *fieldname,
|
||||
bool value);
|
||||
|
||||
/* '"fieldname" : null' or 'null' if fieldname is NULL */
|
||||
void json_add_null(struct json_stream *stream, const char *fieldname);
|
||||
|
||||
/* '"fieldname" : "0189abcdef..."' or "0189abcdef..." if fieldname is NULL */
|
||||
void json_add_hex(struct json_stream *result, const char *fieldname,
|
||||
const void *data, size_t len);
|
||||
/* '"fieldname" : "0189abcdef..."' or "0189abcdef..." if fieldname is NULL */
|
||||
void json_add_hex_talarr(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const tal_t *data);
|
||||
|
||||
void json_add_timeabs(struct json_stream *result, const char *fieldname,
|
||||
struct timeabs t);
|
||||
|
||||
/* used in log.c and notification.c*/
|
||||
void json_add_time(struct json_stream *result, const char *fieldname,
|
||||
struct timespec ts);
|
||||
|
||||
/* Add ISO_8601 timestamp string, i.e. "2019-09-07T15:50+01:00" */
|
||||
void json_add_timeiso(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
struct timeabs *time);
|
||||
|
||||
/* Add any json token */
|
||||
void json_add_tok(struct json_stream *result, const char *fieldname,
|
||||
const jsmntok_t *tok, const char *buffer);
|
||||
|
||||
/* Add an error code */
|
||||
void json_add_errcode(struct json_stream *result, const char *fieldname,
|
||||
errcode_t code);
|
||||
|
||||
/* Add "bolt11" or "bolt12" field, depending on invstring. */
|
||||
void json_add_invstring(struct json_stream *result, const char *invstring);
|
||||
|
||||
/* '"fieldname" : "0289abcdef..."' or "0289abcdef..." if fieldname is NULL */
|
||||
void json_add_pubkey(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct pubkey *key);
|
||||
|
||||
/* '"fieldname" : "89abcdef..."' or "89abcdef..." if fieldname is NULL */
|
||||
void json_add_point32(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct point32 *key);
|
||||
|
||||
/* '"fieldname" : "89abcdef..."' or "89abcdef..." if fieldname is NULL */
|
||||
void json_add_bip340sig(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct bip340sig *sig);
|
||||
|
||||
/* '"fieldname" : "89abcdef..."' or "89abcdef..." if fieldname is NULL */
|
||||
void json_add_secret(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct secret *secret);
|
||||
|
||||
/* '"fieldname" : "0289abcdef..."' or "0289abcdef..." if fieldname is NULL */
|
||||
void json_add_node_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct node_id *id);
|
||||
|
||||
/* '"fieldname" : "0289abcdef..."' or "0289abcdef..." if fieldname is NULL */
|
||||
void json_add_channel_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct channel_id *cid);
|
||||
|
||||
/* '"fieldname" : <hexrev>' or "<hexrev>" if fieldname is NULL */
|
||||
void json_add_txid(struct json_stream *result, const char *fieldname,
|
||||
const struct bitcoin_txid *txid);
|
||||
|
||||
/* '"fieldname" : "txid:n" */
|
||||
void json_add_outpoint(struct json_stream *result, const char *fieldname,
|
||||
const struct bitcoin_outpoint *out);
|
||||
|
||||
/* '"fieldname" : "1234:5:6"' */
|
||||
void json_add_short_channel_id(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct short_channel_id *id);
|
||||
|
||||
/* JSON serialize a network address for a node */
|
||||
void json_add_address(struct json_stream *response, const char *fieldname,
|
||||
const struct wireaddr *addr);
|
||||
|
||||
/* JSON serialize a network address for a node. */
|
||||
void json_add_address_internal(struct json_stream *response,
|
||||
const char *fieldname,
|
||||
const struct wireaddr_internal *addr);
|
||||
|
||||
/* Adds both a 'raw' number field and an 'amount_msat' field */
|
||||
void json_add_amount_msat_compat(struct json_stream *result,
|
||||
struct amount_msat msat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds both a 'raw' number field and an 'amount_msat' field */
|
||||
void json_add_amount_sat_compat(struct json_stream *result,
|
||||
struct amount_sat sat,
|
||||
const char *rawfieldname,
|
||||
const char *msatfieldname)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field */
|
||||
void json_add_amount_msat_only(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_msat msat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field */
|
||||
void json_add_amount_sat_only(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field */
|
||||
void json_add_amount_sat_msat(struct json_stream *result,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* Adds an 'msat' field, and an older deprecated field. */
|
||||
void json_add_amount_sats_deprecated(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const char *msatfieldname,
|
||||
struct amount_sat sat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
/* This is used to create requests, *never* for output (output is always
|
||||
* msat!) */
|
||||
void json_add_sats(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
struct amount_sat sat)
|
||||
NO_NULL_ARGS;
|
||||
|
||||
void json_add_sha256(struct json_stream *result, const char *fieldname,
|
||||
const struct sha256 *hash);
|
||||
|
||||
void json_add_preimage(struct json_stream *result, const char *fieldname,
|
||||
const struct preimage *preimage);
|
||||
|
||||
/* '"fieldname" : "010000000001..."' or "010000000001..." if fieldname is NULL */
|
||||
void json_add_tx(struct json_stream *result,
|
||||
const char *fieldname,
|
||||
const struct bitcoin_tx *tx);
|
||||
|
||||
/* '"fieldname" : "cHNidP8BAJoCAAAAAljo..." or "cHNidP8BAJoCAAAAAljo..." if fieldname is NULL */
|
||||
void json_add_psbt(struct json_stream *stream,
|
||||
const char *fieldname,
|
||||
const struct wally_psbt *psbt);
|
||||
|
||||
/* Add fields from the lease_rates to a json stream.
|
||||
* Note that field names are set */
|
||||
void json_add_lease_rates(struct json_stream *result,
|
||||
const struct lease_rates *rates);
|
||||
#endif /* LIGHTNING_COMMON_JSON_STREAM_H */
|
||||
|
||||
369
common/param.c
369
common/param.c
@@ -1,369 +0,0 @@
|
||||
#include "config.h"
|
||||
#include <ccan/asort/asort.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
|
||||
struct param {
|
||||
const char *name;
|
||||
bool is_set;
|
||||
enum param_style style;
|
||||
param_cbx cbx;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static bool param_add(struct param **params,
|
||||
const char *name,
|
||||
enum param_style style,
|
||||
param_cbx cbx, void *arg)
|
||||
{
|
||||
#if DEVELOPER
|
||||
if (!(name && cbx && arg))
|
||||
return false;
|
||||
#endif
|
||||
struct param last;
|
||||
|
||||
last.is_set = false;
|
||||
last.name = name;
|
||||
last.style = style;
|
||||
last.cbx = cbx;
|
||||
last.arg = arg;
|
||||
|
||||
tal_arr_expand(params, last);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* FIXME: To support the deprecated p_req_dup_ok */
|
||||
static bool is_required(enum param_style style)
|
||||
{
|
||||
return style == PARAM_REQUIRED || style == PARAM_REQUIRED_ALLOW_DUPS;
|
||||
}
|
||||
|
||||
static struct command_result *make_callback(struct command *cmd,
|
||||
struct param *def,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok)
|
||||
{
|
||||
/* If it had a default, free that now to avoid leak */
|
||||
if (def->style == PARAM_OPTIONAL_WITH_DEFAULT && !def->is_set)
|
||||
tal_free(*(void **)def->arg);
|
||||
|
||||
def->is_set = true;
|
||||
|
||||
return def->cbx(cmd, def->name, buffer, tok, def->arg);
|
||||
}
|
||||
|
||||
static struct command_result *post_check(struct command *cmd,
|
||||
struct param *params)
|
||||
{
|
||||
struct param *first = params;
|
||||
struct param *last = first + tal_count(params);
|
||||
|
||||
/* Make sure required params were provided. */
|
||||
while (first != last && is_required(first->style)) {
|
||||
if (!first->is_set) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"missing required parameter: %s",
|
||||
first->name);
|
||||
}
|
||||
first++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct command_result *parse_by_position(struct command *cmd,
|
||||
struct param *params,
|
||||
const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
bool allow_extra)
|
||||
{
|
||||
struct command_result *res;
|
||||
const jsmntok_t *tok;
|
||||
size_t i;
|
||||
|
||||
json_for_each_arr(i, tok, tokens) {
|
||||
/* check for unexpected trailing params */
|
||||
if (i == tal_count(params)) {
|
||||
if (!allow_extra) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"too many parameters:"
|
||||
" got %u, expected %zu",
|
||||
tokens->size,
|
||||
tal_count(params));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!json_tok_is_null(buffer, tok)) {
|
||||
res = make_callback(cmd, params+i, buffer, tok);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return post_check(cmd, params);
|
||||
}
|
||||
|
||||
static struct param *find_param(struct param *params, const char *start,
|
||||
size_t n)
|
||||
{
|
||||
struct param *first = params;
|
||||
struct param *last = first + tal_count(params);
|
||||
|
||||
while (first != last) {
|
||||
size_t arglen = strcspn(first->name, "|");
|
||||
if (memeq(first->name, arglen, start, n))
|
||||
return first;
|
||||
if (deprecated_apis
|
||||
&& first->name[arglen]
|
||||
&& memeq(first->name + arglen + 1,
|
||||
strlen(first->name + arglen + 1),
|
||||
start, n))
|
||||
return first;
|
||||
first++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct command_result *parse_by_name(struct command *cmd,
|
||||
struct param *params,
|
||||
const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
bool allow_extra)
|
||||
{
|
||||
size_t i;
|
||||
const jsmntok_t *t;
|
||||
|
||||
json_for_each_obj(i, t, tokens) {
|
||||
struct param *p = find_param(params, buffer + t->start,
|
||||
t->end - t->start);
|
||||
if (!p) {
|
||||
if (!allow_extra) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"unknown parameter: %.*s, this may be caused by a failure to autodetect key=value-style parameters. Please try using the -k flag and explicit key=value pairs of parameters.",
|
||||
t->end - t->start,
|
||||
buffer + t->start);
|
||||
}
|
||||
} else {
|
||||
struct command_result *res;
|
||||
|
||||
if (p->is_set) {
|
||||
if (p->style == PARAM_REQUIRED_ALLOW_DUPS)
|
||||
continue;
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"duplicate json names: %s",
|
||||
p->name);
|
||||
}
|
||||
|
||||
res = make_callback(cmd, p, buffer, t + 1);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return post_check(cmd, params);
|
||||
}
|
||||
|
||||
#if DEVELOPER
|
||||
static int comp_by_name(const struct param *a, const struct param *b,
|
||||
void *unused)
|
||||
{
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
static int comp_by_arg(const struct param *a, const struct param *b,
|
||||
void *unused)
|
||||
{
|
||||
/* size_t could be larger than int: don't turn a 4bn difference into 0 */
|
||||
if (a->arg > b->arg)
|
||||
return 1;
|
||||
else if (a->arg < b->arg)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This comparator is a bit different, but works well.
|
||||
* Return 0 if @a is optional and @b is required. Otherwise return 1.
|
||||
*/
|
||||
static int comp_req_order(const struct param *a, const struct param *b,
|
||||
void *unused)
|
||||
{
|
||||
if (!is_required(a->style) && is_required(b->style))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure 2 sequential items in @params are not equal (based on
|
||||
* provided comparator).
|
||||
*/
|
||||
static bool check_distinct(struct param *params,
|
||||
int (*compar) (const struct param *a,
|
||||
const struct param *b, void *unused))
|
||||
{
|
||||
struct param *first = params;
|
||||
struct param *last = first + tal_count(params);
|
||||
first++;
|
||||
while (first != last) {
|
||||
if (compar(first - 1, first, NULL) == 0)
|
||||
return false;
|
||||
first++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check_unique(struct param *copy,
|
||||
int (*compar) (const struct param *a,
|
||||
const struct param *b, void *unused))
|
||||
{
|
||||
asort(copy, tal_count(copy), compar, NULL);
|
||||
return check_distinct(copy, compar);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify consistent internal state.
|
||||
*/
|
||||
static bool check_params(struct param *params)
|
||||
{
|
||||
if (tal_count(params) < 2)
|
||||
return true;
|
||||
|
||||
/* make sure there are no required params following optional */
|
||||
if (!check_distinct(params, comp_req_order))
|
||||
return false;
|
||||
|
||||
/* duplicate so we can sort */
|
||||
struct param *copy = tal_dup_talarr(params, struct param, params);
|
||||
|
||||
/* check for repeated names and args */
|
||||
if (!check_unique(copy, comp_by_name))
|
||||
return false;
|
||||
if (!check_unique(copy, comp_by_arg))
|
||||
return false;
|
||||
|
||||
tal_free(copy);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *param_usage(const tal_t *ctx,
|
||||
const struct param *params)
|
||||
{
|
||||
char *usage = tal_strdup(ctx, "");
|
||||
for (size_t i = 0; i < tal_count(params); i++) {
|
||||
/* Don't print |deprecated part! */
|
||||
int len = strcspn(params[i].name, "|");
|
||||
if (i != 0)
|
||||
tal_append_fmt(&usage, " ");
|
||||
if (is_required(params[i].style))
|
||||
tal_append_fmt(&usage, "%.*s", len, params[i].name);
|
||||
else
|
||||
tal_append_fmt(&usage, "[%.*s]", len, params[i].name);
|
||||
}
|
||||
return usage;
|
||||
}
|
||||
|
||||
static struct command_result *param_arr(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
struct param *params,
|
||||
bool allow_extra)
|
||||
{
|
||||
#if DEVELOPER
|
||||
if (!check_params(params)) {
|
||||
return command_fail(cmd, PARAM_DEV_ERROR,
|
||||
"developer error: check_params");
|
||||
}
|
||||
#endif
|
||||
if (tokens->type == JSMN_ARRAY)
|
||||
return parse_by_position(cmd, params, buffer, tokens, allow_extra);
|
||||
else if (tokens->type == JSMN_OBJECT)
|
||||
return parse_by_name(cmd, params, buffer, tokens, allow_extra);
|
||||
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Expected array or object for params");
|
||||
}
|
||||
|
||||
const char *param_subcommand(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
const char *name, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct param *params = tal_arr(cmd, struct param, 0);
|
||||
const char *arg, **names = tal_arr(tmpctx, const char *, 1);
|
||||
const char *subcmd;
|
||||
|
||||
param_add(¶ms, "subcommand", PARAM_REQUIRED, (void *)param_string, &subcmd);
|
||||
names[0] = name;
|
||||
va_start(ap, name);
|
||||
while ((arg = va_arg(ap, const char *)) != NULL)
|
||||
tal_arr_expand(&names, arg);
|
||||
va_end(ap);
|
||||
|
||||
if (command_usage_only(cmd)) {
|
||||
char *usage = tal_strdup(cmd, "subcommand");
|
||||
for (size_t i = 0; i < tal_count(names); i++)
|
||||
tal_append_fmt(&usage, "%c%s",
|
||||
i == 0 ? '=' : '|', names[i]);
|
||||
command_set_usage(cmd, usage);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check it's valid */
|
||||
if (param_arr(cmd, buffer, tokens, params, true) != NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check it's one of the known ones. */
|
||||
for (size_t i = 0; i < tal_count(names); i++)
|
||||
if (streq(subcmd, names[i]))
|
||||
return subcmd;
|
||||
|
||||
/* We really do ignore this. */
|
||||
struct command_result *ignore;
|
||||
ignore = command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Unknown subcommand '%s'", subcmd);
|
||||
assert(ignore);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool param(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t tokens[], ...)
|
||||
{
|
||||
struct param *params = tal_arr(tmpctx, struct param, 0);
|
||||
const char *name;
|
||||
va_list ap;
|
||||
bool allow_extra = false;
|
||||
|
||||
va_start(ap, tokens);
|
||||
while ((name = va_arg(ap, const char *)) != NULL) {
|
||||
enum param_style style = va_arg(ap, enum param_style);
|
||||
param_cbx cbx = va_arg(ap, param_cbx);
|
||||
void *arg = va_arg(ap, void *);
|
||||
if (streq(name, "")) {
|
||||
allow_extra = true;
|
||||
continue;
|
||||
}
|
||||
if (!param_add(¶ms, name, style, cbx, arg)) {
|
||||
/* We really do ignore this return! */
|
||||
struct command_result *ignore;
|
||||
ignore = command_fail(cmd, PARAM_DEV_ERROR,
|
||||
"developer error: param_add %s", name);
|
||||
assert(ignore);
|
||||
va_end(ap);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
if (command_usage_only(cmd)) {
|
||||
command_set_usage(cmd, param_usage(cmd, params));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Always return false if we're simply checking command parameters;
|
||||
* normally this returns true if all parameters are valid. */
|
||||
return param_arr(cmd, buffer, tokens, params, allow_extra) == NULL
|
||||
&& !command_check_only(cmd);
|
||||
}
|
||||
139
common/param.h
139
common/param.h
@@ -1,139 +0,0 @@
|
||||
#ifndef LIGHTNING_COMMON_PARAM_H
|
||||
#define LIGHTNING_COMMON_PARAM_H
|
||||
#include "config.h"
|
||||
#include <common/json.h>
|
||||
|
||||
/*~ Greetings adventurer!
|
||||
*
|
||||
* Do you want to automatically validate json input and unmarshal it into
|
||||
* local variables, all using typesafe callbacks? And on error,
|
||||
* call command_fail with a proper error message? Then you've come to the
|
||||
* right place!
|
||||
*
|
||||
* Here is a simple example of using the system:
|
||||
*
|
||||
* unsigned *cltv;
|
||||
* u64 *msatoshi;
|
||||
* const jsmntok_t *note;
|
||||
* u64 *expiry;
|
||||
*
|
||||
* if (!param(cmd, buffer, params,
|
||||
* p_req("cltv", json_tok_number, &cltv),
|
||||
* p_opt("amount_msat|msatoshi", json_tok_u64, &msatoshi),
|
||||
* p_opt("note", json_tok_tok, ¬e),
|
||||
* p_opt_def("expiry", json_tok_u64, &expiry, 3600),
|
||||
* NULL))
|
||||
* return;
|
||||
*
|
||||
* If param() returns true then you're good to go.
|
||||
*
|
||||
* All the command handlers throughout the code use this system.
|
||||
* json_invoice() is a great example. The common callbacks can be found in
|
||||
* common/json_tok.c. Use them directly or feel free to write your own.
|
||||
*/
|
||||
struct command;
|
||||
|
||||
/* A dummy type returned by command_ functions, to ensure you return them
|
||||
* immediately */
|
||||
struct command_result;
|
||||
|
||||
/*
|
||||
* Parse the json tokens. @params can be an array of values or an object
|
||||
* of named values.
|
||||
*/
|
||||
bool param(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t params[], ...) LAST_ARG_NULL;
|
||||
|
||||
/*
|
||||
* The callback signature.
|
||||
*
|
||||
* Callbacks must return NULL on success. On failure they
|
||||
* must return command_fail(...).
|
||||
*/
|
||||
typedef struct command_result *(*param_cbx)(struct command *cmd,
|
||||
const char *name,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
void **arg);
|
||||
|
||||
/**
|
||||
* Parse the first json value.
|
||||
*
|
||||
* name...: NULL-terminated array of valid values.
|
||||
*
|
||||
* Returns subcommand: if it returns NULL if you should return
|
||||
* command_param_failed() immediately.
|
||||
*/
|
||||
const char *param_subcommand(struct command *cmd, const char *buffer,
|
||||
const jsmntok_t tokens[],
|
||||
const char *name, ...) LAST_ARG_NULL;
|
||||
|
||||
enum param_style {
|
||||
PARAM_REQUIRED,
|
||||
PARAM_REQUIRED_ALLOW_DUPS,
|
||||
PARAM_OPTIONAL,
|
||||
PARAM_OPTIONAL_WITH_DEFAULT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Add a required parameter.
|
||||
* name can be <normal>|<deprecated> if it's been renamed.
|
||||
*/
|
||||
#define p_req(name, cbx, arg) \
|
||||
name"", \
|
||||
PARAM_REQUIRED, \
|
||||
(param_cbx)(cbx), \
|
||||
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, \
|
||||
(arg)) == (struct command_result *)NULL)
|
||||
|
||||
/*
|
||||
* Add an optional parameter. *arg is set to NULL if it isn't found.
|
||||
* name can be <normal>|<deprecated> if it's been renamed.
|
||||
*/
|
||||
#define p_opt(name, cbx, arg) \
|
||||
name"", \
|
||||
PARAM_OPTIONAL, \
|
||||
(param_cbx)(cbx), \
|
||||
({ *arg = NULL; \
|
||||
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, \
|
||||
(arg)) == (struct command_result *)NULL); })
|
||||
|
||||
/*
|
||||
* Add an required parameter, like p_req, but ignore duplicates.
|
||||
*/
|
||||
#define p_req_dup_ok(name, cbx, arg) \
|
||||
name"", \
|
||||
PARAM_REQUIRED_ALLOW_DUPS, \
|
||||
(param_cbx)(cbx), \
|
||||
({ *arg = NULL; \
|
||||
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, \
|
||||
(arg)) == (struct command_result *)NULL); })
|
||||
|
||||
/*
|
||||
* Add an optional parameter. *arg is set to @def if it isn't found.
|
||||
* name can be <normal>|<deprecated> if it's been renamed.
|
||||
*/
|
||||
#define p_opt_def(name, cbx, arg, def) \
|
||||
name"", \
|
||||
PARAM_OPTIONAL_WITH_DEFAULT, \
|
||||
(param_cbx)(cbx), \
|
||||
({ (*arg) = tal((cmd), typeof(**arg)); \
|
||||
(**arg) = (def); \
|
||||
(arg) + 0*sizeof((cbx)((struct command *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const char *)NULL, \
|
||||
(const jsmntok_t *)NULL, \
|
||||
(arg)) == (struct command_result *)NULL); })
|
||||
|
||||
/* Special flag for 'check' which allows any parameters. */
|
||||
#define p_opt_any() "", PARAM_OPTIONAL, NULL, NULL
|
||||
#endif /* LIGHTNING_COMMON_PARAM_H */
|
||||
@@ -21,8 +21,8 @@ ALL_TEST_PROGRAMS += $(COMMON_TEST_PROGRAMS)
|
||||
# Sphinx test wants to decode TLVs.
|
||||
common/test/run-sphinx: wire/onion$(EXP)_wiregen.o wire/towire.o wire/fromwire.o
|
||||
common/test/run-blindedpath_enctlv common/test/run-blindedpath_onion: common/base32.o common/wireaddr.o wire/onion$(EXP)_wiregen.o wire/peer$(EXP)_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o
|
||||
common/test/run-route_blinding_test: wire/onion$(EXP)_wiregen.o wire/peer$(EXP)_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o common/json.o common/json_helpers.o common/coin_mvt.o
|
||||
common/test/run-route_blinding_override_test: common/base32.o common/wireaddr.o wire/onion$(EXP)_wiregen.o wire/peer$(EXP)_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o common/json.o common/json_helpers.o common/coin_mvt.o
|
||||
common/test/run-route_blinding_test: wire/onion$(EXP)_wiregen.o wire/peer$(EXP)_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o common/coin_mvt.o
|
||||
common/test/run-route_blinding_override_test: common/base32.o common/wireaddr.o wire/onion$(EXP)_wiregen.o wire/peer$(EXP)_wiregen.o wire/towire.o wire/fromwire.o wire/tlvstream.o common/coin_mvt.o
|
||||
|
||||
common/test/run-param \
|
||||
common/test/run-json: \
|
||||
@@ -31,7 +31,6 @@ common/test/run-json: \
|
||||
common/bigsize.o \
|
||||
common/channel_id.o \
|
||||
common/coin_mvt.o \
|
||||
common/json.o \
|
||||
common/json_stream.o \
|
||||
common/lease_rates.o \
|
||||
common/node_id.o \
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <common/amount.h>
|
||||
#include <common/json.c>
|
||||
#include <common/json_parse.c>
|
||||
#include <common/json_parse_simple.c>
|
||||
#include <common/setup.h>
|
||||
|
||||
static const char *reason;
|
||||
@@ -74,16 +75,18 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
/* Generated stub for fromwire_u8_array */
|
||||
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for mvt_tag_str */
|
||||
const char *mvt_tag_str(enum mvt_tag tag UNNEEDED)
|
||||
{ fprintf(stderr, "mvt_tag_str called!\n"); abort(); }
|
||||
/* Generated stub for node_id_from_hexstr */
|
||||
bool node_id_from_hexstr(const char *str UNNEEDED, size_t slen UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "node_id_from_hexstr called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_msat */
|
||||
bool parse_amount_msat(struct amount_msat *msat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_sat */
|
||||
bool parse_amount_sat(struct amount_sat *sat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_sat called!\n"); abort(); }
|
||||
/* Generated stub for towire */
|
||||
void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
|
||||
{ fprintf(stderr, "towire called!\n"); abort(); }
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
#include "../bolt12.c"
|
||||
#include "../bech32_util.c"
|
||||
#include "../bech32.c"
|
||||
#include "../json.c"
|
||||
#include "../json_parse.c"
|
||||
#include "../json_parse_simple.c"
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/tal/path/path.h>
|
||||
@@ -89,19 +90,21 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
/* Generated stub for fromwire_u8_array */
|
||||
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for merkle_tlv */
|
||||
void merkle_tlv(const struct tlv_field *fields UNNEEDED, struct sha256 *merkle UNNEEDED)
|
||||
{ fprintf(stderr, "merkle_tlv called!\n"); abort(); }
|
||||
/* Generated stub for mvt_tag_str */
|
||||
const char *mvt_tag_str(enum mvt_tag tag UNNEEDED)
|
||||
{ fprintf(stderr, "mvt_tag_str called!\n"); abort(); }
|
||||
/* Generated stub for node_id_from_hexstr */
|
||||
bool node_id_from_hexstr(const char *str UNNEEDED, size_t slen UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "node_id_from_hexstr called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_msat */
|
||||
bool parse_amount_msat(struct amount_msat *msat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_sat */
|
||||
bool parse_amount_sat(struct amount_sat *sat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_sat called!\n"); abort(); }
|
||||
/* Generated stub for sighash_from_merkle */
|
||||
void sighash_from_merkle(const char *messagename UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "../amount.c"
|
||||
#include "../bigsize.c"
|
||||
#include "../bolt12_merkle.c"
|
||||
#include "../json.c"
|
||||
#include "../json_parse.c"
|
||||
#include "../../wire/fromwire.c"
|
||||
#include "../../wire/tlvstream.c"
|
||||
#if EXPERIMENTAL_FEATURES
|
||||
@@ -28,16 +28,47 @@ void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct n
|
||||
/* Generated stub for fromwire_onionmsg_path */
|
||||
struct onionmsg_path *fromwire_onionmsg_path(const tal_t *ctx UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_onionmsg_path called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_get_arr */
|
||||
const jsmntok_t *json_get_arr(const jsmntok_t tok[] UNNEEDED, size_t index UNNEEDED)
|
||||
{ fprintf(stderr, "json_get_arr called!\n"); abort(); }
|
||||
/* Generated stub for json_get_member */
|
||||
const jsmntok_t *json_get_member(const char *buffer UNNEEDED, const jsmntok_t tok[] UNNEEDED,
|
||||
const char *label UNNEEDED)
|
||||
{ fprintf(stderr, "json_get_member called!\n"); abort(); }
|
||||
/* Generated stub for json_get_membern */
|
||||
const jsmntok_t *json_get_membern(const char *buffer UNNEEDED,
|
||||
const jsmntok_t tok[] UNNEEDED,
|
||||
const char *label UNNEEDED, size_t len UNNEEDED)
|
||||
{ fprintf(stderr, "json_get_membern called!\n"); abort(); }
|
||||
/* Generated stub for json_next */
|
||||
const jsmntok_t *json_next(const jsmntok_t *tok UNNEEDED)
|
||||
{ fprintf(stderr, "json_next called!\n"); abort(); }
|
||||
/* Generated stub for json_strdup */
|
||||
char *json_strdup(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
|
||||
{ fprintf(stderr, "json_strdup called!\n"); abort(); }
|
||||
/* Generated stub for json_to_u32 */
|
||||
bool json_to_u32(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
uint32_t *num UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_u32 called!\n"); abort(); }
|
||||
/* Generated stub for json_to_u64 */
|
||||
bool json_to_u64(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
uint64_t *num UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_u64 called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_full */
|
||||
const char *json_tok_full(const char *buffer UNNEEDED, const jsmntok_t *t UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_full called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_full_len */
|
||||
int json_tok_full_len(const jsmntok_t *t UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_full_len called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_streq */
|
||||
bool json_tok_streq(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, const char *str UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_streq called!\n"); abort(); }
|
||||
/* Generated stub for mvt_tag_str */
|
||||
const char *mvt_tag_str(enum mvt_tag tag UNNEEDED)
|
||||
{ fprintf(stderr, "mvt_tag_str called!\n"); abort(); }
|
||||
/* Generated stub for node_id_from_hexstr */
|
||||
bool node_id_from_hexstr(const char *str UNNEEDED, size_t slen UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "node_id_from_hexstr called!\n"); abort(); }
|
||||
/* Generated stub for towire */
|
||||
void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
|
||||
{ fprintf(stderr, "towire called!\n"); abort(); }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "config.h"
|
||||
#include "../bolt12.c"
|
||||
#include "../json.c"
|
||||
#include "../json_parse.c"
|
||||
#include "../json_parse_simple.c"
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/tal/path/path.h>
|
||||
@@ -92,19 +93,21 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
/* Generated stub for fromwire_u8_array */
|
||||
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for merkle_tlv */
|
||||
void merkle_tlv(const struct tlv_field *fields UNNEEDED, struct sha256 *merkle UNNEEDED)
|
||||
{ fprintf(stderr, "merkle_tlv called!\n"); abort(); }
|
||||
/* Generated stub for mvt_tag_str */
|
||||
const char *mvt_tag_str(enum mvt_tag tag UNNEEDED)
|
||||
{ fprintf(stderr, "mvt_tag_str called!\n"); abort(); }
|
||||
/* Generated stub for node_id_from_hexstr */
|
||||
bool node_id_from_hexstr(const char *str UNNEEDED, size_t slen UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "node_id_from_hexstr called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_msat */
|
||||
bool parse_amount_msat(struct amount_msat *msat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_sat */
|
||||
bool parse_amount_sat(struct amount_sat *sat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_sat called!\n"); abort(); }
|
||||
/* Generated stub for sighash_from_merkle */
|
||||
void sighash_from_merkle(const char *messagename UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "config.h"
|
||||
#include "../json_helpers.c"
|
||||
#include "../json_parse.c"
|
||||
#include "../json_parse_simple.c"
|
||||
#include <assert.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/channel_type.h>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "config.h"
|
||||
#include <common/amount.h>
|
||||
#include <common/json.c>
|
||||
#include <common/json_param.c>
|
||||
#include <common/json_parse_simple.c>
|
||||
#include <common/setup.h>
|
||||
#include <stdio.h>
|
||||
#include <wire/wire.h>
|
||||
|
||||
/* AUTOGENERATED MOCKS START */
|
||||
@@ -36,6 +38,22 @@ struct amount_asset amount_sat_to_asset(struct amount_sat *sat UNNEEDED, const u
|
||||
/* Generated stub for amount_tx_fee */
|
||||
struct amount_sat amount_tx_fee(u32 fee_per_kw UNNEEDED, size_t weight UNNEEDED)
|
||||
{ fprintf(stderr, "amount_tx_fee called!\n"); abort(); }
|
||||
/* Generated stub for command_check_only */
|
||||
bool command_check_only(const struct command *cmd UNNEEDED)
|
||||
{ fprintf(stderr, "command_check_only called!\n"); abort(); }
|
||||
/* Generated stub for command_fail */
|
||||
struct command_result *command_fail(struct command *cmd UNNEEDED, errcode_t code UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
|
||||
{ fprintf(stderr, "command_fail called!\n"); abort(); }
|
||||
/* Generated stub for command_set_usage */
|
||||
void command_set_usage(struct command *cmd UNNEEDED, const char *usage UNNEEDED)
|
||||
{ fprintf(stderr, "command_set_usage called!\n"); abort(); }
|
||||
/* Generated stub for command_usage_only */
|
||||
bool command_usage_only(const struct command *cmd UNNEEDED)
|
||||
{ fprintf(stderr, "command_usage_only called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for fromwire */
|
||||
const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire called!\n"); abort(); }
|
||||
@@ -68,16 +86,75 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
/* Generated stub for fromwire_u8_array */
|
||||
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_scan */
|
||||
const char *json_scan(const tal_t *ctx UNNEEDED,
|
||||
const char *buffer UNNEEDED,
|
||||
const jsmntok_t *tok UNNEEDED,
|
||||
const char *guide UNNEEDED,
|
||||
...)
|
||||
{ fprintf(stderr, "json_scan called!\n"); abort(); }
|
||||
/* Generated stub for json_to_channel_id */
|
||||
bool json_to_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct channel_id *cid UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_to_millionths */
|
||||
bool json_to_millionths(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
u64 *millionths UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_millionths called!\n"); abort(); }
|
||||
/* Generated stub for json_to_msat */
|
||||
bool json_to_msat(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct amount_msat *msat UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_msat called!\n"); abort(); }
|
||||
/* Generated stub for json_to_node_id */
|
||||
bool json_to_node_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_to_number */
|
||||
bool json_to_number(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
unsigned int *num UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_number called!\n"); abort(); }
|
||||
/* Generated stub for json_to_outpoint */
|
||||
bool json_to_outpoint(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct bitcoin_outpoint *op UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_outpoint called!\n"); abort(); }
|
||||
/* Generated stub for json_to_pubkey */
|
||||
bool json_to_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct pubkey *pubkey UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_pubkey called!\n"); abort(); }
|
||||
/* Generated stub for json_to_short_channel_id */
|
||||
bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct short_channel_id *scid UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_to_txid */
|
||||
bool json_to_txid(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct bitcoin_txid *txid UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_txid called!\n"); abort(); }
|
||||
/* Generated stub for json_to_u16 */
|
||||
bool json_to_u16(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
uint16_t *num UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_u16 called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_bin_from_hex */
|
||||
u8 *json_tok_bin_from_hex(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_bin_from_hex called!\n"); abort(); }
|
||||
/* Generated stub for lease_rates_fromhex */
|
||||
struct lease_rates *lease_rates_fromhex(const tal_t *ctx UNNEEDED,
|
||||
const char *hexdata UNNEEDED, size_t len UNNEEDED)
|
||||
{ fprintf(stderr, "lease_rates_fromhex called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_msat */
|
||||
bool parse_amount_msat(struct amount_msat *msat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_sat */
|
||||
bool parse_amount_sat(struct amount_sat *sat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_sat called!\n"); abort(); }
|
||||
/* Generated stub for segwit_addr_decode */
|
||||
int segwit_addr_decode(
|
||||
int* ver UNNEEDED,
|
||||
uint8_t* prog UNNEEDED,
|
||||
size_t* prog_len UNNEEDED,
|
||||
const char* hrp UNNEEDED,
|
||||
const char* addr
|
||||
)
|
||||
{ fprintf(stderr, "segwit_addr_decode called!\n"); abort(); }
|
||||
/* Generated stub for towire */
|
||||
void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
|
||||
{ fprintf(stderr, "towire called!\n"); abort(); }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "config.h"
|
||||
#include "../json.c"
|
||||
#include "../json_parse.c"
|
||||
#include "../json_parse_simple.c"
|
||||
#include <common/amount.h>
|
||||
#include <common/setup.h>
|
||||
#include <wire/wire.h>
|
||||
@@ -68,16 +69,18 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
/* Generated stub for fromwire_u8_array */
|
||||
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for mvt_tag_str */
|
||||
const char *mvt_tag_str(enum mvt_tag tag UNNEEDED)
|
||||
{ fprintf(stderr, "mvt_tag_str called!\n"); abort(); }
|
||||
/* Generated stub for node_id_from_hexstr */
|
||||
bool node_id_from_hexstr(const char *str UNNEEDED, size_t slen UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "node_id_from_hexstr called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_msat */
|
||||
bool parse_amount_msat(struct amount_msat *msat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_sat */
|
||||
bool parse_amount_sat(struct amount_sat *sat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_sat called!\n"); abort(); }
|
||||
/* Generated stub for towire */
|
||||
void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
|
||||
{ fprintf(stderr, "towire called!\n"); abort(); }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "config.h"
|
||||
#include "../json_tok.c"
|
||||
#include "../param.c"
|
||||
#include "../json_parse.c"
|
||||
#include "../json_parse_simple.c"
|
||||
#include "../json_param.c"
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <common/channel_type.h>
|
||||
#include <common/setup.h>
|
||||
@@ -42,34 +43,6 @@ bool fromwire_tlv(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
void *record UNNEEDED, struct tlv_field **fields UNNEEDED,
|
||||
const u64 *extra_types UNNEEDED, size_t *err_off UNNEEDED, u64 *err_type UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_tlv called!\n"); abort(); }
|
||||
/* Generated stub for json_to_channel_id */
|
||||
bool json_to_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct channel_id *cid UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_to_msat */
|
||||
bool json_to_msat(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct amount_msat *msat UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_msat called!\n"); abort(); }
|
||||
/* Generated stub for json_to_node_id */
|
||||
bool json_to_node_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_to_outpoint */
|
||||
bool json_to_outpoint(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct bitcoin_outpoint *op UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_outpoint called!\n"); abort(); }
|
||||
/* Generated stub for json_to_pubkey */
|
||||
bool json_to_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct pubkey *pubkey UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_pubkey called!\n"); abort(); }
|
||||
/* Generated stub for json_to_short_channel_id */
|
||||
bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct short_channel_id *scid UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_to_txid */
|
||||
bool json_to_txid(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct bitcoin_txid *txid UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_txid called!\n"); abort(); }
|
||||
/* Generated stub for segwit_addr_decode */
|
||||
int segwit_addr_decode(
|
||||
int* ver UNNEEDED,
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/tal/path/path.h>
|
||||
#include <common/channel_id.h>
|
||||
#include <common/json.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/setup.h>
|
||||
#include <common/wireaddr.h>
|
||||
@@ -21,9 +20,6 @@ bool amount_asset_is_main(struct amount_asset *asset UNNEEDED)
|
||||
/* Generated stub for amount_asset_to_sat */
|
||||
struct amount_sat amount_asset_to_sat(struct amount_asset *asset UNNEEDED)
|
||||
{ fprintf(stderr, "amount_asset_to_sat called!\n"); abort(); }
|
||||
/* Generated stub for amount_msat */
|
||||
struct amount_msat amount_msat(u64 millisatoshis UNNEEDED)
|
||||
{ fprintf(stderr, "amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for amount_sat */
|
||||
struct amount_sat amount_sat(u64 satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "amount_sat called!\n"); abort(); }
|
||||
@@ -53,14 +49,6 @@ struct amount_asset amount_sat_to_asset(struct amount_sat *sat UNNEEDED, const u
|
||||
/* Generated stub for amount_tx_fee */
|
||||
struct amount_sat amount_tx_fee(u32 fee_per_kw UNNEEDED, size_t weight UNNEEDED)
|
||||
{ fprintf(stderr, "amount_tx_fee called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for fmt_amount_msat */
|
||||
const char *fmt_amount_msat(const tal_t *ctx UNNEEDED, struct amount_msat msat UNNEEDED)
|
||||
{ fprintf(stderr, "fmt_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for fmt_amount_sat */
|
||||
const char *fmt_amount_sat(const tal_t *ctx UNNEEDED, struct amount_sat sat UNNEEDED)
|
||||
{ fprintf(stderr, "fmt_amount_sat called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_amount_msat */
|
||||
struct amount_msat fromwire_amount_msat(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_amount_msat called!\n"); abort(); }
|
||||
@@ -74,31 +62,34 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
/* Generated stub for fromwire_node_id */
|
||||
void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
/* Generated stub for json_object_start */
|
||||
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
|
||||
/* Generated stub for node_id_from_hexstr */
|
||||
bool node_id_from_hexstr(const char *str UNNEEDED, size_t slen UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "node_id_from_hexstr called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_msat */
|
||||
bool parse_amount_msat(struct amount_msat *msat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_sat */
|
||||
bool parse_amount_sat(struct amount_sat *sat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_sat called!\n"); abort(); }
|
||||
/* Generated stub for json_get_member */
|
||||
const jsmntok_t *json_get_member(const char *buffer UNNEEDED, const jsmntok_t tok[] UNNEEDED,
|
||||
const char *label UNNEEDED)
|
||||
{ fprintf(stderr, "json_get_member called!\n"); abort(); }
|
||||
/* Generated stub for json_next */
|
||||
const jsmntok_t *json_next(const jsmntok_t *tok UNNEEDED)
|
||||
{ fprintf(stderr, "json_next called!\n"); abort(); }
|
||||
/* Generated stub for json_to_pubkey */
|
||||
bool json_to_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct pubkey *pubkey UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_pubkey called!\n"); abort(); }
|
||||
/* Generated stub for json_to_secret */
|
||||
bool json_to_secret(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, struct secret *dest UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_secret called!\n"); abort(); }
|
||||
/* Generated stub for json_to_short_channel_id */
|
||||
bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct short_channel_id *scid UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_bin_from_hex */
|
||||
u8 *json_tok_bin_from_hex(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_bin_from_hex called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_startswith */
|
||||
bool json_tok_startswith(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
const char *prefix UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_startswith called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_streq */
|
||||
bool json_tok_streq(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, const char *str UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_streq called!\n"); abort(); }
|
||||
/* Generated stub for towire_amount_msat */
|
||||
void towire_amount_msat(u8 **pptr UNNEEDED, const struct amount_msat msat UNNEEDED)
|
||||
{ fprintf(stderr, "towire_amount_msat called!\n"); abort(); }
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/tal/path/path.h>
|
||||
#include <common/channel_id.h>
|
||||
#include <common/json.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/setup.h>
|
||||
#include <common/wireaddr.h>
|
||||
@@ -21,9 +20,6 @@ bool amount_asset_is_main(struct amount_asset *asset UNNEEDED)
|
||||
/* Generated stub for amount_asset_to_sat */
|
||||
struct amount_sat amount_asset_to_sat(struct amount_asset *asset UNNEEDED)
|
||||
{ fprintf(stderr, "amount_asset_to_sat called!\n"); abort(); }
|
||||
/* Generated stub for amount_msat */
|
||||
struct amount_msat amount_msat(u64 millisatoshis UNNEEDED)
|
||||
{ fprintf(stderr, "amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for amount_sat */
|
||||
struct amount_sat amount_sat(u64 satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "amount_sat called!\n"); abort(); }
|
||||
@@ -53,17 +49,6 @@ struct amount_asset amount_sat_to_asset(struct amount_sat *sat UNNEEDED, const u
|
||||
/* Generated stub for amount_tx_fee */
|
||||
struct amount_sat amount_tx_fee(u32 fee_per_kw UNNEEDED, size_t weight UNNEEDED)
|
||||
{ fprintf(stderr, "amount_tx_fee called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for fmt_amount_msat */
|
||||
const char *fmt_amount_msat(const tal_t *ctx UNNEEDED, struct amount_msat msat UNNEEDED)
|
||||
{ fprintf(stderr, "fmt_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for fmt_amount_sat */
|
||||
const char *fmt_amount_sat(const tal_t *ctx UNNEEDED, struct amount_sat sat UNNEEDED)
|
||||
{ fprintf(stderr, "fmt_amount_sat called!\n"); abort(); }
|
||||
/* Generated stub for fmt_wireaddr_without_port */
|
||||
char *fmt_wireaddr_without_port(const tal_t *ctx UNNEEDED, const struct wireaddr *a UNNEEDED)
|
||||
{ fprintf(stderr, "fmt_wireaddr_without_port called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_amount_msat */
|
||||
struct amount_msat fromwire_amount_msat(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_amount_msat called!\n"); abort(); }
|
||||
@@ -77,31 +62,34 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
/* Generated stub for fromwire_node_id */
|
||||
void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
/* Generated stub for json_object_start */
|
||||
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
|
||||
/* Generated stub for node_id_from_hexstr */
|
||||
bool node_id_from_hexstr(const char *str UNNEEDED, size_t slen UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "node_id_from_hexstr called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_msat */
|
||||
bool parse_amount_msat(struct amount_msat *msat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_msat called!\n"); abort(); }
|
||||
/* Generated stub for parse_amount_sat */
|
||||
bool parse_amount_sat(struct amount_sat *sat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
|
||||
{ fprintf(stderr, "parse_amount_sat called!\n"); abort(); }
|
||||
/* Generated stub for json_get_member */
|
||||
const jsmntok_t *json_get_member(const char *buffer UNNEEDED, const jsmntok_t tok[] UNNEEDED,
|
||||
const char *label UNNEEDED)
|
||||
{ fprintf(stderr, "json_get_member called!\n"); abort(); }
|
||||
/* Generated stub for json_next */
|
||||
const jsmntok_t *json_next(const jsmntok_t *tok UNNEEDED)
|
||||
{ fprintf(stderr, "json_next called!\n"); abort(); }
|
||||
/* Generated stub for json_to_pubkey */
|
||||
bool json_to_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct pubkey *pubkey UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_pubkey called!\n"); abort(); }
|
||||
/* Generated stub for json_to_secret */
|
||||
bool json_to_secret(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, struct secret *dest UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_secret called!\n"); abort(); }
|
||||
/* Generated stub for json_to_short_channel_id */
|
||||
bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct short_channel_id *scid UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_bin_from_hex */
|
||||
u8 *json_tok_bin_from_hex(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_bin_from_hex called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_startswith */
|
||||
bool json_tok_startswith(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
const char *prefix UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_startswith called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_streq */
|
||||
bool json_tok_streq(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, const char *str UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_streq called!\n"); abort(); }
|
||||
/* Generated stub for towire_amount_msat */
|
||||
void towire_amount_msat(u8 **pptr UNNEEDED, const struct amount_msat msat UNNEEDED)
|
||||
{ fprintf(stderr, "towire_amount_msat called!\n"); abort(); }
|
||||
|
||||
@@ -29,14 +29,13 @@ DEVTOOLS_COMMON_OBJS := \
|
||||
common/hash_u5.o \
|
||||
common/hmac.o \
|
||||
common/htlc_state.o \
|
||||
common/json_parse.o \
|
||||
common/json_parse_simple.o \
|
||||
common/memleak.o \
|
||||
common/node_id.o \
|
||||
common/per_peer_state.o \
|
||||
common/psbt_open.o \
|
||||
common/pseudorand.o \
|
||||
common/json.o \
|
||||
common/json_helpers.o \
|
||||
common/json_stream.o \
|
||||
common/setup.o \
|
||||
common/type_to_string.o \
|
||||
common/utils.o \
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/ecdh.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/onion.h>
|
||||
#include <common/sphinx.h>
|
||||
#include <common/version.h>
|
||||
|
||||
@@ -17,8 +17,6 @@ GOSSIPD_TEST_COMMON_OBJS := \
|
||||
common/features.o \
|
||||
common/hmac.o \
|
||||
common/node_id.o \
|
||||
common/json.o \
|
||||
common/json_helpers.o \
|
||||
common/lease_rates.o \
|
||||
common/onion.o \
|
||||
common/pseudorand.o \
|
||||
@@ -46,6 +44,10 @@ gossipd/test/run-onion_message: \
|
||||
common/onion.o \
|
||||
common/sphinx.o \
|
||||
|
||||
# JSON needed for this test
|
||||
gossipd/test/run-extended-info: \
|
||||
common/json_parse.o \
|
||||
common/json_parse_simple.o
|
||||
|
||||
$(GOSSIPD_TEST_PROGRAMS): $(GOSSIPD_TEST_COMMON_OBJS) $(BITCOIN_OBJS)
|
||||
|
||||
|
||||
@@ -59,8 +59,6 @@ bool cupdate_different(struct gossip_store *gs UNNEEDED,
|
||||
const struct half_chan *hc UNNEEDED,
|
||||
const u8 *cupdate UNNEEDED)
|
||||
{ fprintf(stderr, "cupdate_different called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for ecdh */
|
||||
void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
|
||||
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
||||
@@ -94,22 +92,6 @@ void gossip_store_mark_channel_deleted(struct gossip_store *gs UNNEEDED,
|
||||
struct gossip_store *gossip_store_new(struct routing_state *rstate UNNEEDED,
|
||||
struct list_head *peers UNNEEDED)
|
||||
{ fprintf(stderr, "gossip_store_new called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
/* Generated stub for json_object_start */
|
||||
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
|
||||
/* Generated stub for memleak_add_helper_ */
|
||||
void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED,
|
||||
const tal_t *)){ }
|
||||
|
||||
@@ -27,8 +27,6 @@ bool blinding_next_pubkey(const struct pubkey *pk UNNEEDED,
|
||||
/* Generated stub for daemon_conn_send */
|
||||
void daemon_conn_send(struct daemon_conn *dc UNNEEDED, const u8 *msg UNNEEDED)
|
||||
{ fprintf(stderr, "daemon_conn_send called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for ecdh */
|
||||
void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
|
||||
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
||||
@@ -64,22 +62,6 @@ u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *updat
|
||||
u8 *handle_node_announcement(struct routing_state *rstate UNNEEDED, const u8 *node UNNEEDED,
|
||||
struct peer *peer UNNEEDED, bool *was_unknown UNNEEDED)
|
||||
{ fprintf(stderr, "handle_node_announcement called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
/* Generated stub for json_object_start */
|
||||
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
|
||||
/* Generated stub for master_badmsg */
|
||||
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
|
||||
{ fprintf(stderr, "master_badmsg called!\n"); abort(); }
|
||||
|
||||
@@ -45,8 +45,6 @@ bigsize_t *decode_scid_query_flags(const tal_t *ctx UNNEEDED,
|
||||
/* Generated stub for decode_short_ids */
|
||||
struct short_channel_id *decode_short_ids(const tal_t *ctx UNNEEDED, const u8 *encoded UNNEEDED)
|
||||
{ fprintf(stderr, "decode_short_ids called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for ecdh */
|
||||
void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
|
||||
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
||||
@@ -90,22 +88,6 @@ u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *updat
|
||||
u8 *handle_node_announcement(struct routing_state *rstate UNNEEDED, const u8 *node UNNEEDED,
|
||||
struct peer *peer UNNEEDED, bool *was_unknown UNNEEDED)
|
||||
{ fprintf(stderr, "handle_node_announcement called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
/* Generated stub for json_object_start */
|
||||
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
|
||||
/* Generated stub for master_badmsg */
|
||||
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
|
||||
{ fprintf(stderr, "master_badmsg called!\n"); abort(); }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <common/blinding.h>
|
||||
#include <common/channel_type.h>
|
||||
#include <common/ecdh.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/onionreply.h>
|
||||
#include <common/setup.h>
|
||||
@@ -45,8 +45,6 @@ bigsize_t *decode_scid_query_flags(const tal_t *ctx UNNEEDED,
|
||||
/* Generated stub for decode_short_ids */
|
||||
struct short_channel_id *decode_short_ids(const tal_t *ctx UNNEEDED, const u8 *encoded UNNEEDED)
|
||||
{ fprintf(stderr, "decode_short_ids called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for ecdh */
|
||||
void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
|
||||
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
||||
@@ -67,22 +65,6 @@ const u8 *gossip_store_get(const tal_t *ctx UNNEEDED,
|
||||
struct gossip_store *gs UNNEEDED,
|
||||
u64 offset UNNEEDED)
|
||||
{ fprintf(stderr, "gossip_store_get called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
/* Generated stub for json_object_start */
|
||||
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
|
||||
/* Generated stub for master_badmsg */
|
||||
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
|
||||
{ fprintf(stderr, "master_badmsg called!\n"); abort(); }
|
||||
|
||||
@@ -26,27 +26,9 @@ bool blinding_next_pubkey(const struct pubkey *pk UNNEEDED,
|
||||
const struct sha256 *h UNNEEDED,
|
||||
struct pubkey *next UNNEEDED)
|
||||
{ fprintf(stderr, "blinding_next_pubkey called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for ecdh */
|
||||
void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
|
||||
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
/* Generated stub for json_object_start */
|
||||
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
|
||||
/* Generated stub for new_onionreply */
|
||||
struct onionreply *new_onionreply(const tal_t *ctx UNNEEDED, const u8 *contents TAKES UNNEEDED)
|
||||
{ fprintf(stderr, "new_onionreply called!\n"); abort(); }
|
||||
|
||||
@@ -30,8 +30,6 @@ bool cupdate_different(struct gossip_store *gs UNNEEDED,
|
||||
const struct half_chan *hc UNNEEDED,
|
||||
const u8 *cupdate UNNEEDED)
|
||||
{ fprintf(stderr, "cupdate_different called!\n"); abort(); }
|
||||
/* Generated stub for deprecated_apis */
|
||||
bool deprecated_apis;
|
||||
/* Generated stub for ecdh */
|
||||
void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
|
||||
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
||||
@@ -61,22 +59,6 @@ const u8 *gossip_store_get_private_update(const tal_t *ctx UNNEEDED,
|
||||
void gossip_store_mark_channel_deleted(struct gossip_store *gs UNNEEDED,
|
||||
const struct short_channel_id *scid UNNEEDED)
|
||||
{ fprintf(stderr, "gossip_store_mark_channel_deleted called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
/* Generated stub for json_object_start */
|
||||
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
|
||||
/* Generated stub for memleak_add_helper_ */
|
||||
void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED,
|
||||
const tal_t *)){ }
|
||||
|
||||
@@ -101,17 +101,16 @@ LIGHTNINGD_COMMON_OBJS := \
|
||||
common/htlc_wire.o \
|
||||
common/key_derive.o \
|
||||
common/keyset.o \
|
||||
common/json.o \
|
||||
common/json_helpers.o \
|
||||
common/json_param.o \
|
||||
common/json_parse.o \
|
||||
common/json_parse_simple.o \
|
||||
common/json_stream.o \
|
||||
common/json_tok.o \
|
||||
common/lease_rates.o \
|
||||
common/memleak.o \
|
||||
common/msg_queue.o \
|
||||
common/node_id.o \
|
||||
common/onion.o \
|
||||
common/onionreply.o \
|
||||
common/param.o \
|
||||
common/penalty_base.o \
|
||||
common/per_peer_state.o \
|
||||
common/permute_tx.o \
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/io/io.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/memleak.h>
|
||||
#include <db/exec.h>
|
||||
#include <lightningd/bitcoind.h>
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/htlc_tx.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/param.h>
|
||||
#include <common/timeout.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <db/exec.h>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <common/closing_fee.h>
|
||||
#include <common/fee_states.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <common/wire_error.h>
|
||||
#include <connectd/connectd_wiregen.h>
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
#include <ccan/cast/cast.h>
|
||||
#include <channeld/channeld_wiregen.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/param.h>
|
||||
#include <common/shutdown_scriptpubkey.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <common/wire_error.h>
|
||||
|
||||
@@ -12,9 +12,7 @@
|
||||
#include <common/fee_states.h>
|
||||
#include <common/initial_commit_tx.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/shutdown_scriptpubkey.h>
|
||||
#include <common/timeout.h>
|
||||
#include <common/type_to_string.h>
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/param.h>
|
||||
#include <common/timeout.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <connectd/connectd_wiregen.h>
|
||||
@@ -17,7 +15,6 @@
|
||||
#include <lightningd/connect_control.h>
|
||||
#include <lightningd/dual_open_control.h>
|
||||
#include <lightningd/hsm_control.h>
|
||||
#include <lightningd/jsonrpc.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <lightningd/onion_message.h>
|
||||
#include <lightningd/opening_common.h>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "config.h"
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <lightningd/jsonrpc.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/blockheight_states.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/psbt_open.h>
|
||||
#include <common/shutdown_scriptpubkey.h>
|
||||
#include <common/type_to_string.h>
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
#include <ccan/ptrint/ptrint.h>
|
||||
#include <channeld/channeld_wiregen.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <gossipd/gossipd_wiregen.h>
|
||||
#include <hsmd/capabilities.h>
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
#include <common/errcode.h>
|
||||
#include <common/hsm_encryption.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/jsonrpc_errors.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <errno.h>
|
||||
#include <hsmd/hsmd_wiregen.h>
|
||||
|
||||
@@ -9,11 +9,9 @@
|
||||
#include <common/bolt12_merkle.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/onion.h>
|
||||
#include <common/overflows.h>
|
||||
#include <common/param.h>
|
||||
#include <common/random_select.h>
|
||||
#include <common/timeout.h>
|
||||
#include <common/type_to_string.h>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "config.h"
|
||||
#include <bitcoin/pubkey.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <lightningd/chaintopology.h>
|
||||
#include <lightningd/json.h>
|
||||
|
||||
|
||||
@@ -22,10 +22,8 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/param.h>
|
||||
#include <common/timeout.h>
|
||||
#include <db/exec.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "config.h"
|
||||
#include <ccan/list/list.h>
|
||||
#include <common/autodata.h>
|
||||
#include <common/json.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/status_levels.h>
|
||||
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
#include <ccan/tal/link/link.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/param.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <lightningd/log.h>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#include <backtrace.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/param.h>
|
||||
#include <common/timeout.h>
|
||||
#include <connectd/connectd_wiregen.h>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "config.h"
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <lightningd/channel.h>
|
||||
#include <lightningd/coin_mvts.h>
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
#include <common/bolt12_merkle.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <errno.h>
|
||||
#include <hsmd/hsmd_wiregen.h>
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <common/blindedpath.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <connectd/connectd_wiregen.h>
|
||||
#include <lightningd/channel.h>
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
#include <common/configdir.h>
|
||||
#include <common/fee_states.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/param.h>
|
||||
#include <common/scb_wiregen.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <connectd/connectd_wiregen.h>
|
||||
|
||||
@@ -12,9 +12,7 @@
|
||||
#include <common/features.h>
|
||||
#include <common/hsm_encryption.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <common/version.h>
|
||||
#include <common/wireaddr.h>
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
#include <common/bolt12_merkle.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/onion.h>
|
||||
#include <common/onionreply.h>
|
||||
#include <common/param.h>
|
||||
#include <common/route.h>
|
||||
#include <common/timeout.h>
|
||||
#include <common/type_to_string.h>
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
#include <common/htlc_trim.h>
|
||||
#include <common/initial_commit_tx.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/jsonrpc_errors.h>
|
||||
#include <common/key_derive.h>
|
||||
#include <common/param.h>
|
||||
#include <common/scb_wiregen.h>
|
||||
#include <common/shutdown_scriptpubkey.h>
|
||||
#include <common/status.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <ccan/list/list.h>
|
||||
#include <common/channel_config.h>
|
||||
#include <common/htlc.h>
|
||||
#include <common/json.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/node_id.h>
|
||||
#include <common/wireaddr.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
@@ -6,11 +6,9 @@
|
||||
#include <common/configdir.h>
|
||||
#include <common/ecdh.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/onion.h>
|
||||
#include <common/onionreply.h>
|
||||
#include <common/param.h>
|
||||
#include <common/timeout.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <db/exec.h>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "config.h"
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <connectd/connectd_wiregen.h>
|
||||
#include <lightningd/channel.h>
|
||||
#include <lightningd/jsonrpc.h>
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <common/configdir.h>
|
||||
#include <common/features.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/timeout.h>
|
||||
#include <common/version.h>
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
#include <ccan/tal/path/path.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/param.h>
|
||||
#include <common/timeout.h>
|
||||
#include <errno.h>
|
||||
#include <lightningd/notification.h>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "config.h"
|
||||
#include <ccan/io/io.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/memleak.h>
|
||||
#include <db/exec.h>
|
||||
#include <db/utils.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "config.h"
|
||||
#include <common/bolt11.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_parse.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <gossipd/gossipd_wiregen.h>
|
||||
#include <lightningd/channel.h>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#include "config.h"
|
||||
#include <common/bech32.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/json_param.h>
|
||||
#include <errno.h>
|
||||
#include <hsmd/hsmd_wiregen.h>
|
||||
#include <lightningd/json.h>
|
||||
|
||||
@@ -15,7 +15,7 @@ LIGHTNINGD_TEST_COMMON_OBJS := \
|
||||
common/daemon_conn.o \
|
||||
common/htlc_state.o \
|
||||
common/htlc_wire.o \
|
||||
common/json.o \
|
||||
common/json_parse_simple.o \
|
||||
common/key_derive.o \
|
||||
common/pseudorand.o \
|
||||
common/random_select.o \
|
||||
|
||||
@@ -111,16 +111,6 @@ void htlcs_notify_new_block(struct lightningd *ld UNNEEDED, u32 height UNNEEDED)
|
||||
void htlcs_resubmit(struct lightningd *ld UNNEEDED,
|
||||
struct htlc_in_map *unconnected_htlcs_in UNNEEDED)
|
||||
{ fprintf(stderr, "htlcs_resubmit called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for jsonrpc_listen */
|
||||
void jsonrpc_listen(struct jsonrpc *rpc UNNEEDED, struct lightningd *ld UNNEEDED)
|
||||
{ fprintf(stderr, "jsonrpc_listen called!\n"); abort(); }
|
||||
|
||||
@@ -331,23 +331,38 @@ void json_add_amount_sat_msat(struct json_stream *result UNNEEDED,
|
||||
void json_add_bolt11(struct json_stream *response UNNEEDED,
|
||||
const struct bolt11 *b11 UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_bolt11 called!\n"); abort(); }
|
||||
/* Generated stub for json_add_bool */
|
||||
void json_add_bool(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
bool value UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_bool called!\n"); abort(); }
|
||||
/* Generated stub for json_add_escaped_string */
|
||||
void json_add_escaped_string(struct json_stream *result UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
const struct json_escape *esc TAKES UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_escaped_string called!\n"); abort(); }
|
||||
/* Generated stub for json_add_hex_talarr */
|
||||
void json_add_hex_talarr(struct json_stream *result UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
const tal_t *data UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_hex_talarr called!\n"); abort(); }
|
||||
/* Generated stub for json_add_invstring */
|
||||
void json_add_invstring(struct json_stream *result UNNEEDED, const char *invstring UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_invstring called!\n"); abort(); }
|
||||
/* Generated stub for json_add_log */
|
||||
void json_add_log(struct json_stream *result UNNEEDED,
|
||||
const struct log_book *lr UNNEEDED,
|
||||
const struct node_id *node_id UNNEEDED,
|
||||
enum log_level minlevel UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_log called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_add_node_id */
|
||||
void json_add_node_id(struct json_stream *response UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
const struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_num */
|
||||
void json_add_num(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
unsigned int value UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_num called!\n"); abort(); }
|
||||
/* Generated stub for json_add_preimage */
|
||||
void json_add_preimage(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
const struct preimage *preimage UNNEEDED)
|
||||
@@ -366,6 +381,18 @@ void json_add_short_channel_id(struct json_stream *response UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
const struct short_channel_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_short_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_string */
|
||||
void json_add_string(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED, const char *value TAKES UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_string called!\n"); abort(); }
|
||||
/* Generated stub for json_add_stringn */
|
||||
void json_add_stringn(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
const char *value TAKES UNNEEDED, size_t value_len UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_stringn called!\n"); abort(); }
|
||||
/* Generated stub for json_add_timeiso */
|
||||
void json_add_timeiso(struct json_stream *result UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
struct timeabs *time UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_timeiso called!\n"); abort(); }
|
||||
/* Generated stub for json_add_tx */
|
||||
void json_add_tx(struct json_stream *result UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
@@ -375,6 +402,14 @@ void json_add_tx(struct json_stream *result UNNEEDED,
|
||||
void json_add_txid(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
const struct bitcoin_txid *txid UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_txid called!\n"); abort(); }
|
||||
/* Generated stub for json_add_u32 */
|
||||
void json_add_u32(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
uint32_t value UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_u32 called!\n"); abort(); }
|
||||
/* Generated stub for json_add_u64 */
|
||||
void json_add_u64(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
uint64_t value UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_u64 called!\n"); abort(); }
|
||||
/* Generated stub for json_add_uncommitted_channel */
|
||||
void json_add_uncommitted_channel(struct json_stream *response UNNEEDED,
|
||||
const struct uncommitted_channel *uc UNNEEDED)
|
||||
@@ -389,16 +424,19 @@ void json_array_end(struct json_stream *js UNNEEDED)
|
||||
/* Generated stub for json_array_start */
|
||||
void json_array_start(struct json_stream *js UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_array_start called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
/* Generated stub for json_object_start */
|
||||
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
|
||||
/* Generated stub for json_scan */
|
||||
const char *json_scan(const tal_t *ctx UNNEEDED,
|
||||
const char *buffer UNNEEDED,
|
||||
const jsmntok_t *tok UNNEEDED,
|
||||
const char *guide UNNEEDED,
|
||||
...)
|
||||
{ fprintf(stderr, "json_scan called!\n"); abort(); }
|
||||
/* Generated stub for json_stream_fail */
|
||||
struct json_stream *json_stream_fail(struct command *cmd UNNEEDED,
|
||||
errcode_t code UNNEEDED,
|
||||
@@ -421,10 +459,21 @@ bool json_to_msat(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
bool json_to_node_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_to_number */
|
||||
bool json_to_number(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
unsigned int *num UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_number called!\n"); abort(); }
|
||||
/* Generated stub for json_to_short_channel_id */
|
||||
bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct short_channel_id *scid UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_to_u16 */
|
||||
bool json_to_u16(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
uint16_t *num UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_u16 called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_bin_from_hex */
|
||||
u8 *json_tok_bin_from_hex(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_bin_from_hex called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_channel_id */
|
||||
bool json_tok_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct channel_id *cid UNNEEDED)
|
||||
|
||||
@@ -30,10 +30,9 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
/* Generated stub for fromwire_node_id */
|
||||
void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_sha256 */
|
||||
void json_add_sha256(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
const struct sha256 *hash UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_sha256 called!\n"); abort(); }
|
||||
/* Generated stub for json_to_errcode */
|
||||
bool json_to_errcode(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, errcode_t *errcode UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_errcode called!\n"); abort(); }
|
||||
/* Generated stub for json_to_pubkey */
|
||||
bool json_to_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct pubkey *pubkey UNNEEDED)
|
||||
|
||||
@@ -27,6 +27,11 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
/* Generated stub for fromwire_node_id */
|
||||
void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_hex_talarr */
|
||||
void json_add_hex_talarr(struct json_stream *result UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
const tal_t *data UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_hex_talarr called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
@@ -38,16 +43,23 @@ void json_add_node_id(struct json_stream *response UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
const struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_add_num */
|
||||
void json_add_num(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
unsigned int value UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_num called!\n"); abort(); }
|
||||
/* Generated stub for json_add_string */
|
||||
void json_add_string(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED, const char *value TAKES UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_string called!\n"); abort(); }
|
||||
/* Generated stub for json_add_time */
|
||||
void json_add_time(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
struct timespec ts UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_time called!\n"); abort(); }
|
||||
/* Generated stub for json_array_end */
|
||||
void json_array_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_array_end called!\n"); abort(); }
|
||||
/* Generated stub for json_array_start */
|
||||
void json_array_start(struct json_stream *js UNNEEDED, const char *fieldname UNNEEDED)
|
||||
{ fprintf(stderr, "json_array_start called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for json_object_end */
|
||||
void json_object_end(struct json_stream *js UNNEEDED)
|
||||
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
||||
|
||||
@@ -75,16 +75,6 @@ bool fromwire_status_peer_error(const tal_t *ctx UNNEEDED, const void *p UNNEEDE
|
||||
/* Generated stub for fromwire_status_version */
|
||||
bool fromwire_status_version(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, wirestring **version UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_status_version called!\n"); abort(); }
|
||||
/* Generated stub for json_add_member */
|
||||
void json_add_member(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED,
|
||||
bool quote UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "json_add_member called!\n"); abort(); }
|
||||
/* Generated stub for json_member_direct */
|
||||
char *json_member_direct(struct json_stream *js UNNEEDED,
|
||||
const char *fieldname UNNEEDED, size_t extra UNNEEDED)
|
||||
{ fprintf(stderr, "json_member_direct called!\n"); abort(); }
|
||||
/* Generated stub for log_ */
|
||||
void log_(struct log *log UNNEEDED, enum log_level level UNNEEDED,
|
||||
const struct node_id *node_id UNNEEDED,
|
||||
|
||||
@@ -134,14 +134,13 @@ PLUGIN_COMMON_OBJS := \
|
||||
common/daemon.o \
|
||||
common/features.o \
|
||||
common/hash_u5.o \
|
||||
common/json.o \
|
||||
common/json_helpers.o \
|
||||
common/json_param.o \
|
||||
common/json_parse.o \
|
||||
common/json_parse_simple.o \
|
||||
common/json_stream.o \
|
||||
common/json_tok.o \
|
||||
common/lease_rates.o \
|
||||
common/memleak.o \
|
||||
common/node_id.o \
|
||||
common/param.o \
|
||||
common/psbt_open.o \
|
||||
common/pseudorand.o \
|
||||
common/random_select.o \
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "config.h"
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <plugins/libplugin.h>
|
||||
|
||||
static u64 cycle_seconds = 0, expired_by = 86400;
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
#include <ccan/pipecmd/pipecmd.h>
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/memleak.h>
|
||||
#include <errno.h>
|
||||
#include <plugins/libplugin.h>
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <ccan/time/time.h>
|
||||
#include <common/hsm_encryption.h>
|
||||
#include <common/json.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/scb_wiregen.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include <common/bolt12_merkle.h>
|
||||
#include <common/dijkstra.h>
|
||||
#include <common/gossmap.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/overflows.h>
|
||||
#include <common/route.h>
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/json_out/json_out.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/lease_rates.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/overflows.h>
|
||||
#include <common/psbt_open.h>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "config.h"
|
||||
#include <bitcoin/preimage.h>
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/asort/asort.h>
|
||||
#include <ccan/cast/cast.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <plugins/libplugin-pay.h>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#define LIGHTNING_PLUGINS_LIBPLUGIN_H
|
||||
#include "config.h"
|
||||
|
||||
#include <bitcoin/tx.h>
|
||||
#include <ccan/intmap/intmap.h>
|
||||
#include <ccan/membuf/membuf.h>
|
||||
#include <ccan/strmap/strmap.h>
|
||||
@@ -11,12 +12,9 @@
|
||||
#include <common/errcode.h>
|
||||
#include <common/features.h>
|
||||
#include <common/htlc.h>
|
||||
#include <common/json.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/jsonrpc_errors.h>
|
||||
#include <common/node_id.h>
|
||||
#include <common/param.h>
|
||||
#include <common/status_levels.h>
|
||||
#include <common/utils.h>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <common/bolt11_json.h>
|
||||
#include <common/bolt12_merkle.h>
|
||||
#include <common/iso4217.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <plugins/offers.h>
|
||||
#include <plugins/offers_inv_hook.h>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef LIGHTNING_PLUGINS_OFFERS_H
|
||||
#define LIGHTNING_PLUGINS_OFFERS_H
|
||||
#include "config.h"
|
||||
#include <common/json.h>
|
||||
|
||||
struct command_result;
|
||||
struct command;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/bolt12_merkle.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <plugins/offers.h>
|
||||
#include <plugins/offers_inv_hook.h>
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/bolt12.h>
|
||||
#include <common/iso4217.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/overflows.h>
|
||||
#include <plugins/offers_offer.h>
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/bolt12_merkle.h>
|
||||
#include <common/gossmap.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/pseudorand.h>
|
||||
#include <common/type_to_string.h>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "config.h"
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <plugins/spender/fundchannel.h>
|
||||
|
||||
static struct command_result *
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/addr.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/psbt_open.h>
|
||||
#include <common/pseudorand.h>
|
||||
#include <common/type_to_string.h>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/json_out/json_out.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/psbt_open.h>
|
||||
#include <common/pseudorand.h>
|
||||
#include <common/type_to_string.h>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/dijkstra.h>
|
||||
#include <common/gossmap.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/pseudorand.h>
|
||||
#include <common/route.h>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#include <bitcoin/psbt.h>
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <common/addr.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/psbt_open.h>
|
||||
#include <common/pseudorand.h>
|
||||
|
||||
@@ -8,7 +8,7 @@ $(PLUGIN_TESTLIBPLUGIN_OBJS): $(PLUGIN_LIB_HEADER)
|
||||
PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_SRC := tests/plugins/test_selfdisable_after_getmanifest.c
|
||||
PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_OBJS := $(PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_SRC:.c=.o)
|
||||
|
||||
tests/plugins/test_selfdisable_after_getmanifest: bitcoin/chainparams.o $(PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_OBJS) common/autodata.o common/json.o common/json_stream.o common/setup.o common/utils.o $(JSMN_OBJS) $(CCAN_OBJS)
|
||||
tests/plugins/test_selfdisable_after_getmanifest: bitcoin/chainparams.o $(PLUGIN_TESTSELFDISABLE_AFTER_GETMANIFEST_OBJS) common/autodata.o common/json_parse_simple.o common/setup.o common/utils.o $(JSMN_OBJS) $(CCAN_OBJS)
|
||||
|
||||
# Make sure these depend on everything.
|
||||
ALL_TEST_PROGRAMS += tests/plugins/test_libplugin tests/plugins/test_selfdisable_after_getmanifest
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "config.h"
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/json_stream.h>
|
||||
#include <common/memleak.h>
|
||||
#include <plugins/libplugin.h>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user