X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fbitcoinrpc.cpp;h=b411be47000122b796aab9d1541dfec13f27f081;hb=cc5173a20534bd761caca6c5291cadc42a0ba5d7;hp=8f2b94cc04eab21e6523950256fd1086f6146221;hpb=4f08c5536ca06a0f273a3b4a00e4307e2ca4e8e2;p=novacoin.git diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 8f2b94c..b411be4 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -4,35 +4,24 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "init.h" -#include "util.h" -#include "sync.h" -#include "ui_interface.h" #include "base58.h" #include "bitcoinrpc.h" #include "db.h" +#include "interface.h" +#include "sync.h" +#include "util.h" #undef printf -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + #include -#include -#include -#include -#include +#include +#include + #include +#include #define printf OutputDebugStringF -using namespace std; -using namespace boost; using namespace json_spirit; std::unique_ptr g_server; @@ -46,7 +35,7 @@ static inline unsigned short GetDefaultRPCPort() return GetBoolArg("-testnet", false) ? 18344 : 8344; } -Object JSONRPCError(int code, const string& message) +Object JSONRPCError(int code, const std::string& message) { Object error; error.push_back(Pair("code", code)); @@ -55,11 +44,11 @@ Object JSONRPCError(int code, const string& message) } void RPCTypeCheck(const Array& params, - const list& typesExpected, + const std::list& typesExpected, bool fAllowNull) { unsigned int i = 0; - BOOST_FOREACH(Value_type t, typesExpected) + for(Value_type t : typesExpected) { if (params.size() <= i) break; @@ -67,7 +56,7 @@ void RPCTypeCheck(const Array& params, const Value& v = params[i]; if (!((v.type() == t) || (fAllowNull && (v.type() == null_type)))) { - string err = strprintf("Expected type %s, got %s", + std::string err = strprintf("Expected type %s, got %s", Value_type_name[t], Value_type_name[v.type()]); throw JSONRPCError(RPC_TYPE_ERROR, err); } @@ -76,10 +65,10 @@ void RPCTypeCheck(const Array& params, } void RPCTypeCheck(const Object& o, - const map& typesExpected, + const std::map& typesExpected, bool fAllowNull) { - BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) + for(const auto& t : typesExpected) { const Value& v = find_value(o, t.first); if (!fAllowNull && v.type() == null_type) @@ -87,7 +76,7 @@ void RPCTypeCheck(const Object& o, if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type)))) { - string err = strprintf("Expected type %s for %s, got %s", + std::string err = strprintf("Expected type %s for %s, got %s", Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]); throw JSONRPCError(RPC_TYPE_ERROR, err); } @@ -97,7 +86,7 @@ void RPCTypeCheck(const Object& o, int64_t AmountFromValue(const Value& value) { double dAmount = value.get_real(); - if (dAmount <= 0.0 || dAmount > MAX_MONEY) + if (dAmount <= 0.0 || dAmount > (double) (MAX_MONEY / 100000000)) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); int64_t nAmount = roundint64(dAmount * COIN); if (!MoneyRange(nAmount)) @@ -125,9 +114,9 @@ std::string HexBits(unsigned int nBits) // Utilities: convert hex-encoded Values // (throws error if not hex). // -uint256 ParseHashV(const Value& v, string strName) +uint256 ParseHashV(const Value& v, const std::string& strName) { - string strHex; + std::string strHex; if (v.type() == str_type) strHex = v.get_str(); if (!IsHex(strHex)) // Note: IsHex("") is false @@ -137,14 +126,14 @@ uint256 ParseHashV(const Value& v, string strName) return result; } -uint256 ParseHashO(const Object& o, string strKey) +uint256 ParseHashO(const Object& o, const std::string& strKey) { return ParseHashV(find_value(o, strKey), strKey); } -vector ParseHexV(const Value& v, string strName) +std::vector ParseHexV(const Value& v, const std::string& strName) { - string strHex; + std::string strHex; if (v.type() == str_type) strHex = v.get_str(); if (!IsHex(strHex)) @@ -152,7 +141,7 @@ vector ParseHexV(const Value& v, string strName) return ParseHex(strHex); } -vector ParseHexO(const Object& o, string strKey) +std::vector ParseHexO(const Object& o, const std::string& strKey) { return ParseHexV(find_value(o, strKey), strKey); } @@ -162,16 +151,16 @@ vector ParseHexO(const Object& o, string strKey) /// Note: This interface may still be subject to change. /// -string CRPCTable::help(string strCommand) const +std::string CRPCTable::help(const std::string& strCommand) const { - string strRet; - set setDone; - for (map::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi) + std::string strRet; + std::set setDone; + for (const auto & mapCommand : mapCommands) { - const CRPCCommand *pcmd = mi->second; - string strMethod = mi->first; + const CRPCCommand *pcmd = mapCommand.second; + std::string strMethod = mapCommand.first; // We already filter duplicates, but these deprecated screw up the sort order - if (strMethod.find("label") != string::npos) + if (strMethod.find("label") != std::string::npos) continue; if (!strCommand.empty() && strMethod != strCommand) continue; @@ -182,14 +171,14 @@ string CRPCTable::help(string strCommand) const if (setDone.insert(pfn).second) (*pfn)(params, true); } - catch (std::exception& e) + catch (const std::exception& e) { // Help text is returned in an exception - string strHelp = string(e.what()); + std::string strHelp = std::string(e.what()); if (strCommand.empty()) - if (strHelp.find('\n') != string::npos) + if (strHelp.find('\n') != std::string::npos) strHelp = strHelp.substr(0, strHelp.find('\n')); - strRet += strHelp + "\n"; + strRet += strHelp + '\n'; } } if (strRet.empty()) @@ -201,12 +190,12 @@ string CRPCTable::help(string strCommand) const Value help(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) - throw runtime_error( + throw std::runtime_error( "help [command]\n" "List commands, or get help for a command."); - string strCommand; - if (params.size() > 0) + std::string strCommand; + if (!params.empty()) strCommand = params[0].get_str(); return tableRPC.help(strCommand); @@ -216,12 +205,12 @@ Value help(const Array& params, bool fHelp) Value stop(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) - throw runtime_error( + throw std::runtime_error( "stop \n" " is true or false to detach the database or not for this stop only\n" "Stop NovaCoin server (and possibly override the detachdb config value)."); // Shutdown will take long enough that the response should get back - if (params.size() > 0) + if (!params.empty()) bitdb.SetDetach(params[0].get_bool()); StartShutdown(); return "NovaCoin server stopping"; @@ -327,31 +316,30 @@ static const CRPCCommand vRPCCommands[] = CRPCTable::CRPCTable() { - unsigned int vcidx; - for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++) + for (const auto & vRPCCommand : vRPCCommands) { const CRPCCommand *pcmd; - pcmd = &vRPCCommands[vcidx]; + pcmd = &vRPCCommand; mapCommands[pcmd->name] = pcmd; } } -const CRPCCommand *CRPCTable::operator[](string name) const +const CRPCCommand *CRPCTable::operator[](const std::string& name) const { - map::const_iterator it = mapCommands.find(name); + auto it = mapCommands.find(name); if (it == mapCommands.end()) - return NULL; + return nullptr; return (*it).second; } bool HTTPAuthorized(ix::WebSocketHttpHeaders& mapHeaders) { - string strAuth = mapHeaders["authorization"]; + std::string strAuth = mapHeaders["authorization"]; if (strAuth.substr(0,6) != "Basic ") return false; - string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); - string strUserPass = DecodeBase64(strUserPass64); + std::string strUserPass64 = strAuth.substr(6); boost::algorithm::trim(strUserPass64); + std::string strUserPass = DecodeBase64(strUserPass64); return TimingResistantEqual(strUserPass, strRPCUserColonPass); } @@ -365,7 +353,7 @@ bool HTTPAuthorized(ix::WebSocketHttpHeaders& mapHeaders) // http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx // -string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) +std::string JSONRPCRequest(const std::string& strMethod, const Array& params, const Value& id) { Object request; request.push_back(Pair("method", strMethod)); @@ -386,13 +374,13 @@ Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) return reply; } -string JSONRPCReply(const Value& result, const Value& error, const Value& id) +std::string JSONRPCReply(const Value& result, const Value& error, const Value& id) { Object reply = JSONRPCReplyObj(result, error, id); return write_string(Value(reply), false) + "\n"; } -string ErrorReply(const Object& objError, const Value& id) +std::string ErrorReply(const Object& objError, const Value& id) { // Send error reply from json-rpc error object int nStatus = HTTP_INTERNAL_SERVER_ERROR; @@ -406,7 +394,7 @@ class JSONRequest { public: Value id; - string strMethod; + std::string strMethod; Array params; JSONRequest() { id = Value::null; } @@ -458,7 +446,7 @@ static Object JSONRPCExecOne(const Value& req) { rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); } - catch (std::exception& e) + catch (const std::exception& e) { rpc_result = JSONRPCReplyObj(Value::null, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); @@ -467,11 +455,11 @@ static Object JSONRPCExecOne(const Value& req) return rpc_result; } -static string JSONRPCExecBatch(const Array& vReq) +static std::string JSONRPCExecBatch(const Array& vReq) { Array ret; - for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) - ret.push_back(JSONRPCExecOne(vReq[reqIdx])); + for (const auto & reqIdx : vReq) + ret.push_back(JSONRPCExecOne(reqIdx)); return write_string(Value(ret), false) + "\n"; } @@ -480,12 +468,12 @@ static CCriticalSection cs_THREAD_RPCHANDLER; void StartRPCServer() { -strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; if (mapArgs["-rpcpassword"].empty()) { unsigned char rand_pwd[32]; RAND_bytes(rand_pwd, 32); - string strWhatAmI = "To use novacoind"; + std::string strWhatAmI = "To use novacoind"; if (mapArgs.count("-server")) strWhatAmI = strprintf(_("To use the %s option"), "\"-server\""); else if (mapArgs.count("-daemon")) @@ -505,29 +493,29 @@ strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; return; } - string host = GetArg("-rpchost", "127.0.0.1"); + std::string host = GetArg("-rpchost", "127.0.0.1"); int port = GetArg("-rpcport", GetDefaultRPCPort()); - g_server = std::unique_ptr(new ix::HttpServer(port, host)); + g_server = std::make_unique(port, host); LOCK(cs_THREAD_RPCHANDLER); - g_server->setOnConnectionCallback([](ix::HttpRequestPtr request, std::shared_ptr connectionState) -> ix::HttpResponsePtr { + g_server->setOnConnectionCallback([](const ix::HttpRequestPtr& request, const std::shared_ptr& connectionState) -> ix::HttpResponsePtr { ix::WebSocketHttpHeaders headers; - headers["Server"] = string("novacoin-json-rpc/") + FormatFullVersion(); - headers["WWW-Authenticate"] = "Basic realm=\"jsonrpc\""; + headers["Server"] = std::string("novacoin-json-rpc/") + FormatFullVersion(); + headers["WWW-Authenticate"] = R"(Basic realm="jsonrpc")"; if (!HTTPAuthorized(request->headers)) { printf("ThreadRPCServer incorrect password attempt from %s\n", connectionState->getRemoteIp().c_str()); connectionState->setTerminated(); - return std::make_shared(401, "Unauthorized", ix::HttpErrorCode::Ok, headers, "Not authorized"); + return std::make_shared(HTTP_UNAUTHORIZED, "Unauthorized", ix::HttpErrorCode::Ok, headers, "Not authorized"); } if (request->method != "POST") { connectionState->setTerminated(); - return std::make_shared(400, "Bad request", ix::HttpErrorCode::Ok, headers, "Bad request"); + return std::make_shared(HTTP_BAD_REQUEST, "Bad request", ix::HttpErrorCode::Ok, headers, "Bad request"); } JSONRequest jreq; @@ -539,7 +527,7 @@ strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; if (!read_string(request->body, valRequest)) throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); - string strReply; + std::string strReply; // singleton request if (valRequest.type() == obj_type) { @@ -564,11 +552,11 @@ strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } catch(Object& objError) { - return std::make_shared(500, "Internal Server Error", ix::HttpErrorCode::Ok, headers, ErrorReply(objError, jreq.id)); + return std::make_shared(HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", ix::HttpErrorCode::Ok, headers, ErrorReply(objError, jreq.id)); } - catch(std::exception& e) + catch(const std::exception& e) { - return std::make_shared(500, "Internal Server Error", ix::HttpErrorCode::Ok, headers, ErrorReply(JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id)); + return std::make_shared(HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", ix::HttpErrorCode::Ok, headers, ErrorReply(JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id)); } }); @@ -593,7 +581,7 @@ void StopRPCServer() vnThreadsRunning[THREAD_RPCLISTENER]--; } -json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const + json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const { // Find method const CRPCCommand *pcmd = tableRPC[strMethod]; @@ -601,10 +589,10 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); // Observe safe mode - string strWarning = GetWarnings("rpc"); + std::string strWarning = GetWarnings("rpc"); if (!strWarning.empty() && !GetBoolArg("-disablesafemode") && !pcmd->okSafeMode) - throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); + throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + strWarning); try { @@ -620,7 +608,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s } return result; } - catch (std::exception& e) + catch (const std::exception& e) { throw JSONRPCError(RPC_MISC_ERROR, e.what()); } @@ -629,30 +617,29 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s std::vector CRPCTable::listCommands() const { std::vector commandList; - typedef std::map commandMap; - - std::transform( mapCommands.begin(), mapCommands.end(), - std::back_inserter(commandList), - boost::bind(&commandMap::value_type::first,_1) ); + for (const auto& i : mapCommands) commandList.emplace_back(i.first); return commandList; } -Object CallRPC(const string& strMethod, const Array& params) +Object CallRPC(const std::string& strMethod, const Array& params) { if (mapArgs["-rpcuser"].empty() && mapArgs["-rpcpassword"].empty()) - throw runtime_error(strprintf( + throw std::runtime_error(strprintf( _("You must set rpcpassword= in the configuration file:\n%s\n" "If the file does not exist, create it with owner-readable-only file permissions."), GetConfigFile().string().c_str())); + // Init net subsystem + ix::initNetSystem(); + // Create HTTP client ix::HttpClient httpClient; ix::HttpRequestArgsPtr args = httpClient.createRequest(); // HTTP basic authentication ix::WebSocketHttpHeaders mapRequestHeaders; - string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); - mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64; + std::string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); + mapRequestHeaders["Authorization"] = std::string("Basic ") + strUserPass64; args->extraHeaders = mapRequestHeaders; // Timeouts @@ -660,32 +647,32 @@ Object CallRPC(const string& strMethod, const Array& params) args->transferTimeout = GetArgInt("-rpc_transfertimeout", 30000); bool fUseSSL = GetBoolArg("-rpcssl"); - string url = string(fUseSSL ? "https://" : "http://") + GetArg("-rpcconnect", "127.0.0.1") + ":" + GetArg("-rpcport", itostr(GetDefaultRPCPort())); + std::string url = std::string(fUseSSL ? "https://" : "http://") + GetArg("-rpcconnect", "127.0.0.1") + ":" + GetArg("-rpcport", itostr(GetDefaultRPCPort())); // Send request - string strRequest = JSONRPCRequest(strMethod, params, GetRandInt(INT32_MAX)); + std::string strRequest = JSONRPCRequest(strMethod, params, GetRandInt(INT32_MAX)); auto out = httpClient.post(url, strRequest, args); // Process reply int nStatus = out->statusCode; - string strReply = out->body; + std::string strReply = out->body; ix::WebSocketHttpHeaders mapHeaders = out->headers; // Receive reply if (nStatus == HTTP_UNAUTHORIZED) - throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); - else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR) - throw runtime_error(strprintf("server returned HTTP error %d", nStatus)); + throw std::runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); + else if (nStatus >= HTTP_BAD_REQUEST && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR) + throw std::runtime_error(strprintf("server returned HTTP error %d", nStatus)); else if (strReply.empty()) - throw runtime_error("no response from server"); + throw std::runtime_error("no response from server"); // Parse reply Value valReply; if (!read_string(strReply, valReply)) - throw runtime_error("couldn't parse reply from server"); + throw std::runtime_error("couldn't parse reply from server"); const Object& reply = valReply.get_obj(); if (reply.empty()) - throw runtime_error("expected reply to have result, error and id properties"); + throw std::runtime_error("expected reply to have result, error and id properties"); return reply; } @@ -702,9 +689,9 @@ void ConvertTo(Value& value, bool fAllowNull=false) { // reinterpret string as unquoted json value Value value2; - string strJSON = value.get_str(); + std::string strJSON = value.get_str(); if (!read_string(strJSON, value2)) - throw runtime_error(string("Error parsing JSON:")+strJSON); + throw std::runtime_error(std::string("Error parsing JSON:")+strJSON); ConvertTo(value2, fAllowNull); value = value2; } @@ -718,7 +705,7 @@ void ConvertTo(Value& value, bool fAllowNull=false) Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams) { Array params; - BOOST_FOREACH(const std::string ¶m, strParams) + for(const auto ¶m : strParams) params.push_back(param); size_t n = params.size(); @@ -791,7 +778,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector strParams(&argv[2], &argv[argc]); @@ -836,14 +823,14 @@ int CommandLineRPC(int argc, char *argv[]) strPrint = write_string(result, true); } } - catch (std::exception& e) + catch (const std::exception& e) { - strPrint = string("error: ") + e.what(); + strPrint = std::string("error: ") + e.what(); nRet = 87; } catch (...) { - PrintException(NULL, "CommandLineRPC()"); + PrintException(nullptr, "CommandLineRPC()"); } if (!strPrint.empty())