Browse Source

param: make command_fail/command_success WARN_UNUSED_RESULT.

This causes a compiler warning if we don't do something with the
result (hopefully return immediately!).

We use was_pending() to ignore the result in the case where we
complete a command in a callback (thus really do want to ignore
the result).

This actually fixes one bug: we didn't return after command_fail
in json_getroute with a bad seed value.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
plugin-7
Rusty Russell 6 years ago
parent
commit
819078fe18
  1. 2
      common/json_command.h
  2. 6
      common/param.c
  3. 3
      lightningd/chaintopology.c
  4. 2
      lightningd/connect_control.c
  5. 40
      lightningd/gossip_control.c
  6. 19
      lightningd/invoice.c
  7. 12
      lightningd/jsonrpc.h
  8. 13
      lightningd/memdump.c
  9. 47
      lightningd/opening_control.c
  10. 14
      lightningd/pay.c
  11. 35
      lightningd/payalgo.c
  12. 84
      lightningd/peer_control.c
  13. 7
      lightningd/ping.c
  14. 2
      tools/mockup.sh
  15. 9
      wallet/walletrpc.c

2
common/json_command.h

@ -12,7 +12,7 @@ struct command_result;
/* Caller supplied this: param assumes it can call it. */
struct command_result *command_fail(struct command *cmd, int code,
const char *fmt, ...)
PRINTF_FMT(3, 4);
PRINTF_FMT(3, 4) WARN_UNUSED_RESULT;
/* Also caller supplied: is this invoked simply to get usage? */
bool command_usage_only(const struct command *cmd);

6
common/param.c

@ -280,8 +280,10 @@ bool param(struct command *cmd, const char *buffer,
continue;
}
if (!param_add(&params, name, required, cbx, arg)) {
command_fail(cmd, PARAM_DEV_ERROR,
"developer error: param_add %s", name);
/* We really do ignore this return! */
if (command_fail(cmd, PARAM_DEV_ERROR,
"developer error: param_add %s", name))
;
va_end(ap);
return false;
}

3
lightningd/chaintopology.c

@ -139,7 +139,8 @@ static void broadcast_remainder(struct bitcoind *bitcoind,
txs->cursor++;
if (txs->cursor == tal_count(txs->txs)) {
if (txs->cmd)
command_success(txs->cmd, null_response(txs->cmd));
was_pending(command_success(txs->cmd,
null_response(txs->cmd)));
tal_free(txs);
return;
}

2
lightningd/connect_control.c

@ -245,7 +245,7 @@ static void connect_failed(struct lightningd *ld, const u8 *msg)
/* We can have multiple connect commands: fail them all */
while ((c = find_connect(ld, &id)) != NULL) {
/* They delete themselves from list */
command_fail(c->cmd, LIGHTNINGD, "%s", err);
was_pending(command_fail(c->cmd, LIGHTNINGD, "%s", err));
}
/* If we have an active channel, then reconnect. */

40
lightningd/gossip_control.c

@ -201,7 +201,8 @@ static void json_getnodes_reply(struct subd *gossip UNUSED, const u8 *reply,
size_t i, j;
if (!fromwire_gossip_getnodes_reply(reply, reply, &nodes)) {
command_fail(cmd, LIGHTNINGD, "Malformed gossip_getnodes response");
was_pending(command_fail(cmd, LIGHTNINGD,
"Malformed gossip_getnodes response"));
return;
}
@ -241,7 +242,7 @@ static void json_getnodes_reply(struct subd *gossip UNUSED, const u8 *reply,
}
json_array_end(response);
json_object_end(response);
command_success(cmd, response);
was_pending(command_success(cmd, response));
}
static struct command_result *json_listnodes(struct command *cmd,
@ -278,7 +279,8 @@ static void json_getroute_reply(struct subd *gossip UNUSED, const u8 *reply, con
fromwire_gossip_getroute_reply(reply, reply, &hops);
if (tal_count(hops) == 0) {
command_fail(cmd, LIGHTNINGD, "Could not find a route");
was_pending(command_fail(cmd, LIGHTNINGD,
"Could not find a route"));
return;
}
@ -286,7 +288,7 @@ static void json_getroute_reply(struct subd *gossip UNUSED, const u8 *reply, con
json_object_start(response, NULL);
json_add_route(response, "route", hops, tal_count(hops));
json_object_end(response);
command_success(cmd, response);
was_pending(command_success(cmd, response));
}
static struct command_result *json_getroute(struct command *cmd,
@ -325,8 +327,9 @@ static struct command_result *json_getroute(struct command *cmd,
if (seedtok) {
if (seedtok->end - seedtok->start > sizeof(seed))
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"seed must be < %zu bytes", sizeof(seed));
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"seed must be < %zu bytes",
sizeof(seed));
memset(&seed, 0, sizeof(seed));
memcpy(&seed, buffer + seedtok->start,
@ -360,7 +363,8 @@ static void json_listchannels_reply(struct subd *gossip UNUSED, const u8 *reply,
struct json_stream *response;
if (!fromwire_gossip_getchannels_reply(reply, reply, &entries)) {
command_fail(cmd, LIGHTNINGD, "Invalid reply from gossipd");
was_pending(command_fail(cmd, LIGHTNINGD,
"Invalid reply from gossipd"));
return;
}
@ -396,7 +400,7 @@ static void json_listchannels_reply(struct subd *gossip UNUSED, const u8 *reply,
}
json_array_end(response);
json_object_end(response);
command_success(cmd, response);
was_pending(command_success(cmd, response));
}
static struct command_result *json_listchannels(struct command *cmd,
@ -432,14 +436,14 @@ static void json_scids_reply(struct subd *gossip UNUSED, const u8 *reply,
struct json_stream *response;
if (!fromwire_gossip_scids_reply(reply, &ok, &complete)) {
command_fail(cmd, LIGHTNINGD,
"Gossip gave bad gossip_scids_reply");
was_pending(command_fail(cmd, LIGHTNINGD,
"Gossip gave bad gossip_scids_reply"));
return;
}
if (!ok) {
command_fail(cmd, LIGHTNINGD,
"Gossip refused to query peer");
was_pending(command_fail(cmd, LIGHTNINGD,
"Gossip refused to query peer"));
return;
}
@ -447,7 +451,7 @@ static void json_scids_reply(struct subd *gossip UNUSED, const u8 *reply,
json_object_start(response, NULL);
json_add_bool(response, "complete", complete);
json_object_end(response);
command_success(cmd, response);
was_pending(command_success(cmd, response));
}
static struct command_result *json_dev_query_scids(struct command *cmd,
@ -538,14 +542,14 @@ static void json_channel_range_reply(struct subd *gossip UNUSED, const u8 *reply
&final_num_blocks,
&final_complete,
&scids)) {
command_fail(cmd, LIGHTNINGD,
"Gossip gave bad gossip_query_channel_range_reply");
was_pending(command_fail(cmd, LIGHTNINGD,
"Gossip gave bad gossip_query_channel_range_reply"));
return;
}
if (final_num_blocks == 0 && final_num_blocks == 0 && !final_complete) {
command_fail(cmd, LIGHTNINGD,
"Gossip refused to query peer");
was_pending(command_fail(cmd, LIGHTNINGD,
"Gossip refused to query peer"));
return;
}
@ -561,7 +565,7 @@ static void json_channel_range_reply(struct subd *gossip UNUSED, const u8 *reply
json_add_short_channel_id(response, NULL, &scids[i]);
json_array_end(response);
json_object_end(response);
command_success(cmd, response);
was_pending(command_success(cmd, response));
}
static struct command_result *json_dev_query_channel_range(struct command *cmd,

19
lightningd/invoice.c

@ -84,7 +84,8 @@ static struct command_result *tell_waiter(struct command *cmd,
static void tell_waiter_deleted(struct command *cmd)
{
command_fail(cmd, LIGHTNINGD, "Invoice deleted during wait");
was_pending(command_fail(cmd, LIGHTNINGD,
"Invoice deleted during wait"));
}
static void wait_on_invoice(const struct invoice *invoice, void *cmd)
{
@ -240,8 +241,9 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
/* Check duplicate preimage (unlikely unless they specified it!) */
if (wallet_invoice_find_by_rhash(wallet,
&invoice, &info->b11->payment_hash)) {
command_fail(info->cmd, INVOICE_PREIMAGE_ALREADY_EXISTS,
"preimage already used");
was_pending(command_fail(info->cmd,
INVOICE_PREIMAGE_ALREADY_EXISTS,
"preimage already used"));
return;
}
@ -254,8 +256,9 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
info->b11->description,
&info->payment_preimage,
&info->b11->payment_hash)) {
command_fail(info->cmd, INVOICE_LABEL_ALREADY_EXISTS,
"Duplicate label '%s'", info->label->s);
was_pending(command_fail(info->cmd, INVOICE_LABEL_ALREADY_EXISTS,
"Duplicate label '%s'",
info->label->s));
return;
}
@ -289,7 +292,7 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
}
json_object_end(response);
command_success(info->cmd, response);
was_pending(command_success(info->cmd, response));
}
static struct command_result *json_invoice(struct command *cmd,
@ -563,7 +566,7 @@ static struct command_result *json_waitanyinvoice(struct command *cmd,
/* Set command as pending. We do not know if
* wallet_invoice_waitany will return immediately
* or not, so indicating pending is safest. */
command_still_pending(cmd);
fixme_ignore(command_still_pending(cmd));
/* Find next paid invoice. */
wallet_invoice_waitany(cmd, wallet, *pay_index,
@ -610,7 +613,7 @@ static struct command_result *json_waitinvoice(struct command *cmd,
return tell_waiter(cmd, &i);
} else {
/* There is an unpaid one matching, let's wait... */
command_still_pending(cmd);
fixme_ignore(command_still_pending(cmd));
wallet_invoice_waitone(cmd, wallet, i,
&wait_on_invoice, (void *) cmd);
return command_its_complicated();

12
lightningd/jsonrpc.h

@ -96,12 +96,15 @@ struct json_stream *null_response(struct command *cmd);
/* These returned values are never NULL. */
struct command_result *command_success(struct command *cmd,
struct json_stream *response);
struct json_stream *response)
WARN_UNUSED_RESULT;
struct command_result *command_failed(struct command *cmd,
struct json_stream *result);
struct json_stream *result)
WARN_UNUSED_RESULT;
/* Mainly for documentation, that we plan to close this later. */
struct command_result *command_still_pending(struct command *cmd);
struct command_result *command_still_pending(struct command *cmd)
WARN_UNUSED_RESULT;
/* For low-level JSON stream access: */
struct json_stream *json_stream_raw_for_cmd(struct command *cmd);
@ -109,7 +112,8 @@ struct command_result *command_raw_complete(struct command *cmd,
struct json_stream *result);
/* To return if param() fails. */
extern struct command_result *command_param_failed(void);
extern struct command_result *command_param_failed(void)
WARN_UNUSED_RESULT;
/* Wrapper for pending commands (ignores return) */
static inline void was_pending(const struct command_result *res)

13
lightningd/memdump.c

@ -181,7 +181,7 @@ static void report_leak_info2(struct leak_info *leak_info)
scan_mem(leak_info->cmd, response, leak_info->cmd->ld, leak_info->leaker);
json_object_end(response);
command_success(leak_info->cmd, response);
was_pending(command_success(leak_info->cmd, response));
}
static void report_leak_info(struct command *cmd, struct subd *leaker)
@ -205,7 +205,8 @@ static void gossip_dev_memleak_done(struct subd *gossipd,
bool found_leak;
if (!fromwire_gossip_dev_memleak_reply(reply, &found_leak)) {
command_fail(cmd, LIGHTNINGD, "Bad gossip_dev_memleak");
was_pending(command_fail(cmd, LIGHTNINGD,
"Bad gossip_dev_memleak"));
return;
}
@ -221,7 +222,8 @@ static void connect_dev_memleak_done(struct subd *connectd,
bool found_leak;
if (!fromwire_connect_dev_memleak_reply(reply, &found_leak)) {
command_fail(cmd, LIGHTNINGD, "Bad connect_dev_memleak");
was_pending(command_fail(cmd, LIGHTNINGD,
"Bad connect_dev_memleak"));
return;
}
@ -243,7 +245,8 @@ static void hsm_dev_memleak_done(struct subd *hsmd,
bool found_leak;
if (!fromwire_hsm_dev_memleak_reply(reply, &found_leak)) {
command_fail(cmd, LIGHTNINGD, "Bad hsm_dev_memleak");
was_pending(command_fail(cmd, LIGHTNINGD,
"Bad hsm_dev_memleak"));
return;
}
@ -299,7 +302,7 @@ static struct command_result *json_memleak(struct command *cmd,
/* For simplicity, we mark pending, though an error may complete it
* immediately. */
command_still_pending(cmd);
fixme_ignore(command_still_pending(cmd));
/* This calls opening_memleak_done() async when all done. */
opening_dev_memleak(cmd);

47
lightningd/opening_control.c

@ -84,7 +84,7 @@ static void uncommitted_channel_disconnect(struct uncommitted_channel *uc,
log_info(uc->log, "%s", desc);
subd_send_msg(uc->peer->ld->connectd, msg);
if (uc->fc)
command_fail(uc->fc->cmd, LIGHTNINGD, "%s", desc);
was_pending(command_fail(uc->fc->cmd, LIGHTNINGD, "%s", desc));
}
void kill_uncommitted_channel(struct uncommitted_channel *uc,
@ -264,8 +264,9 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
log_broken(fc->uc->log,
"bad OPENING_FUNDER_REPLY %s",
tal_hex(resp, resp));
command_fail(fc->cmd, LIGHTNINGD, "bad OPENING_FUNDER_REPLY %s",
tal_hex(fc->cmd, resp));
was_pending(command_fail(fc->cmd, LIGHTNINGD,
"bad OPENING_FUNDER_REPLY %s",
tal_hex(fc->cmd, resp)));
goto failed;
}
log_debug(ld->log,
@ -311,17 +312,18 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
&fc->uc->local_funding_pubkey),
type_to_string(fc, struct pubkey,
&channel_info.remote_fundingkey));
command_fail(fc->cmd, JSONRPC2_INVALID_PARAMS,
"Funding txid mismatch:"
" satoshi %"PRIu64" change %"PRIu64
" changeidx %u"
" localkey %s remotekey %s",
fc->wtx.amount,
fc->wtx.change, fc->wtx.change_key_index,
type_to_string(fc, struct pubkey,
&fc->uc->local_funding_pubkey),
type_to_string(fc, struct pubkey,
&channel_info.remote_fundingkey));
was_pending(command_fail(fc->cmd, JSONRPC2_INVALID_PARAMS,
"Funding txid mismatch:"
" satoshi %"PRIu64" change %"PRIu64
" changeidx %u"
" localkey %s remotekey %s",
fc->wtx.amount,
fc->wtx.change,
fc->wtx.change_key_index,
type_to_string(fc, struct pubkey,
&fc->uc->local_funding_pubkey),
type_to_string(fc, struct pubkey,
&channel_info.remote_fundingkey)));
goto failed;
}
@ -337,8 +339,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
&channel_info,
feerate);
if (!channel) {
command_fail(fc->cmd, LIGHTNINGD,
"Key generation failure");
was_pending(command_fail(fc->cmd, LIGHTNINGD,
"Key generation failure"));
goto failed;
}
@ -387,7 +389,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
json_add_string(response, "channel_id",
type_to_string(tmpctx, struct channel_id, &cid));
json_object_end(response);
command_success(fc->cmd, response);
was_pending(command_success(fc->cmd, response));
subd_release_channel(openingd, fc->uc);
fc->uc->openingd = NULL;
@ -507,14 +509,14 @@ static void opening_funder_failed(struct subd *openingd, const u8 *msg,
log_broken(uc->log,
"bad OPENING_FUNDER_FAILED %s",
tal_hex(tmpctx, msg));
command_fail(uc->fc->cmd, LIGHTNINGD,
"bad OPENING_FUNDER_FAILED %s",
tal_hex(uc->fc->cmd, msg));
was_pending(command_fail(uc->fc->cmd, LIGHTNINGD,
"bad OPENING_FUNDER_FAILED %s",
tal_hex(uc->fc->cmd, msg)));
tal_free(uc);
return;
}
command_fail(uc->fc->cmd, LIGHTNINGD, "%s", desc);
was_pending(command_fail(uc->fc->cmd, LIGHTNINGD, "%s", desc));
/* Clear uc->fc, so we can try again, and so we don't fail twice
* if they close. */
@ -890,7 +892,8 @@ static void opening_memleak_req_done(struct subd *openingd,
tal_del_destructor2(openingd, opening_died_forget_memleak, cmd);
if (!fromwire_opening_dev_memleak_reply(msg, &found_leak)) {
command_fail(cmd, LIGHTNINGD, "Bad opening_dev_memleak");
was_pending(command_fail(cmd, LIGHTNINGD,
"Bad opening_dev_memleak"));
return;
}

14
lightningd/pay.c

@ -856,7 +856,7 @@ json_sendpay_success(struct command *cmd,
json_object_start(response, NULL);
json_add_payment_fields(response, r->payment);
json_object_end(response);
command_success(cmd, response);
was_pending(command_success(cmd, response));
}
static void json_waitsendpay_on_resolve(const struct sendpay_result *r,
@ -879,7 +879,8 @@ 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:
command_fail(cmd, r->errorcode, "%s", r->details);
was_pending(command_fail(cmd, r->errorcode, "%s",
r->details));
return;
case PAY_UNPARSEABLE_ONION:
@ -892,7 +893,7 @@ static void json_waitsendpay_on_resolve(const struct sendpay_result *r,
json_object_start(data, NULL);
json_add_hex_talarr(data, "onionreply", r->onionreply);
json_object_end(data);
command_failed(cmd, data);
was_pending(command_failed(cmd, data));
return;
case PAY_DESTINATION_PERM_FAIL:
@ -916,7 +917,7 @@ 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);
command_failed(cmd, data);
was_pending(command_failed(cmd, data));
return;
}
abort();
@ -936,7 +937,7 @@ static void json_sendpay_on_resolve(const struct sendpay_result* r,
"Monitor status with listpayments or waitsendpay");
json_add_payment_fields(response, r->payment);
json_object_end(response);
command_success(cmd, response);
was_pending(command_success(cmd, response));
} else
json_waitsendpay_on_resolve(r, cmd);
}
@ -1024,7 +1025,8 @@ AUTODATA(json_command, &sendpay_command);
static void waitsendpay_timeout(struct command *cmd)
{
command_fail(cmd, PAY_IN_PROGRESS, "Timed out while waiting");
was_pending(command_fail(cmd, PAY_IN_PROGRESS,
"Timed out while waiting"));
}
static struct command_result *json_waitsendpay(struct command *cmd,

35
lightningd/payalgo.c

@ -206,7 +206,7 @@ json_pay_success(struct pay *pay,
pay->route, tal_count(pay->route));
json_add_failures(response, "failures", &pay->pay_failures);
json_object_end(response);
command_success(cmd, response);
was_pending(command_success(cmd, response));
}
static void json_pay_failure(struct pay *pay,
@ -226,7 +226,7 @@ static void json_pay_failure(struct pay *pay,
json_add_payment_fields(data, r->payment);
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
command_failed(pay->cmd, data);
was_pending(command_failed(pay->cmd, data));
return;
case PAY_RHASH_ALREADY_USED:
@ -237,7 +237,7 @@ static void json_pay_failure(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_failed(pay->cmd, data);
was_pending(command_failed(pay->cmd, data));
return;
case PAY_UNPARSEABLE_ONION:
@ -266,7 +266,7 @@ static void json_pay_failure(struct pay *pay,
fail->channel_update);
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
command_failed(pay->cmd, data);
was_pending(command_failed(pay->cmd, data));
return;
case PAY_TRY_OTHER_ROUTE:
@ -305,7 +305,7 @@ static const char *should_delay_retry(const tal_t *ctx,
}
/* Start a payment attempt. */
static bool json_pay_try(struct pay *pay);
static struct command_result *json_pay_try(struct pay *pay);
/* Used when delaying. */
static void do_pay_try(struct pay *pay)
@ -426,7 +426,7 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
command_failed(pay->cmd, data);
was_pending(command_failed(pay->cmd, data));
return;
}
@ -474,7 +474,7 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
json_add_failures(data, "failures", &pay->pay_failures);
json_object_end(data);
command_failed(pay->cmd, data);
was_pending(command_failed(pay->cmd, data));
return;
}
if (fee_too_high || delay_too_high) {
@ -501,9 +501,9 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
&json_pay_sendpay_resume, pay);
}
/* Start a payment attempt. Return true if deferred,
* false if resolved now. */
static bool json_pay_try(struct pay *pay)
/* Start a payment attempt. Return NULL if deferred, otherwise
* command_failed(). */
static struct command_result *json_pay_try(struct pay *pay)
{
u8 *req;
struct command *cmd = pay->cmd;
@ -524,8 +524,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_failed(cmd, data);
return false;
return command_failed(cmd, data);
}
/* Clear previous try memory. */
@ -566,7 +565,7 @@ static bool json_pay_try(struct pay *pay)
&seed);
subd_req(pay->try_parent, cmd->ld->gossip, req, -1, 0, json_pay_getroute_reply, pay);
return true;
return NULL;
}
static void json_pay_stop_retrying(struct pay *pay)
@ -607,6 +606,7 @@ static struct command_result *json_pay(struct command *cmd,
unsigned int *retryfor;
unsigned int *maxdelay;
unsigned int *exemptfee;
struct command_result *res;
if (!param(cmd, buffer, params,
p_req("bolt11", param_string, &b11str),
@ -681,15 +681,14 @@ static struct command_result *json_pay(struct command *cmd,
pay->description = b11->description;
/* Initiate payment */
if (json_pay_try(pay))
command_still_pending(cmd);
else
return command_its_complicated();
res = json_pay_try(pay);
if (res)
return res;
/* Set up timeout. */
new_reltimer(&cmd->ld->timers, pay, time_from_sec(*retryfor),
&json_pay_stop_retrying, pay);
return command_its_complicated();
return command_still_pending(cmd);
}
static const struct json_command pay_command = {

84
lightningd/peer_control.c

@ -241,7 +241,7 @@ resolve_one_close_command(struct close_command *cc, bool cooperative)
json_add_string(result, "type", "unilateral");
json_object_end(result);
command_success(cc->cmd, result);
was_pending(command_success(cc->cmd, result));
}
/* Resolve a close command for a channel that will be closed soon. */
@ -270,8 +270,8 @@ destroy_close_command_on_channel_destroy(struct channel *_ UNUSED,
* Clear the cc->channel first so that we will not try to
* remove a destructor. */
cc->channel = NULL;
command_fail(cc->cmd, LIGHTNINGD,
"Channel forgotten before proper close.");
was_pending(command_fail(cc->cmd, LIGHTNINGD,
"Channel forgotten before proper close."));
}
/* Destroy the close command structure. */
@ -303,9 +303,9 @@ close_command_timeout(struct close_command *cc)
else
/* Fail the command directly, which will resolve the
* command and destroy the close_command. */
command_fail(cc->cmd, LIGHTNINGD,
"Channel close negotiation not finished "
"before timeout");
was_pending(command_fail(cc->cmd, LIGHTNINGD,
"Channel close negotiation not finished "
"before timeout"));
}
/* Construct a close command structure and add to ld. */
@ -842,52 +842,51 @@ static const struct json_command listpeers_command = {
};
AUTODATA(json_command, &listpeers_command);
static struct channel *
static struct command_result *
command_find_channel(struct command *cmd,
const char *buffer, const jsmntok_t *tok)
const char *buffer, const jsmntok_t *tok,
struct channel **channel)
{
struct lightningd *ld = cmd->ld;
struct channel_id cid;
struct channel_id channel_cid;
struct short_channel_id scid;
struct peer *peer;
struct channel *channel;
if (json_tok_channel_id(buffer, tok, &cid)) {
list_for_each(&ld->peers, peer, list) {
channel = peer_active_channel(peer);
if (!channel)
*channel = peer_active_channel(peer);
if (!*channel)
continue;
derive_channel_id(&channel_cid,
&channel->funding_txid,
channel->funding_outnum);
&(*channel)->funding_txid,
(*channel)->funding_outnum);
if (channel_id_eq(&channel_cid, &cid))
return channel;
return NULL;
}
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Channel ID not found: '%.*s'",
tok->end - tok->start,
buffer + tok->start);
return NULL;
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Channel ID not found: '%.*s'",
tok->end - tok->start,
buffer + tok->start);
} else if (json_to_short_channel_id(buffer, tok, &scid)) {
list_for_each(&ld->peers, peer, list) {
channel = peer_active_channel(peer);
if (!channel)
*channel = peer_active_channel(peer);
if (!*channel)
continue;
if (channel->scid && channel->scid->u64 == scid.u64)
return channel;
if ((*channel)->scid
&& (*channel)->scid->u64 == scid.u64)
return NULL;
}
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Short channel ID not found: '%.*s'",
tok->end - tok->start,
buffer + tok->start);
return NULL;
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Short channel ID not found: '%.*s'",
tok->end - tok->start,
buffer + tok->start);
} else {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Given id is not a channel ID or "
"short channel ID: '%.*s'",
json_tok_full_len(tok), json_tok_full(buffer, tok));
return NULL;
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Given id is not a channel ID or "
"short channel ID: '%.*s'",
json_tok_full_len(tok),
json_tok_full(buffer, tok));
}
}
@ -913,9 +912,10 @@ static struct command_result *json_close(struct command *cmd,
if (peer)
channel = peer_active_channel(peer);
else {
channel = command_find_channel(cmd, buffer, idtok);
if (!channel)
return command_its_complicated();
struct command_result *res;
res = command_find_channel(cmd, buffer, idtok, &channel);
if (res)
return res;
}
if (!channel && peer) {
@ -1307,14 +1307,14 @@ static void process_dev_forget_channel(struct bitcoind *bitcoind UNUSED,
struct json_stream *response;
struct dev_forget_channel_cmd *forget = arg;
if (txout != NULL && !forget->force) {
command_fail(forget->cmd, LIGHTNINGD,
was_pending(command_fail(forget->cmd, LIGHTNINGD,
"Cowardly refusing to forget channel with an "
"unspent funding output, if you know what "
"you're doing you can override with "
"`force=true`, otherwise consider `close` or "
"`dev-fail`! If you force and the channel "
"confirms we will not track the funds in the "
"channel");
"channel"));
return;
}
response = json_stream_success(forget->cmd);
@ -1329,7 +1329,7 @@ static void process_dev_forget_channel(struct bitcoind *bitcoind UNUSED,
"dev_forget_channel");
delete_channel(forget->channel);
command_success(forget->cmd, response);
was_pending(command_success(forget->cmd, response));
}
static struct command_result *json_dev_forget_channel(struct command *cmd,
@ -1428,7 +1428,8 @@ static void channeld_memleak_req_done(struct subd *channeld,
tal_del_destructor2(channeld, subd_died_forget_memleak, cmd);
if (!fromwire_channel_dev_memleak_reply(msg, &found_leak)) {
command_fail(cmd, LIGHTNINGD, "Bad channel_dev_memleak");
was_pending(command_fail(cmd, LIGHTNINGD,
"Bad channel_dev_memleak"));
return;
}
peer_memleak_req_done(channeld, found_leak, cmd);
@ -1442,7 +1443,8 @@ static void onchaind_memleak_req_done(struct subd *onchaind,
tal_del_destructor2(onchaind, subd_died_forget_memleak, cmd);
if (!fromwire_onchain_dev_memleak_reply(msg, &found_leak)) {
command_fail(cmd, LIGHTNINGD, "Bad onchain_dev_memleak");
was_pending(command_fail(cmd, LIGHTNINGD,
"Bad onchain_dev_memleak"));
return;
}
peer_memleak_req_done(onchaind, found_leak, cmd);

7
lightningd/ping.c

@ -66,16 +66,17 @@ void ping_reply(struct subd *subd, const u8 *msg)
assert(pc);
if (!ok)
command_fail(pc->cmd, LIGHTNINGD, "Bad reply message");
was_pending(command_fail(pc->cmd, LIGHTNINGD,
"Bad reply message"));
else if (!sent)
command_fail(pc->cmd, LIGHTNINGD, "Unknown peer");
was_pending(command_fail(pc->cmd, LIGHTNINGD, "Unknown peer"));
else {
struct json_stream *response = json_stream_success(pc->cmd);
json_object_start(response, NULL);
json_add_num(response, "totlen", totlen);
json_object_end(response);
command_success(pc->cmd, response);
was_pending(command_success(pc->cmd, response));
}
}

2
tools/mockup.sh

@ -33,5 +33,5 @@ for SYMBOL; do
END=$(tail -n "+${LINE}" < "$FILE" | grep -n ';$');
NUM=${END%%:*}
tail -n "+${LINE}" < "$FILE" | head -n "$NUM" | sed 's/^extern *//' | sed 's/PRINTF_FMT([^)]*)//' | sed 's/NORETURN//g' | sed 's/LAST_ARG_NULL//g' | sed 's/,/ UNNEEDED,/g' | sed 's/\([a-z0-9A-Z*_]* [a-z0-9A-Z*_]*\));/\1 UNNEEDED);/' | sed "s/;\$/$STUB/" | sed 's/\s*$//'
tail -n "+${LINE}" < "$FILE" | head -n "$NUM" | sed 's/^extern *//' | sed 's/PRINTF_FMT([^)]*)//' | sed 's/NORETURN//g' | sed 's/LAST_ARG_NULL//g' | sed 's/WARN_UNUSED_RESULT//g' | sed 's/,/ UNNEEDED,/g' | sed 's/\([a-z0-9A-Z*_]* [a-z0-9A-Z*_]*\));/\1 UNNEEDED);/' | sed "s/;\$/$STUB/" | sed 's/\s*$//'
done

9
wallet/walletrpc.c

@ -71,10 +71,11 @@ static void wallet_withdrawal_broadcast(struct bitcoind *bitcoind UNUSED,
json_add_string(response, "tx", withdraw->hextx);
json_add_string(response, "txid", output);
json_object_end(response);
command_success(cmd, response);
was_pending(command_success(cmd, response));
} else {
command_fail(cmd, LIGHTNINGD,
"Error broadcasting transaction: %s", output);
was_pending(command_fail(cmd, LIGHTNINGD,
"Error broadcasting transaction: %s",
output));
}
}
@ -503,7 +504,7 @@ static void process_utxo_result(struct bitcoind *bitcoind,
/* Complete the response */
json_array_end(rescan->response);
json_object_end(rescan->response);
command_success(rescan->cmd, rescan->response);
was_pending(command_success(rescan->cmd, rescan->response));
} else {
bitcoind_gettxout(
bitcoind->ld->topology->bitcoind, &rescan->utxos[0]->txid,

Loading…
Cancel
Save