jsonrpc: make explicit call to indicate cmd is still pending.

jsonrpc handlers usually directly call command_success or
command_fail; not doing that implies they're waiting for something
async.

Put an explicit call (currently a noop) there, and add debugging
checks to make sure it's used.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-12-15 20:45:54 +10:30 committed by Christian Decker
parent 42b9df59c1
commit 8c665835fa
8 changed files with 38 additions and 8 deletions

View File

@ -96,6 +96,7 @@ static void json_dev_ping(struct command *cmd,
}
subd_req(owner, owner, take(msg), -1, 0, ping_reply, cmd);
command_still_pending(cmd);
}
static const struct json_command dev_ping_command = {

View File

@ -174,6 +174,7 @@ static void json_getnodes(struct command *cmd, const char *buffer,
{
u8 *req = towire_gossip_getnodes_request(cmd);
subd_req(cmd, cmd->ld->gossip, req, -1, 0, json_getnodes_reply, cmd);
command_still_pending(cmd);
}
static const struct json_command getnodes_command = {
@ -256,6 +257,7 @@ static void json_getroute(struct command *cmd, const char *buffer, const jsmntok
}
u8 *req = towire_gossip_getroute_request(cmd, &ld->id, &id, msatoshi, riskfactor*1000, cltv);
subd_req(ld->gossip, ld->gossip, req, -1, 0, json_getroute_reply, cmd);
command_still_pending(cmd);
}
static const struct json_command getroute_command = {
@ -315,6 +317,7 @@ static void json_getchannels(struct command *cmd, const char *buffer,
u8 *req = towire_gossip_getchannels_request(cmd);
subd_req(cmd->ld->gossip, cmd->ld->gossip,
req, -1, 0, json_getchannels_reply, cmd);
command_still_pending(cmd);
}
static const struct json_command getchannels_command = {

View File

@ -394,6 +394,7 @@ static void json_waitanyinvoice(struct command *cmd,
w = tal(cmd, struct invoice_waiter);
w->cmd = cmd;
list_add_tail(&invs->invoice_waiters, &w->list);
command_still_pending(cmd);
}
static const struct json_command waitanyinvoice_command = {
@ -439,6 +440,7 @@ static void json_waitinvoice(struct command *cmd,
w = tal(cmd, struct invoice_waiter);
w->cmd = cmd;
list_add_tail(&invs->invoice_waiters, &w->list);
command_still_pending(cmd);
}
}

View File

@ -438,6 +438,11 @@ void command_fail(struct command *cmd, const char *fmt, ...)
jcon->current = tal_free(cmd);
}
void command_still_pending(struct command *cmd)
{
cmd->pending = true;
}
static void json_command_malformed(struct json_connection *jcon,
const char *id,
const char *error)
@ -476,6 +481,7 @@ static void parse_request(struct json_connection *jcon, const jsmntok_t tok[])
jcon->current = tal(jcon->ld, struct command);
jcon->current->jcon = jcon;
jcon->current->ld = jcon->ld;
jcon->current->pending = false;
jcon->current->id = tal_strndup(jcon->current,
json_tok_contents(jcon->buffer, id),
json_tok_len(id));
@ -509,6 +515,10 @@ static void parse_request(struct json_connection *jcon, const jsmntok_t tok[])
db_begin_transaction(jcon->ld->wallet->db);
cmd->dispatch(jcon->current, jcon->buffer, params);
db_commit_transaction(jcon->ld->wallet->db);
/* If they didn't complete it, they must call command_still_pending */
if (jcon->current)
assert(jcon->current->pending);
}
static struct io_plan *write_json(struct io_conn *conn,

View File

@ -16,6 +16,8 @@ struct command {
const char *id;
/* The connection, or NULL if it closed. */
struct json_connection *jcon;
/* Have we been marked by command_still_pending? For debugging... */
bool pending;
};
struct json_connection {
@ -56,6 +58,9 @@ struct json_result *null_response(const tal_t *ctx);
void command_success(struct command *cmd, struct json_result *response);
void PRINTF_FMT(2, 3) command_fail(struct command *cmd, const char *fmt, ...);
/* Mainly for documentation, that we plan to close this later. */
void command_still_pending(struct command *cmd);
/* '"fieldname" : "0289abcdef..."' or "0289abcdef..." if fieldname is NULL */
void json_add_pubkey(struct json_result *response,
const char *fieldname,

View File

@ -144,7 +144,8 @@ static void pay_command_destroyed(struct pay_command *pc)
list_del(&pc->list);
}
static void send_payment(struct command *cmd,
/* Returns true if it's still pending. */
static bool send_payment(struct command *cmd,
const struct sha256 *rhash,
const struct route_hop *route)
{
@ -189,7 +190,7 @@ static void send_payment(struct command *cmd,
if (pc->out) {
log_add(cmd->ld->log, "... still in progress");
command_fail(cmd, "still in progress");
return;
return false;
}
if (pc->rval) {
size_t old_nhops = tal_count(pc->ids);
@ -199,7 +200,7 @@ static void send_payment(struct command *cmd,
command_fail(cmd,
"already succeeded with amount %"
PRIu64, pc->msatoshi);
return;
return false;
}
if (!structeq(&pc->ids[old_nhops-1], &ids[n_hops-1])) {
char *previd;
@ -208,10 +209,10 @@ static void send_payment(struct command *cmd,
command_fail(cmd,
"already succeeded to %s",
previd);
return;
return false;
}
json_pay_success(cmd, pc->rval);
return;
return false;
}
/* FIXME: We can free failed ones... */
log_add(cmd->ld->log, "... retrying");
@ -220,7 +221,7 @@ static void send_payment(struct command *cmd,
peer = peer_by_id(cmd->ld, &ids[0]);
if (!peer) {
command_fail(cmd, "no connection to first peer found");
return;
return false;
}
randombytes_buf(&sessionkey, sizeof(sessionkey));
@ -272,8 +273,9 @@ static void send_payment(struct command *cmd,
if (failcode) {
command_fail(cmd, "first peer not ready: %s",
onion_type_name(failcode));
return;
return false;
}
return true;
}
static void json_sendpay(struct command *cmd,
@ -364,7 +366,8 @@ static void json_sendpay(struct command *cmd,
return;
}
send_payment(cmd, &rhash, route);
if (send_payment(cmd, &rhash, route))
command_still_pending(cmd);
}
static const struct json_command sendpay_command = {
@ -468,6 +471,7 @@ static void json_pay(struct command *cmd,
msatoshi, riskfactor*1000,
b11->min_final_cltv_expiry);
subd_req(pay, cmd->ld->gossip, req, -1, 0, json_pay_getroute_reply, pay);
command_still_pending(cmd);
}
static const struct json_command pay_command = {

View File

@ -823,6 +823,7 @@ static void json_connect(struct command *cmd,
/* Leave this here for gossip_peer_connected */
new_connect(cmd->ld, &id, cmd);
command_still_pending(cmd);
}
static const struct json_command connect_command = {
@ -966,6 +967,7 @@ static void json_getpeers(struct command *cmd,
subd_req(cmd, cmd->ld->gossip,
take(towire_gossip_getpeers_request(cmd)),
-1, 0, gossipd_getpeers_complete, gpa);
command_still_pending(cmd);
}
static const struct json_command getpeers_command = {
@ -2616,6 +2618,7 @@ static void json_fund_channel(struct command *cmd,
msg = towire_gossipctl_release_peer(cmd, &fc->peerid);
subd_req(fc, cmd->ld->gossip, msg, -1, 2, gossip_peer_released, fc);
command_still_pending(cmd);
}
static const struct json_command fund_channel_command = {
@ -2818,6 +2821,7 @@ static void json_dev_reenable_commit(struct command *cmd,
msg = towire_channel_dev_reenable_commit(peer);
subd_req(peer, peer->owner, take(msg), -1, 0,
dev_reenable_commit_finished, cmd);
command_still_pending(cmd);
}
static const struct json_command dev_reenable_commit = {

View File

@ -326,6 +326,7 @@ static void json_withdraw(struct command *cmd,
withdraw->hextx = tal_hex(withdraw, linearize_tx(cmd, tx));
bitcoind_sendrawtx(cmd->ld->topology->bitcoind, withdraw->hextx,
wallet_withdrawal_broadcast, withdraw);
command_still_pending(cmd);
}
static const struct json_command withdraw_command = {