aboutsummaryrefslogtreecommitdiff
path: root/src/bitcoin-cli.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bitcoin-cli.cpp')
-rw-r--r--src/bitcoin-cli.cpp114
1 files changed, 69 insertions, 45 deletions
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 38fbc29faf..1b638e99e9 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -5,7 +5,6 @@
#include "chainparamsbase.h"
#include "clientversion.h"
-#include "init.h"
#include "rpcclient.h"
#include "rpcprotocol.h"
#include "util.h"
@@ -46,12 +45,41 @@ std::string HelpMessageCli()
//
// Start
//
+
+//
+// Exception thrown on connection error. This error is used to determine
+// when to wait if -rpcwait is given.
+//
+class CConnectionFailed : public std::runtime_error
+{
+public:
+
+ explicit inline CConnectionFailed(const std::string& msg) :
+ std::runtime_error(msg)
+ {}
+
+};
+
static bool AppInitRPC(int argc, char* argv[])
{
//
// Parameters
//
ParseParameters(argc, argv);
+ if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) {
+ std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n";
+ if (!mapArgs.count("-version")) {
+ strUsage += "\n" + _("Usage:") + "\n" +
+ " bitcoin-cli [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" +
+ " bitcoin-cli [options] help " + _("List commands") + "\n" +
+ " bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n";
+
+ strUsage += "\n" + HelpMessageCli();
+ }
+
+ fprintf(stdout, "%s", strUsage.c_str());
+ return false;
+ }
if (!boost::filesystem::is_directory(GetDataDir(false))) {
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
return false;
@@ -67,20 +95,6 @@ static bool AppInitRPC(int argc, char* argv[])
fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
return false;
}
- if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) {
- std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n";
- if (!mapArgs.count("-version")) {
- strUsage += "\n" + _("Usage:") + "\n" +
- " bitcoin-cli [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" +
- " bitcoin-cli [options] help " + _("List commands") + "\n" +
- " bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n";
-
- strUsage += "\n" + HelpMessageCli();
- }
-
- fprintf(stdout, "%s", strUsage.c_str());
- return false;
- }
return true;
}
@@ -101,15 +115,9 @@ Object CallRPC(const string& strMethod, const Array& params)
SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
- bool fWait = GetBoolArg("-rpcwait", false); // -rpcwait means try until server has started
- do {
- bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
- if (fConnected) break;
- if (fWait)
- MilliSleep(1000);
- else
- throw runtime_error("couldn't connect to server");
- } while (fWait);
+ const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
+ if (!fConnected)
+ throw CConnectionFailed("couldn't connect to server");
// HTTP basic authentication
string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
@@ -168,27 +176,43 @@ int CommandLineRPC(int argc, char *argv[])
std::vector<std::string> strParams(&argv[2], &argv[argc]);
Array params = RPCConvertValues(strMethod, strParams);
- // Execute
- Object reply = CallRPC(strMethod, params);
-
- // Parse reply
- const Value& result = find_value(reply, "result");
- const Value& error = find_value(reply, "error");
-
- if (error.type() != null_type) {
- // Error
- strPrint = "error: " + write_string(error, false);
- int code = find_value(error.get_obj(), "code").get_int();
- nRet = abs(code);
- } else {
- // Result
- if (result.type() == null_type)
- strPrint = "";
- else if (result.type() == str_type)
- strPrint = result.get_str();
- else
- strPrint = write_string(result, true);
- }
+ // Execute and handle connection failures with -rpcwait
+ const bool fWait = GetBoolArg("-rpcwait", false);
+ do {
+ try {
+ const Object reply = CallRPC(strMethod, params);
+
+ // Parse reply
+ const Value& result = find_value(reply, "result");
+ const Value& error = find_value(reply, "error");
+
+ if (error.type() != null_type) {
+ // Error
+ const int code = find_value(error.get_obj(), "code").get_int();
+ if (fWait && code == RPC_IN_WARMUP)
+ throw CConnectionFailed("server in warmup");
+ strPrint = "error: " + write_string(error, false);
+ nRet = abs(code);
+ } else {
+ // Result
+ if (result.type() == null_type)
+ strPrint = "";
+ else if (result.type() == str_type)
+ strPrint = result.get_str();
+ else
+ strPrint = write_string(result, true);
+ }
+
+ // Connection succeeded, no need to retry.
+ break;
+ }
+ catch (const CConnectionFailed& e) {
+ if (fWait)
+ MilliSleep(1000);
+ else
+ throw;
+ }
+ } while (fWait);
}
catch (boost::thread_interrupted) {
throw;