|
@ -1,25 +1,15 @@ |
|
|
/* JSON core and helpers */ |
|
|
/* JSON core and helpers */ |
|
|
#include <arpa/inet.h> |
|
|
|
|
|
#include <assert.h> |
|
|
#include <assert.h> |
|
|
#include <bitcoin/preimage.h> |
|
|
|
|
|
#include <bitcoin/privkey.h> |
|
|
|
|
|
#include <bitcoin/pubkey.h> |
|
|
|
|
|
#include <bitcoin/short_channel_id.h> |
|
|
|
|
|
#include <bitcoin/tx.h> |
|
|
|
|
|
#include <ccan/build_assert/build_assert.h> |
|
|
#include <ccan/build_assert/build_assert.h> |
|
|
#include <ccan/json_escape/json_escape.h> |
|
|
#include <ccan/json_escape/json_escape.h> |
|
|
#include <ccan/mem/mem.h> |
|
|
#include <ccan/mem/mem.h> |
|
|
#include <ccan/str/hex/hex.h> |
|
|
#include <ccan/str/hex/hex.h> |
|
|
#include <ccan/tal/str/str.h> |
|
|
#include <ccan/tal/str/str.h> |
|
|
#include <ccan/time/time.h> |
|
|
#include <ccan/time/time.h> |
|
|
#include <common/amount.h> |
|
|
|
|
|
#include <common/json.h> |
|
|
#include <common/json.h> |
|
|
#include <common/json_stream.h> |
|
|
#include <common/json_stream.h> |
|
|
#include <common/node_id.h> |
|
|
|
|
|
#include <common/overflows.h> |
|
|
#include <common/overflows.h> |
|
|
#include <common/type_to_string.h> |
|
|
|
|
|
#include <common/utils.h> |
|
|
#include <common/utils.h> |
|
|
#include <common/wireaddr.h> |
|
|
|
|
|
#include <ctype.h> |
|
|
#include <ctype.h> |
|
|
#include <errno.h> |
|
|
#include <errno.h> |
|
|
#include <inttypes.h> |
|
|
#include <inttypes.h> |
|
@ -235,12 +225,6 @@ bool json_to_bool(const char *buffer, const jsmntok_t *tok, bool *b) |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
u8 *json_tok_bin_from_hex(const tal_t *ctx, const char *buffer, const jsmntok_t *tok) |
|
|
u8 *json_tok_bin_from_hex(const tal_t *ctx, const char *buffer, const jsmntok_t *tok) |
|
|
{ |
|
|
{ |
|
|
u8 *result; |
|
|
u8 *result; |
|
@ -255,12 +239,6 @@ u8 *json_tok_bin_from_hex(const tal_t *ctx, const char *buffer, const jsmntok_t |
|
|
return result; |
|
|
return result; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool json_tok_is_num(const char *buffer, const jsmntok_t *tok) |
|
|
bool json_tok_is_num(const char *buffer, const jsmntok_t *tok) |
|
|
{ |
|
|
{ |
|
|
if (tok->type != JSMN_PRIMITIVE) |
|
|
if (tok->type != JSMN_PRIMITIVE) |
|
@ -474,112 +452,6 @@ const jsmntok_t *json_delve(const char *buffer, |
|
|
return tok; |
|
|
return tok; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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_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_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_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); |
|
|
|
|
|
char *addrstr = tal_arr(response, char, INET6_ADDRSTRLEN); |
|
|
|
|
|
if (addr->type == ADDR_TYPE_IPV4) { |
|
|
|
|
|
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) { |
|
|
|
|
|
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) { |
|
|
|
|
|
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); |
|
|
|
|
|
} |
|
|
|
|
|
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_num(struct json_stream *result, const char *fieldname, unsigned int value) |
|
|
void json_add_num(struct json_stream *result, const char *fieldname, unsigned int value) |
|
|
{ |
|
|
{ |
|
|
json_add_member(result, fieldname, false, "%u", value); |
|
|
json_add_member(result, fieldname, false, "%u", value); |
|
@ -658,13 +530,6 @@ void json_add_hex_talarr(struct json_stream *result, |
|
|
json_add_hex(result, fieldname, data, tal_bytelen(data)); |
|
|
json_add_hex(result, fieldname, data, tal_bytelen(data)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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_escaped_string(struct json_stream *result, const char *fieldname, |
|
|
void json_add_escaped_string(struct json_stream *result, const char *fieldname, |
|
|
const struct json_escape *esc TAKES) |
|
|
const struct json_escape *esc TAKES) |
|
|
{ |
|
|
{ |
|
@ -681,42 +546,6 @@ void json_add_escaped_string(struct json_stream *result, const char *fieldname, |
|
|
tal_free(esc); |
|
|
tal_free(esc); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void json_add_amount_msat_compat(struct json_stream *result, |
|
|
|
|
|
struct amount_msat msat, |
|
|
|
|
|
const char *rawfieldname, |
|
|
|
|
|
const char *msatfieldname) |
|
|
|
|
|
{ |
|
|
|
|
|
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) |
|
|
|
|
|
{ |
|
|
|
|
|
json_add_string(result, msatfieldname, |
|
|
|
|
|
type_to_string(tmpctx, struct amount_msat, &msat)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void json_add_amount_sat_compat(struct json_stream *result, |
|
|
|
|
|
struct amount_sat sat, |
|
|
|
|
|
const char *rawfieldname, |
|
|
|
|
|
const char *msatfieldname) |
|
|
|
|
|
{ |
|
|
|
|
|
json_add_u64(result, rawfieldname, sat.satoshis); /* Raw: low-level helper */ |
|
|
|
|
|
json_add_amount_sat_only(result, msatfieldname, sat); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void json_add_amount_sat_only(struct json_stream *result, |
|
|
|
|
|
const char *msatfieldname, |
|
|
|
|
|
struct amount_sat sat) |
|
|
|
|
|
{ |
|
|
|
|
|
struct amount_msat msat; |
|
|
|
|
|
if (amount_sat_to_msat(&msat, sat)) |
|
|
|
|
|
json_add_string(result, msatfieldname, |
|
|
|
|
|
type_to_string(tmpctx, struct amount_msat, &msat)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void json_add_timeabs(struct json_stream *result, const char *fieldname, |
|
|
void json_add_timeabs(struct json_stream *result, const char *fieldname, |
|
|
struct timeabs t) |
|
|
struct timeabs t) |
|
|
{ |
|
|
{ |
|
@ -735,24 +564,6 @@ void json_add_time(struct json_stream *result, const char *fieldname, |
|
|
json_add_string(result, fieldname, timebuf); |
|
|
json_add_string(result, fieldname, timebuf); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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_tok(struct json_stream *result, const char *fieldname, |
|
|
void json_add_tok(struct json_stream *result, const char *fieldname, |
|
|
const jsmntok_t *tok, const char *buffer) |
|
|
const jsmntok_t *tok, const char *buffer) |
|
|
{ |
|
|
{ |
|
|