diff --git a/src/bench/descriptors.cpp b/src/bench/descriptors.cpp index c45456645b9..ac5580a4e8e 100644 --- a/src/bench/descriptors.cpp +++ b/src/bench/descriptors.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -19,7 +20,7 @@ static void ExpandDescriptor(benchmark::Bench& bench) { ECC_Context ecc_context{}; - const auto desc_str = "sh(wsh(multi(16,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06,0399eb0a5487515802dc14544cf10b3666623762fbed2ec38a3975716e2c29c232)))"; + constexpr std::string_view desc_str{"sh(wsh(multi(16,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06,0399eb0a5487515802dc14544cf10b3666623762fbed2ec38a3975716e2c29c232)))"}; const std::pair range = {0, 1000}; FlatSigningProvider provider; std::string error; diff --git a/src/blockfilter.cpp b/src/blockfilter.cpp index 5e6702ccc3c..94bcc497ceb 100644 --- a/src/blockfilter.cpp +++ b/src/blockfilter.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -151,7 +152,8 @@ const std::string& BlockFilterTypeName(BlockFilterType filter_type) return it != g_filter_types.end() ? it->second : unknown_retval; } -bool BlockFilterTypeByName(const std::string& name, BlockFilterType& filter_type) { +bool BlockFilterTypeByName(std::string_view name, BlockFilterType& filter_type) +{ for (const auto& entry : g_filter_types) { if (entry.second == name) { filter_type = entry.first; diff --git a/src/blockfilter.h b/src/blockfilter.h index 8eab4afa76d..b70afb901f9 100644 --- a/src/blockfilter.h +++ b/src/blockfilter.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -99,7 +100,7 @@ enum class BlockFilterType : uint8_t const std::string& BlockFilterTypeName(BlockFilterType filter_type); /** Find a filter type by its human-readable name. */ -bool BlockFilterTypeByName(const std::string& name, BlockFilterType& filter_type); +bool BlockFilterTypeByName(std::string_view name, BlockFilterType& filter_type); /** Get a list of known filter types. */ const std::set& AllBlockFilterTypes(); diff --git a/src/common/messages.cpp b/src/common/messages.cpp index fc0b4a8861f..e1169c7672c 100644 --- a/src/common/messages.cpp +++ b/src/common/messages.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -91,7 +92,7 @@ std::string InvalidEstimateModeErrorMessage() return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\""; } -bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode) +bool FeeModeFromString(std::string_view mode_string, FeeEstimateMode& fee_estimate_mode) { auto searchkey = ToUpper(mode_string); for (const auto& pair : FeeModeMap()) { diff --git a/src/common/messages.h b/src/common/messages.h index 5827fccee08..5d33edac3cf 100644 --- a/src/common/messages.h +++ b/src/common/messages.h @@ -12,6 +12,7 @@ #define BITCOIN_COMMON_MESSAGES_H #include +#include struct bilingual_str; @@ -23,7 +24,7 @@ enum class TransactionError; namespace common { enum class PSBTError; -bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode); +bool FeeModeFromString(std::string_view mode_string, FeeEstimateMode& fee_estimate_mode); std::string StringForFeeReason(FeeReason reason); std::string FeeModes(const std::string& delimiter); std::string FeeModeInfo(std::pair& mode); diff --git a/src/net.cpp b/src/net.cpp index 66e99936ea0..bf5f98eb586 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -39,11 +39,12 @@ #include #include -#include #include #include +#include #include #include +#include #include TRACEPOINT_SEMAPHORE(net, closed_connection); @@ -331,7 +332,7 @@ bool IsLocal(const CService& addr) return mapLocalHost.count(addr) > 0; } -bool CConnman::AlreadyConnectedToHost(const std::string& host) const +bool CConnman::AlreadyConnectedToHost(std::string_view host) const { LOCK(m_nodes_mutex); return std::ranges::any_of(m_nodes, [&host](CNode* node) { return node->m_addr_name == host; }); @@ -3589,11 +3590,11 @@ bool CConnman::AddNode(const AddedNodeParams& add) return true; } -bool CConnman::RemoveAddedNode(const std::string& strNode) +bool CConnman::RemoveAddedNode(std::string_view node) { LOCK(m_added_nodes_mutex); for (auto it = m_added_node_params.begin(); it != m_added_node_params.end(); ++it) { - if (strNode == it->m_added_node) { + if (node == it->m_added_node) { m_added_node_params.erase(it); return true; } @@ -3652,7 +3653,7 @@ void CConnman::GetNodeStats(std::vector& vstats) const } } -bool CConnman::DisconnectNode(const std::string& strNode) +bool CConnman::DisconnectNode(std::string_view strNode) { LOCK(m_nodes_mutex); auto it = std::ranges::find_if(m_nodes, [&strNode](CNode* node) { return node->m_addr_name == strNode; }); diff --git a/src/net.h b/src/net.h index d806b42a1ec..25cb8236a3c 100644 --- a/src/net.h +++ b/src/net.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -1248,7 +1249,7 @@ public: int GetExtraBlockRelayCount() const; bool AddNode(const AddedNodeParams& add) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex); - bool RemoveAddedNode(const std::string& node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex); + bool RemoveAddedNode(std::string_view node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex); bool AddedNodesContain(const CAddress& addr) const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex); std::vector GetAddedNodeInfo(bool include_connected) const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex); @@ -1271,7 +1272,7 @@ public: std::map getNetLocalAddresses() const; uint32_t GetMappedAS(const CNetAddr& addr) const; void GetNodeStats(std::vector& vstats) const; - bool DisconnectNode(const std::string& node); + bool DisconnectNode(std::string_view node); bool DisconnectNode(const CSubNet& subnet); bool DisconnectNode(const CNetAddr& addr); bool DisconnectNode(NodeId id); @@ -1403,7 +1404,7 @@ private: * @param[in] host String of the form "host[:port]", e.g. "localhost" or "localhost:8333" or "1.2.3.4:8333". * @return true if connected to `host`. */ - bool AlreadyConnectedToHost(const std::string& host) const; + bool AlreadyConnectedToHost(std::string_view host) const; /** * Determine whether we're already connected to a given address:port. diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 7eb58f3ec86..fb2c254076a 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include using util::ContainsNoNUL; @@ -208,7 +209,7 @@ static void Checksum(std::span addr_pubkey, uint8_t (&checksum)[C }; // namespace torv3 -bool CNetAddr::SetSpecial(const std::string& addr) +bool CNetAddr::SetSpecial(std::string_view addr) { if (!ContainsNoNUL(addr)) { return false; @@ -225,16 +226,11 @@ bool CNetAddr::SetSpecial(const std::string& addr) return false; } -bool CNetAddr::SetTor(const std::string& addr) +bool CNetAddr::SetTor(std::string_view addr) { - static const char* suffix{".onion"}; - static constexpr size_t suffix_len{6}; - - if (addr.size() <= suffix_len || addr.substr(addr.size() - suffix_len) != suffix) { - return false; - } - - auto input = DecodeBase32(std::string_view{addr}.substr(0, addr.size() - suffix_len)); + if (!addr.ends_with(".onion")) return false; + addr.remove_suffix(6); + auto input = DecodeBase32(addr); if (!input) { return false; @@ -264,7 +260,7 @@ bool CNetAddr::SetTor(const std::string& addr) return false; } -bool CNetAddr::SetI2P(const std::string& addr) +bool CNetAddr::SetI2P(std::string_view addr) { // I2P addresses that we support consist of 52 base32 characters + ".b32.i2p". static constexpr size_t b32_len{52}; @@ -277,7 +273,7 @@ bool CNetAddr::SetI2P(const std::string& addr) // Remove the ".b32.i2p" suffix and pad to a multiple of 8 chars, so DecodeBase32() // can decode it. - const std::string b32_padded = addr.substr(0, b32_len) + "===="; + const std::string b32_padded{tfm::format("%s====", addr.substr(0, b32_len))}; auto address_bytes = DecodeBase32(b32_padded); diff --git a/src/netaddress.h b/src/netaddress.h index 7c311e2f3ab..48dbf03a023 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -18,6 +18,7 @@ #include #include #include +#include #include /** @@ -151,7 +152,7 @@ public: * @returns Whether the operation was successful. * @see CNetAddr::IsTor(), CNetAddr::IsI2P() */ - bool SetSpecial(const std::string& addr); + bool SetSpecial(std::string_view addr); bool IsBindAny() const; // INADDR_ANY equivalent [[nodiscard]] bool IsIPv4() const { return m_net == NET_IPV4; } // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) @@ -279,7 +280,7 @@ private: * @returns Whether the operation was successful. * @see CNetAddr::IsTor() */ - bool SetTor(const std::string& addr); + bool SetTor(std::string_view addr); /** * Parse an I2P address and set this object to it. @@ -288,7 +289,7 @@ private: * @returns Whether the operation was successful. * @see CNetAddr::IsI2P() */ - bool SetI2P(const std::string& addr); + bool SetI2P(std::string_view addr); /** * Size of CNetAddr when serialized as ADDRv1 (pre-BIP155) (in bytes). diff --git a/src/outputtype.cpp b/src/outputtype.cpp index d4c2d95cfc1..082641f5e2e 100644 --- a/src/outputtype.cpp +++ b/src/outputtype.cpp @@ -20,7 +20,7 @@ static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32"; static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m"; static const std::string OUTPUT_TYPE_STRING_UNKNOWN = "unknown"; -std::optional ParseOutputType(const std::string& type) +std::optional ParseOutputType(std::string_view type) { if (type == OUTPUT_TYPE_STRING_LEGACY) { return OutputType::LEGACY; diff --git a/src/outputtype.h b/src/outputtype.h index 5a6f053918c..4dde381b356 100644 --- a/src/outputtype.h +++ b/src/outputtype.h @@ -12,6 +12,7 @@ #include #include #include +#include #include enum class OutputType { @@ -29,7 +30,7 @@ static constexpr auto OUTPUT_TYPES = std::array{ OutputType::BECH32M, }; -std::optional ParseOutputType(const std::string& str); +std::optional ParseOutputType(std::string_view str); const std::string& FormatOutputType(OutputType type); std::string FormatAllOutputTypes(); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index cab4a43409b..2ff5f52977a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,8 @@ #include #include #include +#include +#include #include using kernel::CCoinsStats; @@ -936,7 +939,7 @@ static RPCHelpMan pruneblockchain() }; } -CoinStatsHashType ParseHashType(const std::string& hash_type_input) +CoinStatsHashType ParseHashType(std::string_view hash_type_input) { if (hash_type_input == "hash_serialized_3") { return CoinStatsHashType::HASH_SERIALIZED; @@ -1038,7 +1041,7 @@ static RPCHelpMan gettxoutsetinfo() UniValue ret(UniValue::VOBJ); const CBlockIndex* pindex{nullptr}; - const CoinStatsHashType hash_type{request.params[0].isNull() ? CoinStatsHashType::HASH_SERIALIZED : ParseHashType(request.params[0].get_str())}; + const CoinStatsHashType hash_type{ParseHashType(self.Arg("hash_type"))}; bool index_requested = request.params[2].isNull() || request.params[2].get_bool(); NodeContext& node = EnsureAnyNodeContext(request.context); @@ -2328,7 +2331,7 @@ static RPCHelpMan scantxoutset() [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { UniValue result(UniValue::VOBJ); - const auto action{self.Arg("action")}; + const auto action{self.Arg("action")}; if (action == "status") { CoinsViewScanReserver reserver; if (reserver.reserve()) { @@ -2524,7 +2527,8 @@ static RPCHelpMan scanblocks() [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { UniValue ret(UniValue::VOBJ); - if (request.params[0].get_str() == "status") { + auto action{self.Arg("action")}; + if (action == "status") { BlockFiltersScanReserver reserver; if (reserver.reserve()) { // no scan in progress @@ -2533,7 +2537,7 @@ static RPCHelpMan scanblocks() ret.pushKV("progress", g_scanfilter_progress.load()); ret.pushKV("current_height", g_scanfilter_progress_height.load()); return ret; - } else if (request.params[0].get_str() == "abort") { + } else if (action == "abort") { BlockFiltersScanReserver reserver; if (reserver.reserve()) { // reserve was possible which means no scan was running @@ -2542,12 +2546,12 @@ static RPCHelpMan scanblocks() // set the abort flag g_scanfilter_should_abort_scan = true; return true; - } else if (request.params[0].get_str() == "start") { + } else if (action == "start") { BlockFiltersScanReserver reserver; if (!reserver.reserve()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan already in progress, use action \"abort\" or \"status\""); } - const std::string filtertype_name{request.params[4].isNull() ? "basic" : request.params[4].get_str()}; + auto filtertype_name{self.Arg("filtertype")}; BlockFilterType filtertype; if (!BlockFilterTypeByName(filtertype_name, filtertype)) { @@ -2559,7 +2563,7 @@ static RPCHelpMan scanblocks() BlockFilterIndex* index = GetBlockFilterIndex(filtertype); if (!index) { - throw JSONRPCError(RPC_MISC_ERROR, "Index is not enabled for filtertype " + filtertype_name); + throw JSONRPCError(RPC_MISC_ERROR, tfm::format("Index is not enabled for filtertype %s", filtertype_name)); } NodeContext& node = EnsureAnyNodeContext(request.context); @@ -2658,9 +2662,8 @@ static RPCHelpMan scanblocks() ret.pushKV("to_height", start_index->nHeight); // start_index is always the last scanned block here ret.pushKV("relevant_blocks", std::move(blocks)); ret.pushKV("completed", completed); - } - else { - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid action '%s'", request.params[0].get_str())); + } else { + throw JSONRPCError(RPC_INVALID_PARAMETER, tfm::format("Invalid action '%s'", action)); } return ret; }, @@ -2925,10 +2928,7 @@ static RPCHelpMan getblockfilter() [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { uint256 block_hash = ParseHashV(request.params[0], "blockhash"); - std::string filtertype_name = BlockFilterTypeName(BlockFilterType::BASIC); - if (!request.params[1].isNull()) { - filtertype_name = request.params[1].get_str(); - } + auto filtertype_name{self.Arg("filtertype")}; BlockFilterType filtertype; if (!BlockFilterTypeByName(filtertype_name, filtertype)) { @@ -2937,7 +2937,7 @@ static RPCHelpMan getblockfilter() BlockFilterIndex* index = GetBlockFilterIndex(filtertype); if (!index) { - throw JSONRPCError(RPC_MISC_ERROR, "Index is not enabled for filtertype " + filtertype_name); + throw JSONRPCError(RPC_MISC_ERROR, tfm::format("Index is not enabled for filtertype %s", filtertype_name)); } const CBlockIndex* block_index; @@ -3064,7 +3064,7 @@ static RPCHelpMan dumptxoutset() NodeContext& node = EnsureAnyNodeContext(request.context); const CBlockIndex* tip{WITH_LOCK(::cs_main, return node.chainman->ActiveChain().Tip())}; const CBlockIndex* target_index{nullptr}; - const std::string snapshot_type{self.Arg("type")}; + const auto snapshot_type{self.Arg("type")}; const UniValue options{request.params[2].isNull() ? UniValue::VOBJ : request.params[2]}; if (options.exists("rollback")) { if (!snapshot_type.empty() && snapshot_type != "rollback") { @@ -3083,10 +3083,10 @@ static RPCHelpMan dumptxoutset() } const ArgsManager& args{EnsureAnyArgsman(request.context)}; - const fs::path path = fsbridge::AbsPathJoin(args.GetDataDirNet(), fs::u8path(request.params[0].get_str())); + const fs::path path = fsbridge::AbsPathJoin(args.GetDataDirNet(), fs::u8path(self.Arg("path"))); // Write to a temporary path and then move into `path` on completion // to avoid confusion due to an interruption. - const fs::path temppath = fsbridge::AbsPathJoin(args.GetDataDirNet(), fs::u8path(request.params[0].get_str() + ".incomplete")); + const fs::path temppath = path + ".incomplete"; if (fs::exists(path)) { throw JSONRPCError( @@ -3355,7 +3355,7 @@ static RPCHelpMan loadtxoutset() { NodeContext& node = EnsureAnyNodeContext(request.context); ChainstateManager& chainman = EnsureChainman(node); - const fs::path path{AbsPathForConfigVal(EnsureArgsman(node), fs::u8path(self.Arg("path")))}; + const fs::path path{AbsPathForConfigVal(EnsureArgsman(node), fs::u8path(self.Arg("path")))}; FILE* file{fsbridge::fopen(path, "rb")}; AutoFile afile{file}; diff --git a/src/rpc/fees.cpp b/src/rpc/fees.cpp index 92c7a922f28..ceb341e46af 100644 --- a/src/rpc/fees.cpp +++ b/src/rpc/fees.cpp @@ -21,6 +21,7 @@ #include #include #include +#include using common::FeeModeFromString; using common::FeeModesDetail; @@ -67,18 +68,15 @@ static RPCHelpMan estimatesmartfee() CHECK_NONFATAL(mempool.m_opts.signals)->SyncWithValidationInterfaceQueue(); unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target); - bool conservative = false; - if (!request.params[1].isNull()) { - FeeEstimateMode fee_mode; - if (!FeeModeFromString(request.params[1].get_str(), fee_mode)) { - throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage()); - } - if (fee_mode == FeeEstimateMode::CONSERVATIVE) conservative = true; + FeeEstimateMode fee_mode; + if (!FeeModeFromString(self.Arg("estimate_mode"), fee_mode)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage()); } UniValue result(UniValue::VOBJ); UniValue errors(UniValue::VARR); FeeCalculation feeCalc; + bool conservative{fee_mode == FeeEstimateMode::CONSERVATIVE}; CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)}; if (feeRate != CFeeRate(0)) { CFeeRate min_mempool_feerate{mempool.GetMinFee()}; diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index cb1ea5dd3e2..1ba24a61a9f 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -28,6 +28,7 @@ #include #include +#include #include using node::DumpMempool; @@ -768,7 +769,7 @@ static RPCHelpMan importmempool() throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Can only import the mempool after the block download and sync is done."); } - const fs::path load_path{fs::u8path(request.params[0].get_str())}; + const fs::path load_path{fs::u8path(self.Arg("filepath"))}; const UniValue& use_current_time{request.params[1]["use_current_time"]}; const UniValue& apply_fee_delta{request.params[1]["apply_fee_delta_priority"]}; const UniValue& apply_unbroadcast{request.params[1]["apply_unbroadcast_set"]}; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 850cdb70c4e..2639b916129 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -181,7 +181,7 @@ static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const return blockHashes; } -static bool getScriptFromDescriptor(const std::string& descriptor, CScript& script, std::string& error) +static bool getScriptFromDescriptor(std::string_view descriptor, CScript& script, std::string& error) { FlatSigningProvider key_provider; const auto descs = Parse(descriptor, key_provider, error, /* require_checksum = */ false); @@ -241,7 +241,7 @@ static RPCHelpMan generatetodescriptor() CScript coinbase_output_script; std::string error; - if (!getScriptFromDescriptor(self.Arg("descriptor"), coinbase_output_script, error)) { + if (!getScriptFromDescriptor(self.Arg("descriptor"), coinbase_output_script, error)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index da01a60b9ec..c97d4c75af0 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -36,11 +36,11 @@ #include #include #include +#include #include using node::NodeContext; using util::Join; -using util::TrimString; const std::vector CONNECTION_TYPE_DOC{ "outbound-full-relay (default automatic connections)", @@ -333,7 +333,7 @@ static RPCHelpMan addnode() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - const auto command{self.Arg("command")}; + const auto command{self.Arg("command")}; if (command != "onetry" && command != "add" && command != "remove") { throw std::runtime_error( self.ToString()); @@ -342,7 +342,7 @@ static RPCHelpMan addnode() NodeContext& node = EnsureAnyNodeContext(request.context); CConnman& connman = EnsureConnman(node); - const auto node_arg{self.Arg("node")}; + const auto node_arg{self.Arg("node")}; bool node_v2transport = connman.GetLocalServices() & NODE_P2P_V2; bool use_v2transport = self.MaybeArg("v2transport").value_or(node_v2transport); @@ -353,13 +353,13 @@ static RPCHelpMan addnode() if (command == "onetry") { CAddress addr; - connman.OpenNetworkConnection(addr, /*fCountFailure=*/false, /*grant_outbound=*/{}, node_arg.c_str(), ConnectionType::MANUAL, use_v2transport); + connman.OpenNetworkConnection(addr, /*fCountFailure=*/false, /*grant_outbound=*/{}, std::string{node_arg}.c_str(), ConnectionType::MANUAL, use_v2transport); return UniValue::VNULL; } if (command == "add") { - if (!connman.AddNode({node_arg, use_v2transport})) { + if (!connman.AddNode({std::string{node_arg}, use_v2transport})) { throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added"); } } @@ -402,7 +402,7 @@ static RPCHelpMan addconnection() } const std::string address = request.params[0].get_str(); - const std::string conn_type_in{TrimString(request.params[1].get_str())}; + auto conn_type_in{util::TrimStringView(self.Arg("connection_type"))}; ConnectionType conn_type{}; if (conn_type_in == "outbound-full-relay") { conn_type = ConnectionType::OUTBOUND_FULL_RELAY; @@ -462,16 +462,15 @@ static RPCHelpMan disconnectnode() CConnman& connman = EnsureConnman(node); bool success; - const UniValue &address_arg = request.params[0]; - const UniValue &id_arg = request.params[1]; + auto address{self.MaybeArg("address")}; + auto node_id{self.MaybeArg("nodeid")}; - if (!address_arg.isNull() && id_arg.isNull()) { + if (address && !node_id) { /* handle disconnect-by-address */ - success = connman.DisconnectNode(address_arg.get_str()); - } else if (!id_arg.isNull() && (address_arg.isNull() || (address_arg.isStr() && address_arg.get_str().empty()))) { + success = connman.DisconnectNode(*address); + } else if (node_id && (!address || address->empty())) { /* handle disconnect-by-id */ - NodeId nodeid = (NodeId) id_arg.getInt(); - success = connman.DisconnectNode(nodeid); + success = connman.DisconnectNode(*node_id); } else { throw JSONRPCError(RPC_INVALID_PARAMS, "Only one of address and nodeid should be provided."); } @@ -523,10 +522,10 @@ static RPCHelpMan getaddednodeinfo() std::vector vInfo = connman.GetAddedNodeInfo(/*include_connected=*/true); - if (!request.params[0].isNull()) { + if (auto node{self.MaybeArg("node")}) { bool found = false; for (const AddedNodeInfo& info : vInfo) { - if (info.m_params.m_added_node == request.params[0].get_str()) { + if (info.m_params.m_added_node == *node) { vInfo.assign(1, info); found = true; break; @@ -754,10 +753,8 @@ static RPCHelpMan setban() }, [&](const RPCHelpMan& help, const JSONRPCRequest& request) -> UniValue { - std::string strCommand; - if (!request.params[1].isNull()) - strCommand = request.params[1].get_str(); - if (strCommand != "add" && strCommand != "remove") { + auto command{help.Arg("command")}; + if (command != "add" && command != "remove") { throw std::runtime_error(help.ToString()); } NodeContext& node = EnsureAnyNodeContext(request.context); @@ -765,25 +762,23 @@ static RPCHelpMan setban() CSubNet subNet; CNetAddr netAddr; - bool isSubnet = false; - - if (request.params[0].get_str().find('/') != std::string::npos) - isSubnet = true; + std::string subnet_arg{help.Arg("subnet")}; + const bool isSubnet{subnet_arg.find('/') != subnet_arg.npos}; if (!isSubnet) { - const std::optional addr{LookupHost(request.params[0].get_str(), false)}; + const std::optional addr{LookupHost(subnet_arg, false)}; if (addr.has_value()) { netAddr = static_cast(MaybeFlipIPv6toCJDNS(CService{addr.value(), /*port=*/0})); } + } else { + subNet = LookupSubNet(subnet_arg); } - else - subNet = LookupSubNet(request.params[0].get_str()); - if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) ) + if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) ) { throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Invalid IP/Subnet"); + } - if (strCommand == "add") - { + if (command == "add") { if (isSubnet ? banman.IsBanned(subNet) : banman.IsBanned(netAddr)) { throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned"); } @@ -809,9 +804,7 @@ static RPCHelpMan setban() node.connman->DisconnectNode(netAddr); } } - } - else if(strCommand == "remove") - { + } else if(command == "remove") { if (!( isSubnet ? banman.Unban(subNet) : banman.Unban(netAddr) )) { throw JSONRPCError(RPC_CLIENT_INVALID_IP_OR_SUBNET, "Error: Unban failed. Requested address/subnet was not previously manually banned."); } @@ -1051,11 +1044,11 @@ static RPCHelpMan sendmsgtopeer() HelpExampleCli("sendmsgtopeer", "0 \"addr\" \"ffffff\"") + HelpExampleRpc("sendmsgtopeer", "0 \"addr\" \"ffffff\"")}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { const NodeId peer_id{request.params[0].getInt()}; - const std::string& msg_type{request.params[1].get_str()}; + const auto msg_type{self.Arg("msg_type")}; if (msg_type.size() > CMessageHeader::MESSAGE_TYPE_SIZE) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Error: msg_type too long, max length is %i", CMessageHeader::MESSAGE_TYPE_SIZE)); } - auto msg{TryParseHex(request.params[2].get_str())}; + auto msg{TryParseHex(self.Arg("msg"))}; if (!msg.has_value()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Error parsing input for msg"); } diff --git a/src/rpc/node.cpp b/src/rpc/node.cpp index a5da8785df4..c922b27f688 100644 --- a/src/rpc/node.cpp +++ b/src/rpc/node.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #ifdef HAVE_MALLOC_INFO #include #endif +#include using node::NodeContext; @@ -176,7 +178,7 @@ static RPCHelpMan getmemoryinfo() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - std::string mode = request.params[0].isNull() ? "stats" : request.params[0].get_str(); + auto mode{self.Arg("mode")}; if (mode == "stats") { UniValue obj(UniValue::VOBJ); obj.pushKV("locked", RPCLockedMemoryInfo()); @@ -188,7 +190,7 @@ static RPCHelpMan getmemoryinfo() throw JSONRPCError(RPC_INVALID_PARAMETER, "mallocinfo mode not available"); #endif } else { - throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown mode " + mode); + throw JSONRPCError(RPC_INVALID_PARAMETER, tfm::format("unknown mode %s", mode)); } }, }; @@ -385,7 +387,7 @@ static RPCHelpMan getindexinfo() [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { UniValue result(UniValue::VOBJ); - const std::string index_name = request.params[0].isNull() ? "" : request.params[0].get_str(); + const std::string index_name{self.MaybeArg("index_name").value_or("")}; if (g_txindex) { result.pushKVs(SummaryToJSON(g_txindex->GetSummary(), index_name)); diff --git a/src/rpc/output_script.cpp b/src/rpc/output_script.cpp index 43624c98eac..5c1151f0e0b 100644 --- a/src/rpc/output_script.cpp +++ b/src/rpc/output_script.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -130,20 +131,17 @@ static RPCHelpMan createmultisig() } // Get the output type - OutputType output_type = OutputType::LEGACY; - if (!request.params[2].isNull()) { - std::optional parsed = ParseOutputType(request.params[2].get_str()); - if (!parsed) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[2].get_str())); - } else if (parsed.value() == OutputType::BECH32M) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "createmultisig cannot create bech32m multisig addresses"); - } - output_type = parsed.value(); + auto address_type{self.Arg("address_type")}; + auto output_type{ParseOutputType(address_type)}; + if (!output_type) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, tfm::format("Unknown address type '%s'", address_type)); + } else if (output_type.value() == OutputType::BECH32M) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "createmultisig cannot create bech32m multisig addresses"); } FlatSigningProvider keystore; CScript inner; - const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, keystore, inner); + const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type.value(), keystore, inner); // Make the descriptor std::unique_ptr descriptor = InferDescriptor(GetScriptForDestination(dest), keystore); @@ -154,7 +152,7 @@ static RPCHelpMan createmultisig() result.pushKV("descriptor", descriptor->ToString()); UniValue warnings(UniValue::VARR); - if (descriptor->GetOutputType() != output_type) { + if (descriptor->GetOutputType() != output_type.value()) { // Only warns if the user has explicitly chosen an address type we cannot generate warnings.push_back("Unable to make chosen address type, please ensure no uncompressed public keys are present."); } @@ -198,7 +196,7 @@ static RPCHelpMan getdescriptorinfo() { FlatSigningProvider provider; std::string error; - auto descs = Parse(request.params[0].get_str(), provider, error); + auto descs = Parse(self.Arg("descriptor"), provider, error); if (descs.empty()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); } @@ -303,7 +301,7 @@ static RPCHelpMan deriveaddresses() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - const std::string desc_str = request.params[0].get_str(); + auto desc_str{self.Arg("descriptor")}; int64_t range_begin = 0; int64_t range_end = 0; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 2edf13fd236..5fd733d056b 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include using util::SplitString; @@ -65,7 +66,7 @@ struct RPCCommandExecution } }; -std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& helpreq) const +std::string CRPCTable::help(std::string_view strCommand, const JSONRPCRequest& helpreq) const { std::string strRet; std::string category; @@ -130,16 +131,13 @@ static RPCHelpMan help() RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue { - std::string strCommand; - if (jsonRequest.params.size() > 0) { - strCommand = jsonRequest.params[0].get_str(); - } - if (strCommand == "dump_all_command_conversions") { + auto command{self.MaybeArg("command")}; + if (command == "dump_all_command_conversions") { // Used for testing only, undocumented return tableRPC.dumpArgMap(jsonRequest); } - return tableRPC.help(strCommand, jsonRequest); + return tableRPC.help(command.value_or(""), jsonRequest); }, }; } diff --git a/src/rpc/server.h b/src/rpc/server.h index 84accccba9e..cb68c1def79 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -89,7 +89,7 @@ private: std::map> mapCommands; public: CRPCTable(); - std::string help(const std::string& name, const JSONRPCRequest& helpreq) const; + std::string help(std::string_view name, const JSONRPCRequest& helpreq) const; /** * Execute a method. diff --git a/src/rpc/signmessage.cpp b/src/rpc/signmessage.cpp index 5597f8d237e..a3fb0bbf218 100644 --- a/src/rpc/signmessage.cpp +++ b/src/rpc/signmessage.cpp @@ -38,11 +38,9 @@ static RPCHelpMan verifymessage() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - std::string strAddress = self.Arg("address"); - std::string strSign = self.Arg("signature"); - std::string strMessage = self.Arg("message"); - - switch (MessageVerify(strAddress, strSign, strMessage)) { + switch (MessageVerify(std::string{self.Arg("address")}, + std::string{self.Arg("signature")}, + std::string{self.Arg("message")})) { case MessageVerificationResult::ERR_INVALID_ADDRESS: throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); case MessageVerificationResult::ERR_ADDRESS_NO_KEY: diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index 0604dec2dc9..4813324c050 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -724,7 +724,8 @@ static void CheckRequiredOrDefault(const RPCArg& param) TMPL_INST(nullptr, const UniValue*, maybe_arg;); TMPL_INST(nullptr, std::optional, maybe_arg ? std::optional{maybe_arg->get_real()} : std::nullopt;); TMPL_INST(nullptr, std::optional, maybe_arg ? std::optional{maybe_arg->get_bool()} : std::nullopt;); -TMPL_INST(nullptr, const std::string*, maybe_arg ? &maybe_arg->get_str() : nullptr;); +TMPL_INST(nullptr, std::optional, maybe_arg ? std::optional{maybe_arg->getInt()} : std::nullopt;); +TMPL_INST(nullptr, std::optional, maybe_arg ? std::optional{maybe_arg->get_str()} : std::nullopt;); // Required arg or optional arg with default value. TMPL_INST(CheckRequiredOrDefault, const UniValue&, *CHECK_NONFATAL(maybe_arg);); @@ -732,7 +733,7 @@ TMPL_INST(CheckRequiredOrDefault, bool, CHECK_NONFATAL(maybe_arg)->get_bool();); TMPL_INST(CheckRequiredOrDefault, int, CHECK_NONFATAL(maybe_arg)->getInt();); TMPL_INST(CheckRequiredOrDefault, uint64_t, CHECK_NONFATAL(maybe_arg)->getInt();); TMPL_INST(CheckRequiredOrDefault, uint32_t, CHECK_NONFATAL(maybe_arg)->getInt();); -TMPL_INST(CheckRequiredOrDefault, const std::string&, CHECK_NONFATAL(maybe_arg)->get_str();); +TMPL_INST(CheckRequiredOrDefault, std::string_view, CHECK_NONFATAL(maybe_arg)->get_str();); bool RPCHelpMan::IsValidNumArgs(size_t num_args) const { diff --git a/src/rpc/util.h b/src/rpc/util.h index 1650d2da1f6..f82ccbf832e 100644 --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -445,8 +445,8 @@ public: { auto i{GetParamIndex(key)}; // Return argument (required or with default value). - if constexpr (std::is_integral_v || std::is_floating_point_v) { - // Return numbers by value. + if constexpr (std::is_trivially_copyable_v) { + // Return trivially copyable types by value. return ArgValue(i); } else { // Return everything else by reference. @@ -466,7 +466,7 @@ public: * * The instantiation of this helper for type R must match the corresponding RPCArg::Type. * - * @return For integral and floating-point types, a std::optional is returned. + * @return For trivially copyable types, a std::optional is returned. * For other types, a R* pointer to the argument is returned. If the * argument is not provided, std::nullopt or a null pointer is returned. * @@ -477,8 +477,8 @@ public: { auto i{GetParamIndex(key)}; // Return optional argument (without default). - if constexpr (std::is_integral_v || std::is_floating_point_v) { - // Return numbers by value, wrapped in optional. + if constexpr (std::is_trivially_copyable_v) { + // Return trivially copyable types by value, wrapped in optional. return ArgValue>(i); } else { // Return other types by pointer. diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index d0436702124..2a4e17b4b5f 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -2730,13 +2730,12 @@ bool CheckChecksum(std::span& sp, bool require_checksum, std::string return true; } -std::vector> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum) +std::vector> Parse(std::span descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum) { - std::span sp{descriptor}; - if (!CheckChecksum(sp, require_checksum, error)) return {}; + if (!CheckChecksum(descriptor, require_checksum, error)) return {}; uint32_t key_exp_index = 0; - auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error); - if (sp.size() == 0 && !ret.empty()) { + auto ret = ParseScript(key_exp_index, descriptor, ParseScriptContext::TOP, out, error); + if (descriptor.empty() && !ret.empty()) { std::vector> descs; descs.reserve(ret.size()); for (auto& r : ret) { diff --git a/src/script/descriptor.h b/src/script/descriptor.h index 473649a3144..9a018300ebe 100644 --- a/src/script/descriptor.h +++ b/src/script/descriptor.h @@ -175,7 +175,7 @@ struct Descriptor { * If a parse error occurs, or the checksum is missing/invalid, or anything * else is wrong, an empty vector is returned. */ -std::vector> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum = false); +std::vector> Parse(std::span descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum = false); /** Get the checksum for a `descriptor`. * diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 5d81b4287dd..99d1c6589ae 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -14,6 +14,7 @@ #include #include +#include #include @@ -621,9 +622,9 @@ BOOST_AUTO_TEST_CASE(rpc_arg_helper) //! Check that `self.Arg` returns the same value as the `request.params` accessors RPCHelpMan::RPCMethodImpl check_positional = [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { BOOST_CHECK_EQUAL(self.Arg("req_int"), request.params[0].getInt()); - BOOST_CHECK_EQUAL(self.Arg("req_str"), request.params[1].get_str()); + BOOST_CHECK_EQUAL(self.Arg("req_str"), request.params[1].get_str()); BOOST_CHECK_EQUAL(self.Arg("def_uint64_t"), request.params[2].isNull() ? DEFAULT_UINT64_T : request.params[2].getInt()); - BOOST_CHECK_EQUAL(self.Arg("def_string"), request.params[3].isNull() ? DEFAULT_STRING : request.params[3].get_str()); + BOOST_CHECK_EQUAL(self.Arg("def_string"), request.params[3].isNull() ? DEFAULT_STRING : request.params[3].get_str()); BOOST_CHECK_EQUAL(self.Arg("def_bool"), request.params[4].isNull() ? DEFAULT_BOOL : request.params[4].get_bool()); if (!request.params[5].isNull()) { BOOST_CHECK_EQUAL(self.MaybeArg("opt_double").value(), request.params[5].get_real()); @@ -631,10 +632,9 @@ BOOST_AUTO_TEST_CASE(rpc_arg_helper) BOOST_CHECK(!self.MaybeArg("opt_double")); } if (!request.params[6].isNull()) { - BOOST_CHECK(self.MaybeArg("opt_string")); - BOOST_CHECK_EQUAL(*self.MaybeArg("opt_string"), request.params[6].get_str()); + BOOST_CHECK_EQUAL(self.MaybeArg("opt_string"), request.params[6].get_str()); } else { - BOOST_CHECK(!self.MaybeArg("opt_string")); + BOOST_CHECK(!self.MaybeArg("opt_string")); } return UniValue{}; }; diff --git a/src/util/fs.h b/src/util/fs.h index 22b53a0ca63..8b5c0460257 100644 --- a/src/util/fs.h +++ b/src/util/fs.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -77,7 +78,7 @@ public: } }; -static inline path u8path(const std::string& utf8_str) +static inline path u8path(std::string_view utf8_str) { return std::filesystem::path(std::u8string{utf8_str.begin(), utf8_str.end()}); } diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp index 4aef0dda886..7aeb60f76bb 100644 --- a/src/wallet/rpc/coins.cpp +++ b/src/wallet/rpc/coins.cpp @@ -196,8 +196,7 @@ RPCHelpMan getbalance() LOCK(pwallet->cs_wallet); - const auto dummy_value{self.MaybeArg("dummy")}; - if (dummy_value && *dummy_value != "*") { + if (self.MaybeArg("dummy").value_or("*") != "*") { throw JSONRPCError(RPC_METHOD_DEPRECATED, "dummy first argument must be excluded or set to \"*\"."); } diff --git a/src/wallet/rpc/util.cpp b/src/wallet/rpc/util.cpp index 79703985354..d68e6c65269 100644 --- a/src/wallet/rpc/util.cpp +++ b/src/wallet/rpc/util.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -29,7 +30,7 @@ bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) { return avoid_reuse; } -std::string EnsureUniqueWalletName(const JSONRPCRequest& request, const std::string* wallet_name) +std::string EnsureUniqueWalletName(const JSONRPCRequest& request, std::optional wallet_name) { std::string endpoint_wallet; if (GetWalletNameFromJSONRPCRequest(request, endpoint_wallet)) { @@ -47,7 +48,7 @@ std::string EnsureUniqueWalletName(const JSONRPCRequest& request, const std::str "Either the RPC endpoint wallet or the wallet name parameter must be provided"); } - return *wallet_name; + return std::string{*wallet_name}; } bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string& wallet_name) diff --git a/src/wallet/rpc/util.h b/src/wallet/rpc/util.h index 0c586be4a49..d649721431a 100644 --- a/src/wallet/rpc/util.h +++ b/src/wallet/rpc/util.h @@ -11,7 +11,9 @@ #include #include +#include #include +#include #include class JSONRPCRequest; @@ -42,7 +44,7 @@ bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string& * Ensures that a wallet name is specified across the endpoint and wallet_name. * Throws `RPC_INVALID_PARAMETER` if none or different wallet names are specified. */ -std::string EnsureUniqueWalletName(const JSONRPCRequest& request, const std::string* wallet_name); +std::string EnsureUniqueWalletName(const JSONRPCRequest& request, std::optional wallet_name); void EnsureWalletIsUnlocked(const CWallet&); WalletContext& EnsureWalletContext(const std::any& context); diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp index 8e1cec55654..3d45c1606e9 100644 --- a/src/wallet/rpc/wallet.cpp +++ b/src/wallet/rpc/wallet.cpp @@ -19,6 +19,7 @@ #include #include +#include namespace wallet { @@ -456,7 +457,7 @@ static RPCHelpMan unloadwallet() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - const std::string wallet_name{EnsureUniqueWalletName(request, self.MaybeArg("wallet_name"))}; + const std::string wallet_name{EnsureUniqueWalletName(request, self.MaybeArg("wallet_name"))}; WalletContext& context = EnsureWalletContext(request.context); std::shared_ptr wallet = GetWallet(context, wallet_name); @@ -613,7 +614,7 @@ static RPCHelpMan migratewallet() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - const std::string wallet_name{EnsureUniqueWalletName(request, self.MaybeArg("wallet_name"))}; + const std::string wallet_name{EnsureUniqueWalletName(request, self.MaybeArg("wallet_name"))}; SecureString wallet_pass; wallet_pass.reserve(100); diff --git a/src/wallet/test/wallet_rpc_tests.cpp b/src/wallet/test/wallet_rpc_tests.cpp index fb33d3668da..8bf5eab443a 100644 --- a/src/wallet/test/wallet_rpc_tests.cpp +++ b/src/wallet/test/wallet_rpc_tests.cpp @@ -17,7 +17,7 @@ static std::string TestWalletName(const std::string& endpoint, std::optional