From 41c250ba9451da2b6ca647317952669f0a6ee776 Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Fri, 11 Jul 2014 13:26:31 +0200 Subject: [PATCH 1/2] Implement "daemon warmup" for the RPC interface. Fix https://github.com/chronokings/huntercoin/issues/63 by starting the RPC daemon early during start up. Until everything necessary is initialised, it simply returns an error early on when called. --- src/bitcoinrpc.cpp | 6 ++++++ src/bitcoinrpc.h | 7 +++++++ src/init.cpp | 24 ++++++++++++++++++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 29786d92f..8552a3666 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -47,6 +47,8 @@ using namespace boost; using namespace boost::asio; using namespace json_spirit; +const char* rpcWarmupStatus = "uninitialised"; + void ThreadRPCServer2(void* parg); Value sendtoaddress(const Array& params, bool fHelp); @@ -4057,6 +4059,10 @@ void ThreadRPCServer2(void* parg) // Parse id now so errors from here on will have the id id = find_value(request, "id"); + // Bail early if not yet initialised. + if (rpcWarmupStatus) + throw JSONRPCError (RPC_IN_WARMUP, rpcWarmupStatus); + // Parse method Value valMethod = find_value(request, "method"); if (valMethod.type() == null_type) diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 30a2bb22c..17b375283 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -78,6 +78,13 @@ enum RPCErrorCode // Async method call interrupted. RPC_ASYNC_INTERRUPT = -100, + // Daemon in warm-up phase. + RPC_IN_WARMUP = -101, }; +/* Keep track of current "warmup status". This is set to a descriptive + string while initialising everything, and NULL if the RPC process + can function as normal. */ +extern const char* rpcWarmupStatus; + #endif diff --git a/src/init.cpp b/src/init.cpp index e3bd50a65..1a171ebbf 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -367,6 +367,14 @@ bool AppInit2(int argc, char* argv[]) strErrors = ""; int64 nStart; + /* Start the RPC server already here. This is to make it available + "immediately" upon starting the daemon process. Until everything + is initialised, it will always just return a "status error" and + not try to access the uninitialised stuff. */ + if (fServer) + CreateThread(ThreadRPCServer, NULL); + + rpcWarmupStatus = "loading addresses"; printf("Loading addresses...\n"); nStart = GetTimeMillis(); if (!LoadAddresses()) @@ -398,12 +406,14 @@ bool AppInit2(int argc, char* argv[]) CNameDB dbName("cr+"); } + rpcWarmupStatus = "loading block index"; printf("Loading block index...\n"); nStart = GetTimeMillis(); if (!LoadBlockIndex()) strErrors += _("Error loading blkindex.dat \n"); printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); + rpcWarmupStatus = "loading wallet"; printf("Loading wallet...\n"); nStart = GetTimeMillis(); bool fFirstRun; @@ -421,8 +431,11 @@ bool AppInit2(int argc, char* argv[]) /* Rescan for name index now if we need to do it. */ if (needNameRescan) - rescanfornames (); - + { + rpcWarmupStatus = "rescanning for names"; + rescanfornames (); + } + // Read -mininput before -rescan, otherwise rescan will skip transactions // lower than the default mininput if (mapArgs.count("-mininput")) @@ -434,6 +447,7 @@ bool AppInit2(int argc, char* argv[]) } } + rpcWarmupStatus = "rescanning blockchain"; CBlockIndex *pindexRescan = pindexBest; if (GetBoolArg("-rescan")) pindexRescan = pindexGenesisBlock; @@ -470,6 +484,7 @@ bool AppInit2(int argc, char* argv[]) } // Add wallet transactions that aren't already in a block to mapTransactions + rpcWarmupStatus = "reaccept wallet transactions"; pwalletMain->ReacceptWalletTransactions(); // @@ -578,8 +593,9 @@ bool AppInit2(int argc, char* argv[]) if (!CreateThread(StartNode, NULL)) wxMessageBox("Error: CreateThread(StartNode) failed", "Namecoin"); - if (fServer) - CreateThread(ThreadRPCServer, NULL); + /* We're done initialising, from now on, the RPC daemon + can work as usual. */ + rpcWarmupStatus = NULL; #if defined(__WXMSW__) && defined(GUI) if (fFirstRun) From e9bcbc7e5b5dcd6f7435dbea353885a4e6bd9ab8 Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Mon, 14 Jul 2014 07:58:37 +0200 Subject: [PATCH 2/2] Update changelog. --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 5d718f4eb..20e1e2593 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,7 @@ * New command line / .conf file option: -walletpath=customwalletfilename.dat (digital-dreamer) * "Pay To" in the Qt can be used to send coins also to a name, like "sendtoname" (Domob) * New RPC block info: height, confirmations, chainwork, nextblockhash. Change: No previousblockhash for block 0 (RyanC) +* The RPC interface now returns an error while initialising, instead of not accepting connections at all (Domob) v0.3.75 =======