Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement "daemon warmup" for the RPC interface. #137

Merged
merged 2 commits into from
Jul 27, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -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
=======
Expand Down
6 changes: 6 additions & 0 deletions src/bitcoinrpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions src/bitcoinrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
24 changes: 20 additions & 4 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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;
Expand All @@ -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"))
Expand All @@ -434,6 +447,7 @@ bool AppInit2(int argc, char* argv[])
}
}

rpcWarmupStatus = "rescanning blockchain";
CBlockIndex *pindexRescan = pindexBest;
if (GetBoolArg("-rescan"))
pindexRescan = pindexGenesisBlock;
Expand Down Expand Up @@ -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();

//
Expand Down Expand Up @@ -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)
Expand Down