mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
param: Encapsulate hops parsing in a param_hops_array helper
Suggested-by: Rusty Russell <@rustyrussell> Signed-off-by: Christian Decker <@cdecker>
This commit is contained in:
parent
f569b52681
commit
55d8dcc907
@ -256,3 +256,71 @@ struct command_result *param_bin_from_hex(struct command *cmd, const char *name,
|
||||
"'%s' should be a hex value, not '%.*s'",
|
||||
name, tok->end - tok->start, buffer + tok->start);
|
||||
}
|
||||
|
||||
struct command_result *param_hops_array(struct command *cmd, const char *name,
|
||||
const char *buffer, const jsmntok_t *tok,
|
||||
struct sphinx_hop **hops)
|
||||
{
|
||||
const jsmntok_t *hop, *payloadtok, *typetok, *pubkeytok;
|
||||
struct sphinx_hop h;
|
||||
size_t i;
|
||||
if (tok->type != JSMN_ARRAY) {
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"'%s' should be an array of hops, got '%.*s'", name,
|
||||
tok->end - tok->start, buffer + tok->start);
|
||||
}
|
||||
|
||||
*hops = tal_arr(cmd, struct sphinx_hop, 0);
|
||||
|
||||
json_for_each_arr(i, hop, tok) {
|
||||
|
||||
payloadtok = json_get_member(buffer, hop, "payload");
|
||||
typetok = json_get_member(buffer, hop, "type");
|
||||
pubkeytok = json_get_member(buffer, hop, "pubkey");
|
||||
|
||||
if (!pubkeytok)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Hop %zu does not have a pubkey", i);
|
||||
|
||||
if (!payloadtok)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Hop %zu does not have a payload", i);
|
||||
|
||||
h.payload = json_tok_bin_from_hex(*hops, buffer, payloadtok);
|
||||
if (!json_to_pubkey(buffer, pubkeytok, &h.pubkey))
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"'pubkey' should be a pubkey, not '%.*s'",
|
||||
pubkeytok->end - pubkeytok->start,
|
||||
buffer + pubkeytok->start);
|
||||
|
||||
if (!h.payload)
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"'payload' should be a hex encoded binary, not '%.*s'",
|
||||
pubkeytok->end - pubkeytok->start,
|
||||
buffer + pubkeytok->start);
|
||||
|
||||
if (!typetok || json_tok_streq(buffer, typetok, "tlv")) {
|
||||
h.type = SPHINX_TLV_PAYLOAD;
|
||||
} else if (json_tok_streq(buffer, typetok, "legacy")) {
|
||||
h.type = SPHINX_V0_PAYLOAD;
|
||||
} else {
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Unknown payload type for hop %zu: '%.*s'", i,
|
||||
pubkeytok->end - pubkeytok->start,
|
||||
buffer + pubkeytok->start);
|
||||
}
|
||||
|
||||
tal_arr_expand(hops, h);
|
||||
}
|
||||
|
||||
if (tal_count(*hops) == 0) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"At least one hop must be specified.");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <common/json.h>
|
||||
#include <common/node_id.h>
|
||||
#include <common/sphinx.h>
|
||||
#include <wire/wire.h>
|
||||
|
||||
struct amount_msat;
|
||||
@ -121,4 +122,8 @@ struct command_result *param_bin_from_hex(struct command *cmd, const char *name,
|
||||
const char *buffer, const jsmntok_t *tok,
|
||||
u8 **bin);
|
||||
|
||||
struct command_result *param_hops_array(struct command *cmd, const char *name,
|
||||
const char *buffer, const jsmntok_t *tok,
|
||||
struct sphinx_hop **hops);
|
||||
|
||||
#endif /* LIGHTNING_COMMON_JSON_TOK_H */
|
||||
|
@ -50,6 +50,10 @@ bool json_to_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEED
|
||||
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_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(); }
|
||||
/* AUTOGENERATED MOCKS END */
|
||||
|
||||
/* We do this lightningd-style: */
|
||||
|
@ -1370,18 +1370,15 @@ static struct command_result *json_createonion(struct command *cmd,
|
||||
const jsmntok_t *obj UNNEEDED,
|
||||
const jsmntok_t *params)
|
||||
{
|
||||
const jsmntok_t *hopstok, *hop, *payloadtok, *typetok, *pubkeytok;
|
||||
enum sphinx_payload_type type;
|
||||
size_t i, hop_count = 0;
|
||||
struct json_stream *response;
|
||||
struct pubkey pubkey;
|
||||
struct secret *session_key, *shared_secrets;
|
||||
struct sphinx_path *sp;
|
||||
u8 *assocdata, *payload, *serialized;
|
||||
u8 *assocdata, *serialized;
|
||||
struct onionpacket *packet;
|
||||
struct sphinx_hop *hops;
|
||||
|
||||
if (!param(cmd, buffer, params,
|
||||
p_req("hops", param_array, &hopstok),
|
||||
p_req("hops", param_hops_array, &hops),
|
||||
p_req("assocdata", param_bin_from_hex, &assocdata),
|
||||
p_opt("session_key", param_secret, &session_key),
|
||||
NULL)) {
|
||||
@ -1393,48 +1390,9 @@ static struct command_result *json_createonion(struct command *cmd,
|
||||
else
|
||||
sp = sphinx_path_new_with_key(cmd, assocdata, session_key);
|
||||
|
||||
json_for_each_arr(i, hop, hopstok) {
|
||||
payloadtok = json_get_member(buffer, hop, "payload");
|
||||
typetok = json_get_member(buffer, hop, "type");
|
||||
pubkeytok = json_get_member(buffer, hop, "pubkey");
|
||||
|
||||
if (!pubkeytok)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||
"Hop %zu does not have a pubkey", i);
|
||||
|
||||
if (!payloadtok)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||
"Hop %zu does not have a payload", i);
|
||||
|
||||
payload = json_tok_bin_from_hex(cmd, buffer, payloadtok);
|
||||
if (!json_to_pubkey(buffer, pubkeytok, &pubkey))
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"'pubkey' should be a pubkey, not '%.*s'",
|
||||
pubkeytok->end - pubkeytok->start,
|
||||
buffer + pubkeytok->start);
|
||||
|
||||
if (!payload)
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"'payload' should be a hex encoded binary, not '%.*s'",
|
||||
pubkeytok->end - pubkeytok->start,
|
||||
buffer + pubkeytok->start);
|
||||
|
||||
if (!typetok || !json_tok_streq(buffer, typetok, "legacy")) {
|
||||
type = SPHINX_RAW_PAYLOAD;
|
||||
} else {
|
||||
type = SPHINX_V0_PAYLOAD;
|
||||
}
|
||||
|
||||
sphinx_add_raw_hop(sp, &pubkey, type, payload);
|
||||
hop_count++;
|
||||
}
|
||||
|
||||
if (hop_count == 0)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||
"Cannot create an onion without hops.");
|
||||
|
||||
for (size_t i=0; i<tal_count(hops); i++)
|
||||
sphinx_add_raw_hop(sp, &hops[i].pubkey, hops[i].type,
|
||||
hops[i].payload);
|
||||
|
||||
packet = create_onionpacket(cmd, sp, &shared_secrets);
|
||||
if (!packet)
|
||||
@ -1446,7 +1404,7 @@ static struct command_result *json_createonion(struct command *cmd,
|
||||
response = json_stream_success(cmd);
|
||||
json_add_hex(response, "onion", serialized, tal_bytelen(serialized));
|
||||
json_array_start(response, "shared_secrets");
|
||||
for (size_t i=0; i<hop_count; i++) {
|
||||
for (size_t i=0; i<tal_count(hops); i++) {
|
||||
json_add_secret(response, NULL, &shared_secrets[i]);
|
||||
}
|
||||
json_array_end(response);
|
||||
|
Loading…
Reference in New Issue
Block a user