diff options
Diffstat (limited to 'src/rpc')
-rw-r--r-- | src/rpc/blockchain.cpp | 75 | ||||
-rw-r--r-- | src/rpc/mining.cpp | 33 | ||||
-rw-r--r-- | src/rpc/misc.cpp | 30 | ||||
-rw-r--r-- | src/rpc/net.cpp | 38 | ||||
-rw-r--r-- | src/rpc/protocol.cpp | 21 | ||||
-rw-r--r-- | src/rpc/protocol.h | 2 | ||||
-rw-r--r-- | src/rpc/rawtransaction.cpp | 48 | ||||
-rw-r--r-- | src/rpc/safemode.cpp | 14 | ||||
-rw-r--r-- | src/rpc/safemode.h | 12 | ||||
-rw-r--r-- | src/rpc/server.cpp | 17 | ||||
-rw-r--r-- | src/rpc/server.h | 4 |
11 files changed, 162 insertions, 132 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 701608e132..ef61e5a55d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -125,7 +125,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx if(txDetails) { UniValue objTx(UniValue::VOBJ); - TxToUniv(*tx, uint256(), objTx); + TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags()); txs.push_back(objTx); } else @@ -944,9 +944,10 @@ UniValue gettxout(const JSONRPCRequest& request) "gettxout \"txid\" n ( include_mempool )\n" "\nReturns details about an unspent transaction output.\n" "\nArguments:\n" - "1. \"txid\" (string, required) The transaction id\n" - "2. n (numeric, required) vout number\n" - "3. include_mempool (boolean, optional) Whether to include the mempool\n" + "1. \"txid\" (string, required) The transaction id\n" + "2. \"n\" (numeric, required) vout number\n" + "3. \"include_mempool\" (boolean, optional) Whether to include the mempool. Default: true." + " Note that an unspent output that is spent in the mempool won't appear.\n" "\nResult:\n" "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" @@ -1018,8 +1019,8 @@ UniValue gettxout(const JSONRPCRequest& request) UniValue verifychain(const JSONRPCRequest& request) { - int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL); - int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); + int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL); + int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); if (request.fHelp || request.params.size() > 2) throw std::runtime_error( "verifychain ( checklevel nblocks )\n" @@ -1324,7 +1325,7 @@ UniValue mempoolInfoToJSON() ret.push_back(Pair("size", (int64_t) mempool.size())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); - size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; ret.push_back(Pair("maxmempool", (int64_t) maxmempool)); ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK()))); @@ -1343,7 +1344,7 @@ UniValue getmempoolinfo(const JSONRPCRequest& request) " \"bytes\": xxxxx, (numeric) Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted\n" " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n" " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n" - " \"mempoolminfee\": xxxxx (numeric) Minimum feerate (" + CURRENCY_UNIT + " per KB) for tx to be accepted\n" + " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmempoolinfo", "") @@ -1489,11 +1490,11 @@ UniValue getchaintxstats(const JSONRPCRequest& request) const CBlockIndex* pindex; int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month - if (request.params.size() > 0 && !request.params[0].isNull()) { + if (!request.params[0].isNull()) { blockcount = request.params[0].get_int(); } - bool havehash = request.params.size() > 1 && !request.params[1].isNull(); + bool havehash = !request.params[1].isNull(); uint256 hash; if (havehash) { hash = uint256S(request.params[1].get_str()); @@ -1532,35 +1533,35 @@ UniValue getchaintxstats(const JSONRPCRequest& request) } static const CRPCCommand commands[] = -{ // category name actor (function) okSafe argNames - // --------------------- ------------------------ ----------------------- ------ ---------- - { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} }, - { "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} }, - { "blockchain", "getbestblockhash", &getbestblockhash, true, {} }, - { "blockchain", "getblockcount", &getblockcount, true, {} }, - { "blockchain", "getblock", &getblock, true, {"blockhash","verbosity|verbose"} }, - { "blockchain", "getblockhash", &getblockhash, true, {"height"} }, - { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} }, - { "blockchain", "getchaintips", &getchaintips, true, {} }, - { "blockchain", "getdifficulty", &getdifficulty, true, {} }, - { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} }, - { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} }, - { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} }, - { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} }, - { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} }, - { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} }, - { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} }, - { "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} }, - { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} }, - - { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} }, +{ // category name actor (function) argNames + // --------------------- ------------------------ ----------------------- ---------- + { "blockchain", "getblockchaininfo", &getblockchaininfo, {} }, + { "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} }, + { "blockchain", "getbestblockhash", &getbestblockhash, {} }, + { "blockchain", "getblockcount", &getblockcount, {} }, + { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} }, + { "blockchain", "getblockhash", &getblockhash, {"height"} }, + { "blockchain", "getblockheader", &getblockheader, {"blockhash","verbose"} }, + { "blockchain", "getchaintips", &getchaintips, {} }, + { "blockchain", "getdifficulty", &getdifficulty, {} }, + { "blockchain", "getmempoolancestors", &getmempoolancestors, {"txid","verbose"} }, + { "blockchain", "getmempooldescendants", &getmempooldescendants, {"txid","verbose"} }, + { "blockchain", "getmempoolentry", &getmempoolentry, {"txid"} }, + { "blockchain", "getmempoolinfo", &getmempoolinfo, {} }, + { "blockchain", "getrawmempool", &getrawmempool, {"verbose"} }, + { "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} }, + { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} }, + { "blockchain", "pruneblockchain", &pruneblockchain, {"height"} }, + { "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} }, + + { "blockchain", "preciousblock", &preciousblock, {"blockhash"} }, /* Not shown in help */ - { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} }, - { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} }, - { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} }, - { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} }, - { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} }, + { "hidden", "invalidateblock", &invalidateblock, {"blockhash"} }, + { "hidden", "reconsiderblock", &reconsiderblock, {"blockhash"} }, + { "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} }, + { "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} }, + { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} }, }; void RegisterBlockchainRPCCommands(CRPCTable &t) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index f498b5c8ea..73860f375f 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -336,7 +336,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request) " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" " ,...\n" " ],\n" - " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" + " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" " \"weight\" : n, (numeric) total transaction weight, as counted for purposes of block limits\n" " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n" @@ -346,7 +346,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request) " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" " \"flags\" : \"xx\" (string) key name is to be ignored, and value included in scriptSig\n" " },\n" - " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n" + " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)\n" " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" " \"target\" : \"xxxx\", (string) The hash target\n" " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" @@ -686,7 +686,7 @@ public: bool found; CValidationState state; - submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {} + explicit submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {} protected: void BlockChecked(const CBlock& block, const CValidationState& stateIn) override { @@ -825,7 +825,7 @@ UniValue estimatesmartfee(const JSONRPCRequest& request) " \"CONSERVATIVE\"\n" "\nResult:\n" "{\n" - " \"feerate\" : x.x, (numeric, optional) estimate fee-per-kilobyte (in BTC)\n" + " \"feerate\" : x.x, (numeric, optional) estimate fee rate in " + CURRENCY_UNIT + "/kB\n" " \"errors\": [ str... ] (json array of strings, optional) Errors encountered during processing\n" " \"blocks\" : n (numeric) block number where estimate was found\n" "}\n" @@ -842,7 +842,7 @@ UniValue estimatesmartfee(const JSONRPCRequest& request) RPCTypeCheckArgument(request.params[0], UniValue::VNUM); unsigned int conf_target = ParseConfirmTarget(request.params[0]); bool conservative = true; - if (request.params.size() > 1 && !request.params[1].isNull()) { + if (!request.params[1].isNull()) { FeeEstimateMode fee_mode; if (!FeeModeFromString(request.params[1].get_str(), fee_mode)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter"); @@ -884,7 +884,7 @@ UniValue estimaterawfee(const JSONRPCRequest& request) "\nResult:\n" "{\n" " \"short\" : { (json object, optional) estimate for short time horizon\n" - " \"feerate\" : x.x, (numeric, optional) estimate fee-per-kilobyte (in BTC)\n" + " \"feerate\" : x.x, (numeric, optional) estimate fee rate in " + CURRENCY_UNIT + "/kB\n" " \"decay\" : x.x, (numeric) exponential decay (per block) for historical moving average of confirmation data\n" " \"scale\" : x, (numeric) The resolution of confirmation targets at this time horizon\n" " \"pass\" : { (json object, optional) information about the lowest range of feerates to succeed in meeting the threshold\n" @@ -967,20 +967,21 @@ UniValue estimaterawfee(const JSONRPCRequest& request) } static const CRPCCommand commands[] = -{ // category name actor (function) okSafeMode +{ // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- - { "mining", "getnetworkhashps", &getnetworkhashps, true, {"nblocks","height"} }, - { "mining", "getmininginfo", &getmininginfo, true, {} }, - { "mining", "prioritisetransaction", &prioritisetransaction, true, {"txid","dummy","fee_delta"} }, - { "mining", "getblocktemplate", &getblocktemplate, true, {"template_request"} }, - { "mining", "submitblock", &submitblock, true, {"hexdata","dummy"} }, + { "mining", "getnetworkhashps", &getnetworkhashps, {"nblocks","height"} }, + { "mining", "getmininginfo", &getmininginfo, {} }, + { "mining", "prioritisetransaction", &prioritisetransaction, {"txid","dummy","fee_delta"} }, + { "mining", "getblocktemplate", &getblocktemplate, {"template_request"} }, + { "mining", "submitblock", &submitblock, {"hexdata","dummy"} }, + - { "generating", "generatetoaddress", &generatetoaddress, true, {"nblocks","address","maxtries"} }, + { "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} }, - { "util", "estimatefee", &estimatefee, true, {"nblocks"} }, - { "util", "estimatesmartfee", &estimatesmartfee, true, {"conf_target", "estimate_mode"} }, + { "util", "estimatefee", &estimatefee, {"nblocks"} }, + { "util", "estimatesmartfee", &estimatesmartfee, {"nblocks", "estimate_mode"} }, - { "hidden", "estimaterawfee", &estimaterawfee, true, {"conf_target", "threshold"} }, + { "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} }, }; void RegisterMiningRPCCommands(CRPCTable &t) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index efff4a99ae..76eefabd29 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -125,7 +125,7 @@ class DescribeAddressVisitor : public boost::static_visitor<UniValue> public: CWallet * const pwallet; - DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} + explicit DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); } @@ -552,7 +552,7 @@ UniValue getmemoryinfo(const JSONRPCRequest& request) + HelpExampleRpc("getmemoryinfo", "") ); - std::string mode = (request.params.size() < 1 || request.params[0].isNull()) ? "stats" : request.params[0].get_str(); + std::string mode = request.params[0].isNull() ? "stats" : request.params[0].get_str(); if (mode == "stats") { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("locked", RPCLockedMemoryInfo())); @@ -603,11 +603,11 @@ UniValue logging(const JSONRPCRequest& request) } uint32_t originalLogCategories = logCategories; - if (request.params.size() > 0 && request.params[0].isArray()) { + if (request.params[0].isArray()) { logCategories |= getCategoryMask(request.params[0]); } - if (request.params.size() > 1 && request.params[1].isArray()) { + if (request.params[1].isArray()) { logCategories &= ~getCategoryMask(request.params[1]); } @@ -649,20 +649,20 @@ UniValue echo(const JSONRPCRequest& request) } static const CRPCCommand commands[] = -{ // category name actor (function) okSafeMode +{ // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- - { "control", "getinfo", &getinfo, true, {} }, /* uses wallet if enabled */ - { "control", "getmemoryinfo", &getmemoryinfo, true, {"mode"} }, - { "util", "validateaddress", &validateaddress, true, {"address"} }, /* uses wallet if enabled */ - { "util", "createmultisig", &createmultisig, true, {"nrequired","keys"} }, - { "util", "verifymessage", &verifymessage, true, {"address","signature","message"} }, - { "util", "signmessagewithprivkey", &signmessagewithprivkey, true, {"privkey","message"} }, + { "control", "getinfo", &getinfo, {} }, /* uses wallet if enabled */ + { "control", "getmemoryinfo", &getmemoryinfo, {"mode"} }, + { "util", "validateaddress", &validateaddress, {"address"} }, /* uses wallet if enabled */ + { "util", "createmultisig", &createmultisig, {"nrequired","keys"} }, + { "util", "verifymessage", &verifymessage, {"address","signature","message"} }, + { "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} }, /* Not shown in help */ - { "hidden", "setmocktime", &setmocktime, true, {"timestamp"}}, - { "hidden", "echo", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, - { "hidden", "echojson", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, - { "hidden", "logging", &logging, true, {"include", "exclude"}}, + { "hidden", "setmocktime", &setmocktime, {"timestamp"}}, + { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, + { "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, + { "hidden", "logging", &logging, {"include", "exclude"}}, }; void RegisterMiscRPCCommands(CRPCTable &t) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index e463a4eda4..7faf216047 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -193,7 +193,7 @@ UniValue getpeerinfo(const JSONRPCRequest& request) UniValue addnode(const JSONRPCRequest& request) { std::string strCommand; - if (request.params.size() == 2) + if (!request.params[1].isNull()) strCommand = request.params[1].get_str(); if (request.fHelp || request.params.size() != 2 || (strCommand != "onetry" && strCommand != "add" && strCommand != "remove")) @@ -258,7 +258,7 @@ UniValue disconnectnode(const JSONRPCRequest& request) bool success; const UniValue &address_arg = request.params[0]; - const UniValue &id_arg = request.params.size() < 2 ? NullUniValue : request.params[1]; + const UniValue &id_arg = request.params[1]; if (!address_arg.isNull() && id_arg.isNull()) { /* handle disconnect-by-address */ @@ -311,7 +311,7 @@ UniValue getaddednodeinfo(const JSONRPCRequest& request) std::vector<AddedNodeInfo> vInfo = g_connman->GetAddedNodeInfo(); - if (request.params.size() == 1 && !request.params[0].isNull()) { + if (!request.params[0].isNull()) { bool found = false; for (const AddedNodeInfo& info : vInfo) { if (info.strAddedNode == request.params[0].get_str()) { @@ -490,7 +490,7 @@ UniValue getnetworkinfo(const JSONRPCRequest& request) UniValue setban(const JSONRPCRequest& request) { std::string strCommand; - if (request.params.size() >= 2) + if (!request.params[1].isNull()) strCommand = request.params[1].get_str(); if (request.fHelp || request.params.size() < 2 || (strCommand != "add" && strCommand != "remove")) @@ -534,11 +534,11 @@ UniValue setban(const JSONRPCRequest& request) throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned"); int64_t banTime = 0; //use standard bantime if not specified - if (request.params.size() >= 3 && !request.params[2].isNull()) + if (!request.params[2].isNull()) banTime = request.params[2].get_int64(); bool absolute = false; - if (request.params.size() == 4 && request.params[3].isTrue()) + if (request.params[3].isTrue()) absolute = true; isSubnet ? g_connman->Ban(subNet, BanReasonManuallyAdded, banTime, absolute) : g_connman->Ban(netAddr, BanReasonManuallyAdded, banTime, absolute); @@ -623,20 +623,20 @@ UniValue setnetworkactive(const JSONRPCRequest& request) } static const CRPCCommand commands[] = -{ // category name actor (function) okSafeMode +{ // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- - { "network", "getconnectioncount", &getconnectioncount, true, {} }, - { "network", "ping", &ping, true, {} }, - { "network", "getpeerinfo", &getpeerinfo, true, {} }, - { "network", "addnode", &addnode, true, {"node","command"} }, - { "network", "disconnectnode", &disconnectnode, true, {"address", "nodeid"} }, - { "network", "getaddednodeinfo", &getaddednodeinfo, true, {"node"} }, - { "network", "getnettotals", &getnettotals, true, {} }, - { "network", "getnetworkinfo", &getnetworkinfo, true, {} }, - { "network", "setban", &setban, true, {"subnet", "command", "bantime", "absolute"} }, - { "network", "listbanned", &listbanned, true, {} }, - { "network", "clearbanned", &clearbanned, true, {} }, - { "network", "setnetworkactive", &setnetworkactive, true, {"state"} }, + { "network", "getconnectioncount", &getconnectioncount, {} }, + { "network", "ping", &ping, {} }, + { "network", "getpeerinfo", &getpeerinfo, {} }, + { "network", "addnode", &addnode, {"node","command"} }, + { "network", "disconnectnode", &disconnectnode, {"address", "nodeid"} }, + { "network", "getaddednodeinfo", &getaddednodeinfo, {"node"} }, + { "network", "getnettotals", &getnettotals, {} }, + { "network", "getnetworkinfo", &getnetworkinfo, {} }, + { "network", "setban", &setban, {"subnet", "command", "bantime", "absolute"} }, + { "network", "listbanned", &listbanned, {} }, + { "network", "clearbanned", &clearbanned, {} }, + { "network", "setnetworkactive", &setnetworkactive, {"state"} }, }; void RegisterNetRPCCommands(CRPCTable &t) diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index 823a5775f6..dc6bcec382 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -66,9 +66,14 @@ static const std::string COOKIEAUTH_USER = "__cookie__"; /** Default name for auth cookie file */ static const std::string COOKIEAUTH_FILE = ".cookie"; -fs::path GetAuthCookieFile() +/** Get name of RPC authentication cookie file */ +static fs::path GetAuthCookieFile(bool temp=false) { - fs::path path(GetArg("-rpccookiefile", COOKIEAUTH_FILE)); + std::string arg = gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE); + if (temp) { + arg += ".tmp"; + } + fs::path path(arg); if (!path.is_complete()) path = GetDataDir() / path; return path; } @@ -84,14 +89,20 @@ bool GenerateAuthCookie(std::string *cookie_out) * these are set to 077 in init.cpp unless overridden with -sysperms. */ std::ofstream file; - fs::path filepath = GetAuthCookieFile(); - file.open(filepath.string().c_str()); + fs::path filepath_tmp = GetAuthCookieFile(true); + file.open(filepath_tmp.string().c_str()); if (!file.is_open()) { - LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath.string()); + LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath_tmp.string()); return false; } file << cookie; file.close(); + + fs::path filepath = GetAuthCookieFile(false); + if (!RenameOver(filepath_tmp, filepath)) { + LogPrintf("Unable to rename cookie authentication file %s to %s\n", filepath_tmp.string(), filepath.string()); + return false; + } LogPrintf("Generated RPC authentication cookie %s\n", filepath.string()); if (cookie_out) diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h index 4bd4702d62..5c9c64f67d 100644 --- a/src/rpc/protocol.h +++ b/src/rpc/protocol.h @@ -91,8 +91,6 @@ UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const Un std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id); UniValue JSONRPCError(int code, const std::string& message); -/** Get name of RPC authentication cookie file */ -fs::path GetAuthCookieFile(); /** Generate a new RPC authentication cookie and write it to disk */ bool GenerateAuthCookie(std::string *cookie_out); /** Read the RPC authentication cookie from disk */ diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 8100511854..27daefaf5a 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -16,6 +16,7 @@ #include "policy/policy.h" #include "policy/rbf.h" #include "primitives/transaction.h" +#include "rpc/safemode.h" #include "rpc/server.h" #include "script/script.h" #include "script/script_error.h" @@ -41,7 +42,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) // Blockchain contextual information (confirmations and blocktime) is not // available to code in bitcoin-common, so we query them here and push the // data into the returned UniValue. - TxToUniv(tx, uint256(), entry); + TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags()); if (!hashBlock.IsNull()) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); @@ -160,13 +161,10 @@ UniValue getrawtransaction(const JSONRPCRequest& request) : "No such mempool transaction. Use -txindex to enable blockchain transaction queries") + ". Use gettransaction for wallet transactions."); - std::string strHex = EncodeHexTx(*tx, RPCSerializationFlags()); - if (!fVerbose) - return strHex; + return EncodeHexTx(*tx, RPCSerializationFlags()); UniValue result(UniValue::VOBJ); - result.push_back(Pair("hex", strHex)); TxToJSON(*tx, hashBlock, result); return result; } @@ -339,14 +337,14 @@ UniValue createrawtransaction(const JSONRPCRequest& request) CMutableTransaction rawTx; - if (request.params.size() > 2 && !request.params[2].isNull()) { + if (!request.params[2].isNull()) { int64_t nLockTime = request.params[2].get_int64(); if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range"); rawTx.nLockTime = nLockTime; } - bool rbfOptIn = request.params.size() > 3 ? request.params[3].isTrue() : false; + bool rbfOptIn = request.params[3].isTrue(); for (unsigned int idx = 0; idx < inputs.size(); idx++) { const UniValue& input = inputs[idx]; @@ -483,7 +481,7 @@ UniValue decoderawtransaction(const JSONRPCRequest& request) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); UniValue result(UniValue::VOBJ); - TxToUniv(CTransaction(std::move(mtx)), uint256(), result); + TxToUniv(CTransaction(std::move(mtx)), uint256(), result, false); return result; } @@ -572,7 +570,7 @@ UniValue combinerawtransaction(const JSONRPCRequest& request) " ]\n" "\nResult:\n" - "\"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n" + "\"hex\" (string) The hex-encoded raw transaction with signature(s)\n" "\nExamples:\n" + HelpExampleCli("combinerawtransaction", "[\"myhex1\", \"myhex2\", \"myhex3\"]") @@ -706,6 +704,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) + HelpExampleRpc("signrawtransaction", "\"myhex\"") ); + ObserveSafeMode(); #ifdef ENABLE_WALLET LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr); #else @@ -735,7 +734,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) bool fGivenKeys = false; CBasicKeyStore tempKeystore; - if (request.params.size() > 2 && !request.params[2].isNull()) { + if (!request.params[2].isNull()) { fGivenKeys = true; UniValue keys = request.params[2].get_array(); for (unsigned int idx = 0; idx < keys.size(); idx++) { @@ -757,7 +756,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) #endif // Add previous txouts given in the RPC call: - if (request.params.size() > 1 && !request.params[1].isNull()) { + if (!request.params[1].isNull()) { UniValue prevTxs = request.params[1].get_array(); for (unsigned int idx = 0; idx < prevTxs.size(); idx++) { const UniValue& p = prevTxs[idx]; @@ -828,7 +827,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) #endif int nHashType = SIGHASH_ALL; - if (request.params.size() > 3 && !request.params[3].isNull()) { + if (!request.params[3].isNull()) { static std::map<std::string, int> mapSigHashValues = { {std::string("ALL"), int(SIGHASH_ALL)}, {std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)}, @@ -911,6 +910,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) + HelpExampleRpc("sendrawtransaction", "\"signedhex\"") ); + ObserveSafeMode(); LOCK(cs_main); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); @@ -922,7 +922,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) const uint256& hashTx = tx->GetHash(); CAmount nMaxRawTxFee = maxTxFee; - if (request.params.size() > 1 && request.params[1].get_bool()) + if (!request.params[1].isNull() && request.params[1].get_bool()) nMaxRawTxFee = 0; CCoinsViewCache &view = *pcoinsTip; @@ -962,18 +962,18 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) } static const CRPCCommand commands[] = -{ // category name actor (function) okSafeMode +{ // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- - { "rawtransactions", "getrawtransaction", &getrawtransaction, true, {"txid","verbose"} }, - { "rawtransactions", "createrawtransaction", &createrawtransaction, true, {"inputs","outputs","locktime","replaceable"} }, - { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, {"hexstring"} }, - { "rawtransactions", "decodescript", &decodescript, true, {"hexstring"} }, - { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, {"hexstring","allowhighfees"} }, - { "rawtransactions", "combinerawtransaction", &combinerawtransaction, true, {"txs"} }, - { "rawtransactions", "signrawtransaction", &signrawtransaction, false, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */ - - { "blockchain", "gettxoutproof", &gettxoutproof, true, {"txids", "blockhash"} }, - { "blockchain", "verifytxoutproof", &verifytxoutproof, true, {"proof"} }, + { "rawtransactions", "getrawtransaction", &getrawtransaction, {"txid","verbose"} }, + { "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime","replaceable"} }, + { "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring"} }, + { "rawtransactions", "decodescript", &decodescript, {"hexstring"} }, + { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees"} }, + { "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} }, + { "rawtransactions", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */ + + { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} }, + { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} }, }; void RegisterRawTransactionRPCCommands(CRPCTable &t) diff --git a/src/rpc/safemode.cpp b/src/rpc/safemode.cpp new file mode 100644 index 0000000000..24770ad47f --- /dev/null +++ b/src/rpc/safemode.cpp @@ -0,0 +1,14 @@ +#include "safemode.h" + +#include "rpc/protocol.h" +#include "util.h" +#include "warnings.h" + +void ObserveSafeMode() +{ + std::string warning = GetWarnings("rpc"); + if (warning != "" && !gArgs.GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE)) { + throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + warning); + } +} + diff --git a/src/rpc/safemode.h b/src/rpc/safemode.h new file mode 100644 index 0000000000..8466d6b2f9 --- /dev/null +++ b/src/rpc/safemode.h @@ -0,0 +1,12 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_RPC_SAFEMODE_H +#define BITCOIN_RPC_SAFEMODE_H + +static const bool DEFAULT_DISABLE_SAFEMODE = true; + +void ObserveSafeMode(); + +#endif // BITCOIN_RPC_SAFEMODE_H diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 1799c8e98e..428ab3b9b0 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -51,11 +51,6 @@ void RPCServer::OnStopped(std::function<void ()> slot) g_rpcSignals.Stopped.connect(slot); } -void RPCServer::OnPreCommand(std::function<void (const CRPCCommand&)> slot) -{ - g_rpcSignals.PreCommand.connect(boost::bind(slot, _1)); -} - void RPCTypeCheck(const UniValue& params, const std::list<UniValue::VType>& typesExpected, bool fAllowNull) @@ -267,12 +262,12 @@ UniValue uptime(const JSONRPCRequest& jsonRequest) * Call Table */ static const CRPCCommand vRPCCommands[] = -{ // category name actor (function) okSafe argNames - // --------------------- ------------------------ ----------------------- ------ ---------- +{ // category name actor (function) argNames + // --------------------- ------------------------ ----------------------- ---------- /* Overall control/query calls */ - { "control", "help", &help, true, {"command"} }, - { "control", "stop", &stop, true, {} }, - { "control", "uptime", &uptime, true, {} }, + { "control", "help", &help, {"command"} }, + { "control", "stop", &stop, {} }, + { "control", "uptime", &uptime, {} }, }; CRPCTable::CRPCTable() @@ -552,7 +547,7 @@ void RPCRunLater(const std::string& name, std::function<void(void)> func, int64_ int RPCSerializationFlags() { int flag = 0; - if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0) + if (gArgs.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0) flag |= SERIALIZE_TRANSACTION_NO_WITNESS; return flag; } diff --git a/src/rpc/server.h b/src/rpc/server.h index dd6f763245..777acbcb94 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -25,13 +25,12 @@ namespace RPCServer { void OnStarted(std::function<void ()> slot); void OnStopped(std::function<void ()> slot); - void OnPreCommand(std::function<void (const CRPCCommand&)> slot); } /** Wrapper for UniValue::VType, which includes typeAny: * Used to denote don't care type. Only used by RPCTypeCheckObj */ struct UniValueType { - UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {} + explicit UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {} UniValueType() : typeAny(true) {} bool typeAny; UniValue::VType type; @@ -134,7 +133,6 @@ public: std::string category; std::string name; rpcfn_type actor; - bool okSafeMode; std::vector<std::string> argNames; }; |