diff --git a/lightningd/dev_ping.c b/lightningd/dev_ping.c index c66229a77..bb8896781 100644 --- a/lightningd/dev_ping.c +++ b/lightningd/dev_ping.c @@ -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 = { diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 792d4a47c..eaa9ea912 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -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 = { diff --git a/lightningd/invoice.c b/lightningd/invoice.c index b31943566..55703d13e 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -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); } } diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 5075dcc90..d6043bcfa 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -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, diff --git a/lightningd/jsonrpc.h b/lightningd/jsonrpc.h index 3627a397f..9989f5dbd 100644 --- a/lightningd/jsonrpc.h +++ b/lightningd/jsonrpc.h @@ -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, diff --git a/lightningd/pay.c b/lightningd/pay.c index 851f259ba..94da4e7eb 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -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 = { diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 992c5aa91..bfe466ee8 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -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 = { diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index 7afa4782f..1b86b8d3a 100644 --- a/wallet/walletrpc.c +++ b/wallet/walletrpc.c @@ -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 = {