diff options
Diffstat (limited to 'src/rpcserver.cpp')
-rw-r--r-- | src/rpcserver.cpp | 69 |
1 files changed, 32 insertions, 37 deletions
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 2f28971589..68091010f7 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -11,7 +11,6 @@ #include "sync.h" #include "ui_interface.h" #include "util.h" -#include "utilmoneystr.h" #include "utilstrencodings.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" @@ -121,10 +120,10 @@ void RPCTypeCheckObj(const UniValue& o, CAmount AmountFromValue(const UniValue& value) { - if (!value.isReal() && !value.isNum()) - throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number"); + if (!value.isNum() && !value.isStr()) + throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string"); CAmount amount; - if (!ParseMoney(value.getValStr(), amount)) + if (!ParseFixedPoint(value.getValStr(), 8, &amount)) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); if (!MoneyRange(amount)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range"); @@ -133,7 +132,12 @@ CAmount AmountFromValue(const UniValue& value) UniValue ValueFromAmount(const CAmount& amount) { - return UniValue(UniValue::VREAL, FormatMoney(amount)); + bool sign = amount < 0; + int64_t n_abs = (sign ? -amount : amount); + int64_t quotient = n_abs / COIN; + int64_t remainder = n_abs % COIN; + return UniValue(UniValue::VNUM, + strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder)); } uint256 ParseHashV(const UniValue& v, string strName) @@ -289,6 +293,7 @@ static const CRPCCommand vRPCCommands[] = { "blockchain", "getblockcount", &getblockcount, true }, { "blockchain", "getblock", &getblock, true }, { "blockchain", "getblockhash", &getblockhash, true }, + { "blockchain", "getblockheader", &getblockheader, true }, { "blockchain", "getchaintips", &getchaintips, true }, { "blockchain", "getdifficulty", &getdifficulty, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, @@ -306,12 +311,10 @@ static const CRPCCommand vRPCCommands[] = { "mining", "prioritisetransaction", &prioritisetransaction, true }, { "mining", "submitblock", &submitblock, true }, -#ifdef ENABLE_WALLET /* Coin generation */ { "generating", "getgenerate", &getgenerate, true }, { "generating", "setgenerate", &setgenerate, true }, { "generating", "generate", &generate, true }, -#endif /* Raw transactions */ { "rawtransactions", "createrawtransaction", &createrawtransaction, true }, @@ -598,28 +601,18 @@ void StartRPCThreads() strAllowed += subnet.ToString() + " "; LogPrint("rpc", "Allowing RPC connections from: %s\n", strAllowed); - strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; - if (((mapArgs["-rpcpassword"] == "") || - (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword()) + if (mapArgs["-rpcpassword"] == "") { - unsigned char rand_pwd[32]; - GetRandBytes(rand_pwd, 32); - uiInterface.ThreadSafeMessageBox(strprintf( - _("To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:\n" - "%s\n" - "It is recommended you use the following random password:\n" - "rpcuser=bitcoinrpc\n" - "rpcpassword=%s\n" - "(you do not need to remember this password)\n" - "The username and password MUST NOT be the same.\n" - "If the file does not exist, create it with owner-readable-only file permissions.\n" - "It is also recommended to set alertnotify so you are notified of problems;\n" - "for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"), - GetConfigFile().string(), - EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32)), - "", CClientUIInterface::MSG_ERROR | CClientUIInterface::SECURE); - StartShutdown(); - return; + LogPrintf("No rpcpassword set - using random cookie authentication\n"); + if (!GenerateAuthCookie(&strRPCUserColonPass)) { + uiInterface.ThreadSafeMessageBox( + _("Error: A fatal internal error occured, see debug.log for details"), // Same message as AbortNode + "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return; + } + } else { + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } assert(rpc_io_service == NULL); @@ -759,17 +752,19 @@ void StopRPCThreads() { acceptor->cancel(ec); if (ec) - LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message()); + LogPrintf("%s: Warning: %s when cancelling acceptor\n", __func__, ec.message()); } rpc_acceptors.clear(); BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers) { timer.second->cancel(ec); if (ec) - LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message()); + LogPrintf("%s: Warning: %s when cancelling timer\n", __func__, ec.message()); } deadlineTimers.clear(); + DeleteAuthCookie(); + rpc_io_service->stop(); g_rpcSignals.Stopped(); if (rpc_worker_group != NULL) @@ -932,13 +927,6 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, if (!valRequest.read(strRequest)) throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); - // Return immediately if in warmup - { - LOCK(cs_rpcWarmup); - if (fRPCInWarmup) - throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); - } - string strReply; // singleton request @@ -1010,6 +998,13 @@ void ServiceConnection(AcceptedConnection *conn) UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms) const { + // Return immediately if in warmup + { + LOCK(cs_rpcWarmup); + if (fRPCInWarmup) + throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); + } + // Find method const CRPCCommand *pcmd = tableRPC[strMethod]; if (!pcmd) |