diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index b7af7422d0..1c19804483 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -880,7 +880,7 @@ static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& str try { response = CallRPC(rh, strMethod, args, rpcwallet); if (fWait) { - const UniValue& error = find_value(response, "error"); + const UniValue& error = response.find_value("error"); if (!error.isNull() && error["code"].getInt() == RPC_IN_WARMUP) { throw CConnectionFailed("server in warmup"); } @@ -908,8 +908,8 @@ static void ParseResult(const UniValue& result, std::string& strPrint) static void ParseError(const UniValue& error, std::string& strPrint, int& nRet) { if (error.isObject()) { - const UniValue& err_code = find_value(error, "code"); - const UniValue& err_msg = find_value(error, "message"); + const UniValue& err_code = error.find_value("code"); + const UniValue& err_msg = error.find_value("message"); if (!err_code.isNull()) { strPrint = "error code: " + err_code.getValStr() + "\n"; } @@ -935,15 +935,15 @@ static void GetWalletBalances(UniValue& result) { DefaultRequestHandler rh; const UniValue listwallets = ConnectAndCallRPC(&rh, "listwallets", /* args=*/{}); - if (!find_value(listwallets, "error").isNull()) return; - const UniValue& wallets = find_value(listwallets, "result"); + if (!listwallets.find_value("error").isNull()) return; + const UniValue& wallets = listwallets.find_value("result"); if (wallets.size() <= 1) return; UniValue balances(UniValue::VOBJ); for (const UniValue& wallet : wallets.getValues()) { const std::string& wallet_name = wallet.get_str(); const UniValue getbalances = ConnectAndCallRPC(&rh, "getbalances", /* args=*/{}, wallet_name); - const UniValue& balance = find_value(getbalances, "result")["mine"]["trusted"]; + const UniValue& balance = getbalances.find_value("result")["mine"]["trusted"]; balances.pushKV(wallet_name, balance); } result.pushKV("balances", balances); @@ -979,7 +979,7 @@ static void GetProgressBar(double progress, std::string& progress_bar) */ static void ParseGetInfoResult(UniValue& result) { - if (!find_value(result, "error").isNull()) return; + if (!result.find_value("error").isNull()) return; std::string RESET, GREEN, BLUE, YELLOW, MAGENTA, CYAN; bool should_colorize = false; @@ -1191,9 +1191,9 @@ static int CommandLineRPC(int argc, char *argv[]) rh.reset(new NetinfoRequestHandler()); } else if (gArgs.GetBoolArg("-generate", false)) { const UniValue getnewaddress{GetNewAddress()}; - const UniValue& error{find_value(getnewaddress, "error")}; + const UniValue& error{getnewaddress.find_value("error")}; if (error.isNull()) { - SetGenerateToAddressArgs(find_value(getnewaddress, "result").get_str(), args); + SetGenerateToAddressArgs(getnewaddress.find_value("result").get_str(), args); rh.reset(new GenerateToAddressRequestHandler()); } else { ParseError(error, strPrint, nRet); @@ -1215,8 +1215,8 @@ static int CommandLineRPC(int argc, char *argv[]) const UniValue reply = ConnectAndCallRPC(rh.get(), method, args, wallet_name); // Parse reply - UniValue result = find_value(reply, "result"); - const UniValue& error = find_value(reply, "error"); + UniValue result = reply.find_value("result"); + const UniValue& error = reply.find_value("error"); if (error.isNull()) { if (gArgs.GetBoolArg("-getinfo", false)) { if (!gArgs.IsArgSet("-rpcwallet")) { diff --git a/src/external_signer.cpp b/src/external_signer.cpp index 5524b943f4..6b1e1f0241 100644 --- a/src/external_signer.cpp +++ b/src/external_signer.cpp @@ -30,7 +30,7 @@ bool ExternalSigner::Enumerate(const std::string& command, std::vector(); + int code = objError.find_value("code").getInt(); if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; @@ -213,7 +213,7 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req) } else { const UniValue& request = valRequest[reqIdx].get_obj(); // Parse method - std::string strMethod = find_value(request, "method").get_str(); + std::string strMethod = request.find_value("method").get_str(); if (!g_rpc_whitelist[jreq.authUser].count(strMethod)) { LogPrintf("RPC User %s not allowed to call method %s\n", jreq.authUser, strMethod); req->WriteReply(HTTP_FORBIDDEN); diff --git a/src/mainchainrpc.cpp b/src/mainchainrpc.cpp index 86b96d1e7b..ca4b9d292d 100644 --- a/src/mainchainrpc.cpp +++ b/src/mainchainrpc.cpp @@ -158,18 +158,18 @@ bool IsConfirmedBitcoinBlock(const uint256& hash, const int nMinConfirmationDept UniValue params(UniValue::VARR); params.push_back(hash.GetHex()); UniValue reply = CallMainChainRPC("getblockheader", params); - UniValue errval = find_value(reply, "error"); + UniValue errval = reply.find_value("error"); if (!errval.isNull()) { LogPrintf("WARNING: Got error reply from bitcoind getblockheader: %s\n", errval.write()); return false; } - UniValue result = find_value(reply, "result"); + UniValue result = reply.find_value("result"); if (!result.isObject()) { LogPrintf("ERROR: bitcoind getblockheader result was malformed (not object): %s\n", result.write()); return false; } - UniValue confirmations = find_value(result.get_obj(), "confirmations"); + UniValue confirmations = result.get_obj().find_value("confirmations"); if (!confirmations.isNum() || confirmations.getInt() < nMinConfirmationDepth) { LogPrintf("Insufficient confirmations (got %s, need at least %d).\n", confirmations.write(), nMinConfirmationDepth); return false; @@ -177,7 +177,7 @@ bool IsConfirmedBitcoinBlock(const uint256& hash, const int nMinConfirmationDept // Only perform extra test if nbTxs has been provided (non-zero). if (nbTxs != 0) { - UniValue nTx = find_value(result.get_obj(), "nTx"); + UniValue nTx = result.get_obj().find_value("nTx"); if (!nTx.isNum() || nTx.getInt() != nbTxs) { LogPrintf("ERROR: Invalid number of transactions in merkle block for %s (got %s, need exactly %d)\n", hash.GetHex(), nTx.write(), nbTxs); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 740c0d87d3..150fe0b527 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -249,7 +249,7 @@ bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strRes subelement = lastResult[parsed.value()]; } else if (lastResult.isObject()) - subelement = find_value(lastResult, curarg); + subelement = lastResult.find_value(curarg); else throw std::runtime_error("Invalid result query"); //no array or object: abort lastResult = subelement; @@ -448,8 +448,8 @@ void RPCExecutor::request(const QString &command, const WalletModel* wallet_mode { try // Nice formatting for standard-format error { - int code = find_value(objError, "code").getInt(); - std::string message = find_value(objError, "message").get_str(); + int code = objError.find_value("code").getInt(); + std::string message = objError.find_value("message").get_str(); Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); } catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index ba714156a0..689a73c11d 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -649,7 +649,7 @@ static RPCHelpMan gettxspendingprevout() }, /*fAllowNull=*/false, /*fStrict=*/true); const uint256 txid(ParseHashO(o, "txid")); - const int nOutput{find_value(o, "vout").getInt()}; + const int nOutput{o.find_value("vout").getInt()}; if (nOutput < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative"); } diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 2900c5df07..5e51b2b11c 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -634,7 +634,7 @@ static RPCHelpMan getblocktemplate() if (!request.params[0].isNull()) { const UniValue& oparam = request.params[0].get_obj(); - const UniValue& modeval = find_value(oparam, "mode"); + const UniValue& modeval = oparam.find_value("mode"); if (modeval.isStr()) strMode = modeval.get_str(); else if (modeval.isNull()) @@ -643,11 +643,11 @@ static RPCHelpMan getblocktemplate() } else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); - lpval = find_value(oparam, "longpollid"); + lpval = oparam.find_value("longpollid"); if (strMode == "proposal") { - const UniValue& dataval = find_value(oparam, "data"); + const UniValue& dataval = oparam.find_value("data"); if (!dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); @@ -674,7 +674,7 @@ static RPCHelpMan getblocktemplate() return BIP22ValidationResult(state); } - const UniValue& aClientRules = find_value(oparam, "rules"); + const UniValue& aClientRules = oparam.find_value("rules"); if (aClientRules.isArray()) { for (unsigned int i = 0; i < aClientRules.size(); ++i) { const UniValue& v = aClientRules[i]; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 51e77a5332..d588119160 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -2029,7 +2029,7 @@ static RPCHelpMan createpsbt() std::set new_reissuance; for (unsigned int i = 0; i < rawTx.vin.size(); ++i) { if (!rawTx.vin[i].assetIssuance.IsNull()) { - const UniValue& blind_reissuance_v = find_value(request.params[0].get_array()[i].get_obj(), "blind_reissuance"); + const UniValue& blind_reissuance_v = request.params[0].get_array()[i].get_obj().find_value("blind_reissuance"); bool blind_reissuance = blind_reissuance_v.isNull() ? true : blind_reissuance_v.get_bool(); uint256 entropy; CAsset asset; diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp index e86bd8d96e..61abff806d 100644 --- a/src/rpc/rawtransaction_util.cpp +++ b/src/rpc/rawtransaction_util.cpp @@ -160,7 +160,7 @@ void AddInputs(CMutableTransaction& rawTx, const UniValue& inputs_in, std::optio uint256 txid = ParseHashO(o, "txid"); - const UniValue& vout_v = find_value(o, "vout"); + const UniValue& vout_v = o.find_value("vout"); if (!vout_v.isNum()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); int nOutput = vout_v.getInt(); @@ -178,7 +178,7 @@ void AddInputs(CMutableTransaction& rawTx, const UniValue& inputs_in, std::optio } // set the sequence number if passed in the parameters object - const UniValue& sequenceObj = find_value(o, "sequence"); + const UniValue& sequenceObj = o.find_value("sequence"); if (sequenceObj.isNum()) { int64_t seqNr64 = sequenceObj.getInt(); if (seqNr64 < 0 || seqNr64 > CTxIn::SEQUENCE_FINAL) { @@ -191,11 +191,11 @@ void AddInputs(CMutableTransaction& rawTx, const UniValue& inputs_in, std::optio CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence); // Get issuance stuff if it's there - const UniValue& blinding_nonce_v = find_value(o, "asset_blinding_nonce"); - const UniValue& entropy_v = find_value(o, "asset_entropy"); - const UniValue& amount_v = find_value(o, "issuance_amount"); - const UniValue& issuance_tokens_v = find_value(o, "issuance_tokens"); - const UniValue& blind_reissuance_v = find_value(o, "blind_reissuance"); + const UniValue& blinding_nonce_v = o.find_value("asset_blinding_nonce"); + const UniValue& entropy_v = o.find_value("asset_entropy"); + const UniValue& amount_v = o.find_value("issuance_amount"); + const UniValue& issuance_tokens_v = o.find_value("issuance_tokens"); + const UniValue& blind_reissuance_v = o.find_value("blind_reissuance"); if (!amount_v.isNull() && allow_issuance) { if (!amount_v.isNum()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "issuance_amount is not a number"); @@ -228,9 +228,9 @@ void AddInputs(CMutableTransaction& rawTx, const UniValue& inputs_in, std::optio rawTx.vin.push_back(in); // Get the pegin stuff if it's there - const UniValue& pegin_tx = find_value(o, "pegin_bitcoin_tx"); - const UniValue& pegin_tx_proof = find_value(o, "pegin_txout_proof"); - const UniValue& pegin_script = find_value(o, "pegin_claim_script"); + const UniValue& pegin_tx = o.find_value("pegin_bitcoin_tx"); + const UniValue& pegin_tx_proof = o.find_value("pegin_txout_proof"); + const UniValue& pegin_script = o.find_value("pegin_claim_script"); if (!pegin_tx.isNull() && !pegin_tx_proof.isNull() && !pegin_script.isNull() && allow_peg_in) { if (!IsHex(pegin_script.get_str())) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Given claim_script is not hex."); @@ -331,7 +331,7 @@ void AddOutputs(CMutableTransaction& rawTx, const UniValue& outputs_in, std::map out.nAsset = CAsset(ParseHashO(output, name_)); } else if (name_ == "blinder_index") { // For PSET - psbt_out.m_blinder_index = find_value(output, name_).getInt(); + psbt_out.m_blinder_index = output.find_value(name_).getInt(); } else { CTxDestination destination = DecodeDestination(name_); if (!IsValidDestination(destination)) { @@ -440,7 +440,7 @@ void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keyst uint256 txid = ParseHashO(prevOut, "txid"); - int nOut = find_value(prevOut, "vout").getInt(); + int nOut = prevOut.find_value("vout").getInt(); if (nOut < 0) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout cannot be negative"); } @@ -461,7 +461,7 @@ void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keyst newcoin.out.scriptPubKey = scriptPubKey; newcoin.out.nValue = CConfidentialValue(MAX_MONEY); if (prevOut.exists("amount")) { - newcoin.out.nValue = CConfidentialValue(AmountFromValue(find_value(prevOut, "amount"))); + newcoin.out.nValue = CConfidentialValue(AmountFromValue(prevOut.find_value("amount"))); } else if (prevOut.exists("amountcommitment")) { // Segwit sigs require the amount commitment to be sighashed newcoin.out.nValue.vchCommitment = ParseHexO(prevOut, "amountcommitment"); @@ -479,8 +479,8 @@ void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keyst {"redeemScript", UniValueType(UniValue::VSTR)}, {"witnessScript", UniValueType(UniValue::VSTR)}, }, true); - UniValue rs = find_value(prevOut, "redeemScript"); - UniValue ws = find_value(prevOut, "witnessScript"); + const UniValue& rs{prevOut.find_value("redeemScript")}; + const UniValue& ws{prevOut.find_value("witnessScript")}; if (rs.isNull() && ws.isNull()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Missing redeemScript/witnessScript"); } diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp index 8c21a652bf..7c31c059ad 100644 --- a/src/rpc/request.cpp +++ b/src/rpc/request.cpp @@ -204,10 +204,10 @@ void JSONRPCRequest::parse(const UniValue& valRequest) const UniValue& request = valRequest.get_obj(); // Parse id now so errors from here on will have the id - id = find_value(request, "id"); + id = request.find_value("id"); // Parse method - UniValue valMethod = find_value(request, "method"); + const UniValue& valMethod{request.find_value("method")}; if (valMethod.isNull()) throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); if (!valMethod.isStr()) @@ -220,7 +220,7 @@ void JSONRPCRequest::parse(const UniValue& valRequest) LogPrint(BCLog::RPC, "ThreadRPCServer method=%s user=%s\n", SanitizeString(strMethod), this->authUser); // Parse params - UniValue valParams = find_value(request, "params"); + const UniValue& valParams{request.find_value("params")}; if (valParams.isArray() || valParams.isObject()) params = valParams; else if (valParams.isNull()) diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index f55b6a6923..3063de42da 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -42,7 +42,7 @@ void RPCTypeCheckObj(const UniValue& o, bool fStrict) { for (const auto& t : typesExpected) { - const UniValue& v = find_value(o, t.first); + const UniValue& v = o.find_value(t.first); if (!fAllowNull && v.isNull()) throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first)); @@ -86,7 +86,7 @@ uint256 ParseHashV(const UniValue& v, std::string strName) } uint256 ParseHashO(const UniValue& o, std::string strKey) { - return ParseHashV(find_value(o, strKey), strKey); + return ParseHashV(o.find_value(strKey), strKey); } std::vector ParseHexV(const UniValue& v, std::string strName) { @@ -99,7 +99,7 @@ std::vector ParseHexV(const UniValue& v, std::string strName) } std::vector ParseHexO(const UniValue& o, std::string strKey) { - return ParseHexV(find_value(o, strKey), strKey); + return ParseHexV(o.find_value(strKey), strKey); } namespace { @@ -1152,10 +1152,10 @@ std::vector EvalDescriptorStringOrObject(const UniValue& scanobject, Fl if (scanobject.isStr()) { desc_str = scanobject.get_str(); } else if (scanobject.isObject()) { - UniValue desc_uni = find_value(scanobject, "desc"); + const UniValue& desc_uni{scanobject.find_value("desc")}; if (desc_uni.isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor needs to be provided in scan object"); desc_str = desc_uni.get_str(); - UniValue range_uni = find_value(scanobject, "range"); + const UniValue& range_uni{scanobject.find_value("range")}; if (!range_uni.isNull()) { range = ParseDescriptorRange(range_uni); } diff --git a/src/test/fuzz/rpc.cpp b/src/test/fuzz/rpc.cpp index 9fb83f5cdc..f345e8c9fb 100644 --- a/src/test/fuzz/rpc.cpp +++ b/src/test/fuzz/rpc.cpp @@ -386,7 +386,7 @@ FUZZ_TARGET_INIT(rpc, initialize_rpc) try { rpc_testing_setup->CallRPC(rpc_command, arguments); } catch (const UniValue& json_rpc_error) { - const std::string error_msg{find_value(json_rpc_error, "message").get_str()}; + const std::string error_msg{json_rpc_error.find_value("message").get_str()}; // Once c++20 is allowed, starts_with can be used. // if (error_msg.starts_with("Internal bug detected")) { if (0 == error_msg.rfind("Internal bug detected", 0)) { diff --git a/src/test/interfaces_tests.cpp b/src/test/interfaces_tests.cpp index d37fe35a11..68377e197f 100644 --- a/src/test/interfaces_tests.cpp +++ b/src/test/interfaces_tests.cpp @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(findAncestorByHash) BOOST_AUTO_TEST_CASE(findCommonAncestor) { auto& chain = m_node.chain; - const CChain& active = WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return Assert(m_node.chainman)->ActiveChain()); + const CChain& active{*WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return &Assert(m_node.chainman)->ActiveChain())}; auto* orig_tip = active.Tip(); for (int i = 0; i < 10; ++i) { BlockValidationState state; diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp index fecc9517d8..60a9a55406 100644 --- a/src/test/key_io_tests.cpp +++ b/src/test/key_io_tests.cpp @@ -37,11 +37,11 @@ BOOST_AUTO_TEST_CASE(key_io_valid_parse) std::string exp_base58string = test[0].get_str(); const std::vector exp_payload{ParseHex(test[1].get_str())}; const UniValue &metadata = test[2].get_obj(); - bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); - SelectParams(ChainTypeMetaFrom(find_value(metadata, "chain").get_str())); - bool try_case_flip = find_value(metadata, "tryCaseFlip").isNull() ? false : find_value(metadata, "tryCaseFlip").get_bool(); + bool isPrivkey = metadata.find_value("isPrivkey").get_bool(); + SelectParams(ChainTypeMetaFrom(metadata.find_value("chain").get_str())); + bool try_case_flip = metadata.find_value("tryCaseFlip").isNull() ? false : metadata.find_value("tryCaseFlip").get_bool(); if (isPrivkey) { - bool isCompressed = find_value(metadata, "isCompressed").get_bool(); + bool isCompressed = metadata.find_value("isCompressed").get_bool(); // Must be valid private key privkey = DecodeSecret(exp_base58string); BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest); @@ -96,10 +96,10 @@ BOOST_AUTO_TEST_CASE(key_io_valid_gen) std::string exp_base58string = test[0].get_str(); std::vector exp_payload = ParseHex(test[1].get_str()); const UniValue &metadata = test[2].get_obj(); - bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); - SelectParams(ChainTypeMetaFrom(find_value(metadata, "chain").get_str())); + bool isPrivkey = metadata.find_value("isPrivkey").get_bool(); + SelectParams(ChainTypeMetaFrom(metadata.find_value("chain").get_str())); if (isPrivkey) { - bool isCompressed = find_value(metadata, "isCompressed").get_bool(); + bool isCompressed = metadata.find_value("isCompressed").get_bool(); CKey key; key.Set(exp_payload.begin(), exp_payload.end(), isCompressed); assert(key.IsValid()); diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 5932f1d271..1bd8cba3fb 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -75,7 +75,7 @@ UniValue RPCTestingSetup::CallRPC(std::string args) return result; } catch (const UniValue& objError) { - throw std::runtime_error(find_value(objError, "message").get_str()); + throw std::runtime_error(objError.find_value("message").get_str()); } } @@ -130,9 +130,9 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams) BOOST_CHECK_THROW(CallRPC("decoderawtransaction DEADBEEF"), std::runtime_error); std::string rawtx = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"; BOOST_CHECK_NO_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx)); - BOOST_CHECK_EQUAL(find_value(r.get_obj(), "size").getInt(), 193); - BOOST_CHECK_EQUAL(find_value(r.get_obj(), "version").getInt(), 1); - BOOST_CHECK_EQUAL(find_value(r.get_obj(), "locktime").getInt(), 0); + BOOST_CHECK_EQUAL(r.get_obj().find_value("size").getInt(), 193); + BOOST_CHECK_EQUAL(r.get_obj().find_value("version").getInt(), 1); + BOOST_CHECK_EQUAL(r.get_obj().find_value("locktime").getInt(), 0); BOOST_CHECK_THROW(CallRPC(std::string("decoderawtransaction ")+rawtx+" extra"), std::runtime_error); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx+" false")); BOOST_CHECK_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx+" false extra"), std::runtime_error); @@ -149,20 +149,20 @@ BOOST_AUTO_TEST_CASE(rpc_togglenetwork) UniValue r; r = CallRPC("getnetworkinfo"); - bool netState = find_value(r.get_obj(), "networkactive").get_bool(); + bool netState = r.get_obj().find_value("networkactive").get_bool(); BOOST_CHECK_EQUAL(netState, true); BOOST_CHECK_NO_THROW(CallRPC("setnetworkactive false")); r = CallRPC("getnetworkinfo"); - int numConnection = find_value(r.get_obj(), "connections").getInt(); + int numConnection = r.get_obj().find_value("connections").getInt(); BOOST_CHECK_EQUAL(numConnection, 0); - netState = find_value(r.get_obj(), "networkactive").get_bool(); + netState = r.get_obj().find_value("networkactive").get_bool(); BOOST_CHECK_EQUAL(netState, false); BOOST_CHECK_NO_THROW(CallRPC("setnetworkactive true")); r = CallRPC("getnetworkinfo"); - netState = find_value(r.get_obj(), "networkactive").get_bool(); + netState = r.get_obj().find_value("networkactive").get_bool(); BOOST_CHECK_EQUAL(netState, true); } @@ -180,9 +180,9 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) std::string privkey1 = "\"KzsXybp9jX64P5ekX1KUxRQ79Jht9uzW7LorgwE65i5rWACL6LQe\""; std::string privkey2 = "\"Kyhdf5LuKTRx4ge69ybABsiUAWjVRK4XGxAKk2FQLp2HjGMy87Z4\""; r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" [] "+prevout); - BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == false); + BOOST_CHECK(r.get_obj().find_value("complete").get_bool() == false); r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" ["+privkey1+","+privkey2+"] "+prevout); - BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true); + BOOST_CHECK(r.get_obj().find_value("complete").get_bool() == true); } BOOST_AUTO_TEST_CASE(rpc_createraw_op_return) @@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); UniValue ar = r.get_array(); UniValue o1 = ar[0].get_obj(); - UniValue adr = find_value(o1, "address"); + UniValue adr = o1.find_value("address"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32"); BOOST_CHECK_NO_THROW(CallRPC(std::string("setban 127.0.0.0 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); @@ -336,8 +336,8 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); - int64_t banned_until{find_value(o1, "banned_until").getInt()}; + adr = o1.find_value("address"); + int64_t banned_until{o1.find_value("banned_until").getInt()}; BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); BOOST_CHECK_EQUAL(banned_until, 9907731200); // absolute time check @@ -351,11 +351,11 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); - banned_until = find_value(o1, "banned_until").getInt(); - const int64_t ban_created{find_value(o1, "ban_created").getInt()}; - const int64_t ban_duration{find_value(o1, "ban_duration").getInt()}; - const int64_t time_remaining{find_value(o1, "time_remaining").getInt()}; + adr = o1.find_value("address"); + banned_until = o1.find_value("banned_until").getInt(); + const int64_t ban_created{o1.find_value("ban_created").getInt()}; + const int64_t ban_duration{o1.find_value("ban_duration").getInt()}; + const int64_t time_remaining{o1.find_value("time_remaining").getInt()}; BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); BOOST_CHECK_EQUAL(banned_until, time_remaining_expected + now.count()); BOOST_CHECK_EQUAL(ban_duration, banned_until - ban_created); @@ -385,7 +385,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); + adr = o1.find_value("address"); BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/128"); BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); @@ -393,7 +393,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); + adr = o1.find_value("address"); BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/30"); BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); @@ -401,7 +401,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); + adr = o1.find_value("address"); BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128"); } diff --git a/src/test/system_tests.cpp b/src/test/system_tests.cpp index 4a67e014f4..c341f7c8da 100644 --- a/src/test/system_tests.cpp +++ b/src/test/system_tests.cpp @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(run_command) const UniValue result = RunCommandParseJSON("echo \"{\"success\": true}\""); #endif BOOST_CHECK(result.isObject()); - const UniValue& success = find_value(result, "success"); + const UniValue& success = result.find_value("success"); BOOST_CHECK(!success.isNull()); BOOST_CHECK_EQUAL(success.get_bool(), true); } @@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE(run_command) { const UniValue result = RunCommandParseJSON("cat", "{\"success\": true}"); BOOST_CHECK(result.isObject()); - const UniValue& success = find_value(result, "success"); + const UniValue& success = result.find_value("success"); BOOST_CHECK(!success.isNull()); BOOST_CHECK_EQUAL(success.get_bool(), true); } diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index d501c3fb69..004135ef97 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -123,7 +123,7 @@ public: const UniValue& get_array() const; enum VType type() const { return getType(); } - friend const UniValue& find_value( const UniValue& obj, const std::string& name); + const UniValue& find_value(std::string_view key) const; }; template @@ -201,6 +201,4 @@ static inline bool json_isspace(int ch) extern const UniValue NullUniValue; -const UniValue& find_value( const UniValue& obj, const std::string& name); - #endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 5aa39edb75..c3d19caae0 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -230,12 +230,13 @@ const char *uvTypeName(UniValue::VType t) return nullptr; } -const UniValue& find_value(const UniValue& obj, const std::string& name) +const UniValue& UniValue::find_value(std::string_view key) const { - for (unsigned int i = 0; i < obj.keys.size(); i++) - if (obj.keys[i] == name) - return obj.values.at(i); - + for (unsigned int i = 0; i < keys.size(); ++i) { + if (keys[i] == key) { + return values.at(i); + } + } return NullUniValue; } diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp index 2a8e58849c..14ae3b5ff3 100644 --- a/src/wallet/rpc/coins.cpp +++ b/src/wallet/rpc/coins.cpp @@ -374,7 +374,7 @@ RPCHelpMan lockunspent() }); const uint256 txid(ParseHashO(o, "txid")); - const int nOutput = find_value(o, "vout").getInt(); + const int nOutput = o.find_value("vout").getInt(); if (nOutput < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative"); } diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index 1a341fa871..6ec5d506dd 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -752,7 +752,7 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out, for (const UniValue& input : options["input_weights"].get_array().getValues()) { uint256 txid = ParseHashO(input, "txid"); - const UniValue& vout_v = find_value(input, "vout"); + const UniValue& vout_v = input.find_value("vout"); if (!vout_v.isNum()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); } @@ -761,7 +761,7 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out, throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative"); } - const UniValue& weight_v = find_value(input, "weight"); + const UniValue& weight_v = input.find_value("weight"); if (!weight_v.isNum()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing weight key"); } @@ -1900,7 +1900,7 @@ RPCHelpMan walletcreatefundedpsbt() std::set new_reissuance; for (unsigned int i = 0; i < rawTx.vin.size(); ++i) { if (!rawTx.vin[i].assetIssuance.IsNull()) { - const UniValue& blind_reissuance_v = find_value(request.params[0].get_array()[i].get_obj(), "blind_reissuance"); + const UniValue& blind_reissuance_v = request.params[0].get_array()[i].get_obj().find_value("blind_reissuance"); bool blind_reissuance = blind_reissuance_v.isNull() ? true : blind_reissuance_v.get_bool(); uint256 entropy; CAsset asset; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1757572e57..65101b33a5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4062,7 +4062,7 @@ void CWallet::SetupDescriptorScriptPubKeyMans() if (!signer_res.isObject()) throw std::runtime_error(std::string(__func__) + ": Unexpected result"); for (bool internal : {false, true}) { - const UniValue& descriptor_vals = find_value(signer_res, internal ? "internal" : "receive"); + const UniValue& descriptor_vals = signer_res.find_value(internal ? "internal" : "receive"); if (!descriptor_vals.isArray()) throw std::runtime_error(std::string(__func__) + ": Unexpected result"); for (const UniValue& desc_val : descriptor_vals.get_array().getValues()) { const std::string& desc_str = desc_val.getValStr();