From c9f39804e9ba2b24c715e27336e8ce77905ee6fb Mon Sep 17 00:00:00 2001 From: Daniel McNally Date: Tue, 18 Feb 2020 01:53:36 -0500 Subject: [PATCH] chain: wait for bitcoind rpc to warm up This modifies the `Start` method to handle the `RPC_IN_WARMUP` error code of `-28` by retrying the rpc call to determine the current network every second until it either succeeds or fails with a different code. The current behavior fails and terminates the connection upon receiving this error code. This change allows for connecting to a recently started bitcoind node and starting the client while bitcoind is still warming up. Related issues: https://github.com/lightningnetwork/lnd/issues/1533 & https://github.com/ExchangeUnion/xud-docker/issues/195 --- chain/bitcoind_conn.go | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/chain/bitcoind_conn.go b/chain/bitcoind_conn.go index 902952743e..964d079545 100644 --- a/chain/bitcoind_conn.go +++ b/chain/bitcoind_conn.go @@ -9,6 +9,7 @@ import ( "sync/atomic" "time" + "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/rpcclient" @@ -139,10 +140,32 @@ func (c *BitcoindConn) Start() error { return nil } + var ( + net wire.BitcoinNet + err error + ) + // Verify that the node is running on the expected network. - net, err := c.getCurrentNet() - if err != nil { - return err + btcInWarmup := false + for { + net, err = c.getCurrentNet() + if err == nil { + // No error means bitcoind is responsive and we can proceed. + break + } else if err.(*btcjson.RPCError).Code == btcjson.ErrRPCInWarmup { + // Error code -28 indicates the bitcoind rpc is warming up. + // We will wait and recheck periodically until rpc is ready. + if btcInWarmup == false { + btcInWarmup = true + log.Info("Waiting for bitcoind RPC to finish warming up...") + } + time.Sleep(time.Second * 1) + } else { + return err + } + } + if btcInWarmup == true { + log.Info("Bitcoind finished warming up and RPC is ready") } if net != c.chainParams.Net { return fmt.Errorf("expected network %v, got %v",