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
+145
-147
No files matched your search
@@ -12,6 +12,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ static void ExpandDescriptor(benchmark::Bench& bench)
|
|||||||
{
|
{
|
||||||
ECC_Context ecc_context{};
|
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};
|
const std::pair<int64_t, int64_t> range = {0, 1000};
|
||||||
FlatSigningProvider provider;
|
FlatSigningProvider provider;
|
||||||
std::string error;
|
std::string error;
|
||||||
|
|||||||
+3
-1
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include <blockfilter.h>
|
#include <blockfilter.h>
|
||||||
#include <crypto/siphash.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;
|
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) {
|
for (const auto& entry : g_filter_types) {
|
||||||
if (entry.second == name) {
|
if (entry.second == name) {
|
||||||
filter_type = entry.first;
|
filter_type = entry.first;
|
||||||
|
|||||||
+2
-1
@@ -10,6 +10,7 @@
|
|||||||
#include <ios>
|
#include <ios>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -99,7 +100,7 @@ enum class BlockFilterType : uint8_t
|
|||||||
const std::string& BlockFilterTypeName(BlockFilterType filter_type);
|
const std::string& BlockFilterTypeName(BlockFilterType filter_type);
|
||||||
|
|
||||||
/** Find a filter type by its human-readable name. */
|
/** 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. */
|
/** Get a list of known filter types. */
|
||||||
const std::set<BlockFilterType>& AllBlockFilterTypes();
|
const std::set<BlockFilterType>& AllBlockFilterTypes();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ std::string InvalidEstimateModeErrorMessage()
|
|||||||
return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\"";
|
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);
|
auto searchkey = ToUpper(mode_string);
|
||||||
for (const auto& pair : FeeModeMap()) {
|
for (const auto& pair : FeeModeMap()) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#define BITCOIN_COMMON_MESSAGES_H
|
#define BITCOIN_COMMON_MESSAGES_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
struct bilingual_str;
|
struct bilingual_str;
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ enum class TransactionError;
|
|||||||
|
|
||||||
namespace common {
|
namespace common {
|
||||||
enum class PSBTError;
|
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 StringForFeeReason(FeeReason reason);
|
||||||
std::string FeeModes(const std::string& delimiter);
|
std::string FeeModes(const std::string& delimiter);
|
||||||
std::string FeeModeInfo(std::pair<std::string, FeeEstimateMode>& mode);
|
std::string FeeModeInfo(std::pair<std::string, FeeEstimateMode>& mode);
|
||||||
|
|||||||
+6
-5
@@ -39,11 +39,12 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstring>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
TRACEPOINT_SEMAPHORE(net, closed_connection);
|
TRACEPOINT_SEMAPHORE(net, closed_connection);
|
||||||
@@ -331,7 +332,7 @@ bool IsLocal(const CService& addr)
|
|||||||
return mapLocalHost.count(addr) > 0;
|
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);
|
LOCK(m_nodes_mutex);
|
||||||
return std::ranges::any_of(m_nodes, [&host](CNode* node) { return node->m_addr_name == host; });
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CConnman::RemoveAddedNode(const std::string& strNode)
|
bool CConnman::RemoveAddedNode(std::string_view node)
|
||||||
{
|
{
|
||||||
LOCK(m_added_nodes_mutex);
|
LOCK(m_added_nodes_mutex);
|
||||||
for (auto it = m_added_node_params.begin(); it != m_added_node_params.end(); ++it) {
|
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);
|
m_added_node_params.erase(it);
|
||||||
return true;
|
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);
|
LOCK(m_nodes_mutex);
|
||||||
auto it = std::ranges::find_if(m_nodes, [&strNode](CNode* node) { return node->m_addr_name == strNode; });
|
auto it = std::ranges::find_if(m_nodes, [&strNode](CNode* node) { return node->m_addr_name == strNode; });
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <string_view>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -1248,7 +1249,7 @@ public:
|
|||||||
int GetExtraBlockRelayCount() const;
|
int GetExtraBlockRelayCount() const;
|
||||||
|
|
||||||
bool AddNode(const AddedNodeParams& add) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
|
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);
|
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);
|
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;
|
std::map<CNetAddr, LocalServiceInfo> getNetLocalAddresses() const;
|
||||||
uint32_t GetMappedAS(const CNetAddr& addr) const;
|
uint32_t GetMappedAS(const CNetAddr& addr) const;
|
||||||
void GetNodeStats(std::vector<CNodeStats>& vstats) 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 CSubNet& subnet);
|
||||||
bool DisconnectNode(const CNetAddr& addr);
|
bool DisconnectNode(const CNetAddr& addr);
|
||||||
bool DisconnectNode(NodeId id);
|
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".
|
* @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`.
|
* @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.
|
* Determine whether we're already connected to a given address:port.
|
||||||
|
|||||||
+8
-12
@@ -18,6 +18,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <string_view>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
using util::ContainsNoNUL;
|
using util::ContainsNoNUL;
|
||||||
@@ -208,7 +209,7 @@ static void Checksum(std::span<const uint8_t> addr_pubkey, uint8_t (&checksum)[C
|
|||||||
|
|
||||||
}; // namespace torv3
|
}; // namespace torv3
|
||||||
|
|
||||||
bool CNetAddr::SetSpecial(const std::string& addr)
|
bool CNetAddr::SetSpecial(std::string_view addr)
|
||||||
{
|
{
|
||||||
if (!ContainsNoNUL(addr)) {
|
if (!ContainsNoNUL(addr)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -225,16 +226,11 @@ bool CNetAddr::SetSpecial(const std::string& addr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNetAddr::SetTor(const std::string& addr)
|
bool CNetAddr::SetTor(std::string_view addr)
|
||||||
{
|
{
|
||||||
static const char* suffix{".onion"};
|
if (!addr.ends_with(".onion")) return false;
|
||||||
static constexpr size_t suffix_len{6};
|
addr.remove_suffix(6);
|
||||||
|
auto input = DecodeBase32(addr);
|
||||||
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 (!input) {
|
if (!input) {
|
||||||
return false;
|
return false;
|
||||||
@@ -264,7 +260,7 @@ bool CNetAddr::SetTor(const std::string& addr)
|
|||||||
return false;
|
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".
|
// I2P addresses that we support consist of 52 base32 characters + ".b32.i2p".
|
||||||
static constexpr size_t b32_len{52};
|
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()
|
// Remove the ".b32.i2p" suffix and pad to a multiple of 8 chars, so DecodeBase32()
|
||||||
// can decode it.
|
// 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);
|
auto address_bytes = DecodeBase32(b32_padded);
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -18,6 +18,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -151,7 +152,7 @@ public:
|
|||||||
* @returns Whether the operation was successful.
|
* @returns Whether the operation was successful.
|
||||||
* @see CNetAddr::IsTor(), CNetAddr::IsI2P()
|
* @see CNetAddr::IsTor(), CNetAddr::IsI2P()
|
||||||
*/
|
*/
|
||||||
bool SetSpecial(const std::string& addr);
|
bool SetSpecial(std::string_view addr);
|
||||||
|
|
||||||
bool IsBindAny() const; // INADDR_ANY equivalent
|
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)
|
[[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.
|
* @returns Whether the operation was successful.
|
||||||
* @see CNetAddr::IsTor()
|
* @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.
|
* Parse an I2P address and set this object to it.
|
||||||
@@ -288,7 +289,7 @@ private:
|
|||||||
* @returns Whether the operation was successful.
|
* @returns Whether the operation was successful.
|
||||||
* @see CNetAddr::IsI2P()
|
* @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).
|
* 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_BECH32M = "bech32m";
|
||||||
static const std::string OUTPUT_TYPE_STRING_UNKNOWN = "unknown";
|
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) {
|
if (type == OUTPUT_TYPE_STRING_LEGACY) {
|
||||||
return OutputType::LEGACY;
|
return OutputType::LEGACY;
|
||||||
|
|||||||
+2
-1
@@ -12,6 +12,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
enum class OutputType {
|
enum class OutputType {
|
||||||
@@ -29,7 +30,7 @@ static constexpr auto OUTPUT_TYPES = std::array{
|
|||||||
OutputType::BECH32M,
|
OutputType::BECH32M,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::optional<OutputType> ParseOutputType(const std::string& str);
|
std::optional<OutputType> ParseOutputType(std::string_view str);
|
||||||
const std::string& FormatOutputType(OutputType type);
|
const std::string& FormatOutputType(OutputType type);
|
||||||
std::string FormatAllOutputTypes();
|
std::string FormatAllOutputTypes();
|
||||||
|
|
||||||
|
|||||||
+20
-20
@@ -40,6 +40,7 @@
|
|||||||
#include <serialize.h>
|
#include <serialize.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
#include <sync.h>
|
#include <sync.h>
|
||||||
|
#include <tinyformat.h>
|
||||||
#include <txdb.h>
|
#include <txdb.h>
|
||||||
#include <txmempool.h>
|
#include <txmempool.h>
|
||||||
#include <undo.h>
|
#include <undo.h>
|
||||||
@@ -60,6 +61,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using kernel::CCoinsStats;
|
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") {
|
if (hash_type_input == "hash_serialized_3") {
|
||||||
return CoinStatsHashType::HASH_SERIALIZED;
|
return CoinStatsHashType::HASH_SERIALIZED;
|
||||||
@@ -1038,7 +1041,7 @@ static RPCHelpMan gettxoutsetinfo()
|
|||||||
UniValue ret(UniValue::VOBJ);
|
UniValue ret(UniValue::VOBJ);
|
||||||
|
|
||||||
const CBlockIndex* pindex{nullptr};
|
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();
|
bool index_requested = request.params[2].isNull() || request.params[2].get_bool();
|
||||||
|
|
||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
@@ -2328,7 +2331,7 @@ static RPCHelpMan scantxoutset()
|
|||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
const auto action{self.Arg<std::string>("action")};
|
const auto action{self.Arg<std::string_view>("action")};
|
||||||
if (action == "status") {
|
if (action == "status") {
|
||||||
CoinsViewScanReserver reserver;
|
CoinsViewScanReserver reserver;
|
||||||
if (reserver.reserve()) {
|
if (reserver.reserve()) {
|
||||||
@@ -2524,7 +2527,8 @@ static RPCHelpMan scanblocks()
|
|||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
UniValue ret(UniValue::VOBJ);
|
UniValue ret(UniValue::VOBJ);
|
||||||
if (request.params[0].get_str() == "status") {
|
auto action{self.Arg<std::string_view>("action")};
|
||||||
|
if (action == "status") {
|
||||||
BlockFiltersScanReserver reserver;
|
BlockFiltersScanReserver reserver;
|
||||||
if (reserver.reserve()) {
|
if (reserver.reserve()) {
|
||||||
// no scan in progress
|
// no scan in progress
|
||||||
@@ -2533,7 +2537,7 @@ static RPCHelpMan scanblocks()
|
|||||||
ret.pushKV("progress", g_scanfilter_progress.load());
|
ret.pushKV("progress", g_scanfilter_progress.load());
|
||||||
ret.pushKV("current_height", g_scanfilter_progress_height.load());
|
ret.pushKV("current_height", g_scanfilter_progress_height.load());
|
||||||
return ret;
|
return ret;
|
||||||
} else if (request.params[0].get_str() == "abort") {
|
} else if (action == "abort") {
|
||||||
BlockFiltersScanReserver reserver;
|
BlockFiltersScanReserver reserver;
|
||||||
if (reserver.reserve()) {
|
if (reserver.reserve()) {
|
||||||
// reserve was possible which means no scan was running
|
// reserve was possible which means no scan was running
|
||||||
@@ -2542,12 +2546,12 @@ static RPCHelpMan scanblocks()
|
|||||||
// set the abort flag
|
// set the abort flag
|
||||||
g_scanfilter_should_abort_scan = true;
|
g_scanfilter_should_abort_scan = true;
|
||||||
return true;
|
return true;
|
||||||
} else if (request.params[0].get_str() == "start") {
|
} else if (action == "start") {
|
||||||
BlockFiltersScanReserver reserver;
|
BlockFiltersScanReserver reserver;
|
||||||
if (!reserver.reserve()) {
|
if (!reserver.reserve()) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan already in progress, use action \"abort\" or \"status\"");
|
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;
|
BlockFilterType filtertype;
|
||||||
if (!BlockFilterTypeByName(filtertype_name, filtertype)) {
|
if (!BlockFilterTypeByName(filtertype_name, filtertype)) {
|
||||||
@@ -2559,7 +2563,7 @@ static RPCHelpMan scanblocks()
|
|||||||
|
|
||||||
BlockFilterIndex* index = GetBlockFilterIndex(filtertype);
|
BlockFilterIndex* index = GetBlockFilterIndex(filtertype);
|
||||||
if (!index) {
|
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);
|
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("to_height", start_index->nHeight); // start_index is always the last scanned block here
|
||||||
ret.pushKV("relevant_blocks", std::move(blocks));
|
ret.pushKV("relevant_blocks", std::move(blocks));
|
||||||
ret.pushKV("completed", completed);
|
ret.pushKV("completed", completed);
|
||||||
}
|
} else {
|
||||||
else {
|
throw JSONRPCError(RPC_INVALID_PARAMETER, tfm::format("Invalid action '%s'", action));
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid action '%s'", request.params[0].get_str()));
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
@@ -2925,10 +2928,7 @@ static RPCHelpMan getblockfilter()
|
|||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
uint256 block_hash = ParseHashV(request.params[0], "blockhash");
|
uint256 block_hash = ParseHashV(request.params[0], "blockhash");
|
||||||
std::string filtertype_name = BlockFilterTypeName(BlockFilterType::BASIC);
|
auto filtertype_name{self.Arg<std::string_view>("filtertype")};
|
||||||
if (!request.params[1].isNull()) {
|
|
||||||
filtertype_name = request.params[1].get_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockFilterType filtertype;
|
BlockFilterType filtertype;
|
||||||
if (!BlockFilterTypeByName(filtertype_name, filtertype)) {
|
if (!BlockFilterTypeByName(filtertype_name, filtertype)) {
|
||||||
@@ -2937,7 +2937,7 @@ static RPCHelpMan getblockfilter()
|
|||||||
|
|
||||||
BlockFilterIndex* index = GetBlockFilterIndex(filtertype);
|
BlockFilterIndex* index = GetBlockFilterIndex(filtertype);
|
||||||
if (!index) {
|
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;
|
const CBlockIndex* block_index;
|
||||||
@@ -3064,7 +3064,7 @@ static RPCHelpMan dumptxoutset()
|
|||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
const CBlockIndex* tip{WITH_LOCK(::cs_main, return node.chainman->ActiveChain().Tip())};
|
const CBlockIndex* tip{WITH_LOCK(::cs_main, return node.chainman->ActiveChain().Tip())};
|
||||||
const CBlockIndex* target_index{nullptr};
|
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]};
|
const UniValue options{request.params[2].isNull() ? UniValue::VOBJ : request.params[2]};
|
||||||
if (options.exists("rollback")) {
|
if (options.exists("rollback")) {
|
||||||
if (!snapshot_type.empty() && snapshot_type != "rollback") {
|
if (!snapshot_type.empty() && snapshot_type != "rollback") {
|
||||||
@@ -3083,10 +3083,10 @@ static RPCHelpMan dumptxoutset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ArgsManager& args{EnsureAnyArgsman(request.context)};
|
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
|
// Write to a temporary path and then move into `path` on completion
|
||||||
// to avoid confusion due to an interruption.
|
// 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)) {
|
if (fs::exists(path)) {
|
||||||
throw JSONRPCError(
|
throw JSONRPCError(
|
||||||
@@ -3355,7 +3355,7 @@ static RPCHelpMan loadtxoutset()
|
|||||||
{
|
{
|
||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
ChainstateManager& chainman = EnsureChainman(node);
|
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")};
|
FILE* file{fsbridge::fopen(path, "rb")};
|
||||||
AutoFile afile{file};
|
AutoFile afile{file};
|
||||||
|
|||||||
+3
-5
@@ -21,6 +21,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
using common::FeeModeFromString;
|
using common::FeeModeFromString;
|
||||||
using common::FeeModesDetail;
|
using common::FeeModesDetail;
|
||||||
@@ -67,18 +68,15 @@ static RPCHelpMan estimatesmartfee()
|
|||||||
CHECK_NONFATAL(mempool.m_opts.signals)->SyncWithValidationInterfaceQueue();
|
CHECK_NONFATAL(mempool.m_opts.signals)->SyncWithValidationInterfaceQueue();
|
||||||
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||||
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
||||||
bool conservative = false;
|
|
||||||
if (!request.params[1].isNull()) {
|
|
||||||
FeeEstimateMode fee_mode;
|
FeeEstimateMode fee_mode;
|
||||||
if (!FeeModeFromString(request.params[1].get_str(), fee_mode)) {
|
if (!FeeModeFromString(self.Arg<std::string_view>("estimate_mode"), fee_mode)) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage());
|
throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage());
|
||||||
}
|
}
|
||||||
if (fee_mode == FeeEstimateMode::CONSERVATIVE) conservative = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
UniValue errors(UniValue::VARR);
|
UniValue errors(UniValue::VARR);
|
||||||
FeeCalculation feeCalc;
|
FeeCalculation feeCalc;
|
||||||
|
bool conservative{fee_mode == FeeEstimateMode::CONSERVATIVE};
|
||||||
CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)};
|
CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)};
|
||||||
if (feeRate != CFeeRate(0)) {
|
if (feeRate != CFeeRate(0)) {
|
||||||
CFeeRate min_mempool_feerate{mempool.GetMinFee()};
|
CFeeRate min_mempool_feerate{mempool.GetMinFee()};
|
||||||
|
|||||||
+2
-1
@@ -28,6 +28,7 @@
|
|||||||
#include <util/time.h>
|
#include <util/time.h>
|
||||||
#include <util/vector.h>
|
#include <util/vector.h>
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using node::DumpMempool;
|
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.");
|
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& use_current_time{request.params[1]["use_current_time"]};
|
||||||
const UniValue& apply_fee_delta{request.params[1]["apply_fee_delta_priority"]};
|
const UniValue& apply_fee_delta{request.params[1]["apply_fee_delta_priority"]};
|
||||||
const UniValue& apply_unbroadcast{request.params[1]["apply_unbroadcast_set"]};
|
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;
|
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;
|
FlatSigningProvider key_provider;
|
||||||
const auto descs = Parse(descriptor, key_provider, error, /* require_checksum = */ false);
|
const auto descs = Parse(descriptor, key_provider, error, /* require_checksum = */ false);
|
||||||
@@ -241,7 +241,7 @@ static RPCHelpMan generatetodescriptor()
|
|||||||
|
|
||||||
CScript coinbase_output_script;
|
CScript coinbase_output_script;
|
||||||
std::string error;
|
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);
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-34
@@ -36,11 +36,11 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using node::NodeContext;
|
using node::NodeContext;
|
||||||
using util::Join;
|
using util::Join;
|
||||||
using util::TrimString;
|
|
||||||
|
|
||||||
const std::vector<std::string> CONNECTION_TYPE_DOC{
|
const std::vector<std::string> CONNECTION_TYPE_DOC{
|
||||||
"outbound-full-relay (default automatic connections)",
|
"outbound-full-relay (default automatic connections)",
|
||||||
@@ -333,7 +333,7 @@ static RPCHelpMan addnode()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](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") {
|
if (command != "onetry" && command != "add" && command != "remove") {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
self.ToString());
|
self.ToString());
|
||||||
@@ -342,7 +342,7 @@ static RPCHelpMan addnode()
|
|||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
CConnman& connman = EnsureConnman(node);
|
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 node_v2transport = connman.GetLocalServices() & NODE_P2P_V2;
|
||||||
bool use_v2transport = self.MaybeArg<bool>("v2transport").value_or(node_v2transport);
|
bool use_v2transport = self.MaybeArg<bool>("v2transport").value_or(node_v2transport);
|
||||||
|
|
||||||
@@ -353,13 +353,13 @@ static RPCHelpMan addnode()
|
|||||||
if (command == "onetry")
|
if (command == "onetry")
|
||||||
{
|
{
|
||||||
CAddress addr;
|
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;
|
return UniValue::VNULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == "add")
|
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");
|
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 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{};
|
ConnectionType conn_type{};
|
||||||
if (conn_type_in == "outbound-full-relay") {
|
if (conn_type_in == "outbound-full-relay") {
|
||||||
conn_type = ConnectionType::OUTBOUND_FULL_RELAY;
|
conn_type = ConnectionType::OUTBOUND_FULL_RELAY;
|
||||||
@@ -462,16 +462,15 @@ static RPCHelpMan disconnectnode()
|
|||||||
CConnman& connman = EnsureConnman(node);
|
CConnman& connman = EnsureConnman(node);
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
const UniValue &address_arg = request.params[0];
|
auto address{self.MaybeArg<std::string_view>("address")};
|
||||||
const UniValue &id_arg = request.params[1];
|
auto node_id{self.MaybeArg<int64_t>("nodeid")};
|
||||||
|
|
||||||
if (!address_arg.isNull() && id_arg.isNull()) {
|
if (address && !node_id) {
|
||||||
/* handle disconnect-by-address */
|
/* handle disconnect-by-address */
|
||||||
success = connman.DisconnectNode(address_arg.get_str());
|
success = connman.DisconnectNode(*address);
|
||||||
} else if (!id_arg.isNull() && (address_arg.isNull() || (address_arg.isStr() && address_arg.get_str().empty()))) {
|
} else if (node_id && (!address || address->empty())) {
|
||||||
/* handle disconnect-by-id */
|
/* handle disconnect-by-id */
|
||||||
NodeId nodeid = (NodeId) id_arg.getInt<int64_t>();
|
success = connman.DisconnectNode(*node_id);
|
||||||
success = connman.DisconnectNode(nodeid);
|
|
||||||
} else {
|
} else {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMS, "Only one of address and nodeid should be provided.");
|
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);
|
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;
|
bool found = false;
|
||||||
for (const AddedNodeInfo& info : vInfo) {
|
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);
|
vInfo.assign(1, info);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@@ -754,10 +753,8 @@ static RPCHelpMan setban()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& help, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& help, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
std::string strCommand;
|
auto command{help.Arg<std::string_view>("command")};
|
||||||
if (!request.params[1].isNull())
|
if (command != "add" && command != "remove") {
|
||||||
strCommand = request.params[1].get_str();
|
|
||||||
if (strCommand != "add" && strCommand != "remove") {
|
|
||||||
throw std::runtime_error(help.ToString());
|
throw std::runtime_error(help.ToString());
|
||||||
}
|
}
|
||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
@@ -765,25 +762,23 @@ static RPCHelpMan setban()
|
|||||||
|
|
||||||
CSubNet subNet;
|
CSubNet subNet;
|
||||||
CNetAddr netAddr;
|
CNetAddr netAddr;
|
||||||
bool isSubnet = false;
|
std::string subnet_arg{help.Arg<std::string_view>("subnet")};
|
||||||
|
const bool isSubnet{subnet_arg.find('/') != subnet_arg.npos};
|
||||||
if (request.params[0].get_str().find('/') != std::string::npos)
|
|
||||||
isSubnet = true;
|
|
||||||
|
|
||||||
if (!isSubnet) {
|
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()) {
|
if (addr.has_value()) {
|
||||||
netAddr = static_cast<CNetAddr>(MaybeFlipIPv6toCJDNS(CService{addr.value(), /*port=*/0}));
|
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");
|
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)) {
|
if (isSubnet ? banman.IsBanned(subNet) : banman.IsBanned(netAddr)) {
|
||||||
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
|
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
|
||||||
}
|
}
|
||||||
@@ -809,9 +804,7 @@ static RPCHelpMan setban()
|
|||||||
node.connman->DisconnectNode(netAddr);
|
node.connman->DisconnectNode(netAddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if(command == "remove") {
|
||||||
else if(strCommand == "remove")
|
|
||||||
{
|
|
||||||
if (!( isSubnet ? banman.Unban(subNet) : banman.Unban(netAddr) )) {
|
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.");
|
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\"")},
|
HelpExampleCli("sendmsgtopeer", "0 \"addr\" \"ffffff\"") + HelpExampleRpc("sendmsgtopeer", "0 \"addr\" \"ffffff\"")},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
|
||||||
const NodeId peer_id{request.params[0].getInt<int64_t>()};
|
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) {
|
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));
|
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()) {
|
if (!msg.has_value()) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Error parsing input for msg");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Error parsing input for msg");
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-3
@@ -21,6 +21,7 @@
|
|||||||
#include <rpc/server_util.h>
|
#include <rpc/server_util.h>
|
||||||
#include <rpc/util.h>
|
#include <rpc/util.h>
|
||||||
#include <scheduler.h>
|
#include <scheduler.h>
|
||||||
|
#include <tinyformat.h>
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
#include <util/any.h>
|
#include <util/any.h>
|
||||||
#include <util/check.h>
|
#include <util/check.h>
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
#ifdef HAVE_MALLOC_INFO
|
#ifdef HAVE_MALLOC_INFO
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
using node::NodeContext;
|
using node::NodeContext;
|
||||||
|
|
||||||
@@ -176,7 +178,7 @@ static RPCHelpMan getmemoryinfo()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](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") {
|
if (mode == "stats") {
|
||||||
UniValue obj(UniValue::VOBJ);
|
UniValue obj(UniValue::VOBJ);
|
||||||
obj.pushKV("locked", RPCLockedMemoryInfo());
|
obj.pushKV("locked", RPCLockedMemoryInfo());
|
||||||
@@ -188,7 +190,7 @@ static RPCHelpMan getmemoryinfo()
|
|||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "mallocinfo mode not available");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "mallocinfo mode not available");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} 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
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ);
|
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) {
|
if (g_txindex) {
|
||||||
result.pushKVs(SummaryToJSON(g_txindex->GetSummary(), index_name));
|
result.pushKVs(SummaryToJSON(g_txindex->GetSummary(), index_name));
|
||||||
|
|||||||
+10
-12
@@ -22,6 +22,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -130,20 +131,17 @@ static RPCHelpMan createmultisig()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the output type
|
// Get the output type
|
||||||
OutputType output_type = OutputType::LEGACY;
|
auto address_type{self.Arg<std::string_view>("address_type")};
|
||||||
if (!request.params[2].isNull()) {
|
auto output_type{ParseOutputType(address_type)};
|
||||||
std::optional<OutputType> parsed = ParseOutputType(request.params[2].get_str());
|
if (!output_type) {
|
||||||
if (!parsed) {
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, tfm::format("Unknown address type '%s'", address_type));
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[2].get_str()));
|
} else if (output_type.value() == OutputType::BECH32M) {
|
||||||
} else if (parsed.value() == OutputType::BECH32M) {
|
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "createmultisig cannot create bech32m multisig addresses");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "createmultisig cannot create bech32m multisig addresses");
|
||||||
}
|
}
|
||||||
output_type = parsed.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
FlatSigningProvider keystore;
|
FlatSigningProvider keystore;
|
||||||
CScript inner;
|
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
|
// Make the descriptor
|
||||||
std::unique_ptr<Descriptor> descriptor = InferDescriptor(GetScriptForDestination(dest), keystore);
|
std::unique_ptr<Descriptor> descriptor = InferDescriptor(GetScriptForDestination(dest), keystore);
|
||||||
@@ -154,7 +152,7 @@ static RPCHelpMan createmultisig()
|
|||||||
result.pushKV("descriptor", descriptor->ToString());
|
result.pushKV("descriptor", descriptor->ToString());
|
||||||
|
|
||||||
UniValue warnings(UniValue::VARR);
|
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
|
// 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.");
|
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;
|
FlatSigningProvider provider;
|
||||||
std::string error;
|
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()) {
|
if (descs.empty()) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
|
||||||
}
|
}
|
||||||
@@ -303,7 +301,7 @@ static RPCHelpMan deriveaddresses()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](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_begin = 0;
|
||||||
int64_t range_end = 0;
|
int64_t range_end = 0;
|
||||||
|
|||||||
+5
-7
@@ -26,6 +26,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <string_view>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
using util::SplitString;
|
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 strRet;
|
||||||
std::string category;
|
std::string category;
|
||||||
@@ -130,16 +131,13 @@ static RPCHelpMan help()
|
|||||||
RPCExamples{""},
|
RPCExamples{""},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue
|
||||||
{
|
{
|
||||||
std::string strCommand;
|
auto command{self.MaybeArg<std::string_view>("command")};
|
||||||
if (jsonRequest.params.size() > 0) {
|
if (command == "dump_all_command_conversions") {
|
||||||
strCommand = jsonRequest.params[0].get_str();
|
|
||||||
}
|
|
||||||
if (strCommand == "dump_all_command_conversions") {
|
|
||||||
// Used for testing only, undocumented
|
// Used for testing only, undocumented
|
||||||
return tableRPC.dumpArgMap(jsonRequest);
|
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;
|
std::map<std::string, std::vector<const CRPCCommand*>> mapCommands;
|
||||||
public:
|
public:
|
||||||
CRPCTable();
|
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.
|
* Execute a method.
|
||||||
|
|||||||
@@ -38,11 +38,9 @@ static RPCHelpMan verifymessage()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
std::string strAddress = self.Arg<std::string>("address");
|
switch (MessageVerify(std::string{self.Arg<std::string_view>("address")},
|
||||||
std::string strSign = self.Arg<std::string>("signature");
|
std::string{self.Arg<std::string_view>("signature")},
|
||||||
std::string strMessage = self.Arg<std::string>("message");
|
std::string{self.Arg<std::string_view>("message")})) {
|
||||||
|
|
||||||
switch (MessageVerify(strAddress, strSign, strMessage)) {
|
|
||||||
case MessageVerificationResult::ERR_INVALID_ADDRESS:
|
case MessageVerificationResult::ERR_INVALID_ADDRESS:
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
|
||||||
case MessageVerificationResult::ERR_ADDRESS_NO_KEY:
|
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, 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<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, 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.
|
// Required arg or optional arg with default value.
|
||||||
TMPL_INST(CheckRequiredOrDefault, const UniValue&, *CHECK_NONFATAL(maybe_arg););
|
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, int, CHECK_NONFATAL(maybe_arg)->getInt<int>(););
|
||||||
TMPL_INST(CheckRequiredOrDefault, uint64_t, CHECK_NONFATAL(maybe_arg)->getInt<uint64_t>(););
|
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, 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
|
bool RPCHelpMan::IsValidNumArgs(size_t num_args) const
|
||||||
{
|
{
|
||||||
|
|||||||
+5
-5
@@ -445,8 +445,8 @@ public:
|
|||||||
{
|
{
|
||||||
auto i{GetParamIndex(key)};
|
auto i{GetParamIndex(key)};
|
||||||
// Return argument (required or with default value).
|
// Return argument (required or with default value).
|
||||||
if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
|
if constexpr (std::is_trivially_copyable_v<R>) {
|
||||||
// Return numbers by value.
|
// Return trivially copyable types by value.
|
||||||
return ArgValue<R>(i);
|
return ArgValue<R>(i);
|
||||||
} else {
|
} else {
|
||||||
// Return everything else by reference.
|
// Return everything else by reference.
|
||||||
@@ -466,7 +466,7 @@ public:
|
|||||||
*
|
*
|
||||||
* The instantiation of this helper for type R must match the corresponding RPCArg::Type.
|
* 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
|
* 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.
|
* argument is not provided, std::nullopt or a null pointer is returned.
|
||||||
*
|
*
|
||||||
@@ -477,8 +477,8 @@ public:
|
|||||||
{
|
{
|
||||||
auto i{GetParamIndex(key)};
|
auto i{GetParamIndex(key)};
|
||||||
// Return optional argument (without default).
|
// Return optional argument (without default).
|
||||||
if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
|
if constexpr (std::is_trivially_copyable_v<R>) {
|
||||||
// Return numbers by value, wrapped in optional.
|
// Return trivially copyable types by value, wrapped in optional.
|
||||||
return ArgValue<std::optional<R>>(i);
|
return ArgValue<std::optional<R>>(i);
|
||||||
} else {
|
} else {
|
||||||
// Return other types by pointer.
|
// Return other types by pointer.
|
||||||
|
|||||||
@@ -2730,13 +2730,12 @@ bool CheckChecksum(std::span<const char>& sp, bool require_checksum, std::string
|
|||||||
return true;
|
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(descriptor, require_checksum, error)) return {};
|
||||||
if (!CheckChecksum(sp, require_checksum, error)) return {};
|
|
||||||
uint32_t key_exp_index = 0;
|
uint32_t key_exp_index = 0;
|
||||||
auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
|
auto ret = ParseScript(key_exp_index, descriptor, ParseScriptContext::TOP, out, error);
|
||||||
if (sp.size() == 0 && !ret.empty()) {
|
if (descriptor.empty() && !ret.empty()) {
|
||||||
std::vector<std::unique_ptr<Descriptor>> descs;
|
std::vector<std::unique_ptr<Descriptor>> descs;
|
||||||
descs.reserve(ret.size());
|
descs.reserve(ret.size());
|
||||||
for (auto& r : ret) {
|
for (auto& r : ret) {
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ struct Descriptor {
|
|||||||
* If a parse error occurs, or the checksum is missing/invalid, or anything
|
* If a parse error occurs, or the checksum is missing/invalid, or anything
|
||||||
* else is wrong, an empty vector is returned.
|
* 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`.
|
/** Get the checksum for a `descriptor`.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <util/time.h>
|
#include <util/time.h>
|
||||||
|
|
||||||
#include <any>
|
#include <any>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#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
|
//! Check that `self.Arg` returns the same value as the `request.params` accessors
|
||||||
RPCHelpMan::RPCMethodImpl check_positional = [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
|
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<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<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());
|
BOOST_CHECK_EQUAL(self.Arg<bool>("def_bool"), request.params[4].isNull() ? DEFAULT_BOOL : request.params[4].get_bool());
|
||||||
if (!request.params[5].isNull()) {
|
if (!request.params[5].isNull()) {
|
||||||
BOOST_CHECK_EQUAL(self.MaybeArg<double>("opt_double").value(), request.params[5].get_real());
|
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"));
|
BOOST_CHECK(!self.MaybeArg<double>("opt_double"));
|
||||||
}
|
}
|
||||||
if (!request.params[6].isNull()) {
|
if (!request.params[6].isNull()) {
|
||||||
BOOST_CHECK(self.MaybeArg<std::string>("opt_string"));
|
BOOST_CHECK_EQUAL(self.MaybeArg<std::string_view>("opt_string"), request.params[6].get_str());
|
||||||
BOOST_CHECK_EQUAL(*self.MaybeArg<std::string>("opt_string"), request.params[6].get_str());
|
|
||||||
} else {
|
} else {
|
||||||
BOOST_CHECK(!self.MaybeArg<std::string>("opt_string"));
|
BOOST_CHECK(!self.MaybeArg<std::string_view>("opt_string"));
|
||||||
}
|
}
|
||||||
return UniValue{};
|
return UniValue{};
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-1
@@ -14,6 +14,7 @@
|
|||||||
#include <ios>
|
#include <ios>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#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()});
|
return std::filesystem::path(std::u8string{utf8_str.begin(), utf8_str.end()});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,8 +196,7 @@ RPCHelpMan getbalance()
|
|||||||
|
|
||||||
LOCK(pwallet->cs_wallet);
|
LOCK(pwallet->cs_wallet);
|
||||||
|
|
||||||
const auto dummy_value{self.MaybeArg<std::string>("dummy")};
|
if (self.MaybeArg<std::string_view>("dummy").value_or("*") != "*") {
|
||||||
if (dummy_value && *dummy_value != "*") {
|
|
||||||
throw JSONRPCError(RPC_METHOD_DEPRECATED, "dummy first argument must be excluded or set to \"*\".");
|
throw JSONRPCError(RPC_METHOD_DEPRECATED, "dummy first argument must be excluded or set to \"*\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <wallet/context.h>
|
#include <wallet/context.h>
|
||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) {
|
|||||||
return avoid_reuse;
|
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;
|
std::string endpoint_wallet;
|
||||||
if (GetWalletNameFromJSONRPCRequest(request, 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");
|
"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)
|
bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string& wallet_name)
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
|
|
||||||
#include <any>
|
#include <any>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class JSONRPCRequest;
|
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.
|
* 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.
|
* 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&);
|
void EnsureWalletIsUnlocked(const CWallet&);
|
||||||
WalletContext& EnsureWalletContext(const std::any& context);
|
WalletContext& EnsureWalletContext(const std::any& context);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <wallet/walletutil.h>
|
#include <wallet/walletutil.h>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
|
||||||
namespace wallet {
|
namespace wallet {
|
||||||
@@ -456,7 +457,7 @@ static RPCHelpMan unloadwallet()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](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);
|
WalletContext& context = EnsureWalletContext(request.context);
|
||||||
std::shared_ptr<CWallet> wallet = GetWallet(context, wallet_name);
|
std::shared_ptr<CWallet> wallet = GetWallet(context, wallet_name);
|
||||||
@@ -613,7 +614,7 @@ static RPCHelpMan migratewallet()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](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;
|
SecureString wallet_pass;
|
||||||
wallet_pass.reserve(100);
|
wallet_pass.reserve(100);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ static std::string TestWalletName(const std::string& endpoint, std::optional<std
|
|||||||
{
|
{
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = endpoint;
|
req.URI = endpoint;
|
||||||
return EnsureUniqueWalletName(req, parameter ? &*parameter : nullptr);
|
return EnsureUniqueWalletName(req, parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(wallet_rpc_tests, BasicTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(wallet_rpc_tests, BasicTestingSetup)
|
||||||
|
|||||||
Reference in new issue
Block a user