Browse Source

jsonrpc: declare up front whether a response is success or fail.

Such an API is required for when we stream it directly.  Almost all our
handlers fit this pattern already, or nearly do.

We remove new_json_result() in favor of explicit json_stream_success()
and json_stream_fail(), but still allowing command_fail() if you just
want a simple all-in-one fail wrapper.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.2rc1
Rusty Russell 6 years ago
parent
commit
e46ce0fc84
  1. 2
      lightningd/chaintopology.c
  2. 2
      lightningd/connect_control.c
  3. 14
      lightningd/gossip_control.c
  4. 40
      lightningd/invoice.c
  5. 24
      lightningd/json.c
  6. 22
      lightningd/json.h
  7. 38
      lightningd/jsonrpc.c
  8. 13
      lightningd/jsonrpc.h
  9. 3
      lightningd/log.c
  10. 6
      lightningd/memdump.c
  11. 2
      lightningd/opening_control.c
  12. 16
      lightningd/options.c
  13. 49
      lightningd/pay.c
  14. 80
      lightningd/payalgo.c
  15. 10
      lightningd/peer_control.c
  16. 2
      lightningd/ping.c
  17. 22
      lightningd/test/run-invoice-select-inchan.c
  18. 10
      lightningd/test/run-jsonrpc.c
  19. 12
      lightningd/test/run-param.c
  20. 8
      wallet/test/run-wallet.c
  21. 28
      wallet/walletrpc.c

2
lightningd/chaintopology.c

@ -483,7 +483,7 @@ static void json_feerates(struct command *cmd,
missing = true;
}
response = new_json_result(cmd);
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_object_start(response, json_feerate_style_name(*style));
for (size_t i = 0; i < ARRAY_SIZE(feerates); i++) {

2
lightningd/connect_control.c

@ -65,7 +65,7 @@ static struct connect *find_connect(struct lightningd *ld,
static void connect_cmd_succeed(struct command *cmd, const struct pubkey *id)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_pubkey(response, "id", id);
json_object_end(response);

14
lightningd/gossip_control.c

@ -182,7 +182,7 @@ static void json_getnodes_reply(struct subd *gossip UNUSED, const u8 *reply,
struct command *cmd)
{
struct gossip_getnodes_entry **nodes;
struct json_result *response = new_json_result(cmd);
struct json_result *response;
size_t i, j;
if (!fromwire_gossip_getnodes_reply(reply, reply, &nodes)) {
@ -190,6 +190,7 @@ static void json_getnodes_reply(struct subd *gossip UNUSED, const u8 *reply,
return;
}
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_array_start(response, "nodes");
@ -264,7 +265,7 @@ static void json_getroute_reply(struct subd *gossip UNUSED, const u8 *reply, con
return;
}
response = new_json_result(cmd);
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_route(response, "route", hops, tal_count(hops));
json_object_end(response);
@ -336,13 +337,14 @@ static void json_listchannels_reply(struct subd *gossip UNUSED, const u8 *reply,
{
size_t i;
struct gossip_getchannels_entry *entries;
struct json_result *response = new_json_result(cmd);
struct json_result *response;
if (!fromwire_gossip_getchannels_reply(reply, reply, &entries)) {
command_fail(cmd, LIGHTNINGD, "Invalid reply from gossipd");
return;
}
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_array_start(response, "channels");
for (i = 0; i < tal_count(entries); i++) {
@ -405,7 +407,7 @@ static void json_scids_reply(struct subd *gossip UNUSED, const u8 *reply,
const int *fds UNUSED, struct command *cmd)
{
bool ok, complete;
struct json_result *response = new_json_result(cmd);
struct json_result *response;
if (!fromwire_gossip_scids_reply(reply, &ok, &complete)) {
command_fail(cmd, LIGHTNINGD,
@ -419,6 +421,7 @@ static void json_scids_reply(struct subd *gossip UNUSED, const u8 *reply,
return;
}
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_bool(response, "complete", complete);
json_object_end(response);
@ -500,7 +503,7 @@ AUTODATA(json_command, &dev_send_timestamp_filter);
static void json_channel_range_reply(struct subd *gossip UNUSED, const u8 *reply,
const int *fds UNUSED, struct command *cmd)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
u32 final_first_block, final_num_blocks;
bool final_complete;
struct short_channel_id *scids;
@ -521,6 +524,7 @@ static void json_channel_range_reply(struct subd *gossip UNUSED, const u8 *reply
return;
}
response = json_stream_success(cmd);
json_object_start(response, NULL);
/* As this is a dev interface, we don't bother saving and
* returning all the replies, just the final one. */

40
lightningd/invoice.c

@ -64,19 +64,23 @@ static void json_add_invoice(struct json_result *response,
static void tell_waiter(struct command *cmd, const struct invoice *inv)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
const struct invoice_details *details;
details = wallet_invoice_details(cmd, cmd->ld->wallet, *inv);
if (details->state == PAID) {
response = json_stream_success(cmd);
json_add_invoice(response, details);
if (details->state == PAID)
command_success(cmd, response);
else {
} else {
/* FIXME: -2 should be a constant in jsonrpc_errors.h. */
command_fail_detailed(cmd, -2, response,
response = json_stream_fail(cmd, -2,
"invoice expired during wait");
json_add_invoice(response, details);
command_failed(cmd, response);
}
}
static void tell_waiter_deleted(struct command *cmd)
{
command_fail(cmd, LIGHTNINGD, "Invoice deleted during wait");
@ -209,7 +213,7 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
const int *fs,
struct invoice_info *info)
{
struct json_result *response = new_json_result(info->cmd);
struct json_result *response;
struct route_info *inchans;
bool any_offline;
struct invoice invoice;
@ -257,6 +261,7 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
/* Get details */
details = wallet_invoice_details(info, wallet, invoice);
response = json_stream_success(info->cmd);
json_object_start(response, NULL);
json_add_hex(response, "payment_hash", details->rhash.u.u8,
sizeof(details->rhash));
@ -413,12 +418,13 @@ static void json_listinvoices(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct json_escaped *label;
struct json_result *response = new_json_result(cmd);
struct json_result *response;
struct wallet *wallet = cmd->ld->wallet;
if (!param(cmd, buffer, params,
p_opt("label", json_tok_label, &label),
NULL))
return;
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_array_start(response, "invoices");
json_add_invoices(response, wallet, label);
@ -439,7 +445,7 @@ static void json_delinvoice(struct command *cmd,
{
struct invoice i;
const struct invoice_details *details;
struct json_result *response = new_json_result(cmd);
struct json_result *response;
const char *status, *actual_status;
struct json_escaped *label;
struct wallet *wallet = cmd->ld->wallet;
@ -466,10 +472,6 @@ static void json_delinvoice(struct command *cmd,
return;
}
/* Get invoice details before attempting to delete, as
* otherwise the invoice will be freed. */
json_add_invoice(response, details);
if (!wallet_invoice_delete(wallet, i)) {
log_broken(cmd->ld->log,
"Error attempting to remove invoice %"PRIu64,
@ -478,6 +480,8 @@ static void json_delinvoice(struct command *cmd,
return;
}
response = json_stream_success(cmd);
json_add_invoice(response, details);
command_success(cmd, response);
}
@ -492,7 +496,6 @@ static void json_delexpiredinvoice(struct command *cmd, const char *buffer,
const jsmntok_t *params)
{
u64 *maxexpirytime;
struct json_result *result;
if (!param(cmd, buffer, params,
p_opt_def("maxexpirytime", json_tok_u64, &maxexpirytime,
@ -502,10 +505,7 @@ static void json_delexpiredinvoice(struct command *cmd, const char *buffer,
wallet_invoice_delete_expired(cmd->ld->wallet, *maxexpirytime);
result = new_json_result(cmd);
json_object_start(result, NULL);
json_object_end(result);
command_success(cmd, result);
command_success(cmd, null_response(cmd));
}
static const struct json_command delexpiredinvoice_command = {
"delexpiredinvoice",
@ -520,7 +520,6 @@ static void json_autocleaninvoice(struct command *cmd,
{
u64 *cycle;
u64 *exby;
struct json_result *result;
if (!param(cmd, buffer, params,
p_opt_def("cycle_seconds", json_tok_u64, &cycle, 3600),
@ -530,10 +529,7 @@ static void json_autocleaninvoice(struct command *cmd,
wallet_invoice_autoclean(cmd->ld->wallet, *cycle, *exby);
result = new_json_result(cmd);
json_object_start(result, NULL);
json_object_end(result);
command_success(cmd, result);
command_success(cmd, null_response(cmd));
}
static const struct json_command autocleaninvoice_command = {
"autocleaninvoice",
@ -672,7 +668,7 @@ static void json_decodepay(struct command *cmd,
return;
}
response = new_json_result(cmd);
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_string(response, "currency", b11->chain->bip173_name);

24
lightningd/json.c

@ -703,9 +703,9 @@ void json_add_escaped_string(struct json_result *result, const char *fieldname,
tal_free(esc);
}
struct json_result *new_json_result(const tal_t *ctx)
static struct json_result *new_json_stream(struct command *cmd)
{
struct json_result *r = tal(ctx, struct json_result);
struct json_result *r = tal(cmd, struct json_result);
r->s = tal_strdup(r, "");
#if DEVELOPER
@ -713,9 +713,29 @@ struct json_result *new_json_result(const tal_t *ctx)
#endif
r->indent = 0;
r->empty = true;
assert(!cmd->have_json_stream);
cmd->have_json_stream = true;
return r;
}
struct json_result *json_stream_success(struct command *cmd)
{
cmd->failcode = 0;
return new_json_stream(cmd);
}
struct json_result *json_stream_fail(struct command *cmd,
int code,
const char *errmsg)
{
assert(code);
assert(errmsg);
cmd->failcode = code;
cmd->errmsg = tal_strdup(cmd, errmsg);
return new_json_stream(cmd);
}
const char *json_result_string(const struct json_result *result)
{
#if DEVELOPER

22
lightningd/json.h

@ -170,7 +170,27 @@ void json_array_end(struct json_result *ptr);
/* ' }, ' */
void json_object_end(struct json_result *ptr);
struct json_result *new_json_result(const tal_t *ctx);
/**
* json_stream_success - start streaming a successful json result.
* @cmd: the command we're running.
*
* The returned value should go to command_success() when done.
* json_add_* will be placed into the 'result' field of the JSON reply.
*/
struct json_result *json_stream_success(struct command *cmd);
/**
* json_stream_fail - start streaming a failed json result.
* @cmd: the command we're running.
* @code: the error code from lightningd/jsonrpc_errors.h
* @errmsg: the error string.
*
* The returned value should go to command_failed() when done;
* json_add_* will be placed into the 'data' field of the 'error' JSON reply.
*/
struct json_result *json_stream_fail(struct command *cmd,
int code,
const char *errmsg);
/* '"fieldname" : "value"' or '"value"' if fieldname is NULL. Turns
* any non-printable chars into JSON escapes, but leaves existing escapes alone.

38
lightningd/jsonrpc.c

@ -73,13 +73,14 @@ AUTODATA(json_command, &help_command);
static void json_stop(struct command *cmd,
const char *buffer UNUSED, const jsmntok_t *params UNUSED)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
if (!param(cmd, buffer, params, NULL))
return;
/* This can't have closed yet! */
cmd->jcon->stop = true;
response = json_stream_success(cmd);
json_add_string(response, NULL, "Shutting down");
command_success(cmd, response);
}
@ -95,7 +96,7 @@ AUTODATA(json_command, &stop_command);
static void json_rhash(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
struct sha256 *secret;
if (!param(cmd, buffer, params,
@ -105,6 +106,7 @@ static void json_rhash(struct command *cmd,
/* Hash in place. */
sha256(secret, secret, sizeof(*secret));
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_hex(response, "rhash", secret, sizeof(*secret));
json_object_end(response);
@ -138,11 +140,12 @@ AUTODATA(json_command, &dev_crash_command);
static void json_getinfo(struct command *cmd,
const char *buffer UNUSED, const jsmntok_t *params UNUSED)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
if (!param(cmd, buffer, params, NULL))
return;
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_pubkey(response, "id", &cmd->ld->id);
json_add_string(response, "alias", (const char *)cmd->ld->alias);
@ -222,7 +225,7 @@ static void json_help(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
unsigned int i;
struct json_result *response = new_json_result(cmd);
struct json_result *response;
struct json_command **cmdlist = get_cmdlist();
const jsmntok_t *cmdtok;
@ -234,6 +237,7 @@ static void json_help(struct command *cmd,
if (cmdtok) {
for (i = 0; i < num_cmdlist; i++) {
if (json_tok_streq(buffer, cmdtok, cmdlist[i]->name)) {
response = json_stream_success(cmd);
json_add_help_command(cmd, response, cmdlist[i]);
goto done;
}
@ -245,6 +249,7 @@ static void json_help(struct command *cmd,
return;
}
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_array_start(response, "help");
for (i = 0; i < num_cmdlist; i++) {
@ -341,11 +346,11 @@ static void connection_complete_error(struct json_connection *jcon,
id)));
}
struct json_result *null_response(const tal_t *ctx)
struct json_result *null_response(struct command *cmd)
{
struct json_result *response;
response = new_json_result(ctx);
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_object_end(response);
return response;
@ -365,12 +370,11 @@ void command_success(struct command *cmd, struct json_result *result)
connection_complete_ok(jcon, cmd, cmd->id, result);
}
static void command_fail_v(struct command *cmd,
static void command_fail_generic(struct command *cmd,
int code,
const struct json_result *data,
const char *fmt, va_list ap)
const char *error)
{
char *error;
struct json_connection *jcon = cmd->jcon;
if (!jcon) {
@ -381,8 +385,6 @@ static void command_fail_v(struct command *cmd,
return;
}
error = tal_vfmt(cmd, fmt, ap);
/* cmd->json_cmd can be NULL, if we're failing for command not found! */
log_debug(jcon->log, "Failing %s: %s",
cmd->json_cmd ? cmd->json_cmd->name : "invalid cmd",
@ -392,21 +394,18 @@ static void command_fail_v(struct command *cmd,
connection_complete_error(jcon, cmd, cmd->id, error, code, data);
}
void command_fail(struct command *cmd, int code, const char *fmt, ...)
void command_failed(struct command *cmd, struct json_result *result)
{
va_list ap;
va_start(ap, fmt);
command_fail_v(cmd, code, NULL, fmt, ap);
va_end(ap);
assert(cmd->failcode != 0);
command_fail_generic(cmd, cmd->failcode, result, cmd->errmsg);
}
void command_fail_detailed(struct command *cmd,
int code, const struct json_result *data,
void PRINTF_FMT(3, 4) command_fail(struct command *cmd, int code,
const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
command_fail_v(cmd, code, data, fmt, ap);
command_fail_generic(cmd, code, NULL, tal_vfmt(cmd, fmt, ap));
va_end(ap);
}
@ -457,6 +456,7 @@ static bool parse_request(struct json_connection *jcon, const jsmntok_t tok[])
c->jcon = jcon;
c->ld = jcon->ld;
c->pending = false;
c->have_json_stream = false;
c->id = tal_strndup(c,
json_tok_contents(jcon->buffer, id),
json_tok_len(id));

13
lightningd/jsonrpc.h

@ -38,6 +38,12 @@ struct command {
/* This is created if mode is CMD_USAGE */
const char *usage;
bool *ok;
/* Have we started a json stream already? For debugging. */
bool have_json_stream;
/* FIXME: Temporary. */
int failcode;
const char *errmsg;
};
struct json_connection {
@ -79,14 +85,11 @@ struct json_command {
const char *verbose;
};
struct json_result *null_response(const tal_t *ctx);
struct json_result *null_response(struct command *cmd);
void command_success(struct command *cmd, struct json_result *response);
void command_failed(struct command *cmd, struct json_result *result);
void PRINTF_FMT(3, 4) command_fail(struct command *cmd, int code,
const char *fmt, ...);
void PRINTF_FMT(4, 5) command_fail_detailed(struct command *cmd,
int code,
const struct json_result *data,
const char *fmt, ...);
/* Mainly for documentation, that we plan to close this later. */
void command_still_pending(struct command *cmd);

3
lightningd/log.c

@ -718,7 +718,7 @@ bool json_tok_loglevel(struct command *cmd, const char *name,
static void json_getlog(struct command *cmd,
const char *buffer, const jsmntok_t * params)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
enum log_level *minlevel;
struct log_book *lr = cmd->ld->log_book;
@ -728,6 +728,7 @@ static void json_getlog(struct command *cmd,
NULL))
return;
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_time(response, "created_at", log_init_time(lr)->ts);
json_add_num(response, "bytes_used", (unsigned int) log_used(lr));

6
lightningd/memdump.c

@ -56,11 +56,12 @@ static void json_memdump(struct command *cmd,
const char *buffer UNNEEDED,
const jsmntok_t *params UNNEEDED)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
if (!param(cmd, buffer, params, NULL))
return;
response = json_stream_success(cmd);
add_memdump(response, NULL, NULL, cmd);
command_success(cmd, response);
@ -153,7 +154,7 @@ static void json_memleak(struct command *cmd,
const char *buffer UNNEEDED,
const jsmntok_t *params UNNEEDED)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
if (!param(cmd, buffer, params, NULL))
return;
@ -164,6 +165,7 @@ static void json_memleak(struct command *cmd,
return;
}
response = json_stream_success(cmd);
json_object_start(response, NULL);
scan_mem(cmd, response, cmd->ld);
json_object_end(response);

2
lightningd/opening_control.c

@ -377,7 +377,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
wallet_confirm_utxos(ld->wallet, fc->wtx.utxos);
response = new_json_result(fc->cmd);
response = json_stream_success(fc->cmd);
json_object_start(response, NULL);
linear = linearize_tx(response, fundingtx);
json_add_hex_talarr(response, "tx", linear);

16
lightningd/options.c

@ -978,18 +978,19 @@ static void json_listconfigs(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
size_t i;
struct json_result *response = new_json_result(cmd);
struct json_result *response = NULL;
const jsmntok_t *configtok;
bool found = false;
if (!param(cmd, buffer, params,
p_opt("config", json_tok_tok, &configtok),
NULL))
return;
if (!configtok) {
response = json_stream_success(cmd);
json_object_start(response, NULL);
if (!configtok)
json_add_string(response, "# version", version());
}
for (i = 0; i < opt_count; i++) {
unsigned int len;
@ -1012,20 +1013,23 @@ static void json_listconfigs(struct command *cmd,
name + 1, len - 1))
continue;
found = true;
if (!response) {
response = json_stream_success(cmd);
json_object_start(response, NULL);
}
add_config(cmd->ld, response, &opt_table[i],
name+1, len-1);
}
}
json_object_end(response);
if (configtok && !found) {
if (configtok && !response) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Unknown config option '%.*s'",
configtok->end - configtok->start,
buffer + configtok->start);
return;
}
json_object_end(response);
command_success(cmd, response);
}

49
lightningd/pay.c

@ -851,7 +851,7 @@ json_sendpay_success(struct command *cmd,
assert(r->payment->status == PAYMENT_COMPLETE);
response = new_json_result(cmd);
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_payment_fields(response, r->payment);
json_object_end(response);
@ -863,13 +863,13 @@ static void json_waitsendpay_on_resolve(const struct sendpay_result *r,
{
struct command *cmd = (struct command*) vcmd;
struct json_result *data = NULL;
const char *msg = NULL;
struct routing_failure *fail;
if (r->succeeded)
json_sendpay_success(cmd, r);
else {
struct json_result *data;
switch (r->errorcode) {
/* We will never handle this case */
case PAY_IN_PROGRESS:
@ -878,28 +878,30 @@ static void json_waitsendpay_on_resolve(const struct sendpay_result *r,
case PAY_RHASH_ALREADY_USED:
case PAY_UNSPECIFIED_ERROR:
case PAY_NO_SUCH_PAYMENT:
data = NULL;
msg = r->details;
break;
command_fail(cmd, r->errorcode, "%s", r->details);
return;
case PAY_UNPARSEABLE_ONION:
data = new_json_result(cmd);
json_object_start(data, NULL);
json_add_hex_talarr(data, "onionreply", r->onionreply);
json_object_end(data);
assert(r->details != NULL);
msg = tal_fmt(cmd,
msg = tal_fmt(tmpctx,
"failed: WIRE_PERMANENT_NODE_FAILURE "
"(%s)",
r->details);
break;
data = json_stream_fail(cmd, r->errorcode, msg);
json_object_start(data, NULL);
json_add_hex_talarr(data, "onionreply", r->onionreply);
json_object_end(data);
command_failed(cmd, data);
return;
case PAY_DESTINATION_PERM_FAIL:
case PAY_TRY_OTHER_ROUTE:
fail = r->routing_failure;
data = new_json_result(cmd);
msg = tal_fmt(cmd,
"failed: %s (%s)",
onion_type_name(fail->failcode),
r->details);
data = json_stream_fail(cmd, r->errorcode, msg);
json_object_start(data, NULL);
json_add_num(data, "erring_index",
@ -913,18 +915,10 @@ static void json_waitsendpay_on_resolve(const struct sendpay_result *r,
json_add_hex_talarr(data, "channel_update",
fail->channel_update);
json_object_end(data);
assert(r->details != NULL);
msg = tal_fmt(cmd,
"failed: %s (%s)",
onion_type_name(fail->failcode),
r->details);
break;
command_failed(cmd, data);
return;
}
assert(msg);
command_fail_detailed(cmd, r->errorcode, data, "%s", msg);
abort();
}
}
@ -935,7 +929,7 @@ static void json_sendpay_on_resolve(const struct sendpay_result* r,
if (!r->succeeded && r->errorcode == PAY_IN_PROGRESS) {
/* This is normal for sendpay. Succeed. */
struct json_result *response = new_json_result(cmd);
struct json_result *response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_string(response, "message",
"Monitor status with listpayments or waitsendpay");
@ -1064,7 +1058,7 @@ static void json_listpayments(struct command *cmd, const char *buffer,
const jsmntok_t *params)
{
const struct wallet_payment **payments;
struct json_result *response = new_json_result(cmd);
struct json_result *response;
struct sha256 *rhash;
const char *b11str;
@ -1096,6 +1090,7 @@ static void json_listpayments(struct command *cmd, const char *buffer,
payments = wallet_payment_list(cmd, cmd->ld->wallet, rhash);
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_array_start(response, "payments");

80
lightningd/payalgo.c

@ -196,7 +196,7 @@ json_pay_success(struct pay *pay,
struct command *cmd = pay->cmd;
struct json_result *response;
response = new_json_result(cmd);
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_payment_fields(response, r->payment);
json_add_num(response, "getroute_tries", pay->getroute_tries);
@ -212,42 +212,44 @@ static void json_pay_failure(struct pay *pay,
const struct sendpay_result *r)
{
struct json_result *data;
const char *msg = NULL;
struct routing_failure *fail;
assert(!r->succeeded);
data = new_json_result(pay);
switch (r->errorcode) {
case PAY_IN_PROGRESS:
data = json_stream_fail(pay->cmd, r->errorcode, r->details);
json_object_start(data, NULL);
json_add_num(data, "getroute_tries", pay->getroute_tries);
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
json_add_payment_fields(data, r->payment);
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
msg = r->details;
break;
return;
case PAY_RHASH_ALREADY_USED:
case PAY_STOPPED_RETRYING:
data = json_stream_fail(pay->cmd, r->errorcode, r->details);
json_object_start(data, NULL);
json_add_num(data, "getroute_tries", pay->getroute_tries);
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
msg = r->details;
break;
return;
case PAY_UNPARSEABLE_ONION:
/* Impossible case */
abort();
break;
case PAY_DESTINATION_PERM_FAIL:
fail = r->routing_failure;
assert(r->details != NULL);
data = json_stream_fail(pay->cmd,
r->errorcode,
tal_fmt(tmpctx, "failed: %s (%s)",
onion_type_name(fail->failcode),
r->details));
json_object_start(data, NULL);
json_add_num(data, "erring_index",
fail->erring_index);
@ -261,23 +263,14 @@ static void json_pay_failure(struct pay *pay,
fail->channel_update);
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
assert(r->details != NULL);
msg = tal_fmt(pay,
"failed: %s (%s)",
onion_type_name(fail->failcode),
r->details);
break;
return;
case PAY_TRY_OTHER_ROUTE:
/* Impossible case */
abort();
break;
return;
}
assert(msg);
command_fail_detailed(pay->cmd, r->errorcode, data, "%s", msg);
abort();
}
/* Determine if we should delay before retrying. Return a reason
@ -422,14 +415,14 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
fromwire_gossip_getroute_reply(reply, reply, &route);
if (tal_count(route) == 0) {
data = new_json_result(pay);
data = json_stream_fail(pay->cmd, PAY_ROUTE_NOT_FOUND,
"Could not find a route");
json_object_start(data, NULL);
json_add_num(data, "getroute_tries", pay->getroute_tries);
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
command_fail_detailed(pay->cmd, PAY_ROUTE_NOT_FOUND, data,
"Could not find a route");
command_failed(pay->cmd, data);
return;
}
@ -444,21 +437,6 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
delay_too_high = (route[0].delay > pay->maxdelay);
/* compare fuzz to range */
if ((fee_too_high || delay_too_high) && pay->fuzz < 0.01) {
data = new_json_result(pay);
json_object_start(data, NULL);
json_add_u64(data, "msatoshi", pay->msatoshi);
json_add_u64(data, "fee", fee);
json_add_double(data, "feepercent", feepercent);
json_add_double(data, "maxfeepercent", pay->maxfeepercent);
json_add_u64(data, "delay", (u64) route[0].delay);
json_add_num(data, "maxdelay", pay->maxdelay);
json_add_num(data, "getroute_tries", pay->getroute_tries);
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
json_add_route(data, "route",
route, tal_count(route));
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
err = "";
if (fee_too_high)
err = tal_fmt(pay,
@ -477,9 +455,22 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
"max delay requested is %u.",
err, route[0].delay, pay->maxdelay);
data = json_stream_fail(pay->cmd, PAY_ROUTE_TOO_EXPENSIVE, err);
json_object_start(data, NULL);
json_add_u64(data, "msatoshi", pay->msatoshi);
json_add_u64(data, "fee", fee);
json_add_double(data, "feepercent", feepercent);
json_add_double(data, "maxfeepercent", pay->maxfeepercent);
json_add_u64(data, "delay", (u64) route[0].delay);
json_add_num(data, "maxdelay", pay->maxdelay);
json_add_num(data, "getroute_tries", pay->getroute_tries);
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
json_add_route(data, "route",
route, tal_count(route));
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
command_fail_detailed(pay->cmd, PAY_ROUTE_TOO_EXPENSIVE,
data, "%s", err);
command_failed(pay->cmd, data);
return;
}
if (fee_too_high || delay_too_high) {
@ -519,7 +510,9 @@ static bool json_pay_try(struct pay *pay)
/* If too late anyway, fail now. */
if (time_after(now, pay->expiry)) {
struct json_result *data = new_json_result(cmd);
struct json_result *data
= json_stream_fail(cmd, PAY_INVOICE_EXPIRED,
"Invoice expired");
json_object_start(data, NULL);
json_add_num(data, "now", now.ts.tv_sec);
json_add_num(data, "expiry", pay->expiry.ts.tv_sec);
@ -527,8 +520,7 @@ static bool json_pay_try(struct pay *pay)
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
command_fail_detailed(cmd, PAY_INVOICE_EXPIRED, data,
"Invoice expired");
command_failed(cmd, data);
return false;
}

10
lightningd/peer_control.c

@ -232,7 +232,7 @@ static void remove_sig(struct bitcoin_tx *signed_tx)
static void
resolve_one_close_command(struct close_command *cc, bool cooperative)
{
struct json_result *result = new_json_result(cc);
struct json_result *result = json_stream_success(cc->cmd);
u8 *tx = linearize_tx(result, cc->channel->last_tx);
struct bitcoin_txid txid;
@ -818,7 +818,7 @@ static void json_listpeers(struct command *cmd,
enum log_level *ll;
struct pubkey *specific_id;
struct peer *peer;
struct json_result *response = new_json_result(cmd);
struct json_result *response;
if (!param(cmd, buffer, params,
p_opt("id", json_tok_pubkey, &specific_id),
@ -826,6 +826,7 @@ static void json_listpeers(struct command *cmd,
NULL))
return;
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_array_start(response, "peers");
if (specific_id) {
@ -1083,7 +1084,7 @@ static void json_sign_last_tx(struct command *cmd,
{
struct pubkey *peerid;
struct peer *peer;
struct json_result *response = new_json_result(cmd);
struct json_result *response;
u8 *linear;
struct channel *channel;
@ -1105,6 +1106,7 @@ static void json_sign_last_tx(struct command *cmd,
return;
}
response = json_stream_success(cmd);
log_debug(channel->log, "dev-sign-last-tx: signing tx with %zu outputs",
tal_count(channel->last_tx->output));
sign_last_tx(channel);
@ -1244,7 +1246,7 @@ static void process_dev_forget_channel(struct bitcoind *bitcoind UNUSED,
"channel");
return;
}
response = new_json_result(forget->cmd);
response = json_stream_success(forget->cmd);
json_object_start(response, NULL);
json_add_bool(response, "forced", forget->force);
json_add_bool(response, "funding_unspent", txout != NULL);

2
lightningd/ping.c

@ -69,7 +69,7 @@ void ping_reply(struct subd *subd, const u8 *msg)
else if (!sent)
command_fail(pc->cmd, LIGHTNINGD, "Unknown peer");
else {
struct json_result *response = new_json_result(pc->cmd);
struct json_result *response = json_stream_success(pc->cmd);
json_object_start(response, NULL);
json_add_num(response, "totlen", totlen);

22
lightningd/test/run-invoice-select-inchan.c

@ -48,12 +48,9 @@ bool channel_tell_funding_locked(struct lightningd *ld UNNEEDED,
void command_fail(struct command *cmd UNNEEDED, int code UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "command_fail called!\n"); abort(); }
/* Generated stub for command_fail_detailed */
void command_fail_detailed(struct command *cmd UNNEEDED,
int code UNNEEDED,
const struct json_result *data UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "command_fail_detailed called!\n"); abort(); }
/* Generated stub for command_failed */
void command_failed(struct command *cmd UNNEEDED, struct json_result *result UNNEEDED)
{ fprintf(stderr, "command_failed called!\n"); abort(); }
/* Generated stub for command_still_pending */
void command_still_pending(struct command *cmd UNNEEDED)
{ fprintf(stderr, "command_still_pending called!\n"); abort(); }
@ -162,6 +159,14 @@ void json_object_end(struct json_result *ptr UNNEEDED)
/* Generated stub for json_object_start */
void json_object_start(struct json_result *ptr UNNEEDED, const char *fieldname UNNEEDED)
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
/* Generated stub for json_stream_fail */
struct json_result *json_stream_fail(struct command *cmd UNNEEDED,
int code UNNEEDED,
const char *errmsg UNNEEDED)
{ fprintf(stderr, "json_stream_fail called!\n"); abort(); }
/* Generated stub for json_stream_success */
struct json_result *json_stream_success(struct command *cmd UNNEEDED)
{ fprintf(stderr, "json_stream_success called!\n"); abort(); }
/* Generated stub for json_tok_address_scriptpubkey */
enum address_parse_result json_tok_address_scriptpubkey(const tal_t *ctx UNNEEDED,
const struct chainparams *chainparams UNNEEDED,
@ -258,9 +263,6 @@ void log_io(struct log *log UNNEEDED, enum log_level dir UNNEEDED, const char *c
/* Generated stub for new_bolt11 */
struct bolt11 *new_bolt11(const tal_t *ctx UNNEEDED, u64 *msatoshi UNNEEDED)
{ fprintf(stderr, "new_bolt11 called!\n"); abort(); }
/* Generated stub for new_json_result */
struct json_result *new_json_result(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "new_json_result called!\n"); abort(); }
/* Generated stub for new_log */
struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED, const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "new_log called!\n"); abort(); }
@ -275,7 +277,7 @@ struct oneshot *new_reltimer_(struct timers *timers UNNEEDED,
void (*cb)(void *) UNNEEDED, void *arg UNNEEDED)
{ fprintf(stderr, "new_reltimer_ called!\n"); abort(); }
/* Generated stub for null_response */
struct json_result *null_response(const tal_t *ctx UNNEEDED)
struct json_result *null_response(struct command *cmd UNNEEDED)
{ fprintf(stderr, "null_response called!\n"); abort(); }
/* Generated stub for onchaind_funding_spent */
enum watch_result onchaind_funding_spent(struct channel *channel UNNEEDED,

10
lightningd/test/run-jsonrpc.c

@ -70,7 +70,8 @@ bool deprecated_apis;
static int test_json_filter(void)
{
struct json_result *result = new_json_result(NULL);
struct command *cmd = talz(NULL, struct command);
struct json_result *result = json_stream_success(cmd);
jsmntok_t *toks;
const jsmntok_t *x;
bool valid;
@ -105,7 +106,7 @@ static int test_json_filter(void)
assert((unsigned)str[i] >= ' ');
assert((unsigned)str[i] != 127);
}
tal_free(result);
tal_free(cmd);
return 0;
}
@ -115,7 +116,8 @@ static void test_json_escape(void)
for (i = 1; i < 256; i++) {
char badstr[2];
struct json_result *result = new_json_result(NULL);
struct command *cmd = talz(NULL, struct command);
struct json_result *result = json_stream_success(cmd);
struct json_escaped *esc;
badstr[0] = i;
@ -138,7 +140,7 @@ static void test_json_escape(void)
expect[11] = i;
assert(streq(str, expect));
}
tal_free(result);
tal_free(cmd);
}
}

12
lightningd/test/run-param.c

@ -30,18 +30,6 @@ void command_fail(struct command *cmd, int code, const char *fmt, ...)
va_end(ap);
}
void command_fail_detailed(struct command *cmd, int code,
const struct json_result *data, const char *fmt, ...)
{
failed = true;
va_list ap;
va_start(ap, fmt);
fail_msg = tal_vfmt(cmd, fmt, ap);
fail_msg =
tal_fmt(cmd, "%s data: %s", fail_msg, json_result_string(data));
va_end(ap);
}
/* AUTOGENERATED MOCKS START */
/* Generated stub for feerate_from_style */
u32 feerate_from_style(u32 feerate UNNEEDED, enum feerate_style style UNNEEDED)

8
wallet/test/run-wallet.c

@ -234,6 +234,9 @@ void json_object_end(struct json_result *ptr UNNEEDED)
/* Generated stub for json_object_start */
void json_object_start(struct json_result *ptr UNNEEDED, const char *fieldname UNNEEDED)
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
/* Generated stub for json_stream_success */
struct json_result *json_stream_success(struct command *cmd UNNEEDED)
{ fprintf(stderr, "json_stream_success called!\n"); abort(); }
/* Generated stub for json_tok_bool */
bool json_tok_bool(struct command *cmd UNNEEDED, const char *name UNNEEDED,
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
@ -287,11 +290,8 @@ void log_add(struct log *log UNNEEDED, const char *fmt UNNEEDED, ...)
void log_io(struct log *log UNNEEDED, enum log_level dir UNNEEDED, const char *comment UNNEEDED,
const void *data UNNEEDED, size_t len UNNEEDED)
{ fprintf(stderr, "log_io called!\n"); abort(); }
/* Generated stub for new_json_result */
struct json_result *new_json_result(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "new_json_result called!\n"); abort(); }
/* Generated stub for null_response */
struct json_result *null_response(const tal_t *ctx UNNEEDED)
struct json_result *null_response(struct command *cmd UNNEEDED)
{ fprintf(stderr, "null_response called!\n"); abort(); }
/* Generated stub for onchaind_funding_spent */
enum watch_result onchaind_funding_spent(struct channel *channel UNNEEDED,

28
wallet/walletrpc.c

@ -65,7 +65,7 @@ static void wallet_withdrawal_broadcast(struct bitcoind *bitcoind UNUSED,
* not if we're actually making a payment to ourselves! */
assert(change_satoshi >= withdraw->wtx.change);
struct json_result *response = new_json_result(cmd);
struct json_result *response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_string(response, "tx", withdraw->hextx);
json_add_string(response, "txid", output);
@ -242,7 +242,7 @@ static bool json_tok_newaddr(struct command *cmd, const char *name,
static void json_newaddr(struct command *cmd, const char *buffer UNUSED,
const jsmntok_t *params UNUSED)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
struct ext_key ext;
struct pubkey pubkey;
bool *is_p2wpkh;
@ -283,6 +283,7 @@ static void json_newaddr(struct command *cmd, const char *buffer UNUSED,
return;
}
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_string(response, "address", out);
json_object_end(response);
@ -300,7 +301,7 @@ AUTODATA(json_command, &newaddr_command);
static void json_listaddrs(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
struct ext_key ext;
struct pubkey pubkey;
u64 *bip32_max_index;
@ -312,6 +313,7 @@ static void json_listaddrs(struct command *cmd,
NULL))
return;
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_array_start(response, "addresses");
@ -323,15 +325,12 @@ static void json_listaddrs(struct command *cmd,
if (bip32_key_from_parent(cmd->ld->wallet->bip32_base, keyidx,
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
command_fail(cmd, LIGHTNINGD,
"Keys generation failure");
return;
abort();
}
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey.pubkey,
ext.pub_key, sizeof(ext.pub_key))) {
command_fail(cmd, LIGHTNINGD, "Key parsing failure");
return;
abort();
}
// p2sh
@ -348,9 +347,7 @@ static void json_listaddrs(struct command *cmd,
false,
&redeemscript_p2wpkh);
if (!out_p2wpkh) {
command_fail(cmd, LIGHTNINGD,
"p2wpkh address encoding failure.");
return;
abort();
}
// outputs
@ -382,16 +379,17 @@ AUTODATA(json_command, &listaddrs_command);
static void json_listfunds(struct command *cmd, const char *buffer UNUSED,
const jsmntok_t *params UNUSED)
{
struct json_result *response = new_json_result(cmd);
struct json_result *response;
struct peer *p;
struct utxo **utxos =
wallet_get_utxos(cmd, cmd->ld->wallet, output_state_available);
struct utxo **utxos;
char* out;
struct pubkey funding_pubkey;
if (!param(cmd, buffer, params, NULL))
return;
utxos = wallet_get_utxos(cmd, cmd->ld->wallet, output_state_available);
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_array_start(response, "outputs");
for (size_t i = 0; i < tal_count(utxos); i++) {
@ -513,7 +511,7 @@ static void json_dev_rescan_outputs(struct command *cmd,
if (!param(cmd, buffer, params, NULL))
return;
rescan->response = new_json_result(cmd);
rescan->response = json_stream_success(cmd);
rescan->cmd = cmd;
/* Open the result structure so we can incrementally add results */

Loading…
Cancel
Save