mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 18:57:06 +01:00
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>
This commit is contained in:
parent
68bb36b210
commit
819078fe18
15 changed files with 160 additions and 135 deletions
|
@ -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);
|
||||
|
|
|
@ -280,8 +280,10 @@ bool param(struct command *cmd, const char *buffer,
|
|||
continue;
|
||||
}
|
||||
if (!param_add(¶ms, 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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
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,
|
||||
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));
|
||||
&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,
|
||||
was_pending(command_fail(uc->fc->cmd, LIGHTNINGD,
|
||||
"bad OPENING_FUNDER_FAILED %s",
|
||||
tal_hex(uc->fc->cmd, msg));
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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,
|
||||
was_pending(command_fail(cc->cmd, LIGHTNINGD,
|
||||
"Channel close negotiation not finished "
|
||||
"before timeout");
|
||||
"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,
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Channel ID not found: '%.*s'",
|
||||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
return NULL;
|
||||
} 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,
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Short channel ID not found: '%.*s'",
|
||||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
return NULL;
|
||||
} else {
|
||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
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));
|
||||
return NULL;
|
||||
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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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…
Add table
Reference in a new issue