Merge bitcoin/bitcoin#32983: rpc: refactor: use string_view in Arg/MaybeArg
b63428ac9crpc: refactor: use more (Maybe)Arg<std::string_view> (stickies-v)037830ca0drefactor: increase string_view usage (stickies-v)b3bf18f0barpc: refactor: use string_view in Arg/MaybeArg (stickies-v) Pull request description: The `RPCHelpMan::{Arg,MaybeArg}` helpers avoid copying (potentially) large strings by returning them as `const std::string*` (`MaybeArg`) or `const std::string&` (`Arg`). For `MaybeArg`, this has the not-so-nice effect that users need to deal with raw pointers, potentially also requiring new functions (e.g. [`EnsureUniqueWalletName` ](https://github.com/bitcoin/bitcoin/pull/32845/commits/d127b25199118756122232d9aafff19f1922869b#diff-d8bfcfbdd5fa7d5c52d38c1fe5eeac9ce5c5a794cdfaf683585140fa70a32374R32)) with raw pointers being implemented. This PR aims to improve on this by returning a trivially copyable `std::string_view` (`Arg`) or `std::optional<std::string_view>` (`MaybeArg`), modernizing the interface without introducing any additional copying overhead. In doing so, it also generalizes whether we return by value or by pointer/reference using `std::is_trivially_copyable_v` instead of defining the types manually. In cases where functions currently take a `const std::string&` and it would be too much work / touching consensus logic to update them (`signmessage.cpp`), a `std::string` copy is made (which was already happening anyway). The last 2 commits increase usage of the `{Arg,MaybeArg}<std::string_view>` helpers, and could be dropped/pruned if anything turns out to be controversial - I just think it's a nice little cleanup. ACKs for top commit: maflcko: re-ACKb63428ac9c🎉 achow101: ACKb63428ac9cpablomartin4btc: re-ACK [b63428a](https://github.com/bitcoin/bitcoin/commit/b63428ac9ce2c903670409b3e47b9f6730917ae8) w0xlt: reACK https://github.com/bitcoin/bitcoin/pull/32983/commits/b63428ac9ce2c903670409b3e47b9f6730917ae8 Tree-SHA512: b4942c353a1658c22a88d8c9b402c288ad35265a3b88aa2072b1f9b6d921cd073194ed4b00b807cb48ca440f47c87ef3d8e0dd1a5d814be58fc7743f26288277
This commit is contained in:
32 files changed
+148
-150
No files matched your search
@@ -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;
|
||||
|
||||
+3
-1
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
|
||||
#include <blockfilter.h>
|
||||
#include <crypto/siphash.h>
|
||||
@@ -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;
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@
|
||||
#include <ios>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -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<BlockFilterType>& AllBlockFilterTypes();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define BITCOIN_COMMON_MESSAGES_H
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
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<std::string, FeeEstimateMode>& mode);
|
||||
|
||||
+6
-5
@@ -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);
|
||||
@@ -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<CNodeStats>& 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; });
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <queue>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
@@ -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<AddedNodeInfo> GetAddedNodeInfo(bool include_connected) const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
|
||||
|
||||
@@ -1271,7 +1272,7 @@ public:
|
||||
std::map<CNetAddr, LocalServiceInfo> getNetLocalAddresses() const;
|
||||
uint32_t GetMappedAS(const CNetAddr& addr) const;
|
||||
void GetNodeStats(std::vector<CNodeStats>& 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.
|
||||
|
||||
+8
-12
@@ -18,6 +18,7 @@
|
||||
#include <cstdint>
|
||||
#include <ios>
|
||||
#include <iterator>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
|
||||
using util::ContainsNoNUL;
|
||||
@@ -208,7 +209,7 @@ static void Checksum(std::span<const uint8_t> 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);
|
||||
|
||||
|
||||
+4
-3
@@ -18,6 +18,7 @@
|
||||
#include <cstdint>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
@@ -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).
|
||||
|
||||
+1
-1
@@ -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<OutputType> ParseOutputType(const std::string& type)
|
||||
std::optional<OutputType> ParseOutputType(std::string_view type)
|
||||
{
|
||||
if (type == OUTPUT_TYPE_STRING_LEGACY) {
|
||||
return OutputType::LEGACY;
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
enum class OutputType {
|
||||
@@ -29,7 +30,7 @@ static constexpr auto OUTPUT_TYPES = std::array{
|
||||
OutputType::BECH32M,
|
||||
};
|
||||
|
||||
std::optional<OutputType> ParseOutputType(const std::string& str);
|
||||
std::optional<OutputType> ParseOutputType(std::string_view str);
|
||||
const std::string& FormatOutputType(OutputType type);
|
||||
std::string FormatAllOutputTypes();
|
||||
|
||||
|
||||
+20
-20
@@ -40,6 +40,7 @@
|
||||
#include <serialize.h>
|
||||
#include <streams.h>
|
||||
#include <sync.h>
|
||||
#include <tinyformat.h>
|
||||
#include <txdb.h>
|
||||
#include <txmempool.h>
|
||||
#include <undo.h>
|
||||
@@ -60,6 +61,8 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
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<std::string_view>("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<std::string>("action")};
|
||||
const auto action{self.Arg<std::string_view>("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<std::string_view>("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<std::string_view>("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<std::string_view>("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<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") {
|
||||
@@ -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<std::string_view>("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<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};
|
||||
|
||||
+5
-7
@@ -21,6 +21,7 @@
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
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<std::string_view>("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()};
|
||||
|
||||
+2
-1
@@ -28,6 +28,7 @@
|
||||
#include <util/time.h>
|
||||
#include <util/vector.h>
|
||||
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
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<std::string_view>("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"]};
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+27
-34
@@ -36,11 +36,11 @@
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
using node::NodeContext;
|
||||
using util::Join;
|
||||
using util::TrimString;
|
||||
|
||||
const std::vector<std::string> 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<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");
|
||||
}
|
||||
}
|
||||
@@ -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<std::string_view>("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<std::string_view>("address")};
|
||||
auto node_id{self.MaybeArg<int64_t>("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<int64_t>();
|
||||
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<AddedNodeInfo> vInfo = connman.GetAddedNodeInfo(/*include_connected=*/true);
|
||||
|
||||
if (!request.params[0].isNull()) {
|
||||
if (auto node{self.MaybeArg<std::string_view>("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<std::string_view>("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<std::string_view>("subnet")};
|
||||
const bool isSubnet{subnet_arg.find('/') != subnet_arg.npos};
|
||||
|
||||
if (!isSubnet) {
|
||||
const std::optional<CNetAddr> addr{LookupHost(request.params[0].get_str(), false)};
|
||||
const std::optional<CNetAddr> addr{LookupHost(subnet_arg, false)};
|
||||
if (addr.has_value()) {
|
||||
netAddr = static_cast<CNetAddr>(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<int64_t>()};
|
||||
const std::string& msg_type{request.params[1].get_str()};
|
||||
const auto msg_type{self.Arg<std::string_view>("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<unsigned char>(request.params[2].get_str())};
|
||||
auto msg{TryParseHex<unsigned char>(self.Arg<std::string_view>("msg"))};
|
||||
if (!msg.has_value()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Error parsing input for msg");
|
||||
}
|
||||
|
||||
+5
-3
@@ -21,6 +21,7 @@
|
||||
#include <rpc/server_util.h>
|
||||
#include <rpc/util.h>
|
||||
#include <scheduler.h>
|
||||
#include <tinyformat.h>
|
||||
#include <univalue.h>
|
||||
#include <util/any.h>
|
||||
#include <util/check.h>
|
||||
@@ -30,6 +31,7 @@
|
||||
#ifdef HAVE_MALLOC_INFO
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <string_view>
|
||||
|
||||
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<std::string_view>("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<std::string_view>("index_name").value_or("")};
|
||||
|
||||
if (g_txindex) {
|
||||
result.pushKVs(SummaryToJSON(g_txindex->GetSummary(), index_name));
|
||||
|
||||
+11
-13
@@ -22,6 +22,7 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
@@ -130,20 +131,17 @@ static RPCHelpMan createmultisig()
|
||||
}
|
||||
|
||||
// Get the output type
|
||||
OutputType output_type = OutputType::LEGACY;
|
||||
if (!request.params[2].isNull()) {
|
||||
std::optional<OutputType> 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<std::string_view>("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> 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<std::string_view>("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<std::string_view>("descriptor")};
|
||||
|
||||
int64_t range_begin = 0;
|
||||
int64_t range_end = 0;
|
||||
|
||||
+5
-7
@@ -26,6 +26,7 @@
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
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<std::string_view>("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);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ private:
|
||||
std::map<std::string, std::vector<const CRPCCommand*>> 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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
+3
-2
@@ -724,7 +724,8 @@ 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<int64_t>, maybe_arg ? std::optional{maybe_arg->getInt<int64_t>()} : std::nullopt;);
|
||||
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 +733,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
|
||||
{
|
||||
|
||||
+5
-5
@@ -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.
|
||||
|
||||
@@ -2730,13 +2730,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) {
|
||||
|
||||
@@ -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`.
|
||||
*
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <util/time.h>
|
||||
|
||||
#include <any>
|
||||
#include <string_view>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -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<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());
|
||||
@@ -631,10 +632,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{};
|
||||
};
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@
|
||||
#include <ios>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@@ -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()});
|
||||
}
|
||||
|
||||
@@ -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 \"*\".");
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user