From 584b160cdc3f654956400e50f4ba7f65b2d003e2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 12 Sep 2017 14:25:54 +0930 Subject: [PATCH] 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 --- lightningd/bitcoind.c | 13 +++++++++++++ lightningd/bitcoind.h | 3 +++ tests/test_lightningd.py | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/lightningd/bitcoind.c b/lightningd/bitcoind.c index 777148e56..745dae796 100644 --- a/lightningd/bitcoind.c +++ b/lightningd/bitcoind.c @@ -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; } diff --git a/lightningd/bitcoind.h b/lightningd/bitcoind.h index b067be6f5..69a8046c7 100644 --- a/lightningd/bitcoind.h +++ b/lightningd/bitcoind.h @@ -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); diff --git a/tests/test_lightningd.py b/tests/test_lightningd.py index f23cbbca2..ab7969c56 100644 --- a/tests/test_lightningd.py +++ b/tests/test_lightningd.py @@ -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()