lightningd: avoid errors on shutdown.

lightningd can crash on shutdown if it's in the middle of getchaintips;
we free the conn, the finished callback is called (process_chaintips),
and it reports that it received an empty result.

The simplest fix is to set a flag in the struct bitcoind destructor,
and avoid the callback.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-09-12 14:25:54 +09:30 committed by Christian Decker
parent ec63c0d10b
commit 584b160cdc
3 changed files with 20 additions and 0 deletions

View File

@ -126,6 +126,11 @@ static void bcli_finished(struct io_conn *conn, struct bitcoin_cli *bcli)
*bcli->exitstatus = WEXITSTATUS(status);
bitcoind->req_running = false;
/* Don't continue if were only here because we were freed for shutdown */
if (bitcoind->shutdown)
return;
bcli->process(bcli);
next_bcli(bitcoind);
@ -448,6 +453,12 @@ void bitcoind_getblockhash_(struct bitcoind *bitcoind,
"getblockhash", str, NULL);
}
static void destroy_bitcoind(struct bitcoind *bitcoind)
{
/* Suppresses the callbacks from bcli_finished as we free conns. */
bitcoind->shutdown = true;
}
struct bitcoind *new_bitcoind(const tal_t *ctx, struct log *log)
{
struct bitcoind *bitcoind = tal(ctx, struct bitcoind);
@ -457,7 +468,9 @@ struct bitcoind *new_bitcoind(const tal_t *ctx, struct log *log)
bitcoind->datadir = NULL;
bitcoind->log = log;
bitcoind->req_running = false;
bitcoind->shutdown = false;
list_head_init(&bitcoind->pending);
tal_add_destructor(bitcoind, destroy_bitcoind);
return bitcoind;
}

View File

@ -36,6 +36,9 @@ struct bitcoind {
/* What network are we on? */
const struct chainparams *chainparams;
/* Ignore results, we're shutting down. */
bool shutdown;
};
struct bitcoind *new_bitcoind(const tal_t *ctx, struct log *log);

View File

@ -244,6 +244,10 @@ class LightningDTests(BaseLightningDTests):
else:
lsrc.rpc.sendpay(to_json([routestep]), rhash, async=False)
def test_shutdown(self):
l1 = self.node_factory.get_node()
l1.rpc.stop()
def test_connect(self):
l1,l2 = self.connect()