Browse Source

plugins: use json_scan.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa
Rusty Russell 4 years ago
committed by Christian Decker
parent
commit
b61da8c5a9
  1. 29
      plugins/keysend.c
  2. 30
      plugins/libplugin.c
  3. 93
      plugins/pay.c
  4. 33
      plugins/spender/openchannel.c

29
plugins/keysend.c

@ -2,6 +2,7 @@
#include <ccan/array_size/array_size.h> #include <ccan/array_size/array_size.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <common/gossmap.h> #include <common/gossmap.h>
#include <common/type_to_string.h>
#include <plugins/libplugin-pay.h> #include <plugins/libplugin-pay.h>
#include <plugins/libplugin.h> #include <plugins/libplugin.h>
#include <wire/onion_wire.h> #include <wire/onion_wire.h>
@ -244,13 +245,11 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
const char *buf, const char *buf,
const jsmntok_t *params) const jsmntok_t *params)
{ {
const jsmntok_t *payloadt = json_delve(buf, params, ".onion.payload");
const jsmntok_t *payment_hash_tok = json_delve(buf, params, ".htlc.payment_hash");
const u8 *rawpayload; const u8 *rawpayload;
struct sha256 payment_hash;
size_t max; size_t max;
struct tlv_tlv_payload *payload; struct tlv_tlv_payload *payload;
struct tlv_field *preimage_field = NULL; struct tlv_field *preimage_field = NULL;
char *hexpreimage, *hexpaymenthash;
bigsize_t s; bigsize_t s;
bool unknown_even_type = false; bool unknown_even_type = false;
struct tlv_field *field; struct tlv_field *field;
@ -258,10 +257,11 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
struct out_req *req; struct out_req *req;
struct timeabs now = time_now(); struct timeabs now = time_now();
if (!payloadt) if (!json_scan(buf, params, "{onion:{payload:%},htlc:{payment_hash:%}}",
JSON_SCAN_TAL(cmd, json_tok_bin_from_hex, &rawpayload),
JSON_SCAN(json_to_sha256, &payment_hash)))
return htlc_accepted_continue(cmd, NULL); return htlc_accepted_continue(cmd, NULL);
rawpayload = json_tok_bin_from_hex(cmd, buf, payloadt);
max = tal_bytelen(rawpayload); max = tal_bytelen(rawpayload);
payload = tlv_tlv_payload_new(cmd); payload = tlv_tlv_payload_new(cmd);
@ -272,7 +272,8 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
if (!fromwire_tlv_payload(&rawpayload, &max, payload)) { if (!fromwire_tlv_payload(&rawpayload, &max, payload)) {
plugin_log( plugin_log(
cmd->plugin, LOG_UNUSUAL, "Malformed TLV payload %.*s", cmd->plugin, LOG_UNUSUAL, "Malformed TLV payload %.*s",
payloadt->end - payloadt->start, buf + payloadt->start); json_tok_full_len(params),
json_tok_full(buf, params));
return htlc_accepted_continue(cmd, NULL); return htlc_accepted_continue(cmd, NULL);
} }
@ -318,20 +319,18 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
ki->payload = tal_steal(ki, payload); ki->payload = tal_steal(ki, payload);
ki->preimage_field = preimage_field; ki->preimage_field = preimage_field;
hexpreimage = tal_hex(cmd, preimage_field->value);
/* If the preimage doesn't hash to the payment_hash we must continue, /* If the preimage doesn't hash to the payment_hash we must continue,
* maybe someone else knows how to handle these. */ * maybe someone else knows how to handle these. */
sha256(&ki->payment_hash, preimage_field->value, preimage_field->length); sha256(&ki->payment_hash, preimage_field->value, preimage_field->length);
hexpaymenthash = tal_hexstr(cmd, &ki->payment_hash, sizeof(ki->payment_hash)); if (!sha256_eq(&ki->payment_hash, &payment_hash)) {
if (!json_tok_streq(buf, payment_hash_tok, hexpaymenthash)) {
plugin_log( plugin_log(
cmd->plugin, LOG_UNUSUAL, cmd->plugin, LOG_UNUSUAL,
"Preimage provided by the sender does not match the " "Preimage provided by the sender does not match the "
"payment_hash: SHA256(%s)=%s != %.*s. Ignoring keysend.", "payment_hash: SHA256(%s)=%s != %s. Ignoring keysend.",
hexpreimage, hexpaymenthash, tal_hexstr(tmpctx,
payment_hash_tok->end - payment_hash_tok->start, preimage_field->value, preimage_field->length),
buf + payment_hash_tok->start); type_to_string(tmpctx, struct sha256, &ki->payment_hash),
type_to_string(tmpctx, struct sha256, &payment_hash));
tal_free(ki); tal_free(ki);
return htlc_accepted_continue(cmd, NULL); return htlc_accepted_continue(cmd, NULL);
} }
@ -348,7 +347,7 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
&htlc_accepted_invoice_created, &htlc_accepted_invoice_created,
ki); ki);
plugin_log(cmd->plugin, LOG_INFORM, "Inserting a new invoice for keysend with payment_hash %s", hexpaymenthash); plugin_log(cmd->plugin, LOG_INFORM, "Inserting a new invoice for keysend with payment_hash %s", type_to_string(tmpctx, struct sha256, &payment_hash));
json_add_string(req->js, "msatoshi", "any"); json_add_string(req->js, "msatoshi", "any");
json_add_string(req->js, "label", ki->label); json_add_string(req->js, "label", ki->label);
json_add_string(req->js, "description", "Spontaneous incoming payment through keysend"); json_add_string(req->js, "description", "Spontaneous incoming payment through keysend");

30
plugins/libplugin.c

@ -802,34 +802,36 @@ static struct command_result *handle_init(struct command *cmd,
const char *buf, const char *buf,
const jsmntok_t *params) const jsmntok_t *params)
{ {
const jsmntok_t *configtok, *rpctok, *dirtok, *opttok, *nettok, *fsettok, const jsmntok_t *configtok, *opttok, *t;
*t;
struct sockaddr_un addr; struct sockaddr_un addr;
size_t i; size_t i;
char *dir, *network; char *dir, *network;
struct plugin *p = cmd->plugin; struct plugin *p = cmd->plugin;
bool with_rpc = p->rpc_conn != NULL; bool with_rpc = p->rpc_conn != NULL;
configtok = json_delve(buf, params, ".configuration"); configtok = json_get_member(buf, params, "configuration");
if (!json_scan(buf, configtok,
"{lightning-dir:%"
",network:%"
",feature_set:%"
",rpc-file:%}",
JSON_SCAN_TAL(tmpctx, json_strdup, &dir),
JSON_SCAN_TAL(tmpctx, json_strdup, &network),
JSON_SCAN_TAL(p, json_to_feature_set, &p->our_features),
JSON_SCAN_TAL(p, json_strdup, &p->rpc_location)))
plugin_err(p, "cannot scan init params: %.*s",
json_tok_full_len(params),
json_tok_full(buf, params));
/* Move into lightning directory: other files are relative */ /* Move into lightning directory: other files are relative */
dirtok = json_delve(buf, configtok, ".lightning-dir");
dir = json_strdup(tmpctx, buf, dirtok);
if (chdir(dir) != 0) if (chdir(dir) != 0)
plugin_err(p, "chdir to %s: %s", dir, strerror(errno)); plugin_err(p, "chdir to %s: %s", dir, strerror(errno));
nettok = json_delve(buf, configtok, ".network");
network = json_strdup(tmpctx, buf, nettok);
chainparams = chainparams_for_network(network); chainparams = chainparams_for_network(network);
fsettok = json_delve(buf, configtok, ".feature_set");
p->our_features = json_to_feature_set(p, buf, fsettok);
/* Only attempt to connect if the plugin has configured the rpc_conn /* Only attempt to connect if the plugin has configured the rpc_conn
* already, if that's not the case we were told to run without an RPC * already, if that's not the case we were told to run without an RPC
* connection, so don't even log an error. */ * connection, so don't even log an error. */
rpctok = json_delve(buf, configtok, ".rpc-file");
p->rpc_location = json_strdup(p, buf, rpctok);
/* FIXME: Move this to its own function so we can initialize at a /* FIXME: Move this to its own function so we can initialize at a
* later point in time. */ * later point in time. */
if (p->rpc_conn != NULL) { if (p->rpc_conn != NULL) {
@ -837,9 +839,7 @@ static struct command_result *handle_init(struct command *cmd,
if (strlen(p->rpc_location) + 1 > sizeof(addr.sun_path)) if (strlen(p->rpc_location) + 1 > sizeof(addr.sun_path))
plugin_err(p, "rpc filename '%s' too long", plugin_err(p, "rpc filename '%s' too long",
p->rpc_location); p->rpc_location);
memcpy(addr.sun_path, buf + rpctok->start, strcpy(addr.sun_path, p->rpc_location);
rpctok->end - rpctok->start);
addr.sun_path[rpctok->end - rpctok->start] = '\0';
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
if (connect(p->rpc_conn->fd, (struct sockaddr *)&addr, if (connect(p->rpc_conn->fd, (struct sockaddr *)&addr,

93
plugins/pay.c

@ -394,20 +394,14 @@ execute_waitblockheight(struct command *cmd,
static u32 static u32
get_remote_block_height(const char *buf, const jsmntok_t *error) get_remote_block_height(const char *buf, const jsmntok_t *error)
{ {
const jsmntok_t *raw_message_tok;
const u8 *raw_message; const u8 *raw_message;
size_t raw_message_len; size_t raw_message_len;
u16 type; u16 type;
/* Is there even a raw_message? */ /* Is there even a raw_message? */
raw_message_tok = json_delve(buf, error, ".data.raw_message"); if (!json_scan(buf, error, "{data:{raw_message:%}}",
if (!raw_message_tok) JSON_SCAN_TAL(tmpctx, json_tok_bin_from_hex,
return 0; &raw_message)))
if (raw_message_tok->type != JSMN_STRING)
return 0;
raw_message = json_tok_bin_from_hex(tmpctx, buf, raw_message_tok);
if (!raw_message)
return 0; return 0;
/* BOLT #4: /* BOLT #4:
@ -435,21 +429,19 @@ static struct command_result *waitsendpay_error(struct command *cmd,
struct pay_command *pc) struct pay_command *pc)
{ {
struct pay_attempt *attempt = current_attempt(pc); struct pay_attempt *attempt = current_attempt(pc);
const jsmntok_t *codetok, *failcodetok, *nodeidtok, *scidtok, *dirtok;
errcode_t code; errcode_t code;
int failcode; int failcode;
bool node_err = false;
attempt_failed_tok(pc, "waitsendpay", buf, error); attempt_failed_tok(pc, "waitsendpay", buf, error);
codetok = json_get_member(buf, error, "code"); if (!json_scan(buf, error, "{code:%}",
if (!json_to_errcode(buf, codetok, &code)) JSON_SCAN(json_to_errcode, &code)))
plugin_err(cmd->plugin, "waitsendpay error gave no 'code'? '%.*s'", plugin_err(cmd->plugin, "waitsendpay error gave no 'code'? '%.*s'",
error->end - error->start, buf + error->start); error->end - error->start, buf + error->start);
if (code != PAY_UNPARSEABLE_ONION) { if (code != PAY_UNPARSEABLE_ONION) {
failcodetok = json_delve(buf, error, ".data.failcode"); if (!json_scan(buf, error, "{data:{failcode:%}}",
if (!json_to_int(buf, failcodetok, &failcode)) JSON_SCAN(json_to_int, &failcode)))
plugin_err(cmd->plugin, "waitsendpay error gave no 'failcode'? '%.*s'", plugin_err(cmd->plugin, "waitsendpay error gave no 'failcode'? '%.*s'",
error->end - error->start, buf + error->start); error->end - error->start, buf + error->start);
} }
@ -512,57 +504,54 @@ static struct command_result *waitsendpay_error(struct command *cmd,
return forward_error(cmd, buf, error, pc); return forward_error(cmd, buf, error, pc);
} }
if (time_after(time_now(), pc->stoptime)) {
return waitsendpay_expired(cmd, pc);
}
if (failcode & NODE) { if (failcode & NODE) {
nodeidtok = json_delve(buf, error, ".data.erring_node"); struct node_id id;
if (!nodeidtok) const char *idstr;
if (!json_scan(buf, error, "{data:{erring_node:%}}",
JSON_SCAN(json_to_node_id, &id)))
plugin_err(cmd->plugin, "waitsendpay error no erring_node '%.*s'", plugin_err(cmd->plugin, "waitsendpay error no erring_node '%.*s'",
error->end - error->start, buf + error->start); error->end - error->start, buf + error->start);
node_err = true;
} else {
scidtok = json_delve(buf, error, ".data.erring_channel");
if (!scidtok)
plugin_err(cmd->plugin, "waitsendpay error no erring_channel '%.*s'",
error->end - error->start, buf + error->start);
dirtok = json_delve(buf, error, ".data.erring_direction");
if (!dirtok)
plugin_err(cmd->plugin, "waitsendpay error no erring_direction '%.*s'",
error->end - error->start, buf + error->start);
}
if (time_after(time_now(), pc->stoptime)) { /* FIXME: Keep as node_id, don't use strings. */
return waitsendpay_expired(cmd, pc); idstr = node_id_to_hexstr(tmpctx, &id);
}
if (node_err) {
/* If failure is in routehint part, try next one */ /* If failure is in routehint part, try next one */
if (node_or_channel_in_routehint(pc->plugin, pc->current_routehint, if (node_or_channel_in_routehint(pc->plugin, pc->current_routehint,
buf + nodeidtok->start, idstr, strlen(idstr)))
nodeidtok->end - nodeidtok->start))
return next_routehint(cmd, pc); return next_routehint(cmd, pc);
/* Otherwise, add erring channel to exclusion list. */ /* Otherwise, add erring channel to exclusion list. */
tal_arr_expand(&pc->excludes, tal_arr_expand(&pc->excludes, tal_steal(pc->excludes, idstr));
tal_fmt(pc->excludes, "%.*s",
nodeidtok->end - nodeidtok->start,
buf + nodeidtok->start));
} else { } else {
struct short_channel_id scid;
u32 dir;
const char *scidstr;
if (!json_scan(buf, error, "{data:{erring_channel:%,erring_direction:%}}",
JSON_SCAN(json_to_short_channel_id, &scid),
JSON_SCAN(json_to_number, &dir)))
plugin_err(cmd->plugin, "waitsendpay error no erring_channel/direction '%.*s'",
error->end - error->start, buf + error->start);
scidstr = short_channel_id_to_str(tmpctx, &scid);
/* If failure is in routehint part, try next one */ /* If failure is in routehint part, try next one */
if (node_or_channel_in_routehint(pc->plugin, pc->current_routehint, if (node_or_channel_in_routehint(pc->plugin, pc->current_routehint,
buf + scidtok->start, scidstr, strlen(scidstr)))
scidtok->end - scidtok->start))
return next_routehint(cmd, pc); return next_routehint(cmd, pc);
/* Otherwise, add erring channel to exclusion list. */ /* Otherwise, add erring channel to exclusion list. */
tal_arr_expand(&pc->excludes, tal_arr_expand(&pc->excludes,
tal_fmt(pc->excludes, "%.*s/%c", tal_fmt(pc->excludes, "%s/%u", scidstr, dir));
scidtok->end - scidtok->start,
buf + scidtok->start,
buf[dirtok->start]));
} }
/* Try again. */ /* Try again. */
return start_pay_attempt(cmd, pc, "Excluded %s %s", return start_pay_attempt(cmd, pc, "Excluded %s %s",
node_err ? "node" : "channel", failcode & NODE ? "node" : "channel",
pc->excludes[tal_count(pc->excludes)-1]); pc->excludes[tal_count(pc->excludes)-1]);
} }
@ -765,16 +754,10 @@ static struct command_result *getroute_done(struct command *cmd,
} else } else
attempt->route = json_strdup(pc->ps->attempts, buf, t); attempt->route = json_strdup(pc->ps->attempts, buf, t);
if (!json_to_msat(buf, json_delve(buf, t, "[0].msatoshi"), &fee)) if (!json_scan(buf, t, "[0:{msatoshi:%,delay:%}]",
plugin_err(cmd->plugin, "getroute with invalid msatoshi? %.*s", JSON_SCAN(json_to_msat, &fee),
result->end - result->start, buf); JSON_SCAN(json_to_number, &delay)))
if (!amount_msat_sub(&fee, fee, pc->msat)) plugin_err(cmd->plugin, "getroute with invalid msatoshi/delay? %.*s",
plugin_err(cmd->plugin, "final amount %s less than paid %s",
type_to_string(tmpctx, struct amount_msat, &fee),
type_to_string(tmpctx, struct amount_msat, &pc->msat));
if (!json_to_number(buf, json_delve(buf, t, "[0].delay"), &delay))
plugin_err(cmd->plugin, "getroute with invalid delay? %.*s",
result->end - result->start, buf); result->end - result->start, buf);
if (pc->maxfee_pct_millionths / 100 > UINT32_MAX) if (pc->maxfee_pct_millionths / 100 > UINT32_MAX)

33
plugins/spender/openchannel.c

@ -544,38 +544,17 @@ static void json_peer_sigs(struct command *cmd,
const char *buf, const char *buf,
const jsmntok_t *params) const jsmntok_t *params)
{ {
const jsmntok_t *cid_tok, *psbt_tok;
struct channel_id cid; struct channel_id cid;
const struct wally_psbt *psbt; const struct wally_psbt *psbt;
struct multifundchannel_destination *dest; struct multifundchannel_destination *dest;
cid_tok = json_delve(buf, params, ".openchannel_peer_sigs.channel_id"); if (!json_scan(buf, params,
if (!cid_tok) "{openchannel_peer_sigs:"
"{channel_id:%,signed_psbt:%}}",
JSON_SCAN(json_to_channel_id, &cid),
JSON_SCAN_TAL(cmd, json_to_psbt, &psbt)))
plugin_err(cmd->plugin, plugin_err(cmd->plugin,
"`openchannel_peer_sigs` notification did not " "`openchannel_peer_sigs` did not scan",
"send 'channel_id'? %.*s",
json_tok_full_len(params),
json_tok_full(buf, params));
if (!json_to_channel_id(buf, cid_tok, &cid))
plugin_err(cmd->plugin,
"Unable to parse openchannel_peer_sigs.channel_id "
"%.*s",
json_tok_full_len(params),
json_tok_full(buf, params));
psbt_tok= json_delve(buf, params, ".openchannel_peer_sigs.signed_psbt");
if (!psbt_tok)
plugin_err(cmd->plugin,
"`openchannel_peer_sigs` notification did not "
"include 'signed_psbt'? %.*s",
json_tok_full_len(params),
json_tok_full(buf, params));
psbt = json_to_psbt(cmd, buf, psbt_tok);
if (!psbt)
plugin_err(cmd->plugin,
"Unable to parse openchannel_peer_sigs.signed_psbt "
"%.*s",
json_tok_full_len(params), json_tok_full_len(params),
json_tok_full(buf, params)); json_tok_full(buf, params));

Loading…
Cancel
Save