rpc: refactor: use string_view in Arg/MaybeArg
What changed, and why it matters
This commit is a routine code cleanup in Bitcoin Core's RPC (remote procedure call) handling. It replaces some uses of std::string with std::string_view to avoid unnecessary string copying and modernize the API. There is no security-relevant change here—no bug fix, no vulnerability patch, and no behavior change visible to users.
No action required. This is a non-security refactoring commit. Reviewers may verify that the explicit std::string conversions preserve previous behavior and that no new lifetime issues are introduced by string_view usage.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors RPCHelpMan::Arg/MaybeArg helpers to return std::string_view instead of const std::string& or const std::string*. It updates call sites in RPC, wallet, net, descriptor parsing, and tests to use string_view, and adjusts helper logic to treat trivially-copyable types as by-value returns. A few call sites explicitly construct std::string when the underlying API still requires ownership. The diff is purely a C++ interface modernization with no semantic changes to validation, parsing, or consensus logic.
Changed components
src/rpc/util.hsrc/rpc/util.cppsrc/rpc/blockchain.cppsrc/rpc/mining.cppsrc/rpc/net.cppsrc/rpc/signmessage.cppsrc/wallet/rpc/util.hsrc/wallet/rpc/util.cppsrc/wallet/rpc/coins.cppsrc/wallet/rpc/wallet.cppsrc/net.cppsrc/net.hsrc/script/descriptor.cppsrc/script/descriptor.hsrc/util/fs.hInspect captured patch +51 / −46
diff --git a/src/bench/descriptors.cpp b/src/bench/descriptors.cpp
index c4545664..ac5580a4 100644
--- a/src/bench/descriptors.cpp
+++ b/src/bench/descriptors.cpp
@@ -12,6 +12,7 @@
#include <cstdint>
#include <memory>
#include <string>
+#include <string_view>
#include <utility>
#include <vector>
@@ -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<int64_t, int64_t> range = {0, 1000};
FlatSigningProvider provider;
std::string error;
diff --git a/src/net.cpp b/src/net.cpp
index 584b4280..066acc84 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -39,11 +39,12 @@
#include <algorithm>
#include <array>
-#include <cstring>
#include <cmath>
#include <cstdint>
+#include <cstring>
#include <functional>
#include <optional>
+#include <string_view>
#include <unordered_map>
TRACEPOINT_SEMAPHORE(net, closed_connection);
@@ -3562,11 +3563,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;
}
diff --git a/src/net.h b/src/net.h
index 92aabae6..2b606cbe 100644
--- a/src/net.h
+++ b/src/net.h
@@ -43,6 +43,7 @@
#include <memory>
#include <optional>
#include <queue>
+#include <string_view>
#include <thread>
#include <unordered_set>
#include <vector>
@@ -1222,7 +1223,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<AddedNodeInfo> GetAddedNodeInfo(bool include_connected) const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 4ef863a4..e960a5ed 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -60,6 +60,7 @@
#include <memory>
#include <mutex>
#include <optional>
+#include <string_view>
#include <vector>
using kernel::CCoinsStats;
@@ -2319,7 +2320,7 @@ static RPCHelpMan scantxoutset()
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
UniValue result(UniValue::VOBJ);
- const auto action{self.Arg<std::string>("action")};
+ const auto action{self.Arg<std::string_view>("action")};
if (action == "status") {
CoinsViewScanReserver reserver;
if (reserver.reserve()) {
@@ -3055,7 +3056,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<std::string>("type")};
+ const auto snapshot_type{self.Arg<std::string_view>("type")};
const UniValue options{request.params[2].isNull() ? UniValue::VOBJ : request.params[2]};
if (options.exists("rollback")) {
if (!snapshot_type.empty() && snapshot_type != "rollback") {
@@ -3346,7 +3347,7 @@ static RPCHelpMan loadtxoutset()
{
NodeContext& node = EnsureAnyNodeContext(request.context);
ChainstateManager& chainman = EnsureChainman(node);
- const fs::path path{AbsPathForConfigVal(EnsureArgsman(node), fs::u8path(self.Arg<std::string>("path")))};
+ const fs::path path{AbsPathForConfigVal(EnsureArgsman(node), fs::u8path(self.Arg<std::string_view>("path")))};
FILE* file{fsbridge::fopen(path, "rb")};
AutoFile afile{file};
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 850cdb70..2639b916 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<std::string>("descriptor"), coinbase_output_script, error)) {
+ if (!getScriptFromDescriptor(self.Arg<std::string_view>("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 da01a60b..4c88caca 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -333,7 +333,7 @@ static RPCHelpMan addnode()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- const auto command{self.Arg<std::string>("command")};
+ const auto command{self.Arg<std::string_view>("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<std::string>("node")};
+ const auto node_arg{self.Arg<std::string_view>("node")};
bool node_v2transport = connman.GetLocalServices() & NODE_P2P_V2;
bool use_v2transport = self.MaybeArg<bool>("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");
}
}
diff --git a/src/rpc/signmessage.cpp b/src/rpc/signmessage.cpp
index 5597f8d2..a3fb0bbf 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<std::string>("address");
- std::string strSign = self.Arg<std::string>("signature");
- std::string strMessage = self.Arg<std::string>("message");
-
- switch (MessageVerify(strAddress, strSign, strMessage)) {
+ switch (MessageVerify(std::string{self.Arg<std::string_view>("address")},
+ std::string{self.Arg<std::string_view>("signature")},
+ std::string{self.Arg<std::string_view>("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 0604dec2..dbe90d93 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -724,7 +724,7 @@ static void CheckRequiredOrDefault(const RPCArg& param)
TMPL_INST(nullptr, const UniValue*, maybe_arg;);
TMPL_INST(nullptr, std::optional<double>, maybe_arg ? std::optional{maybe_arg->get_real()} : std::nullopt;);
TMPL_INST(nullptr, std::optional<bool>, 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<std::string_view>, maybe_arg ? std::optional<std::string_view>{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 +732,7 @@ TMPL_INST(CheckRequiredOrDefault, bool, CHECK_NONFATAL(maybe_arg)->get_bool(););
TMPL_INST(CheckRequiredOrDefault, int, CHECK_NONFATAL(maybe_arg)->getInt<int>(););
TMPL_INST(CheckRequiredOrDefault, uint64_t, CHECK_NONFATAL(maybe_arg)->getInt<uint64_t>(););
TMPL_INST(CheckRequiredOrDefault, uint32_t, CHECK_NONFATAL(maybe_arg)->getInt<uint32_t>(););
-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 1650d2da..f82ccbf8 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<R> || std::is_floating_point_v<R>) {
- // Return numbers by value.
+ if constexpr (std::is_trivially_copyable_v<R>) {
+ // Return trivially copyable types by value.
return ArgValue<R>(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<R> is returned.
+ * @return For trivially copyable types, a std::optional<R> 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<R> || std::is_floating_point_v<R>) {
- // Return numbers by value, wrapped in optional.
+ if constexpr (std::is_trivially_copyable_v<R>) {
+ // Return trivially copyable types by value, wrapped in optional.
return ArgValue<std::optional<R>>(i);
} else {
// Return other types by pointer.
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index bd819d36..787c568e 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -2735,13 +2735,12 @@ bool CheckChecksum(std::span<const char>& sp, bool require_checksum, std::string
return true;
}
-std::vector<std::unique_ptr<Descriptor>> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
+std::vector<std::unique_ptr<Descriptor>> Parse(std::span<const char> descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
{
- std::span<const char> 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<std::unique_ptr<Descriptor>> descs;
descs.reserve(ret.size());
for (auto& r : ret) {
diff --git a/src/script/descriptor.h b/src/script/descriptor.h
index 473649a3..9a018300 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<std::unique_ptr<Descriptor>> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum = false);
+std::vector<std::unique_ptr<Descriptor>> Parse(std::span<const char> 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 87303d74..4baedb68 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -14,6 +14,7 @@
#include <util/time.h>
#include <any>
+#include <string_view>
#include <boost/test/unit_test.hpp>
@@ -618,9 +619,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<int>("req_int"), request.params[0].getInt<int>());
- BOOST_CHECK_EQUAL(self.Arg<std::string>("req_str"), request.params[1].get_str());
+ BOOST_CHECK_EQUAL(self.Arg<std::string_view>("req_str"), request.params[1].get_str());
BOOST_CHECK_EQUAL(self.Arg<uint64_t>("def_uint64_t"), request.params[2].isNull() ? DEFAULT_UINT64_T : request.params[2].getInt<uint64_t>());
- BOOST_CHECK_EQUAL(self.Arg<std::string>("def_string"), request.params[3].isNull() ? DEFAULT_STRING : request.params[3].get_str());
+ BOOST_CHECK_EQUAL(self.Arg<std::string_view>("def_string"), request.params[3].isNull() ? DEFAULT_STRING : request.params[3].get_str());
BOOST_CHECK_EQUAL(self.Arg<bool>("def_bool"), request.params[4].isNull() ? DEFAULT_BOOL : request.params[4].get_bool());
if (!request.params[5].isNull()) {
BOOST_CHECK_EQUAL(self.MaybeArg<double>("opt_double").value(), request.params[5].get_real());
@@ -628,10 +629,9 @@ BOOST_AUTO_TEST_CASE(rpc_arg_helper)
BOOST_CHECK(!self.MaybeArg<double>("opt_double"));
}
if (!request.params[6].isNull()) {
- BOOST_CHECK(self.MaybeArg<std::string>("opt_string"));
- BOOST_CHECK_EQUAL(*self.MaybeArg<std::string>("opt_string"), request.params[6].get_str());
+ BOOST_CHECK_EQUAL(self.MaybeArg<std::string_view>("opt_string"), request.params[6].get_str());
} else {
- BOOST_CHECK(!self.MaybeArg<std::string>("opt_string"));
+ BOOST_CHECK(!self.MaybeArg<std::string_view>("opt_string"));
}
return UniValue{};
};
diff --git a/src/util/fs.h b/src/util/fs.h
index 7c313e20..ced5914e 100644
--- a/src/util/fs.h
+++ b/src/util/fs.h
@@ -14,6 +14,7 @@
#include <ios>
#include <ostream>
#include <string>
+#include <string_view>
#include <system_error>
#include <type_traits>
#include <utility>
@@ -72,7 +73,7 @@ public:
path filename() const { return std::filesystem::path::filename(); }
};
-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 4aef0dda..7aeb60f7 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<std::string>("dummy")};
- if (dummy_value && *dummy_value != "*") {
+ if (self.MaybeArg<std::string_view>("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 79703985..d68e6c65 100644
--- a/src/wallet/rpc/util.cpp
+++ b/src/wallet/rpc/util.cpp
@@ -11,6 +11,7 @@
#include <wallet/context.h>
#include <wallet/wallet.h>
+#include <optional>
#include <string_view>
#include <univalue.h>
@@ -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<std::string_view> 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 0c586be4..d6497214 100644
--- a/src/wallet/rpc/util.h
+++ b/src/wallet/rpc/util.h
@@ -11,7 +11,9 @@
#include <any>
#include <memory>
+#include <optional>
#include <string>
+#include <string_view>
#include <vector>
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<std::string_view> 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 8e1cec55..3d45c160 100644
--- a/src/wallet/rpc/wallet.cpp
+++ b/src/wallet/rpc/wallet.cpp
@@ -19,6 +19,7 @@
#include <wallet/walletutil.h>
#include <optional>
+#include <string_view>
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<std::string>("wallet_name"))};
+ const std::string wallet_name{EnsureUniqueWalletName(request, self.MaybeArg<std::string_view>("wallet_name"))};
WalletContext& context = EnsureWalletContext(request.context);
std::shared_ptr<CWallet> 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<std::string>("wallet_name"))};
+ const std::string wallet_name{EnsureUniqueWalletName(request, self.MaybeArg<std::string_view>("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 fb33d366..8bf5eab4 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<std
{
JSONRPCRequest req;
req.URI = endpoint;
- return EnsureUniqueWalletName(req, parameter ? &*parameter : nullptr);
+ return EnsureUniqueWalletName(req, parameter);
}
BOOST_FIXTURE_TEST_SUITE(wallet_rpc_tests, BasicTestingSetup)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.