aboutsummaryrefslogtreecommitdiff
path: root/src/bitcoinrpc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bitcoinrpc.cpp')
-rw-r--r--src/bitcoinrpc.cpp199
1 files changed, 122 insertions, 77 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index d22809ce69..798660dff3 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -113,6 +113,34 @@ std::string HexBits(unsigned int nBits)
return HexStr(BEGIN(uBits.cBits), END(uBits.cBits));
}
+uint256 ParseHashV(const Value& v, string strName)
+{
+ string strHex;
+ if (v.type() == str_type)
+ strHex = v.get_str();
+ if (!IsHex(strHex)) // Note: IsHex("") is false
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
+ uint256 result;
+ result.SetHex(strHex);
+ return result;
+}
+uint256 ParseHashO(const Object& o, string strKey)
+{
+ return ParseHashV(find_value(o, strKey), strKey);
+}
+vector<unsigned char> ParseHexV(const Value& v, string strName)
+{
+ string strHex;
+ if (v.type() == str_type)
+ strHex = v.get_str();
+ if (!IsHex(strHex))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
+ return ParseHex(strHex);
+}
+vector<unsigned char> ParseHexO(const Object& o, string strKey)
+{
+ return ParseHexV(find_value(o, strKey), strKey);
+}
///
@@ -132,6 +160,9 @@ string CRPCTable::help(string strCommand) const
continue;
if (strCommand != "" && strMethod != strCommand)
continue;
+ if (pcmd->reqWallet && !pwalletMain)
+ continue;
+
try
{
Array params;
@@ -190,74 +221,79 @@ Value stop(const Array& params, bool fHelp)
static const CRPCCommand vRPCCommands[] =
-{ // name actor (function) okSafeMode threadSafe
- // ------------------------ ----------------------- ---------- ----------
- { "help", &help, true, true },
- { "stop", &stop, true, true },
- { "getblockcount", &getblockcount, true, false },
- { "getbestblockhash", &getbestblockhash, true, false },
- { "getconnectioncount", &getconnectioncount, true, false },
- { "getpeerinfo", &getpeerinfo, true, false },
- { "addnode", &addnode, true, true },
- { "getaddednodeinfo", &getaddednodeinfo, true, true },
- { "getdifficulty", &getdifficulty, true, false },
- { "getgenerate", &getgenerate, true, false },
- { "setgenerate", &setgenerate, true, false },
- { "gethashespersec", &gethashespersec, true, false },
- { "getinfo", &getinfo, true, false },
- { "getmininginfo", &getmininginfo, true, false },
- { "getnewaddress", &getnewaddress, true, false },
- { "getaccountaddress", &getaccountaddress, true, false },
- { "setaccount", &setaccount, true, false },
- { "getaccount", &getaccount, false, false },
- { "getaddressesbyaccount", &getaddressesbyaccount, true, false },
- { "sendtoaddress", &sendtoaddress, false, false },
- { "getreceivedbyaddress", &getreceivedbyaddress, false, false },
- { "getreceivedbyaccount", &getreceivedbyaccount, false, false },
- { "listreceivedbyaddress", &listreceivedbyaddress, false, false },
- { "listreceivedbyaccount", &listreceivedbyaccount, false, false },
- { "backupwallet", &backupwallet, true, false },
- { "keypoolrefill", &keypoolrefill, true, false },
- { "walletpassphrase", &walletpassphrase, true, false },
- { "walletpassphrasechange", &walletpassphrasechange, false, false },
- { "walletlock", &walletlock, true, false },
- { "encryptwallet", &encryptwallet, false, false },
- { "validateaddress", &validateaddress, true, false },
- { "getbalance", &getbalance, false, false },
- { "move", &movecmd, false, false },
- { "sendfrom", &sendfrom, false, false },
- { "sendmany", &sendmany, false, false },
- { "addmultisigaddress", &addmultisigaddress, false, false },
- { "createmultisig", &createmultisig, true, true },
- { "getrawmempool", &getrawmempool, true, false },
- { "getblock", &getblock, false, false },
- { "getblockhash", &getblockhash, false, false },
- { "gettransaction", &gettransaction, false, false },
- { "listtransactions", &listtransactions, false, false },
- { "listaddressgroupings", &listaddressgroupings, false, false },
- { "signmessage", &signmessage, false, false },
- { "verifymessage", &verifymessage, false, false },
- { "getwork", &getwork, true, false },
- { "listaccounts", &listaccounts, false, false },
- { "settxfee", &settxfee, false, false },
- { "getblocktemplate", &getblocktemplate, true, false },
- { "submitblock", &submitblock, false, false },
- { "listsinceblock", &listsinceblock, false, false },
- { "dumpprivkey", &dumpprivkey, true, false },
- { "dumpwallet", &dumpwallet, true, false },
- { "importprivkey", &importprivkey, false, false },
- { "importwallet", &importwallet, false, false },
- { "listunspent", &listunspent, false, false },
- { "getrawtransaction", &getrawtransaction, false, false },
- { "createrawtransaction", &createrawtransaction, false, false },
- { "decoderawtransaction", &decoderawtransaction, false, false },
- { "signrawtransaction", &signrawtransaction, false, false },
- { "sendrawtransaction", &sendrawtransaction, false, false },
- { "gettxoutsetinfo", &gettxoutsetinfo, true, false },
- { "gettxout", &gettxout, true, false },
- { "lockunspent", &lockunspent, false, false },
- { "listlockunspent", &listlockunspent, false, false },
- { "verifychain", &verifychain, true, false },
+{ // name actor (function) okSafeMode threadSafe reqWallet
+ // ------------------------ ----------------------- ---------- ---------- ---------
+ { "help", &help, true, true, false },
+ { "stop", &stop, true, true, false },
+ { "getblockcount", &getblockcount, true, false, false },
+ { "getbestblockhash", &getbestblockhash, true, false, false },
+ { "getconnectioncount", &getconnectioncount, true, false, false },
+ { "getpeerinfo", &getpeerinfo, true, false, false },
+ { "ping", &ping, true, false, false },
+ { "addnode", &addnode, true, true, false },
+ { "getaddednodeinfo", &getaddednodeinfo, true, true, false },
+ { "getnettotals", &getnettotals, true, true, false },
+ { "getdifficulty", &getdifficulty, true, false, false },
+ { "getnetworkhashps", &getnetworkhashps, true, false, false },
+ { "getgenerate", &getgenerate, true, false, false },
+ { "setgenerate", &setgenerate, true, false, true },
+ { "gethashespersec", &gethashespersec, true, false, false },
+ { "getinfo", &getinfo, true, false, false },
+ { "getmininginfo", &getmininginfo, true, false, false },
+ { "getnewaddress", &getnewaddress, true, false, true },
+ { "getaccountaddress", &getaccountaddress, true, false, true },
+ { "getrawchangeaddress", &getrawchangeaddress, true, false, true },
+ { "setaccount", &setaccount, true, false, true },
+ { "getaccount", &getaccount, false, false, true },
+ { "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
+ { "sendtoaddress", &sendtoaddress, false, false, true },
+ { "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
+ { "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
+ { "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
+ { "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
+ { "backupwallet", &backupwallet, true, false, true },
+ { "keypoolrefill", &keypoolrefill, true, false, true },
+ { "walletpassphrase", &walletpassphrase, true, false, true },
+ { "walletpassphrasechange", &walletpassphrasechange, false, false, true },
+ { "walletlock", &walletlock, true, false, true },
+ { "encryptwallet", &encryptwallet, false, false, true },
+ { "validateaddress", &validateaddress, true, false, false },
+ { "getbalance", &getbalance, false, false, true },
+ { "move", &movecmd, false, false, true },
+ { "sendfrom", &sendfrom, false, false, true },
+ { "sendmany", &sendmany, false, false, true },
+ { "addmultisigaddress", &addmultisigaddress, false, false, true },
+ { "createmultisig", &createmultisig, true, true , false },
+ { "getrawmempool", &getrawmempool, true, false, false },
+ { "getblock", &getblock, false, false, false },
+ { "getblockhash", &getblockhash, false, false, false },
+ { "gettransaction", &gettransaction, false, false, true },
+ { "listtransactions", &listtransactions, false, false, true },
+ { "listaddressgroupings", &listaddressgroupings, false, false, true },
+ { "signmessage", &signmessage, false, false, true },
+ { "verifymessage", &verifymessage, false, false, false },
+ { "getwork", &getwork, true, false, true },
+ { "listaccounts", &listaccounts, false, false, true },
+ { "settxfee", &settxfee, false, false, true },
+ { "getblocktemplate", &getblocktemplate, true, false, false },
+ { "submitblock", &submitblock, false, false, false },
+ { "listsinceblock", &listsinceblock, false, false, true },
+ { "dumpprivkey", &dumpprivkey, true, false, true },
+ { "dumpwallet", &dumpwallet, true, false, true },
+ { "importprivkey", &importprivkey, false, false, true },
+ { "importwallet", &importwallet, false, false, true },
+ { "listunspent", &listunspent, false, false, true },
+ { "getrawtransaction", &getrawtransaction, false, false, false },
+ { "createrawtransaction", &createrawtransaction, false, false, false },
+ { "decoderawtransaction", &decoderawtransaction, false, false, false },
+ { "decodescript", &decodescript, false, false, false },
+ { "signrawtransaction", &signrawtransaction, false, false, false },
+ { "sendrawtransaction", &sendrawtransaction, false, false, false },
+ { "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
+ { "gettxout", &gettxout, true, false, false },
+ { "lockunspent", &lockunspent, false, false, true },
+ { "listlockunspent", &listlockunspent, false, false, true },
+ { "verifychain", &verifychain, true, false, false },
};
CRPCTable::CRPCTable()
@@ -766,12 +802,12 @@ void StartRPCThreads()
filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile;
if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
- else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str());
+ else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str());
filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile;
if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
- else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str());
+ else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str());
string strCiphers = GetArg("-rpcsslciphers", "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str());
@@ -846,7 +882,8 @@ void StopRPCThreads()
deadlineTimers.clear();
rpc_io_service->stop();
- rpc_worker_group->join_all();
+ if (rpc_worker_group != NULL)
+ rpc_worker_group->join_all();
delete rpc_worker_group; rpc_worker_group = NULL;
delete rpc_ssl_context; rpc_ssl_context = NULL;
delete rpc_io_service; rpc_io_service = NULL;
@@ -901,7 +938,7 @@ void JSONRequest::parse(const Value& valRequest)
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
strMethod = valMethod.get_str();
if (strMethod != "getwork" && strMethod != "getblocktemplate")
- printf("ThreadRPCServer method=%s\n", strMethod.c_str());
+ LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod.c_str());
// Parse params
Value valParams = find_value(request, "params");
@@ -975,10 +1012,10 @@ void ServiceConnection(AcceptedConnection *conn)
}
if (!HTTPAuthorized(mapHeaders))
{
- printf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string().c_str());
+ LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string().c_str());
/* Deter brute-forcing short passwords.
- If this results in a DOS the user really
- shouldn't have their RPC port exposed.*/
+ If this results in a DoS the user really
+ shouldn't have their RPC port exposed. */
if (mapArgs["-rpcpassword"].size() < 20)
MilliSleep(250);
@@ -1034,6 +1071,8 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
const CRPCCommand *pcmd = tableRPC[strMethod];
if (!pcmd)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
+ if (pcmd->reqWallet && !pwalletMain)
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
// Observe safe mode
string strWarning = GetWarnings("rpc");
@@ -1048,7 +1087,10 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
{
if (pcmd->threadSafe)
result = pcmd->actor(params, false);
- else {
+ else if (!pwalletMain) {
+ LOCK(cs_main);
+ result = pcmd->actor(params, false);
+ } else {
LOCK2(cs_main, pwalletMain->cs_wallet);
result = pcmd->actor(params, false);
}
@@ -1158,6 +1200,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "getnetworkhashps" && n > 0) ConvertTo<boost::int64_t>(params[0]);
+ if (strMethod == "getnetworkhashps" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]);
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
@@ -1193,6 +1237,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
+ if (strMethod == "sendrawtransaction" && n > 1) ConvertTo<bool>(params[1], true);
if (strMethod == "gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
if (strMethod == "lockunspent" && n > 0) ConvertTo<bool>(params[0]);
@@ -1289,7 +1334,7 @@ int main(int argc, char *argv[])
{
if (argc >= 2 && string(argv[1]) == "-server")
{
- printf("server ready\n");
+ LogPrintf("server ready\n");
ThreadRPCServer(NULL);
}
else