diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 9d4c4e53b..2d66448d8 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -223,7 +223,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str()); // Attach request data - std::string strRequest = JSONRPCRequest(strMethod, params, 1); + std::string strRequest = JSONRPCRequestObj(strMethod, params, 1).write() + "\n"; struct evbuffer * output_buffer = evhttp_request_get_output_buffer(req); assert(output_buffer); evbuffer_add(output_buffer, strRequest.data(), strRequest.size()); diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 6a6c5276c..e35acb6cd 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -127,7 +127,7 @@ static bool multiUserAuthorized(std::string strUserPass) return false; } -static bool RPCAuthorized(const std::string& strAuth) +static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUsernameOut) { if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called return false; @@ -136,7 +136,10 @@ static bool RPCAuthorized(const std::string& strAuth) std::string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); std::string strUserPass = DecodeBase64(strUserPass64); - + + if (strUserPass.find(":") != std::string::npos) + strAuthUsernameOut = strUserPass.substr(0, strUserPass.find(":")); + //Check if authorized under single-user field if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) { return true; @@ -159,7 +162,8 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) return false; } - if (!RPCAuthorized(authHeader.second)) { + JSONRPCRequest jreq; + if (!RPCAuthorized(authHeader.second, jreq.authUser)) { LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", req->GetPeer().ToString()); /* Deter brute-forcing @@ -172,19 +176,21 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) return false; } - JSONRequest jreq; try { // Parse request UniValue valRequest; if (!valRequest.read(req->ReadBody())) throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); + // Set the URI + jreq.URI = req->GetURI(); + std::string strReply; // singleton request if (valRequest.isObject()) { jreq.parse(valRequest); - UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); + UniValue result = tableRPC.execute(jreq); // Send reply strReply = JSONRPCReply(result, NullUniValue, jreq.id); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index a1017e6c1..f10dddf58 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -246,7 +246,10 @@ bool RPCConsole::RPCExecuteCommandLine(std::string &strResult, const std::string std::string strPrint; // Convert argument list to JSON objects in method-dependent way, // and pass it along with the method name to the dispatcher. - lastResult = tableRPC.execute(stack.back()[0], RPCConvertValues(stack.back()[0], std::vector(stack.back().begin() + 1, stack.back().end()))); + JSONRPCRequest req; + req.params = RPCConvertValues(stack.back()[0], std::vector(stack.back().begin() + 1, stack.back().end())); + req.strMethod = stack.back()[0]; + lastResult = tableRPC.execute(req); state = STATE_COMMAND_EXECUTED; curarg.clear(); diff --git a/src/rest.cpp b/src/rest.cpp index c81559212..b8b542062 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -274,7 +274,7 @@ static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPa } // A bit of a hack - dependency on a function defined in rpc/blockchain.cpp -UniValue getblockchaininfo(const UniValue& params, bool fHelp); +UniValue getblockchaininfo(const JSONRPCRequest& request); static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) { @@ -285,8 +285,9 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) switch (rf) { case RF_JSON: { - UniValue rpcParams(UniValue::VARR); - UniValue chainInfoObject = getblockchaininfo(rpcParams, false); + JSONRPCRequest jsonRequest; + jsonRequest.params = UniValue(UniValue::VARR); + UniValue chainInfoObject = getblockchaininfo(jsonRequest); string strJSON = chainInfoObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 5414ac9ff..0c827a1e3 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -146,9 +146,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx return result; } -UniValue getblockcount(const UniValue& params, bool fHelp) +UniValue getblockcount(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getblockcount\n" "\nReturns the number of blocks in the longest block chain.\n" @@ -163,9 +163,9 @@ UniValue getblockcount(const UniValue& params, bool fHelp) return chainActive.Height(); } -UniValue getbestblockhash(const UniValue& params, bool fHelp) +UniValue getbestblockhash(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getbestblockhash\n" "\nReturns the hash of the best (tip) block in the longest block chain.\n" @@ -190,9 +190,9 @@ void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex) cond_blockchange.notify_all(); } -UniValue waitfornewblock(const UniValue& params, bool fHelp) +UniValue waitfornewblock(const JSONRPCRequest& request) { - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "waitfornewblock\n" "\nWaits for a specific new block and returns useful info about it.\n" @@ -209,8 +209,8 @@ UniValue waitfornewblock(const UniValue& params, bool fHelp) + HelpExampleRpc("waitfornewblock", "1000") ); int timeout = 0; - if (params.size() > 0) - timeout = params[0].get_int(); + if (request.params.size() > 0) + timeout = request.params[0].get_int(); CUpdatedBlock block; { @@ -228,9 +228,9 @@ UniValue waitfornewblock(const UniValue& params, bool fHelp) return ret; } -UniValue waitforblock(const UniValue& params, bool fHelp) +UniValue waitforblock(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "waitforblock\n" "\nWaits for a specific new block and returns useful info about it.\n" @@ -249,10 +249,10 @@ UniValue waitforblock(const UniValue& params, bool fHelp) ); int timeout = 0; - uint256 hash = uint256S(params[0].get_str()); + uint256 hash = uint256S(request.params[0].get_str()); - if (params.size() > 1) - timeout = params[1].get_int(); + if (request.params.size() > 1) + timeout = request.params[1].get_int(); CUpdatedBlock block; { @@ -270,9 +270,9 @@ UniValue waitforblock(const UniValue& params, bool fHelp) return ret; } -UniValue waitforblockheight(const UniValue& params, bool fHelp) +UniValue waitforblockheight(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "waitforblock\n" "\nWaits for (at least) block height and returns the height and hash\n" @@ -292,10 +292,10 @@ UniValue waitforblockheight(const UniValue& params, bool fHelp) ); int timeout = 0; - int height = params[0].get_int(); + int height = request.params[0].get_int(); - if (params.size() > 1) - timeout = params[1].get_int(); + if (request.params.size() > 1) + timeout = request.params[1].get_int(); CUpdatedBlock block; { @@ -312,9 +312,9 @@ UniValue waitforblockheight(const UniValue& params, bool fHelp) return ret; } -UniValue getdifficulty(const UniValue& params, bool fHelp) +UniValue getdifficulty(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getdifficulty\n" "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n" @@ -411,9 +411,9 @@ UniValue mempoolToJSON(bool fVerbose = false) } } -UniValue getrawmempool(const UniValue& params, bool fHelp) +UniValue getrawmempool(const JSONRPCRequest& request) { - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "getrawmempool ( verbose )\n" "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" @@ -436,15 +436,15 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) ); bool fVerbose = false; - if (params.size() > 0) - fVerbose = params[0].get_bool(); + if (request.params.size() > 0) + fVerbose = request.params[0].get_bool(); return mempoolToJSON(fVerbose); } -UniValue getmempoolancestors(const UniValue& params, bool fHelp) +UniValue getmempoolancestors(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) { + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw runtime_error( "getmempoolancestors txid (verbose)\n" "\nIf txid is in the mempool, returns all in-mempool ancestors.\n" @@ -469,10 +469,10 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) } bool fVerbose = false; - if (params.size() > 1) - fVerbose = params[1].get_bool(); + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); - uint256 hash = ParseHashV(params[0], "parameter 1"); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); LOCK(mempool.cs); @@ -506,9 +506,9 @@ UniValue getmempoolancestors(const UniValue& params, bool fHelp) } } -UniValue getmempooldescendants(const UniValue& params, bool fHelp) +UniValue getmempooldescendants(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) { + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw runtime_error( "getmempooldescendants txid (verbose)\n" "\nIf txid is in the mempool, returns all in-mempool descendants.\n" @@ -533,10 +533,10 @@ UniValue getmempooldescendants(const UniValue& params, bool fHelp) } bool fVerbose = false; - if (params.size() > 1) - fVerbose = params[1].get_bool(); + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); - uint256 hash = ParseHashV(params[0], "parameter 1"); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); LOCK(mempool.cs); @@ -570,9 +570,9 @@ UniValue getmempooldescendants(const UniValue& params, bool fHelp) } } -UniValue getmempoolentry(const UniValue& params, bool fHelp) +UniValue getmempoolentry(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) { + if (request.fHelp || request.params.size() != 1) { throw runtime_error( "getmempoolentry txid\n" "\nReturns mempool data for given transaction\n" @@ -588,7 +588,7 @@ UniValue getmempoolentry(const UniValue& params, bool fHelp) ); } - uint256 hash = ParseHashV(params[0], "parameter 1"); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); LOCK(mempool.cs); @@ -603,9 +603,9 @@ UniValue getmempoolentry(const UniValue& params, bool fHelp) return info; } -UniValue getblockhash(const UniValue& params, bool fHelp) +UniValue getblockhash(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "getblockhash index\n" "\nReturns hash of block in best-block-chain at index provided.\n" @@ -620,7 +620,7 @@ UniValue getblockhash(const UniValue& params, bool fHelp) LOCK(cs_main); - int nHeight = params[0].get_int(); + int nHeight = request.params[0].get_int(); if (nHeight < 0 || nHeight > chainActive.Height()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); @@ -628,9 +628,9 @@ UniValue getblockhash(const UniValue& params, bool fHelp) return pblockindex->GetBlockHash().GetHex(); } -UniValue getblockheader(const UniValue& params, bool fHelp) +UniValue getblockheader(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "getblockheader \"hash\" ( verbose )\n" "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" @@ -664,12 +664,12 @@ UniValue getblockheader(const UniValue& params, bool fHelp) LOCK(cs_main); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); bool fVerbose = true; - if (params.size() > 1) - fVerbose = params[1].get_bool(); + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); if (mapBlockIndex.count(hash) == 0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); @@ -687,9 +687,9 @@ UniValue getblockheader(const UniValue& params, bool fHelp) return blockheaderToJSON(pblockindex); } -UniValue getblock(const UniValue& params, bool fHelp) +UniValue getblock(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "getblock \"hash\" ( verbose )\n" "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n" @@ -730,12 +730,12 @@ UniValue getblock(const UniValue& params, bool fHelp) LOCK(cs_main); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); bool fVerbose = true; - if (params.size() > 1) - fVerbose = params[1].get_bool(); + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); if (mapBlockIndex.count(hash) == 0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); @@ -814,9 +814,9 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) return true; } -UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) +UniValue gettxoutsetinfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "gettxoutsetinfo\n" "\nReturns statistics about the unspent transaction output set.\n" @@ -854,9 +854,9 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) return ret; } -UniValue gettxout(const UniValue& params, bool fHelp) +UniValue gettxout(const JSONRPCRequest& request) { - if (fHelp || params.size() < 2 || params.size() > 3) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) throw runtime_error( "gettxout \"txid\" n ( includemempool )\n" "\nReturns details about an unspent transaction output.\n" @@ -896,12 +896,12 @@ UniValue gettxout(const UniValue& params, bool fHelp) UniValue ret(UniValue::VOBJ); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); - int n = params[1].get_int(); + int n = request.params[1].get_int(); bool fMempool = true; - if (params.size() > 2) - fMempool = params[2].get_bool(); + if (request.params.size() > 2) + fMempool = request.params[2].get_bool(); CCoins coins; if (fMempool) { @@ -934,11 +934,11 @@ UniValue gettxout(const UniValue& params, bool fHelp) return ret; } -UniValue verifychain(const UniValue& params, bool fHelp) +UniValue verifychain(const JSONRPCRequest& request) { int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL); int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); - if (fHelp || params.size() > 2) + if (request.fHelp || request.params.size() > 2) throw runtime_error( "verifychain ( checklevel numblocks )\n" "\nVerifies blockchain database.\n" @@ -954,10 +954,10 @@ UniValue verifychain(const UniValue& params, bool fHelp) LOCK(cs_main); - if (params.size() > 0) - nCheckLevel = params[0].get_int(); - if (params.size() > 1) - nCheckDepth = params[1].get_int(); + if (request.params.size() > 0) + nCheckLevel = request.params[0].get_int(); + if (request.params.size() > 1) + nCheckDepth = request.params[1].get_int(); return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth); } @@ -1021,9 +1021,9 @@ void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id))); } -UniValue getblockchaininfo(const UniValue& params, bool fHelp) +UniValue getblockchaininfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getblockchaininfo\n" "Returns an object containing various state info regarding block chain processing.\n" @@ -1113,9 +1113,9 @@ struct CompareBlocksByHeight } }; -UniValue getchaintips(const UniValue& params, bool fHelp) +UniValue getchaintips(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getchaintips\n" "Return information about all known tips in the block tree," @@ -1229,9 +1229,9 @@ UniValue mempoolInfoToJSON() return ret; } -UniValue getmempoolinfo(const UniValue& params, bool fHelp) +UniValue getmempoolinfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getmempoolinfo\n" "\nReturns details on the active state of the TX memory pool.\n" @@ -1251,9 +1251,9 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) return mempoolInfoToJSON(); } -UniValue preciousblock(const UniValue& params, bool fHelp) +UniValue preciousblock(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "preciousblock \"hash\"\n" "\nTreats a block as if it were received before others with the same work.\n" @@ -1267,7 +1267,7 @@ UniValue preciousblock(const UniValue& params, bool fHelp) + HelpExampleRpc("preciousblock", "\"blockhash\"") ); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); CBlockIndex* pblockindex; @@ -1289,9 +1289,9 @@ UniValue preciousblock(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue invalidateblock(const UniValue& params, bool fHelp) +UniValue invalidateblock(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "invalidateblock \"hash\"\n" "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n" @@ -1303,7 +1303,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) + HelpExampleRpc("invalidateblock", "\"blockhash\"") ); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); CValidationState state; @@ -1327,9 +1327,9 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue reconsiderblock(const UniValue& params, bool fHelp) +UniValue reconsiderblock(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "reconsiderblock \"hash\"\n" "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" @@ -1342,7 +1342,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) + HelpExampleRpc("reconsiderblock", "\"blockhash\"") ); - std::string strHash = params[0].get_str(); + std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 891b04482..d509dd691 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -74,9 +74,9 @@ UniValue GetNetworkHashPS(int lookup, int height) { return workDiff.getdouble() / timeDiff; } -UniValue getnetworkhashps(const UniValue& params, bool fHelp) +UniValue getnetworkhashps(const JSONRPCRequest& request) { - if (fHelp || params.size() > 2) + if (request.fHelp || request.params.size() > 2) throw runtime_error( "getnetworkhashps ( blocks height )\n" "\nReturns the estimated network hashes per second based on the last n blocks.\n" @@ -93,7 +93,7 @@ UniValue getnetworkhashps(const UniValue& params, bool fHelp) ); LOCK(cs_main); - return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); + return GetNetworkHashPS(request.params.size() > 0 ? request.params[0].get_int() : 120, request.params.size() > 1 ? request.params[1].get_int() : -1); } UniValue generateBlocks(boost::shared_ptr coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript) @@ -146,9 +146,9 @@ UniValue generateBlocks(boost::shared_ptr coinbaseScript, int nG return blockHashes; } -UniValue generate(const UniValue& params, bool fHelp) +UniValue generate(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "generate numblocks ( maxtries )\n" "\nMine up to numblocks blocks immediately (before the RPC call returns)\n" @@ -162,10 +162,10 @@ UniValue generate(const UniValue& params, bool fHelp) + HelpExampleCli("generate", "11") ); - int nGenerate = params[0].get_int(); + int nGenerate = request.params[0].get_int(); uint64_t nMaxTries = 1000000; - if (params.size() > 1) { - nMaxTries = params[1].get_int(); + if (request.params.size() > 1) { + nMaxTries = request.params[1].get_int(); } boost::shared_ptr coinbaseScript; @@ -182,9 +182,9 @@ UniValue generate(const UniValue& params, bool fHelp) return generateBlocks(coinbaseScript, nGenerate, nMaxTries, true); } -UniValue generatetoaddress(const UniValue& params, bool fHelp) +UniValue generatetoaddress(const JSONRPCRequest& request) { - if (fHelp || params.size() < 2 || params.size() > 3) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) throw runtime_error( "generatetoaddress numblocks address (maxtries)\n" "\nMine blocks immediately to a specified address (before the RPC call returns)\n" @@ -199,13 +199,13 @@ UniValue generatetoaddress(const UniValue& params, bool fHelp) + HelpExampleCli("generatetoaddress", "11 \"myaddress\"") ); - int nGenerate = params[0].get_int(); + int nGenerate = request.params[0].get_int(); uint64_t nMaxTries = 1000000; - if (params.size() > 2) { - nMaxTries = params[2].get_int(); + if (request.params.size() > 2) { + nMaxTries = request.params[2].get_int(); } - CBitcoinAddress address(params[1].get_str()); + CBitcoinAddress address(request.params[1].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address"); @@ -215,9 +215,9 @@ UniValue generatetoaddress(const UniValue& params, bool fHelp) return generateBlocks(coinbaseScript, nGenerate, nMaxTries, false); } -UniValue getmininginfo(const UniValue& params, bool fHelp) +UniValue getmininginfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getmininginfo\n" "\nReturns a json object containing mining-related information." @@ -248,7 +248,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); - obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); + obj.push_back(Pair("networkhashps", getnetworkhashps(request))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("chain", Params().NetworkIDString())); return obj; @@ -256,9 +256,9 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts -UniValue prioritisetransaction(const UniValue& params, bool fHelp) +UniValue prioritisetransaction(const JSONRPCRequest& request) { - if (fHelp || params.size() != 3) + if (request.fHelp || request.params.size() != 3) throw runtime_error( "prioritisetransaction \n" "Accepts the transaction into mined blocks at a higher (or lower) priority\n" @@ -279,10 +279,10 @@ UniValue prioritisetransaction(const UniValue& params, bool fHelp) LOCK(cs_main); - uint256 hash = ParseHashStr(params[0].get_str(), "txid"); - CAmount nAmount = params[2].get_int64(); + uint256 hash = ParseHashStr(request.params[0].get_str(), "txid"); + CAmount nAmount = request.params[2].get_int64(); - mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount); + mempool.PrioritiseTransaction(hash, request.params[0].get_str(), request.params[1].get_real(), nAmount); return true; } @@ -315,9 +315,9 @@ std::string gbt_vb_name(const Consensus::DeploymentPos pos) { return s; } -UniValue getblocktemplate(const UniValue& params, bool fHelp) +UniValue getblocktemplate(const JSONRPCRequest& request) { - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "getblocktemplate ( TemplateRequest )\n" "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n" @@ -400,9 +400,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue lpval = NullUniValue; std::set setClientRules; int64_t nMaxVersionPreVB = -1; - if (params.size() > 0) + if (request.params.size() > 0) { - const UniValue& oparam = params[0].get_obj(); + const UniValue& oparam = request.params[0].get_obj(); const UniValue& modeval = find_value(oparam, "mode"); if (modeval.isStr()) strMode = modeval.get_str(); @@ -705,9 +705,9 @@ protected: }; }; -UniValue submitblock(const UniValue& params, bool fHelp) +UniValue submitblock(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n" "\nAttempts to submit new block to network.\n" @@ -727,7 +727,7 @@ UniValue submitblock(const UniValue& params, bool fHelp) ); CBlock block; - if (!DecodeHexBlk(block, params[0].get_str())) + if (!DecodeHexBlk(block, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); uint256 hash = block.GetHash(); @@ -774,9 +774,9 @@ UniValue submitblock(const UniValue& params, bool fHelp) return BIP22ValidationResult(state); } -UniValue estimatefee(const UniValue& params, bool fHelp) +UniValue estimatefee(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "estimatefee nblocks\n" "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n" @@ -792,9 +792,9 @@ UniValue estimatefee(const UniValue& params, bool fHelp) + HelpExampleCli("estimatefee", "6") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); - int nBlocks = params[0].get_int(); + int nBlocks = request.params[0].get_int(); if (nBlocks < 1) nBlocks = 1; @@ -805,9 +805,9 @@ UniValue estimatefee(const UniValue& params, bool fHelp) return ValueFromAmount(feeRate.GetFeePerK()); } -UniValue estimatepriority(const UniValue& params, bool fHelp) +UniValue estimatepriority(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "estimatepriority nblocks\n" "\nEstimates the approximate priority a zero-fee transaction needs to begin\n" @@ -823,18 +823,18 @@ UniValue estimatepriority(const UniValue& params, bool fHelp) + HelpExampleCli("estimatepriority", "6") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); - int nBlocks = params[0].get_int(); + int nBlocks = request.params[0].get_int(); if (nBlocks < 1) nBlocks = 1; return mempool.estimatePriority(nBlocks); } -UniValue estimatesmartfee(const UniValue& params, bool fHelp) +UniValue estimatesmartfee(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "estimatesmartfee nblocks\n" "\nWARNING: This interface is unstable and may disappear or change!\n" @@ -856,9 +856,9 @@ UniValue estimatesmartfee(const UniValue& params, bool fHelp) + HelpExampleCli("estimatesmartfee", "6") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); - int nBlocks = params[0].get_int(); + int nBlocks = request.params[0].get_int(); UniValue result(UniValue::VOBJ); int answerFound; @@ -868,9 +868,9 @@ UniValue estimatesmartfee(const UniValue& params, bool fHelp) return result; } -UniValue estimatesmartpriority(const UniValue& params, bool fHelp) +UniValue estimatesmartpriority(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "estimatesmartpriority nblocks\n" "\nWARNING: This interface is unstable and may disappear or change!\n" @@ -892,9 +892,9 @@ UniValue estimatesmartpriority(const UniValue& params, bool fHelp) + HelpExampleCli("estimatesmartpriority", "6") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); - int nBlocks = params[0].get_int(); + int nBlocks = request.params[0].get_int(); UniValue result(UniValue::VOBJ); int answerFound; diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 6bbb3925d..eaef4856b 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -39,9 +39,9 @@ using namespace std; * * Or alternatively, create a specific query method for the information. **/ -UniValue getinfo(const UniValue& params, bool fHelp) +UniValue getinfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getinfo\n" "\nDEPRECATED. Returns an object containing various state info.\n" @@ -148,9 +148,9 @@ public: }; #endif -UniValue validateaddress(const UniValue& params, bool fHelp) +UniValue validateaddress(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "validateaddress \"bitcoinaddress\"\n" "\nReturn information about the given bitcoin address.\n" @@ -181,7 +181,7 @@ UniValue validateaddress(const UniValue& params, bool fHelp) LOCK(cs_main); #endif - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); bool isValid = address.IsValid(); UniValue ret(UniValue::VOBJ); @@ -278,9 +278,9 @@ CScript _createmultisig_redeemScript(const UniValue& params) return result; } -UniValue createmultisig(const UniValue& params, bool fHelp) +UniValue createmultisig(const JSONRPCRequest& request) { - if (fHelp || params.size() < 2 || params.size() > 2) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) { string msg = "createmultisig nrequired [\"key\",...]\n" "\nCreates a multi-signature address with n signature of m keys required.\n" @@ -310,7 +310,7 @@ UniValue createmultisig(const UniValue& params, bool fHelp) } // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(params); + CScript inner = _createmultisig_redeemScript(request.params); CScriptID innerID(inner); CBitcoinAddress address(innerID); @@ -321,9 +321,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp) return result; } -UniValue verifymessage(const UniValue& params, bool fHelp) +UniValue verifymessage(const JSONRPCRequest& request) { - if (fHelp || params.size() != 3) + if (request.fHelp || request.params.size() != 3) throw runtime_error( "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n" "\nVerify a signed message\n" @@ -346,9 +346,9 @@ UniValue verifymessage(const UniValue& params, bool fHelp) LOCK(cs_main); - string strAddress = params[0].get_str(); - string strSign = params[1].get_str(); - string strMessage = params[2].get_str(); + string strAddress = request.params[0].get_str(); + string strSign = request.params[1].get_str(); + string strMessage = request.params[2].get_str(); CBitcoinAddress addr(strAddress); if (!addr.IsValid()) @@ -375,9 +375,9 @@ UniValue verifymessage(const UniValue& params, bool fHelp) return (pubkey.GetID() == keyID); } -UniValue signmessagewithprivkey(const UniValue& params, bool fHelp) +UniValue signmessagewithprivkey(const JSONRPCRequest& request) { - if (fHelp || params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "signmessagewithprivkey \"privkey\" \"message\"\n" "\nSign a message with the private key of an address\n" @@ -395,8 +395,8 @@ UniValue signmessagewithprivkey(const UniValue& params, bool fHelp) + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"") ); - string strPrivkey = params[0].get_str(); - string strMessage = params[1].get_str(); + string strPrivkey = request.params[0].get_str(); + string strMessage = request.params[1].get_str(); CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(strPrivkey); @@ -417,9 +417,9 @@ UniValue signmessagewithprivkey(const UniValue& params, bool fHelp) return EncodeBase64(&vchSig[0], vchSig.size()); } -UniValue setmocktime(const UniValue& params, bool fHelp) +UniValue setmocktime(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "setmocktime timestamp\n" "\nSet the local time to given timestamp (-regtest only)\n" @@ -437,8 +437,8 @@ UniValue setmocktime(const UniValue& params, bool fHelp) // in a long time. LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); - SetMockTime(params[0].get_int64()); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); + SetMockTime(request.params[0].get_int64()); uint64_t t = GetTime(); if(g_connman) { diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index a8442d869..2b43f08f0 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -23,9 +23,9 @@ using namespace std; -UniValue getconnectioncount(const UniValue& params, bool fHelp) +UniValue getconnectioncount(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getconnectioncount\n" "\nReturns the number of connections to other nodes.\n" @@ -42,9 +42,9 @@ UniValue getconnectioncount(const UniValue& params, bool fHelp) return (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL); } -UniValue ping(const UniValue& params, bool fHelp) +UniValue ping(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "ping\n" "\nRequests that a ping be sent to all other nodes, to measure ping time.\n" @@ -65,9 +65,9 @@ UniValue ping(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue getpeerinfo(const UniValue& params, bool fHelp) +UniValue getpeerinfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getpeerinfo\n" "\nReturns data about each connected network node as a json array of objects.\n" @@ -184,12 +184,12 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) return ret; } -UniValue addnode(const UniValue& params, bool fHelp) +UniValue addnode(const JSONRPCRequest& request) { string strCommand; - if (params.size() == 2) - strCommand = params[1].get_str(); - if (fHelp || params.size() != 2 || + if (request.params.size() == 2) + strCommand = request.params[1].get_str(); + if (request.fHelp || request.params.size() != 2 || (strCommand != "onetry" && strCommand != "add" && strCommand != "remove")) throw runtime_error( "addnode \"node\" \"add|remove|onetry\"\n" @@ -206,7 +206,7 @@ UniValue addnode(const UniValue& params, bool fHelp) if(!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); - string strNode = params[0].get_str(); + string strNode = request.params[0].get_str(); if (strCommand == "onetry") { @@ -229,9 +229,9 @@ UniValue addnode(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue disconnectnode(const UniValue& params, bool fHelp) +UniValue disconnectnode(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "disconnectnode \"node\" \n" "\nImmediately disconnects from the specified node.\n" @@ -245,16 +245,16 @@ UniValue disconnectnode(const UniValue& params, bool fHelp) if(!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); - bool ret = g_connman->DisconnectNode(params[0].get_str()); + bool ret = g_connman->DisconnectNode(request.params[0].get_str()); if (!ret) throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes"); return NullUniValue; } -UniValue getaddednodeinfo(const UniValue& params, bool fHelp) +UniValue getaddednodeinfo(const JSONRPCRequest& request) { - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "getaddednodeinfo ( \"node\" )\n" "\nReturns information about the given added node, or all added nodes\n" @@ -286,10 +286,10 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp) std::vector vInfo = g_connman->GetAddedNodeInfo(); - if (params.size() == 1) { + if (request.params.size() == 1) { bool found = false; for (const AddedNodeInfo& info : vInfo) { - if (info.strAddedNode == params[0].get_str()) { + if (info.strAddedNode == request.params[0].get_str()) { vInfo.assign(1, info); found = true; break; @@ -320,9 +320,9 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp) return ret; } -UniValue getnettotals(const UniValue& params, bool fHelp) +UniValue getnettotals(const JSONRPCRequest& request) { - if (fHelp || params.size() > 0) + if (request.fHelp || request.params.size() > 0) throw runtime_error( "getnettotals\n" "\nReturns information about network traffic, including bytes in, bytes out,\n" @@ -386,9 +386,9 @@ static UniValue GetNetworksInfo() return networks; } -UniValue getnetworkinfo(const UniValue& params, bool fHelp) +UniValue getnetworkinfo(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getnetworkinfo\n" "Returns an object containing various state info regarding P2P networking.\n" @@ -456,12 +456,12 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp) return obj; } -UniValue setban(const UniValue& params, bool fHelp) +UniValue setban(const JSONRPCRequest& request) { string strCommand; - if (params.size() >= 2) - strCommand = params[1].get_str(); - if (fHelp || params.size() < 2 || + if (request.params.size() >= 2) + strCommand = request.params[1].get_str(); + if (request.fHelp || request.params.size() < 2 || (strCommand != "add" && strCommand != "remove")) throw runtime_error( "setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n" @@ -483,16 +483,16 @@ UniValue setban(const UniValue& params, bool fHelp) CNetAddr netAddr; bool isSubnet = false; - if (params[0].get_str().find("/") != string::npos) + if (request.params[0].get_str().find("/") != string::npos) isSubnet = true; if (!isSubnet) { CNetAddr resolved; - LookupHost(params[0].get_str().c_str(), resolved, false); + LookupHost(request.params[0].get_str().c_str(), resolved, false); netAddr = resolved; } else - LookupSubNet(params[0].get_str().c_str(), subNet); + LookupSubNet(request.params[0].get_str().c_str(), subNet); if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) ) throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet"); @@ -503,11 +503,11 @@ UniValue setban(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned"); int64_t banTime = 0; //use standard bantime if not specified - if (params.size() >= 3 && !params[2].isNull()) - banTime = params[2].get_int64(); + if (request.params.size() >= 3 && !request.params[2].isNull()) + banTime = request.params[2].get_int64(); bool absolute = false; - if (params.size() == 4 && params[3].isTrue()) + if (request.params.size() == 4 && request.params[3].isTrue()) absolute = true; isSubnet ? g_connman->Ban(subNet, BanReasonManuallyAdded, banTime, absolute) : g_connman->Ban(netAddr, BanReasonManuallyAdded, banTime, absolute); @@ -520,9 +520,9 @@ UniValue setban(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue listbanned(const UniValue& params, bool fHelp) +UniValue listbanned(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "listbanned\n" "\nList all banned IPs/Subnets.\n" @@ -553,9 +553,9 @@ UniValue listbanned(const UniValue& params, bool fHelp) return bannedAddresses; } -UniValue clearbanned(const UniValue& params, bool fHelp) +UniValue clearbanned(const JSONRPCRequest& request) { - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "clearbanned\n" "\nClear all banned IPs.\n" diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index bb885bb5a..ec186f4fc 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -26,13 +26,13 @@ using namespace std; * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html */ -string JSONRPCRequest(const string& strMethod, const UniValue& params, const UniValue& id) +UniValue JSONRPCRequestObj(const string& strMethod, const UniValue& params, const UniValue& id) { UniValue request(UniValue::VOBJ); request.push_back(Pair("method", strMethod)); request.push_back(Pair("params", params)); request.push_back(Pair("id", id)); - return request.write() + "\n"; + return request; } UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id) diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h index 1d2ef0e41..c74fa0070 100644 --- a/src/rpc/protocol.h +++ b/src/rpc/protocol.h @@ -77,7 +77,7 @@ enum RPCErrorCode RPC_WALLET_ALREADY_UNLOCKED = -17, //!< Wallet is already unlocked }; -std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id); +UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id); UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id); std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id); UniValue JSONRPCError(int code, const std::string& message); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 2ea65b8e9..0656a6175 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -126,9 +126,9 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) } } -UniValue getrawtransaction(const UniValue& params, bool fHelp) +UniValue getrawtransaction(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "getrawtransaction \"txid\" ( verbose )\n" "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n" @@ -198,11 +198,11 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) LOCK(cs_main); - uint256 hash = ParseHashV(params[0], "parameter 1"); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); bool fVerbose = false; - if (params.size() > 1) - fVerbose = (params[1].get_int() != 0); + if (request.params.size() > 1) + fVerbose = (request.params[1].get_int() != 0); CTransaction tx; uint256 hashBlock; @@ -220,9 +220,9 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) return result; } -UniValue gettxoutproof(const UniValue& params, bool fHelp) +UniValue gettxoutproof(const JSONRPCRequest& request) { - if (fHelp || (params.size() != 1 && params.size() != 2)) + if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2)) throw runtime_error( "gettxoutproof [\"txid\",...] ( blockhash )\n" "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n" @@ -244,7 +244,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) set setTxids; uint256 oneTxid; - UniValue txids = params[0].get_array(); + UniValue txids = request.params[0].get_array(); for (unsigned int idx = 0; idx < txids.size(); idx++) { const UniValue& txid = txids[idx]; if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) @@ -261,9 +261,9 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) CBlockIndex* pblockindex = NULL; uint256 hashBlock; - if (params.size() > 1) + if (request.params.size() > 1) { - hashBlock = uint256S(params[1].get_str()); + hashBlock = uint256S(request.params[1].get_str()); if (!mapBlockIndex.count(hashBlock)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); pblockindex = mapBlockIndex[hashBlock]; @@ -301,9 +301,9 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) return strHex; } -UniValue verifytxoutproof(const UniValue& params, bool fHelp) +UniValue verifytxoutproof(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "verifytxoutproof \"proof\"\n" "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n" @@ -314,7 +314,7 @@ UniValue verifytxoutproof(const UniValue& params, bool fHelp) "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n" ); - CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); + CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); CMerkleBlock merkleBlock; ssMB >> merkleBlock; @@ -335,9 +335,9 @@ UniValue verifytxoutproof(const UniValue& params, bool fHelp) return res; } -UniValue createrawtransaction(const UniValue& params, bool fHelp) +UniValue createrawtransaction(const JSONRPCRequest& request) { - if (fHelp || params.size() < 2 || params.size() > 3) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) throw runtime_error( "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime )\n" "\nCreate a transaction spending the given inputs and creating new outputs.\n" @@ -373,17 +373,17 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true); - if (params[0].isNull() || params[1].isNull()) + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true); + if (request.params[0].isNull() || request.params[1].isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null"); - UniValue inputs = params[0].get_array(); - UniValue sendTo = params[1].get_obj(); + UniValue inputs = request.params[0].get_array(); + UniValue sendTo = request.params[1].get_obj(); CMutableTransaction rawTx; - if (params.size() > 2 && !params[2].isNull()) { - int64_t nLockTime = params[2].get_int64(); + if (request.params.size() > 2 && !request.params[2].isNull()) { + int64_t nLockTime = request.params[2].get_int64(); if (nLockTime < 0 || nLockTime > std::numeric_limits::max()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range"); rawTx.nLockTime = nLockTime; @@ -448,9 +448,9 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) return EncodeHexTx(rawTx); } -UniValue decoderawtransaction(const UniValue& params, bool fHelp) +UniValue decoderawtransaction(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "decoderawtransaction \"hexstring\"\n" "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n" @@ -504,11 +504,11 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)); CTransaction tx; - if (!DecodeHexTx(tx, params[0].get_str(), true)) + if (!DecodeHexTx(tx, request.params[0].get_str(), true)) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); UniValue result(UniValue::VOBJ); @@ -517,9 +517,9 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) return result; } -UniValue decodescript(const UniValue& params, bool fHelp) +UniValue decodescript(const JSONRPCRequest& request) { - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "decodescript \"hex\"\n" "\nDecode a hex-encoded script.\n" @@ -542,12 +542,12 @@ UniValue decodescript(const UniValue& params, bool fHelp) + HelpExampleRpc("decodescript", "\"hexstring\"") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)); UniValue r(UniValue::VOBJ); CScript script; - if (params[0].get_str().size() > 0){ - vector scriptData(ParseHexV(params[0], "argument")); + if (request.params[0].get_str().size() > 0){ + vector scriptData(ParseHexV(request.params[0], "argument")); script = CScript(scriptData.begin(), scriptData.end()); } else { // Empty scripts are valid @@ -578,9 +578,9 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std:: vErrorsRet.push_back(entry); } -UniValue signrawtransaction(const UniValue& params, bool fHelp) +UniValue signrawtransaction(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 4) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw runtime_error( "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n" "\nSign inputs for raw transaction (serialized, hex-encoded).\n" @@ -644,9 +644,9 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) #else LOCK(cs_main); #endif - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR), true); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR), true); - vector txData(ParseHexV(params[0], "argument 1")); + vector txData(ParseHexV(request.params[0], "argument 1")); CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); vector txVariants; while (!ssData.empty()) { @@ -687,9 +687,9 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) bool fGivenKeys = false; CBasicKeyStore tempKeystore; - if (params.size() > 2 && !params[2].isNull()) { + if (request.params.size() > 2 && !request.params[2].isNull()) { fGivenKeys = true; - UniValue keys = params[2].get_array(); + UniValue keys = request.params[2].get_array(); for (unsigned int idx = 0; idx < keys.size(); idx++) { UniValue k = keys[idx]; CBitcoinSecret vchSecret; @@ -708,8 +708,8 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) #endif // Add previous txouts given in the RPC call: - if (params.size() > 1 && !params[1].isNull()) { - UniValue prevTxs = params[1].get_array(); + if (request.params.size() > 1 && !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]; if (!p.isObject()) @@ -777,7 +777,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) #endif int nHashType = SIGHASH_ALL; - if (params.size() > 3 && !params[3].isNull()) { + if (request.params.size() > 3 && !request.params[3].isNull()) { static map mapSigHashValues = boost::assign::map_list_of (string("ALL"), int(SIGHASH_ALL)) @@ -787,7 +787,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) (string("SINGLE"), int(SIGHASH_SINGLE)) (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)) ; - string strHashType = params[3].get_str(); + string strHashType = request.params[3].get_str(); if (mapSigHashValues.count(strHashType)) nHashType = mapSigHashValues[strHashType]; else @@ -842,9 +842,9 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) return result; } -UniValue sendrawtransaction(const UniValue& params, bool fHelp) +UniValue sendrawtransaction(const JSONRPCRequest& request) { - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "sendrawtransaction \"hexstring\" ( allowhighfees )\n" "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n" @@ -866,17 +866,17 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); // parse hex string from parameter CTransaction tx; - if (!DecodeHexTx(tx, params[0].get_str())) + if (!DecodeHexTx(tx, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); uint256 hashTx = tx.GetHash(); bool fLimitFree = false; CAmount nMaxRawTxFee = maxTxFee; - if (params.size() > 1 && params[1].get_bool()) + if (request.params.size() > 1 && request.params[1].get_bool()) nMaxRawTxFee = 0; CCoinsViewCache &view = *pcoinsTip; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 5fb97f749..29d0bee1b 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -195,10 +195,11 @@ std::string CRPCTable::help(const std::string& strCommand) const continue; try { - UniValue params; + JSONRPCRequest jreq; + jreq.fHelp = true; rpcfn_type pfn = pcmd->actor; if (setDone.insert(pfn).second) - (*pfn)(params, true); + (*pfn)(jreq); } catch (const std::exception& e) { @@ -228,9 +229,9 @@ std::string CRPCTable::help(const std::string& strCommand) const return strRet; } -UniValue help(const UniValue& params, bool fHelp) +UniValue help(const JSONRPCRequest& jsonRequest) { - if (fHelp || params.size() > 1) + if (jsonRequest.fHelp || jsonRequest.params.size() > 1) throw runtime_error( "help ( \"command\" )\n" "\nList all commands, or get help for a specified command.\n" @@ -241,17 +242,17 @@ UniValue help(const UniValue& params, bool fHelp) ); string strCommand; - if (params.size() > 0) - strCommand = params[0].get_str(); + if (jsonRequest.params.size() > 0) + strCommand = jsonRequest.params[0].get_str(); return tableRPC.help(strCommand); } -UniValue stop(const UniValue& params, bool fHelp) +UniValue stop(const JSONRPCRequest& jsonRequest) { // Accept the deprecated and ignored 'detach' boolean argument - if (fHelp || params.size() > 1) + if (jsonRequest.fHelp || jsonRequest.params.size() > 1) throw runtime_error( "stop\n" "\nStop Bitcoin server."); @@ -354,7 +355,7 @@ bool RPCIsInWarmup(std::string *outStatus) return fRPCInWarmup; } -void JSONRequest::parse(const UniValue& valRequest) +void JSONRPCRequest::parse(const UniValue& valRequest) { // Parse request if (!valRequest.isObject()) @@ -388,11 +389,11 @@ static UniValue JSONRPCExecOne(const UniValue& req) { UniValue rpc_result(UniValue::VOBJ); - JSONRequest jreq; + JSONRPCRequest jreq; try { jreq.parse(req); - UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); + UniValue result = tableRPC.execute(jreq); rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); } catch (const UniValue& objError) @@ -417,7 +418,7 @@ std::string JSONRPCExecBatch(const UniValue& vReq) return ret.write() + "\n"; } -UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms) const +UniValue CRPCTable::execute(const JSONRPCRequest &request) const { // Return immediately if in warmup { @@ -427,7 +428,7 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms } // Find method - const CRPCCommand *pcmd = tableRPC[strMethod]; + const CRPCCommand *pcmd = tableRPC[request.strMethod]; if (!pcmd) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); @@ -436,7 +437,7 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms try { // Execute - return pcmd->actor(params, false); + return pcmd->actor(request); } catch (const std::exception& e) { diff --git a/src/rpc/server.h b/src/rpc/server.h index 4e0aa2c6d..c59886222 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -41,14 +41,17 @@ struct UniValueType { UniValue::VType type; }; -class JSONRequest +class JSONRPCRequest { public: UniValue id; std::string strMethod; UniValue params; + bool fHelp; + std::string URI; + std::string authUser; - JSONRequest() { id = NullUniValue; } + JSONRPCRequest() { id = NullUniValue; params = NullUniValue; fHelp = false; } void parse(const UniValue& valRequest); }; @@ -122,7 +125,7 @@ void RPCUnsetTimerInterface(RPCTimerInterface *iface); */ void RPCRunLater(const std::string& name, boost::function func, int64_t nSeconds); -typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp); +typedef UniValue(*rpcfn_type)(const JSONRPCRequest& jsonRequest); class CRPCCommand { @@ -147,12 +150,11 @@ public: /** * Execute a method. - * @param method Method to execute - * @param params UniValue Array of arguments (JSON objects) + * @param request The JSONRPCRequest to execute * @returns Result of the call. * @throws an exception (UniValue) when an error happens. */ - UniValue execute(const std::string &method, const UniValue ¶ms) const; + UniValue execute(const JSONRPCRequest &request) const; /** * Returns a list of registered commands diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index a15915aad..a3d1a2558 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -24,11 +24,14 @@ UniValue CallRPC(string args) boost::split(vArgs, args, boost::is_any_of(" \t")); string strMethod = vArgs[0]; vArgs.erase(vArgs.begin()); - UniValue params = RPCConvertValues(strMethod, vArgs); + JSONRPCRequest request; + request.strMethod = strMethod; + request.params = RPCConvertValues(strMethod, vArgs); + request.fHelp = false; BOOST_CHECK(tableRPC[strMethod]); rpcfn_type method = tableRPC[strMethod]->actor; try { - UniValue result = (*method)(params, false); + UniValue result = (*method)(request); return result; } catch (const UniValue& objError) { diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index e80fa7dff..8a1bbd568 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -74,12 +74,12 @@ std::string DecodeDumpString(const std::string &str) { return ret.str(); } -UniValue importprivkey(const UniValue& params, bool fHelp) +UniValue importprivkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 3) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw runtime_error( "importprivkey \"bitcoinprivkey\" ( \"label\" rescan )\n" "\nAdds a private key (as returned by dumpprivkey) to your wallet.\n" @@ -104,15 +104,15 @@ UniValue importprivkey(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); - string strSecret = params[0].get_str(); + string strSecret = request.params[0].get_str(); string strLabel = ""; - if (params.size() > 1) - strLabel = params[1].get_str(); + if (request.params.size() > 1) + strLabel = request.params[1].get_str(); // Whether to perform rescan after import bool fRescan = true; - if (params.size() > 2) - fRescan = params[2].get_bool(); + if (request.params.size() > 2) + fRescan = request.params[2].get_bool(); if (fRescan && fPruneMode) throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); @@ -184,12 +184,12 @@ void ImportAddress(const CBitcoinAddress& address, const string& strLabel) pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); } -UniValue importaddress(const UniValue& params, bool fHelp) +UniValue importaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 4) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw runtime_error( "importaddress \"address\" ( \"label\" rescan p2sh )\n" "\nAdds a script (in hex) or address that can be watched as if it were in your wallet but cannot be used to spend.\n" @@ -213,31 +213,31 @@ UniValue importaddress(const UniValue& params, bool fHelp) string strLabel = ""; - if (params.size() > 1) - strLabel = params[1].get_str(); + if (request.params.size() > 1) + strLabel = request.params[1].get_str(); // Whether to perform rescan after import bool fRescan = true; - if (params.size() > 2) - fRescan = params[2].get_bool(); + if (request.params.size() > 2) + fRescan = request.params[2].get_bool(); if (fRescan && fPruneMode) throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); // Whether to import a p2sh version, too bool fP2SH = false; - if (params.size() > 3) - fP2SH = params[3].get_bool(); + if (request.params.size() > 3) + fP2SH = request.params[3].get_bool(); LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); if (address.IsValid()) { if (fP2SH) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead"); ImportAddress(address, strLabel); - } else if (IsHex(params[0].get_str())) { - std::vector data(ParseHex(params[0].get_str())); + } else if (IsHex(request.params[0].get_str())) { + std::vector data(ParseHex(request.params[0].get_str())); ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH); } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); @@ -252,12 +252,12 @@ UniValue importaddress(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue importprunedfunds(const UniValue& params, bool fHelp) +UniValue importprunedfunds(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "importprunedfunds\n" "\nImports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.\n" @@ -267,12 +267,12 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) ); CTransaction tx; - if (!DecodeHexTx(tx, params[0].get_str())) + if (!DecodeHexTx(tx, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); uint256 hashTx = tx.GetHash(); CWalletTx wtx(pwalletMain,tx); - CDataStream ssMB(ParseHexV(params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssMB(ParseHexV(request.params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION); CMerkleBlock merkleBlock; ssMB >> merkleBlock; @@ -311,12 +311,12 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction"); } -UniValue removeprunedfunds(const UniValue& params, bool fHelp) +UniValue removeprunedfunds(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "removeprunedfunds \"txid\"\n" "\nDeletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will effect wallet balances.\n" @@ -331,7 +331,7 @@ UniValue removeprunedfunds(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); uint256 hash; - hash.SetHex(params[0].get_str()); + hash.SetHex(request.params[0].get_str()); vector vHash; vHash.push_back(hash); vector vHashOut; @@ -347,12 +347,12 @@ UniValue removeprunedfunds(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue importpubkey(const UniValue& params, bool fHelp) +UniValue importpubkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 4) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) throw runtime_error( "importpubkey \"pubkey\" ( \"label\" rescan )\n" "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n" @@ -372,20 +372,20 @@ UniValue importpubkey(const UniValue& params, bool fHelp) string strLabel = ""; - if (params.size() > 1) - strLabel = params[1].get_str(); + if (request.params.size() > 1) + strLabel = request.params[1].get_str(); // Whether to perform rescan after import bool fRescan = true; - if (params.size() > 2) - fRescan = params[2].get_bool(); + if (request.params.size() > 2) + fRescan = request.params[2].get_bool(); if (fRescan && fPruneMode) throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); - if (!IsHex(params[0].get_str())) + if (!IsHex(request.params[0].get_str())) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string"); - std::vector data(ParseHex(params[0].get_str())); + std::vector data(ParseHex(request.params[0].get_str())); CPubKey pubKey(data.begin(), data.end()); if (!pubKey.IsFullyValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); @@ -405,12 +405,12 @@ UniValue importpubkey(const UniValue& params, bool fHelp) } -UniValue importwallet(const UniValue& params, bool fHelp) +UniValue importwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "importwallet \"filename\"\n" "\nImports keys from a wallet dump file (see dumpwallet).\n" @@ -433,7 +433,7 @@ UniValue importwallet(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); ifstream file; - file.open(params[0].get_str().c_str(), std::ios::in | std::ios::ate); + file.open(request.params[0].get_str().c_str(), std::ios::in | std::ios::ate); if (!file.is_open()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); @@ -512,12 +512,12 @@ UniValue importwallet(const UniValue& params, bool fHelp) return NullUniValue; } -UniValue dumpprivkey(const UniValue& params, bool fHelp) +UniValue dumpprivkey(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "dumpprivkey \"bitcoinaddress\"\n" "\nReveals the private key corresponding to 'bitcoinaddress'.\n" @@ -536,7 +536,7 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); - string strAddress = params[0].get_str(); + string strAddress = request.params[0].get_str(); CBitcoinAddress address; if (!address.SetString(strAddress)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); @@ -550,12 +550,12 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp) } -UniValue dumpwallet(const UniValue& params, bool fHelp) +UniValue dumpwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "dumpwallet \"filename\"\n" "\nDumps all wallet keys in a human-readable format.\n" @@ -571,7 +571,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); ofstream file; - file.open(params[0].get_str().c_str()); + file.open(request.params[0].get_str().c_str()); if (!file.is_open()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8e95426d1..33620aa6f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -101,12 +101,12 @@ string AccountFromValue(const UniValue& value) return strAccount; } -UniValue getnewaddress(const UniValue& params, bool fHelp) +UniValue getnewaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "getnewaddress ( \"account\" )\n" "\nReturns a new Bitcoin address for receiving payments.\n" @@ -125,8 +125,8 @@ UniValue getnewaddress(const UniValue& params, bool fHelp) // Parse the account first so we don't generate a key if there's an error string strAccount; - if (params.size() > 0) - strAccount = AccountFromValue(params[0]); + if (request.params.size() > 0) + strAccount = AccountFromValue(request.params[0]); if (!pwalletMain->IsLocked()) pwalletMain->TopUpKeyPool(); @@ -153,12 +153,12 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) return CBitcoinAddress(pubKey.GetID()); } -UniValue getaccountaddress(const UniValue& params, bool fHelp) +UniValue getaccountaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "getaccountaddress \"account\"\n" "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n" @@ -176,7 +176,7 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); // Parse the account first so we don't generate a key if there's an error - string strAccount = AccountFromValue(params[0]); + string strAccount = AccountFromValue(request.params[0]); UniValue ret(UniValue::VSTR); @@ -185,12 +185,12 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp) } -UniValue getrawchangeaddress(const UniValue& params, bool fHelp) +UniValue getrawchangeaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "getrawchangeaddress\n" "\nReturns a new Bitcoin address, for receiving change.\n" @@ -220,12 +220,12 @@ UniValue getrawchangeaddress(const UniValue& params, bool fHelp) } -UniValue setaccount(const UniValue& params, bool fHelp) +UniValue setaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "setaccount \"bitcoinaddress\" \"account\"\n" "\nDEPRECATED. Sets the account associated with the given address.\n" @@ -239,13 +239,13 @@ UniValue setaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); string strAccount; - if (params.size() > 1) - strAccount = AccountFromValue(params[1]); + if (request.params.size() > 1) + strAccount = AccountFromValue(request.params[1]); // Only add the account if the address is yours. if (IsMine(*pwalletMain, address.Get())) @@ -266,12 +266,12 @@ UniValue setaccount(const UniValue& params, bool fHelp) } -UniValue getaccount(const UniValue& params, bool fHelp) +UniValue getaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "getaccount \"bitcoinaddress\"\n" "\nDEPRECATED. Returns the account associated with the given address.\n" @@ -286,7 +286,7 @@ UniValue getaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); @@ -298,12 +298,12 @@ UniValue getaccount(const UniValue& params, bool fHelp) } -UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) +UniValue getaddressesbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "getaddressesbyaccount \"account\"\n" "\nDEPRECATED. Returns the list of addresses for the given account.\n" @@ -321,7 +321,7 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string strAccount = AccountFromValue(params[0]); + string strAccount = AccountFromValue(request.params[0]); // Find all addresses that have the given account UniValue ret(UniValue::VARR); @@ -369,12 +369,12 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of the wallet and coins were spent in the copy but not marked as spent here."); } -UniValue sendtoaddress(const UniValue& params, bool fHelp) +UniValue sendtoaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 2 || params.size() > 5) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" "\nSend an amount to a given address.\n" @@ -400,25 +400,25 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); // Amount - CAmount nAmount = AmountFromValue(params[1]); + CAmount nAmount = AmountFromValue(request.params[1]); if (nAmount <= 0) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); // Wallet comments CWalletTx wtx; - if (params.size() > 2 && !params[2].isNull() && !params[2].get_str().empty()) - wtx.mapValue["comment"] = params[2].get_str(); - if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) - wtx.mapValue["to"] = params[3].get_str(); + if (request.params.size() > 2 && !request.params[2].isNull() && !request.params[2].get_str().empty()) + wtx.mapValue["comment"] = request.params[2].get_str(); + if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty()) + wtx.mapValue["to"] = request.params[3].get_str(); bool fSubtractFeeFromAmount = false; - if (params.size() > 4) - fSubtractFeeFromAmount = params[4].get_bool(); + if (request.params.size() > 4) + fSubtractFeeFromAmount = request.params[4].get_bool(); EnsureWalletIsUnlocked(); @@ -427,12 +427,12 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) return wtx.GetHash().GetHex(); } -UniValue listaddressgroupings(const UniValue& params, bool fHelp) +UniValue listaddressgroupings(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp) + if (request.fHelp) throw runtime_error( "listaddressgroupings\n" "\nLists groups of addresses which have had their common ownership\n" @@ -478,12 +478,12 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp) return jsonGroupings; } -UniValue signmessage(const UniValue& params, bool fHelp) +UniValue signmessage(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 2) + if (request.fHelp || request.params.size() != 2) throw runtime_error( "signmessage \"bitcoinaddress\" \"message\"\n" "\nSign a message with the private key of an address" @@ -508,8 +508,8 @@ UniValue signmessage(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); - string strAddress = params[0].get_str(); - string strMessage = params[1].get_str(); + string strAddress = request.params[0].get_str(); + string strMessage = request.params[1].get_str(); CBitcoinAddress addr(strAddress); if (!addr.IsValid()) @@ -534,12 +534,12 @@ UniValue signmessage(const UniValue& params, bool fHelp) return EncodeBase64(&vchSig[0], vchSig.size()); } -UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) +UniValue getreceivedbyaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "getreceivedbyaddress \"bitcoinaddress\" ( minconf )\n" "\nReturns the total amount received by the given bitcoinaddress in transactions with at least minconf confirmations.\n" @@ -562,7 +562,7 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); // Bitcoin address - CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); + CBitcoinAddress address = CBitcoinAddress(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); CScript scriptPubKey = GetScriptForDestination(address.Get()); @@ -571,8 +571,8 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) // Minimum confirmations int nMinDepth = 1; - if (params.size() > 1) - nMinDepth = params[1].get_int(); + if (request.params.size() > 1) + nMinDepth = request.params[1].get_int(); // Tally CAmount nAmount = 0; @@ -592,12 +592,12 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) } -UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) +UniValue getreceivedbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "getreceivedbyaccount \"account\" ( minconf )\n" "\nDEPRECATED. Returns the total amount received by addresses with in transactions with at least [minconf] confirmations.\n" @@ -621,11 +621,11 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) // Minimum confirmations int nMinDepth = 1; - if (params.size() > 1) - nMinDepth = params[1].get_int(); + if (request.params.size() > 1) + nMinDepth = request.params[1].get_int(); // Get the set of pub keys assigned to account - string strAccount = AccountFromValue(params[0]); + string strAccount = AccountFromValue(request.params[0]); set setAddress = pwalletMain->GetAccountAddresses(strAccount); // Tally @@ -649,12 +649,12 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) } -UniValue getbalance(const UniValue& params, bool fHelp) +UniValue getbalance(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 3) + if (request.fHelp || request.params.size() > 3) throw runtime_error( "getbalance ( \"account\" minconf includeWatchonly )\n" "\nIf account is not specified, returns the server's total available balance.\n" @@ -678,18 +678,18 @@ UniValue getbalance(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (params.size() == 0) + if (request.params.size() == 0) return ValueFromAmount(pwalletMain->GetBalance()); int nMinDepth = 1; - if (params.size() > 1) - nMinDepth = params[1].get_int(); + if (request.params.size() > 1) + nMinDepth = request.params[1].get_int(); isminefilter filter = ISMINE_SPENDABLE; - if(params.size() > 2) - if(params[2].get_bool()) + if(request.params.size() > 2) + if(request.params[2].get_bool()) filter = filter | ISMINE_WATCH_ONLY; - if (params[0].get_str() == "*") { + if (request.params[0].get_str() == "*") { // Calculate total balance a different way from GetBalance() // (GetBalance() sums up all unspent TxOuts) // getbalance and "getbalance * 1 true" should return the same number @@ -717,19 +717,19 @@ UniValue getbalance(const UniValue& params, bool fHelp) return ValueFromAmount(nBalance); } - string strAccount = AccountFromValue(params[0]); + string strAccount = AccountFromValue(request.params[0]); CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, filter); return ValueFromAmount(nBalance); } -UniValue getunconfirmedbalance(const UniValue ¶ms, bool fHelp) +UniValue getunconfirmedbalance(const JSONRPCRequest &request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 0) + if (request.fHelp || request.params.size() > 0) throw runtime_error( "getunconfirmedbalance\n" "Returns the server's total unconfirmed balance\n"); @@ -740,12 +740,12 @@ UniValue getunconfirmedbalance(const UniValue ¶ms, bool fHelp) } -UniValue movecmd(const UniValue& params, bool fHelp) +UniValue movecmd(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 3 || params.size() > 5) + if (request.fHelp || request.params.size() < 3 || request.params.size() > 5) throw runtime_error( "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n" "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n" @@ -768,17 +768,17 @@ UniValue movecmd(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string strFrom = AccountFromValue(params[0]); - string strTo = AccountFromValue(params[1]); - CAmount nAmount = AmountFromValue(params[2]); + string strFrom = AccountFromValue(request.params[0]); + string strTo = AccountFromValue(request.params[1]); + CAmount nAmount = AmountFromValue(request.params[2]); if (nAmount <= 0) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); - if (params.size() > 3) + if (request.params.size() > 3) // unused parameter, used to be nMinDepth, keep type-checking it though - (void)params[3].get_int(); + (void)request.params[3].get_int(); string strComment; - if (params.size() > 4) - strComment = params[4].get_str(); + if (request.params.size() > 4) + strComment = request.params[4].get_str(); if (!pwalletMain->AccountMove(strFrom, strTo, nAmount, strComment)) throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); @@ -787,12 +787,12 @@ UniValue movecmd(const UniValue& params, bool fHelp) } -UniValue sendfrom(const UniValue& params, bool fHelp) +UniValue sendfrom(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 3 || params.size() > 6) + if (request.fHelp || request.params.size() < 3 || request.params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n" "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address." @@ -820,23 +820,23 @@ UniValue sendfrom(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string strAccount = AccountFromValue(params[0]); - CBitcoinAddress address(params[1].get_str()); + string strAccount = AccountFromValue(request.params[0]); + CBitcoinAddress address(request.params[1].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); - CAmount nAmount = AmountFromValue(params[2]); + CAmount nAmount = AmountFromValue(request.params[2]); if (nAmount <= 0) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); int nMinDepth = 1; - if (params.size() > 3) - nMinDepth = params[3].get_int(); + if (request.params.size() > 3) + nMinDepth = request.params[3].get_int(); CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 4 && !params[4].isNull() && !params[4].get_str().empty()) - wtx.mapValue["comment"] = params[4].get_str(); - if (params.size() > 5 && !params[5].isNull() && !params[5].get_str().empty()) - wtx.mapValue["to"] = params[5].get_str(); + if (request.params.size() > 4 && !request.params[4].isNull() && !request.params[4].get_str().empty()) + wtx.mapValue["comment"] = request.params[4].get_str(); + if (request.params.size() > 5 && !request.params[5].isNull() && !request.params[5].get_str().empty()) + wtx.mapValue["to"] = request.params[5].get_str(); EnsureWalletIsUnlocked(); @@ -851,12 +851,12 @@ UniValue sendfrom(const UniValue& params, bool fHelp) } -UniValue sendmany(const UniValue& params, bool fHelp) +UniValue sendmany(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 2 || params.size() > 5) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) throw runtime_error( "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n" "\nSend multiple times. Amounts are double-precision floating point numbers." @@ -897,20 +897,20 @@ UniValue sendmany(const UniValue& params, bool fHelp) if (pwalletMain->GetBroadcastTransactions() && !g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); - string strAccount = AccountFromValue(params[0]); - UniValue sendTo = params[1].get_obj(); + string strAccount = AccountFromValue(request.params[0]); + UniValue sendTo = request.params[1].get_obj(); int nMinDepth = 1; - if (params.size() > 2) - nMinDepth = params[2].get_int(); + if (request.params.size() > 2) + nMinDepth = request.params[2].get_int(); CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) - wtx.mapValue["comment"] = params[3].get_str(); + if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty()) + wtx.mapValue["comment"] = request.params[3].get_str(); UniValue subtractFeeFromAmount(UniValue::VARR); - if (params.size() > 4) - subtractFeeFromAmount = params[4].get_array(); + if (request.params.size() > 4) + subtractFeeFromAmount = request.params[4].get_array(); set setAddress; vector vecSend; @@ -968,12 +968,12 @@ UniValue sendmany(const UniValue& params, bool fHelp) // Defined in rpc/misc.cpp extern CScript _createmultisig_redeemScript(const UniValue& params); -UniValue addmultisigaddress(const UniValue& params, bool fHelp) +UniValue addmultisigaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 2 || params.size() > 3) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) { string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n" "\nAdd a nrequired-to-sign multisignature address to the wallet.\n" @@ -1004,11 +1004,11 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); string strAccount; - if (params.size() > 2) - strAccount = AccountFromValue(params[2]); + if (request.params.size() > 2) + strAccount = AccountFromValue(request.params[2]); // Construct using pay-to-script-hash: - CScript inner = _createmultisig_redeemScript(params); + CScript inner = _createmultisig_redeemScript(request.params); CScriptID innerID(inner); pwalletMain->AddCScript(inner); @@ -1061,12 +1061,12 @@ public: } }; -UniValue addwitnessaddress(const UniValue& params, bool fHelp) +UniValue addwitnessaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 1) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) { string msg = "addwitnessaddress \"address\"\n" "\nAdd a witness address for a script (with pubkey or redeemscript known).\n" @@ -1089,7 +1089,7 @@ UniValue addwitnessaddress(const UniValue& params, bool fHelp) } } - CBitcoinAddress address(params[0].get_str()); + CBitcoinAddress address(request.params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); @@ -1239,12 +1239,12 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) return ret; } -UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) +UniValue listreceivedbyaddress(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 3) + if (request.fHelp || request.params.size() > 3) throw runtime_error( "listreceivedbyaddress ( minconf includeempty includeWatchonly)\n" "\nList balances by receiving address.\n" @@ -1274,15 +1274,15 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - return ListReceived(params, false); + return ListReceived(request.params, false); } -UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) +UniValue listreceivedbyaccount(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 3) + if (request.fHelp || request.params.size() > 3) throw runtime_error( "listreceivedbyaccount ( minconf includeempty includeWatchonly)\n" "\nDEPRECATED. List balances by account.\n" @@ -1311,7 +1311,7 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - return ListReceived(params, true); + return ListReceived(request.params, true); } static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) @@ -1413,12 +1413,12 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Un } } -UniValue listtransactions(const UniValue& params, bool fHelp) +UniValue listtransactions(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 4) + if (request.fHelp || request.params.size() > 4) throw runtime_error( "listtransactions ( \"account\" count from includeWatchonly)\n" "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n" @@ -1480,17 +1480,17 @@ UniValue listtransactions(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); string strAccount = "*"; - if (params.size() > 0) - strAccount = params[0].get_str(); + if (request.params.size() > 0) + strAccount = request.params[0].get_str(); int nCount = 10; - if (params.size() > 1) - nCount = params[1].get_int(); + if (request.params.size() > 1) + nCount = request.params[1].get_int(); int nFrom = 0; - if (params.size() > 2) - nFrom = params[2].get_int(); + if (request.params.size() > 2) + nFrom = request.params[2].get_int(); isminefilter filter = ISMINE_SPENDABLE; - if(params.size() > 3) - if(params[3].get_bool()) + if(request.params.size() > 3) + if(request.params[3].get_bool()) filter = filter | ISMINE_WATCH_ONLY; if (nCount < 0) @@ -1540,12 +1540,12 @@ UniValue listtransactions(const UniValue& params, bool fHelp) return ret; } -UniValue listaccounts(const UniValue& params, bool fHelp) +UniValue listaccounts(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 2) + if (request.fHelp || request.params.size() > 2) throw runtime_error( "listaccounts ( minconf includeWatchonly)\n" "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n" @@ -1571,11 +1571,11 @@ UniValue listaccounts(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); int nMinDepth = 1; - if (params.size() > 0) - nMinDepth = params[0].get_int(); + if (request.params.size() > 0) + nMinDepth = request.params[0].get_int(); isminefilter includeWatchonly = ISMINE_SPENDABLE; - if(params.size() > 1) - if(params[1].get_bool()) + if(request.params.size() > 1) + if(request.params[1].get_bool()) includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; map mapAccountBalances; @@ -1619,12 +1619,12 @@ UniValue listaccounts(const UniValue& params, bool fHelp) return ret; } -UniValue listsinceblock(const UniValue& params, bool fHelp) +UniValue listsinceblock(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp) + if (request.fHelp) throw runtime_error( "listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n" "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n" @@ -1667,26 +1667,26 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) int target_confirms = 1; isminefilter filter = ISMINE_SPENDABLE; - if (params.size() > 0) + if (request.params.size() > 0) { uint256 blockId; - blockId.SetHex(params[0].get_str()); + blockId.SetHex(request.params[0].get_str()); BlockMap::iterator it = mapBlockIndex.find(blockId); if (it != mapBlockIndex.end()) pindex = it->second; } - if (params.size() > 1) + if (request.params.size() > 1) { - target_confirms = params[1].get_int(); + target_confirms = request.params[1].get_int(); if (target_confirms < 1) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter"); } - if(params.size() > 2) - if(params[2].get_bool()) + if(request.params.size() > 2) + if(request.params[2].get_bool()) filter = filter | ISMINE_WATCH_ONLY; int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1; @@ -1711,12 +1711,12 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) return ret; } -UniValue gettransaction(const UniValue& params, bool fHelp) +UniValue gettransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "gettransaction \"txid\" ( includeWatchonly )\n" "\nGet detailed information about in-wallet transaction \n" @@ -1758,11 +1758,11 @@ UniValue gettransaction(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); uint256 hash; - hash.SetHex(params[0].get_str()); + hash.SetHex(request.params[0].get_str()); isminefilter filter = ISMINE_SPENDABLE; - if(params.size() > 1) - if(params[1].get_bool()) + if(request.params.size() > 1) + if(request.params[1].get_bool()) filter = filter | ISMINE_WATCH_ONLY; UniValue entry(UniValue::VOBJ); @@ -1791,12 +1791,12 @@ UniValue gettransaction(const UniValue& params, bool fHelp) return entry; } -UniValue abandontransaction(const UniValue& params, bool fHelp) +UniValue abandontransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "abandontransaction \"txid\"\n" "\nMark in-wallet transaction as abandoned\n" @@ -1815,7 +1815,7 @@ UniValue abandontransaction(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); uint256 hash; - hash.SetHex(params[0].get_str()); + hash.SetHex(request.params[0].get_str()); if (!pwalletMain->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); @@ -1826,12 +1826,12 @@ UniValue abandontransaction(const UniValue& params, bool fHelp) } -UniValue backupwallet(const UniValue& params, bool fHelp) +UniValue backupwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (request.fHelp || request.params.size() != 1) throw runtime_error( "backupwallet \"destination\"\n" "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n" @@ -1844,7 +1844,7 @@ UniValue backupwallet(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string strDest = params[0].get_str(); + string strDest = request.params[0].get_str(); if (!pwalletMain->BackupWallet(strDest)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); @@ -1852,12 +1852,12 @@ UniValue backupwallet(const UniValue& params, bool fHelp) } -UniValue keypoolrefill(const UniValue& params, bool fHelp) +UniValue keypoolrefill(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 1) + if (request.fHelp || request.params.size() > 1) throw runtime_error( "keypoolrefill ( newsize )\n" "\nFills the keypool." @@ -1873,10 +1873,10 @@ UniValue keypoolrefill(const UniValue& params, bool fHelp) // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool unsigned int kpSize = 0; - if (params.size() > 0) { - if (params[0].get_int() < 0) + if (request.params.size() > 0) { + if (request.params[0].get_int() < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size."); - kpSize = (unsigned int)params[0].get_int(); + kpSize = (unsigned int)request.params[0].get_int(); } EnsureWalletIsUnlocked(); @@ -1896,12 +1896,12 @@ static void LockWallet(CWallet* pWallet) pWallet->Lock(); } -UniValue walletpassphrase(const UniValue& params, bool fHelp) +UniValue walletpassphrase(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" "\nStores the wallet decryption key in memory for 'timeout' seconds.\n" @@ -1923,17 +1923,17 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (fHelp) + if (request.fHelp) return true; if (!pwalletMain->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called."); - // Note that the walletpassphrase is stored in params[0] which is not mlock()ed + // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed SecureString strWalletPass; strWalletPass.reserve(100); // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) - // Alternately, find a way to make params[0] mlock()'d to begin with. - strWalletPass = params[0].get_str().c_str(); + // Alternately, find a way to make request.params[0] mlock()'d to begin with. + strWalletPass = request.params[0].get_str().c_str(); if (strWalletPass.length() > 0) { @@ -1947,7 +1947,7 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) pwalletMain->TopUpKeyPool(); - int64_t nSleepTime = params[1].get_int64(); + int64_t nSleepTime = request.params[1].get_int64(); LOCK(cs_nWalletUnlockTime); nWalletUnlockTime = GetTime() + nSleepTime; RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); @@ -1956,12 +1956,12 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) } -UniValue walletpassphrasechange(const UniValue& params, bool fHelp) +UniValue walletpassphrasechange(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) throw runtime_error( "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n" @@ -1975,20 +1975,20 @@ UniValue walletpassphrasechange(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (fHelp) + if (request.fHelp) return true; if (!pwalletMain->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string) - // Alternately, find a way to make params[0] mlock()'d to begin with. + // Alternately, find a way to make request.params[0] mlock()'d to begin with. SecureString strOldWalletPass; strOldWalletPass.reserve(100); - strOldWalletPass = params[0].get_str().c_str(); + strOldWalletPass = request.params[0].get_str().c_str(); SecureString strNewWalletPass; strNewWalletPass.reserve(100); - strNewWalletPass = params[1].get_str().c_str(); + strNewWalletPass = request.params[1].get_str().c_str(); if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1) throw runtime_error( @@ -2002,12 +2002,12 @@ UniValue walletpassphrasechange(const UniValue& params, bool fHelp) } -UniValue walletlock(const UniValue& params, bool fHelp) +UniValue walletlock(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 0)) throw runtime_error( "walletlock\n" "\nRemoves the wallet encryption key from memory, locking the wallet.\n" @@ -2026,7 +2026,7 @@ UniValue walletlock(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (fHelp) + if (request.fHelp) return true; if (!pwalletMain->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called."); @@ -2041,12 +2041,12 @@ UniValue walletlock(const UniValue& params, bool fHelp) } -UniValue encryptwallet(const UniValue& params, bool fHelp) +UniValue encryptwallet(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) + if (!pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 1)) throw runtime_error( "encryptwallet \"passphrase\"\n" "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n" @@ -2072,16 +2072,16 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (fHelp) + if (request.fHelp) return true; if (pwalletMain->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called."); // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) - // Alternately, find a way to make params[0] mlock()'d to begin with. + // Alternately, find a way to make request.params[0] mlock()'d to begin with. SecureString strWalletPass; strWalletPass.reserve(100); - strWalletPass = params[0].get_str().c_str(); + strWalletPass = request.params[0].get_str().c_str(); if (strWalletPass.length() < 1) throw runtime_error( @@ -2098,12 +2098,12 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; } -UniValue lockunspent(const UniValue& params, bool fHelp) +UniValue lockunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n" "\nUpdates list of temporarily unspendable outputs.\n" @@ -2142,20 +2142,20 @@ UniValue lockunspent(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - if (params.size() == 1) - RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)); + if (request.params.size() == 1) + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL)); else - RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR)); - bool fUnlock = params[0].get_bool(); + bool fUnlock = request.params[0].get_bool(); - if (params.size() == 1) { + if (request.params.size() == 1) { if (fUnlock) pwalletMain->UnlockAllCoins(); return true; } - UniValue outputs = params[1].get_array(); + UniValue outputs = request.params[1].get_array(); for (unsigned int idx = 0; idx < outputs.size(); idx++) { const UniValue& output = outputs[idx]; if (!output.isObject()) @@ -2187,12 +2187,12 @@ UniValue lockunspent(const UniValue& params, bool fHelp) return true; } -UniValue listlockunspent(const UniValue& params, bool fHelp) +UniValue listlockunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 0) + if (request.fHelp || request.params.size() > 0) throw runtime_error( "listlockunspent\n" "\nReturns list of temporarily unspendable outputs.\n" @@ -2236,12 +2236,12 @@ UniValue listlockunspent(const UniValue& params, bool fHelp) return ret; } -UniValue settxfee(const UniValue& params, bool fHelp) +UniValue settxfee(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 1) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) throw runtime_error( "settxfee amount\n" "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n" @@ -2257,18 +2257,18 @@ UniValue settxfee(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); // Amount - CAmount nAmount = AmountFromValue(params[0]); + CAmount nAmount = AmountFromValue(request.params[0]); payTxFee = CFeeRate(nAmount, 1000); return true; } -UniValue getwalletinfo(const UniValue& params, bool fHelp) +UniValue getwalletinfo(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "getwalletinfo\n" "Returns an object containing various wallet state info.\n" @@ -2309,12 +2309,12 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) return obj; } -UniValue resendwallettransactions(const UniValue& params, bool fHelp) +UniValue resendwallettransactions(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() != 0) + if (request.fHelp || request.params.size() != 0) throw runtime_error( "resendwallettransactions\n" "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n" @@ -2337,12 +2337,12 @@ UniValue resendwallettransactions(const UniValue& params, bool fHelp) return result; } -UniValue listunspent(const UniValue& params, bool fHelp) +UniValue listunspent(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() > 3) + if (request.fHelp || request.params.size() > 3) throw runtime_error( "listunspent ( minconf maxconf [\"address\",...] )\n" "\nReturns array of unspent transaction outputs\n" @@ -2379,19 +2379,19 @@ UniValue listunspent(const UniValue& params, bool fHelp) + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VARR)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VARR)); int nMinDepth = 1; - if (params.size() > 0) - nMinDepth = params[0].get_int(); + if (request.params.size() > 0) + nMinDepth = request.params[0].get_int(); int nMaxDepth = 9999999; - if (params.size() > 1) - nMaxDepth = params[1].get_int(); + if (request.params.size() > 1) + nMaxDepth = request.params[1].get_int(); set setAddress; - if (params.size() > 2) { - UniValue inputs = params[2].get_array(); + if (request.params.size() > 2) { + UniValue inputs = request.params[2].get_array(); for (unsigned int idx = 0; idx < inputs.size(); idx++) { const UniValue& input = inputs[idx]; CBitcoinAddress address(input.get_str()); @@ -2448,12 +2448,12 @@ UniValue listunspent(const UniValue& params, bool fHelp) return results; } -UniValue fundrawtransaction(const UniValue& params, bool fHelp) +UniValue fundrawtransaction(const JSONRPCRequest& request) { - if (!EnsureWalletIsAvailable(fHelp)) + if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 2) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw runtime_error( "fundrawtransaction \"hexstring\" ( options )\n" "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n" @@ -2494,7 +2494,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)); CTxDestination changeAddress = CNoDestination(); int changePosition = -1; @@ -2503,15 +2503,15 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) CFeeRate feeRate = CFeeRate(0); bool overrideEstimatedFeerate = false; - if (params.size() > 1) { - if (params[1].type() == UniValue::VBOOL) { + if (request.params.size() > 1) { + if (request.params[1].type() == UniValue::VBOOL) { // backward compatibility bool only fallback - includeWatching = params[1].get_bool(); + includeWatching = request.params[1].get_bool(); } else { - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); - UniValue options = params[1]; + UniValue options = request.params[1]; RPCTypeCheckObj(options, { @@ -2551,7 +2551,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) // parse hex string from parameter CTransaction origTx; - if (!DecodeHexTx(origTx, params[0].get_str(), true)) + if (!DecodeHexTx(origTx, request.params[0].get_str(), true)) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); if (origTx.vout.size() == 0) @@ -2575,14 +2575,14 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) return result; } -extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp -extern UniValue importprivkey(const UniValue& params, bool fHelp); -extern UniValue importaddress(const UniValue& params, bool fHelp); -extern UniValue importpubkey(const UniValue& params, bool fHelp); -extern UniValue dumpwallet(const UniValue& params, bool fHelp); -extern UniValue importwallet(const UniValue& params, bool fHelp); -extern UniValue importprunedfunds(const UniValue& params, bool fHelp); -extern UniValue removeprunedfunds(const UniValue& params, bool fHelp); +extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp +extern UniValue importprivkey(const JSONRPCRequest& request); +extern UniValue importaddress(const JSONRPCRequest& request); +extern UniValue importpubkey(const JSONRPCRequest& request); +extern UniValue dumpwallet(const JSONRPCRequest& request); +extern UniValue importwallet(const JSONRPCRequest& request); +extern UniValue importprunedfunds(const JSONRPCRequest& request); +extern UniValue removeprunedfunds(const JSONRPCRequest& request); static const CRPCCommand commands[] = { // category name actor (function) okSafeMode