aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am5
-rw-r--r--src/attributes.h13
-rw-r--r--src/base58.cpp4
-rw-r--r--src/base58.h4
-rw-r--r--src/bench/prevector.cpp12
-rw-r--r--src/core_io.h4
-rw-r--r--src/hash.h2
-rw-r--r--src/init.cpp13
-rw-r--r--src/interfaces/node.cpp303
-rw-r--r--src/node/interfaces.cpp (renamed from src/interfaces/chain.cpp)286
-rw-r--r--src/node/transaction.h2
-rw-r--r--src/outputtype.h2
-rw-r--r--src/policy/policy.cpp17
-rw-r--r--src/policy/policy.h2
-rw-r--r--src/psbt.h8
-rw-r--r--src/qt/askpassphrasedialog.cpp2
-rw-r--r--src/qt/bantablemodel.cpp3
-rw-r--r--src/qt/guiutil.cpp3
-rw-r--r--src/qt/notificator.cpp5
-rw-r--r--src/script/descriptor.cpp2
-rw-r--r--src/test/coins_tests.cpp2
-rw-r--r--src/test/fuzz/addition_overflow.cpp2
-rw-r--r--src/test/fuzz/addrman.cpp14
-rw-r--r--src/test/fuzz/multiplication_overflow.cpp2
-rw-r--r--src/test/fuzz/util.h47
-rw-r--r--src/test/util/setup_common.cpp3
-rw-r--r--src/txmempool.cpp19
-rw-r--r--src/txmempool.h17
-rw-r--r--src/util/bip32.h2
-rw-r--r--src/util/moneystr.h2
-rw-r--r--src/util/strencodings.cpp2
-rw-r--r--src/util/strencodings.h14
-rw-r--r--src/util/string.h6
-rw-r--r--src/util/system.h8
-rw-r--r--src/validation.cpp4
-rw-r--r--src/wallet/interfaces.cpp (renamed from src/interfaces/wallet.cpp)25
-rw-r--r--src/wallet/rpcwallet.cpp6
37 files changed, 418 insertions, 449 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7d70d02a4f..4a080ef1fb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -298,14 +298,13 @@ libbitcoin_server_a_SOURCES = \
index/blockfilterindex.cpp \
index/txindex.cpp \
init.cpp \
- interfaces/chain.cpp \
- interfaces/node.cpp \
miner.cpp \
net.cpp \
net_processing.cpp \
node/coin.cpp \
node/coinstats.cpp \
node/context.cpp \
+ node/interfaces.cpp \
node/psbt.cpp \
node/transaction.cpp \
node/ui_interface.cpp \
@@ -358,13 +357,13 @@ endif
libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(SQLITE_CFLAGS)
libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_wallet_a_SOURCES = \
- interfaces/wallet.cpp \
wallet/coincontrol.cpp \
wallet/context.cpp \
wallet/crypter.cpp \
wallet/db.cpp \
wallet/feebumper.cpp \
wallet/fees.cpp \
+ wallet/interfaces.cpp \
wallet/load.cpp \
wallet/rpcdump.cpp \
wallet/rpcwallet.cpp \
diff --git a/src/attributes.h b/src/attributes.h
index 9d5c1d44a0..995c24e13f 100644
--- a/src/attributes.h
+++ b/src/attributes.h
@@ -6,19 +6,6 @@
#ifndef BITCOIN_ATTRIBUTES_H
#define BITCOIN_ATTRIBUTES_H
-#if defined(__has_cpp_attribute)
-# if __has_cpp_attribute(nodiscard)
-# define NODISCARD [[nodiscard]]
-# endif
-#endif
-#ifndef NODISCARD
-# if defined(_MSC_VER) && _MSC_VER >= 1700
-# define NODISCARD _Check_return_
-# else
-# define NODISCARD __attribute__((warn_unused_result))
-# endif
-#endif
-
#if defined(__clang__)
# if __has_attribute(lifetimebound)
# define LIFETIMEBOUND [[clang::lifetimebound]]
diff --git a/src/base58.cpp b/src/base58.cpp
index 0dc6044145..780846c6c5 100644
--- a/src/base58.cpp
+++ b/src/base58.cpp
@@ -35,7 +35,7 @@ static const int8_t mapBase58[256] = {
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
};
-NODISCARD static bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch, int max_ret_len)
+[[nodiscard]] static bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch, int max_ret_len)
{
// Skip leading spaces.
while (*psz && IsSpace(*psz))
@@ -141,7 +141,7 @@ std::string EncodeBase58Check(Span<const unsigned char> input)
return EncodeBase58(vch);
}
-NODISCARD static bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet, int max_ret_len)
+[[nodiscard]] static bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet, int max_ret_len)
{
if (!DecodeBase58(psz, vchRet, max_ret_len > std::numeric_limits<int>::max() - 4 ? std::numeric_limits<int>::max() : max_ret_len + 4) ||
(vchRet.size() < 4)) {
diff --git a/src/base58.h b/src/base58.h
index 468c3e2589..60551a12ae 100644
--- a/src/base58.h
+++ b/src/base58.h
@@ -29,7 +29,7 @@ std::string EncodeBase58(Span<const unsigned char> input);
* Decode a base58-encoded string (str) into a byte vector (vchRet).
* return true if decoding is successful.
*/
-NODISCARD bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret_len);
+[[nodiscard]] bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret_len);
/**
* Encode a byte span into a base58-encoded string, including checksum
@@ -40,6 +40,6 @@ std::string EncodeBase58Check(Span<const unsigned char> input);
* Decode a base58-encoded string (str) that includes a checksum into a byte
* vector (vchRet), return true if decoding is successful
*/
-NODISCARD bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret_len);
+[[nodiscard]] bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret_len);
#endif // BITCOIN_BASE58_H
diff --git a/src/bench/prevector.cpp b/src/bench/prevector.cpp
index a2dbefa54a..73af244ce0 100644
--- a/src/bench/prevector.cpp
+++ b/src/bench/prevector.cpp
@@ -9,24 +9,16 @@
#include <bench/bench.h>
-// GCC 4.8 is missing some C++11 type_traits,
-// https://www.gnu.org/software/gcc/gcc-5/changes.html
-#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
-#define IS_TRIVIALLY_CONSTRUCTIBLE std::has_trivial_default_constructor
-#else
-#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_default_constructible
-#endif
-
struct nontrivial_t {
int x;
nontrivial_t() :x(-1) {}
SERIALIZE_METHODS(nontrivial_t, obj) { READWRITE(obj.x); }
};
-static_assert(!IS_TRIVIALLY_CONSTRUCTIBLE<nontrivial_t>::value,
+static_assert(!std::is_trivially_default_constructible<nontrivial_t>::value,
"expected nontrivial_t to not be trivially constructible");
typedef unsigned char trivial_t;
-static_assert(IS_TRIVIALLY_CONSTRUCTIBLE<trivial_t>::value,
+static_assert(std::is_trivially_default_constructible<trivial_t>::value,
"expected trivial_t to be trivially constructible");
template <typename T>
diff --git a/src/core_io.h b/src/core_io.h
index 80ec80cd50..aaee9c445d 100644
--- a/src/core_io.h
+++ b/src/core_io.h
@@ -22,8 +22,8 @@ class UniValue;
// core_read.cpp
CScript ParseScript(const std::string& s);
std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false);
-NODISCARD bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true);
-NODISCARD bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
+[[nodiscard]] bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true);
+[[nodiscard]] bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
/**
diff --git a/src/hash.h b/src/hash.h
index 6d876076ee..083ac12523 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -197,7 +197,7 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL
}
/** Single-SHA256 a 32-byte input (represented as uint256). */
-NODISCARD uint256 SHA256Uint256(const uint256& input);
+[[nodiscard]] uint256 SHA256Uint256(const uint256& input);
unsigned int MurmurHash3(unsigned int nHashSeed, Span<const unsigned char> vDataToHash);
diff --git a/src/init.cpp b/src/init.cpp
index 1e41616e94..9137050323 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -113,7 +113,7 @@ static fs::path GetPidFile(const ArgsManager& args)
return AbsPathForConfigVal(fs::path(args.GetArg("-pid", BITCOIN_PID_FILENAME)));
}
-NODISCARD static bool CreatePidFile(const ArgsManager& args)
+[[nodiscard]] static bool CreatePidFile(const ArgsManager& args)
{
fsbridge::ofstream file{GetPidFile(args)};
if (file) {
@@ -1389,16 +1389,9 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
assert(!node.connman);
node.connman = MakeUnique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()), args.GetBoolArg("-networkactive", true));
- // Make mempool generally available in the node context. For example the connection manager, wallet, or RPC threads,
- // which are all started after this, may use it from the node context.
assert(!node.mempool);
- node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator);
- if (node.mempool) {
- int ratio = std::min<int>(std::max<int>(args.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
- if (ratio != 0) {
- node.mempool->setSanityCheck(1.0 / ratio);
- }
- }
+ int check_ratio = std::min<int>(std::max<int>(args.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
+ node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator, check_ratio);
assert(!node.chainman);
node.chainman = &g_chainman;
diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp
deleted file mode 100644
index 2c5f8627e6..0000000000
--- a/src/interfaces/node.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright (c) 2018-2020 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include <interfaces/node.h>
-
-#include <addrdb.h>
-#include <banman.h>
-#include <chain.h>
-#include <chainparams.h>
-#include <init.h>
-#include <interfaces/chain.h>
-#include <interfaces/handler.h>
-#include <interfaces/wallet.h>
-#include <net.h>
-#include <net_processing.h>
-#include <netaddress.h>
-#include <netbase.h>
-#include <node/context.h>
-#include <node/ui_interface.h>
-#include <policy/feerate.h>
-#include <policy/fees.h>
-#include <policy/settings.h>
-#include <primitives/block.h>
-#include <rpc/server.h>
-#include <shutdown.h>
-#include <support/allocators/secure.h>
-#include <sync.h>
-#include <txmempool.h>
-#include <util/check.h>
-#include <util/ref.h>
-#include <util/system.h>
-#include <util/translation.h>
-#include <validation.h>
-#include <warnings.h>
-
-#if defined(HAVE_CONFIG_H)
-#include <config/bitcoin-config.h>
-#endif
-
-#include <univalue.h>
-
-#include <boost/signals2/signal.hpp>
-
-namespace interfaces {
-namespace {
-
-class NodeImpl : public Node
-{
-public:
- NodeImpl(NodeContext* context) { setContext(context); }
- void initLogging() override { InitLogging(*Assert(m_context->args)); }
- void initParameterInteraction() override { InitParameterInteraction(*Assert(m_context->args)); }
- bilingual_str getWarnings() override { return GetWarnings(true); }
- uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); }
- bool baseInitialize() override
- {
- return AppInitBasicSetup(gArgs) && AppInitParameterInteraction(gArgs) && AppInitSanityChecks() &&
- AppInitLockDataDirectory() && AppInitInterfaces(*m_context);
- }
- bool appInitMain(interfaces::BlockAndHeaderTipInfo* tip_info) override
- {
- return AppInitMain(m_context_ref, *m_context, tip_info);
- }
- void appShutdown() override
- {
- Interrupt(*m_context);
- Shutdown(*m_context);
- }
- void startShutdown() override
- {
- StartShutdown();
- // Stop RPC for clean shutdown if any of waitfor* commands is executed.
- if (gArgs.GetBoolArg("-server", false)) {
- InterruptRPC();
- StopRPC();
- }
- }
- bool shutdownRequested() override { return ShutdownRequested(); }
- void mapPort(bool use_upnp) override
- {
- if (use_upnp) {
- StartMapPort();
- } else {
- InterruptMapPort();
- StopMapPort();
- }
- }
- bool getProxy(Network net, proxyType& proxy_info) override { return GetProxy(net, proxy_info); }
- size_t getNodeCount(CConnman::NumConnections flags) override
- {
- return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0;
- }
- bool getNodesStats(NodesStats& stats) override
- {
- stats.clear();
-
- if (m_context->connman) {
- std::vector<CNodeStats> stats_temp;
- m_context->connman->GetNodeStats(stats_temp);
-
- stats.reserve(stats_temp.size());
- for (auto& node_stats_temp : stats_temp) {
- stats.emplace_back(std::move(node_stats_temp), false, CNodeStateStats());
- }
-
- // Try to retrieve the CNodeStateStats for each node.
- TRY_LOCK(::cs_main, lockMain);
- if (lockMain) {
- for (auto& node_stats : stats) {
- std::get<1>(node_stats) =
- GetNodeStateStats(std::get<0>(node_stats).nodeid, std::get<2>(node_stats));
- }
- }
- return true;
- }
- return false;
- }
- bool getBanned(banmap_t& banmap) override
- {
- if (m_context->banman) {
- m_context->banman->GetBanned(banmap);
- return true;
- }
- return false;
- }
- bool ban(const CNetAddr& net_addr, int64_t ban_time_offset) override
- {
- if (m_context->banman) {
- m_context->banman->Ban(net_addr, ban_time_offset);
- return true;
- }
- return false;
- }
- bool unban(const CSubNet& ip) override
- {
- if (m_context->banman) {
- m_context->banman->Unban(ip);
- return true;
- }
- return false;
- }
- bool disconnectByAddress(const CNetAddr& net_addr) override
- {
- if (m_context->connman) {
- return m_context->connman->DisconnectNode(net_addr);
- }
- return false;
- }
- bool disconnectById(NodeId id) override
- {
- if (m_context->connman) {
- return m_context->connman->DisconnectNode(id);
- }
- return false;
- }
- int64_t getTotalBytesRecv() override { return m_context->connman ? m_context->connman->GetTotalBytesRecv() : 0; }
- int64_t getTotalBytesSent() override { return m_context->connman ? m_context->connman->GetTotalBytesSent() : 0; }
- size_t getMempoolSize() override { return m_context->mempool ? m_context->mempool->size() : 0; }
- size_t getMempoolDynamicUsage() override { return m_context->mempool ? m_context->mempool->DynamicMemoryUsage() : 0; }
- bool getHeaderTip(int& height, int64_t& block_time) override
- {
- LOCK(::cs_main);
- if (::pindexBestHeader) {
- height = ::pindexBestHeader->nHeight;
- block_time = ::pindexBestHeader->GetBlockTime();
- return true;
- }
- return false;
- }
- int getNumBlocks() override
- {
- LOCK(::cs_main);
- return ::ChainActive().Height();
- }
- uint256 getBestBlockHash() override
- {
- const CBlockIndex* tip = WITH_LOCK(::cs_main, return ::ChainActive().Tip());
- return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
- }
- int64_t getLastBlockTime() override
- {
- LOCK(::cs_main);
- if (::ChainActive().Tip()) {
- return ::ChainActive().Tip()->GetBlockTime();
- }
- return Params().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
- }
- double getVerificationProgress() override
- {
- const CBlockIndex* tip;
- {
- LOCK(::cs_main);
- tip = ::ChainActive().Tip();
- }
- return GuessVerificationProgress(Params().TxData(), tip);
- }
- bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
- bool getReindex() override { return ::fReindex; }
- bool getImporting() override { return ::fImporting; }
- void setNetworkActive(bool active) override
- {
- if (m_context->connman) {
- m_context->connman->SetNetworkActive(active);
- }
- }
- bool getNetworkActive() override { return m_context->connman && m_context->connman->GetNetworkActive(); }
- CFeeRate estimateSmartFee(int num_blocks, bool conservative, int* returned_target = nullptr) override
- {
- FeeCalculation fee_calc;
- CFeeRate result = ::feeEstimator.estimateSmartFee(num_blocks, &fee_calc, conservative);
- if (returned_target) {
- *returned_target = fee_calc.returnedTarget;
- }
- return result;
- }
- CFeeRate getDustRelayFee() override { return ::dustRelayFee; }
- UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
- {
- JSONRPCRequest req(m_context_ref);
- req.params = params;
- req.strMethod = command;
- req.URI = uri;
- return ::tableRPC.execute(req);
- }
- std::vector<std::string> listRpcCommands() override { return ::tableRPC.listCommands(); }
- void rpcSetTimerInterfaceIfUnset(RPCTimerInterface* iface) override { RPCSetTimerInterfaceIfUnset(iface); }
- void rpcUnsetTimerInterface(RPCTimerInterface* iface) override { RPCUnsetTimerInterface(iface); }
- bool getUnspentOutput(const COutPoint& output, Coin& coin) override
- {
- LOCK(::cs_main);
- return ::ChainstateActive().CoinsTip().GetCoin(output, coin);
- }
- WalletClient& walletClient() override
- {
- return *Assert(m_context->wallet_client);
- }
- std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
- {
- return MakeHandler(::uiInterface.InitMessage_connect(fn));
- }
- std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) override
- {
- return MakeHandler(::uiInterface.ThreadSafeMessageBox_connect(fn));
- }
- std::unique_ptr<Handler> handleQuestion(QuestionFn fn) override
- {
- return MakeHandler(::uiInterface.ThreadSafeQuestion_connect(fn));
- }
- std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
- {
- return MakeHandler(::uiInterface.ShowProgress_connect(fn));
- }
- std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
- {
- return MakeHandler(::uiInterface.NotifyNumConnectionsChanged_connect(fn));
- }
- std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) override
- {
- return MakeHandler(::uiInterface.NotifyNetworkActiveChanged_connect(fn));
- }
- std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) override
- {
- return MakeHandler(::uiInterface.NotifyAlertChanged_connect(fn));
- }
- std::unique_ptr<Handler> handleBannedListChanged(BannedListChangedFn fn) override
- {
- return MakeHandler(::uiInterface.BannedListChanged_connect(fn));
- }
- std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
- {
- return MakeHandler(::uiInterface.NotifyBlockTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
- fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
- GuessVerificationProgress(Params().TxData(), block));
- }));
- }
- std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
- {
- return MakeHandler(
- ::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
- fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
- /* verification progress is unused when a header was received */ 0);
- }));
- }
- NodeContext* context() override { return m_context; }
- void setContext(NodeContext* context) override
- {
- m_context = context;
- if (context) {
- m_context_ref.Set(*context);
- } else {
- m_context_ref.Clear();
- }
- }
- NodeContext* m_context{nullptr};
- util::Ref m_context_ref;
-};
-
-} // namespace
-
-std::unique_ptr<Node> MakeNode(NodeContext* context) { return MakeUnique<NodeImpl>(context); }
-
-} // namespace interfaces
diff --git a/src/interfaces/chain.cpp b/src/node/interfaces.cpp
index 4c5ebe66fc..77a5957a56 100644
--- a/src/interfaces/chain.cpp
+++ b/src/node/interfaces.cpp
@@ -2,18 +2,25 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <interfaces/chain.h>
-
+#include <addrdb.h>
+#include <banman.h>
+#include <boost/signals2/signal.hpp>
#include <chain.h>
#include <chainparams.h>
+#include <init.h>
+#include <interfaces/chain.h>
#include <interfaces/handler.h>
+#include <interfaces/node.h>
#include <interfaces/wallet.h>
#include <net.h>
#include <net_processing.h>
+#include <netaddress.h>
+#include <netbase.h>
#include <node/coin.h>
#include <node/context.h>
#include <node/transaction.h>
#include <node/ui_interface.h>
+#include <policy/feerate.h>
#include <policy/fees.h>
#include <policy/policy.h>
#include <policy/rbf.h>
@@ -23,20 +30,287 @@
#include <rpc/protocol.h>
#include <rpc/server.h>
#include <shutdown.h>
+#include <support/allocators/secure.h>
#include <sync.h>
#include <timedata.h>
#include <txmempool.h>
#include <uint256.h>
#include <univalue.h>
+#include <util/check.h>
+#include <util/ref.h>
#include <util/system.h>
+#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
+#include <warnings.h>
+
+#if defined(HAVE_CONFIG_H)
+#include <config/bitcoin-config.h>
+#endif
#include <memory>
#include <utility>
-namespace interfaces {
+using interfaces::BlockTip;
+using interfaces::Chain;
+using interfaces::FoundBlock;
+using interfaces::Handler;
+using interfaces::MakeHandler;
+using interfaces::Node;
+using interfaces::WalletClient;
+
+namespace node {
namespace {
+class NodeImpl : public Node
+{
+public:
+ NodeImpl(NodeContext* context) { setContext(context); }
+ void initLogging() override { InitLogging(*Assert(m_context->args)); }
+ void initParameterInteraction() override { InitParameterInteraction(*Assert(m_context->args)); }
+ bilingual_str getWarnings() override { return GetWarnings(true); }
+ uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); }
+ bool baseInitialize() override
+ {
+ return AppInitBasicSetup(gArgs) && AppInitParameterInteraction(gArgs) && AppInitSanityChecks() &&
+ AppInitLockDataDirectory() && AppInitInterfaces(*m_context);
+ }
+ bool appInitMain(interfaces::BlockAndHeaderTipInfo* tip_info) override
+ {
+ return AppInitMain(m_context_ref, *m_context, tip_info);
+ }
+ void appShutdown() override
+ {
+ Interrupt(*m_context);
+ Shutdown(*m_context);
+ }
+ void startShutdown() override
+ {
+ StartShutdown();
+ // Stop RPC for clean shutdown if any of waitfor* commands is executed.
+ if (gArgs.GetBoolArg("-server", false)) {
+ InterruptRPC();
+ StopRPC();
+ }
+ }
+ bool shutdownRequested() override { return ShutdownRequested(); }
+ void mapPort(bool use_upnp) override
+ {
+ if (use_upnp) {
+ StartMapPort();
+ } else {
+ InterruptMapPort();
+ StopMapPort();
+ }
+ }
+ bool getProxy(Network net, proxyType& proxy_info) override { return GetProxy(net, proxy_info); }
+ size_t getNodeCount(CConnman::NumConnections flags) override
+ {
+ return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0;
+ }
+ bool getNodesStats(NodesStats& stats) override
+ {
+ stats.clear();
+
+ if (m_context->connman) {
+ std::vector<CNodeStats> stats_temp;
+ m_context->connman->GetNodeStats(stats_temp);
+
+ stats.reserve(stats_temp.size());
+ for (auto& node_stats_temp : stats_temp) {
+ stats.emplace_back(std::move(node_stats_temp), false, CNodeStateStats());
+ }
+
+ // Try to retrieve the CNodeStateStats for each node.
+ TRY_LOCK(::cs_main, lockMain);
+ if (lockMain) {
+ for (auto& node_stats : stats) {
+ std::get<1>(node_stats) =
+ GetNodeStateStats(std::get<0>(node_stats).nodeid, std::get<2>(node_stats));
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+ bool getBanned(banmap_t& banmap) override
+ {
+ if (m_context->banman) {
+ m_context->banman->GetBanned(banmap);
+ return true;
+ }
+ return false;
+ }
+ bool ban(const CNetAddr& net_addr, int64_t ban_time_offset) override
+ {
+ if (m_context->banman) {
+ m_context->banman->Ban(net_addr, ban_time_offset);
+ return true;
+ }
+ return false;
+ }
+ bool unban(const CSubNet& ip) override
+ {
+ if (m_context->banman) {
+ m_context->banman->Unban(ip);
+ return true;
+ }
+ return false;
+ }
+ bool disconnectByAddress(const CNetAddr& net_addr) override
+ {
+ if (m_context->connman) {
+ return m_context->connman->DisconnectNode(net_addr);
+ }
+ return false;
+ }
+ bool disconnectById(NodeId id) override
+ {
+ if (m_context->connman) {
+ return m_context->connman->DisconnectNode(id);
+ }
+ return false;
+ }
+ int64_t getTotalBytesRecv() override { return m_context->connman ? m_context->connman->GetTotalBytesRecv() : 0; }
+ int64_t getTotalBytesSent() override { return m_context->connman ? m_context->connman->GetTotalBytesSent() : 0; }
+ size_t getMempoolSize() override { return m_context->mempool ? m_context->mempool->size() : 0; }
+ size_t getMempoolDynamicUsage() override { return m_context->mempool ? m_context->mempool->DynamicMemoryUsage() : 0; }
+ bool getHeaderTip(int& height, int64_t& block_time) override
+ {
+ LOCK(::cs_main);
+ if (::pindexBestHeader) {
+ height = ::pindexBestHeader->nHeight;
+ block_time = ::pindexBestHeader->GetBlockTime();
+ return true;
+ }
+ return false;
+ }
+ int getNumBlocks() override
+ {
+ LOCK(::cs_main);
+ return ::ChainActive().Height();
+ }
+ uint256 getBestBlockHash() override
+ {
+ const CBlockIndex* tip = WITH_LOCK(::cs_main, return ::ChainActive().Tip());
+ return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
+ }
+ int64_t getLastBlockTime() override
+ {
+ LOCK(::cs_main);
+ if (::ChainActive().Tip()) {
+ return ::ChainActive().Tip()->GetBlockTime();
+ }
+ return Params().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
+ }
+ double getVerificationProgress() override
+ {
+ const CBlockIndex* tip;
+ {
+ LOCK(::cs_main);
+ tip = ::ChainActive().Tip();
+ }
+ return GuessVerificationProgress(Params().TxData(), tip);
+ }
+ bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
+ bool getReindex() override { return ::fReindex; }
+ bool getImporting() override { return ::fImporting; }
+ void setNetworkActive(bool active) override
+ {
+ if (m_context->connman) {
+ m_context->connman->SetNetworkActive(active);
+ }
+ }
+ bool getNetworkActive() override { return m_context->connman && m_context->connman->GetNetworkActive(); }
+ CFeeRate estimateSmartFee(int num_blocks, bool conservative, int* returned_target = nullptr) override
+ {
+ FeeCalculation fee_calc;
+ CFeeRate result = ::feeEstimator.estimateSmartFee(num_blocks, &fee_calc, conservative);
+ if (returned_target) {
+ *returned_target = fee_calc.returnedTarget;
+ }
+ return result;
+ }
+ CFeeRate getDustRelayFee() override { return ::dustRelayFee; }
+ UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
+ {
+ JSONRPCRequest req(m_context_ref);
+ req.params = params;
+ req.strMethod = command;
+ req.URI = uri;
+ return ::tableRPC.execute(req);
+ }
+ std::vector<std::string> listRpcCommands() override { return ::tableRPC.listCommands(); }
+ void rpcSetTimerInterfaceIfUnset(RPCTimerInterface* iface) override { RPCSetTimerInterfaceIfUnset(iface); }
+ void rpcUnsetTimerInterface(RPCTimerInterface* iface) override { RPCUnsetTimerInterface(iface); }
+ bool getUnspentOutput(const COutPoint& output, Coin& coin) override
+ {
+ LOCK(::cs_main);
+ return ::ChainstateActive().CoinsTip().GetCoin(output, coin);
+ }
+ WalletClient& walletClient() override
+ {
+ return *Assert(m_context->wallet_client);
+ }
+ std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
+ {
+ return MakeHandler(::uiInterface.InitMessage_connect(fn));
+ }
+ std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) override
+ {
+ return MakeHandler(::uiInterface.ThreadSafeMessageBox_connect(fn));
+ }
+ std::unique_ptr<Handler> handleQuestion(QuestionFn fn) override
+ {
+ return MakeHandler(::uiInterface.ThreadSafeQuestion_connect(fn));
+ }
+ std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
+ {
+ return MakeHandler(::uiInterface.ShowProgress_connect(fn));
+ }
+ std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
+ {
+ return MakeHandler(::uiInterface.NotifyNumConnectionsChanged_connect(fn));
+ }
+ std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) override
+ {
+ return MakeHandler(::uiInterface.NotifyNetworkActiveChanged_connect(fn));
+ }
+ std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) override
+ {
+ return MakeHandler(::uiInterface.NotifyAlertChanged_connect(fn));
+ }
+ std::unique_ptr<Handler> handleBannedListChanged(BannedListChangedFn fn) override
+ {
+ return MakeHandler(::uiInterface.BannedListChanged_connect(fn));
+ }
+ std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
+ {
+ return MakeHandler(::uiInterface.NotifyBlockTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
+ fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
+ GuessVerificationProgress(Params().TxData(), block));
+ }));
+ }
+ std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
+ {
+ return MakeHandler(
+ ::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
+ fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
+ /* verification progress is unused when a header was received */ 0);
+ }));
+ }
+ NodeContext* context() override { return m_context; }
+ void setContext(NodeContext* context) override
+ {
+ m_context = context;
+ if (context) {
+ m_context_ref.Set(*context);
+ } else {
+ m_context_ref.Clear();
+ }
+ }
+ NodeContext* m_context{nullptr};
+ util::Ref m_context_ref;
+};
bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock)
{
@@ -411,7 +685,9 @@ public:
NodeContext& m_node;
};
} // namespace
+} // namespace node
-std::unique_ptr<Chain> MakeChain(NodeContext& node) { return MakeUnique<ChainImpl>(node); }
-
+namespace interfaces {
+std::unique_ptr<Node> MakeNode(NodeContext* context) { return MakeUnique<node::NodeImpl>(context); }
+std::unique_ptr<Chain> MakeChain(NodeContext& context) { return MakeUnique<node::ChainImpl>(context); }
} // namespace interfaces
diff --git a/src/node/transaction.h b/src/node/transaction.h
index 6491700d44..0c016ff04e 100644
--- a/src/node/transaction.h
+++ b/src/node/transaction.h
@@ -36,6 +36,6 @@ static const CFeeRate DEFAULT_MAX_RAW_TX_FEE_RATE{COIN / 10};
* @param[in] wait_callback wait until callbacks have been processed to avoid stale result due to a sequentially RPC.
* return error
*/
-NODISCARD TransactionError BroadcastTransaction(NodeContext& node, CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback);
+[[nodiscard]] TransactionError BroadcastTransaction(NodeContext& node, CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback);
#endif // BITCOIN_NODE_TRANSACTION_H
diff --git a/src/outputtype.h b/src/outputtype.h
index 77a16b1d05..bb7f39323b 100644
--- a/src/outputtype.h
+++ b/src/outputtype.h
@@ -22,7 +22,7 @@ enum class OutputType {
extern const std::array<OutputType, 3> OUTPUT_TYPES;
-NODISCARD bool ParseOutputType(const std::string& str, OutputType& output_type);
+[[nodiscard]] bool ParseOutputType(const std::string& str, OutputType& output_type);
const std::string& FormatOutputType(OutputType type);
/**
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index 91997aa883..4e33fd6cb5 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -92,14 +92,15 @@ bool IsStandardTx(const CTransaction& tx, bool permit_bare_multisig, const CFeeR
for (const CTxIn& txin : tx.vin)
{
- // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
- // keys (remember the 520 byte limit on redeemScript size). That works
- // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
- // bytes of scriptSig, which we round off to 1650 bytes for some minor
- // future-proofing. That's also enough to spend a 20-of-20
- // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
- // considered standard.
- if (txin.scriptSig.size() > 1650) {
+ // Biggest 'standard' txin involving only keys is a 15-of-15 P2SH
+ // multisig with compressed keys (remember the 520 byte limit on
+ // redeemScript size). That works out to a (15*(33+1))+3=513 byte
+ // redeemScript, 513+1+15*(73+1)+3=1627 bytes of scriptSig, which
+ // we round off to 1650(MAX_STANDARD_SCRIPTSIG_SIZE) bytes for
+ // some minor future-proofing. That's also enough to spend a
+ // 20-of-20 CHECKMULTISIG scriptPubKey, though such a scriptPubKey
+ // is not considered standard.
+ if (txin.scriptSig.size() > MAX_STANDARD_SCRIPTSIG_SIZE) {
reason = "scriptsig-size";
return false;
}
diff --git a/src/policy/policy.h b/src/policy/policy.h
index fc144e924b..726a14a27e 100644
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -44,6 +44,8 @@ static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEM_SIZE = 80;
static const unsigned int MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE = 80;
/** The maximum size in bytes of a standard witnessScript */
static const unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
+/** The maximum size of a standard ScriptSig */
+static const unsigned int MAX_STANDARD_SCRIPTSIG_SIZE = 1650;
/** Min feerate for defining dust. Historically this has been based on the
* minRelayTxFee, however changing the dust limit changes which transactions are
* standard and should be done with care and ideally rarely. It makes sense to
diff --git a/src/psbt.h b/src/psbt.h
index 0951b76f83..b566726ee3 100644
--- a/src/psbt.h
+++ b/src/psbt.h
@@ -398,7 +398,7 @@ struct PartiallySignedTransaction
/** Merge psbt into this. The two psbts must have the same underlying CTransaction (i.e. the
* same actual Bitcoin transaction.) Returns true if the merge succeeded, false otherwise. */
- NODISCARD bool Merge(const PartiallySignedTransaction& psbt);
+ [[nodiscard]] bool Merge(const PartiallySignedTransaction& psbt);
bool AddInput(const CTxIn& txin, PSBTInput& psbtin);
bool AddOutput(const CTxOut& txout, const PSBTOutput& psbtout);
PartiallySignedTransaction() {}
@@ -605,11 +605,11 @@ bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransacti
* @param[in] psbtxs the PSBTs to combine
* @return error (OK if we successfully combined the transactions, other error if they were not compatible)
*/
-NODISCARD TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs);
+[[nodiscard]] TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs);
//! Decode a base64ed PSBT into a PartiallySignedTransaction
-NODISCARD bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error);
+[[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error);
//! Decode a raw (binary blob) PSBT into a PartiallySignedTransaction
-NODISCARD bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, const std::string& raw_psbt, std::string& error);
+[[nodiscard]] bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, const std::string& raw_psbt, std::string& error);
#endif // BITCOIN_PSBT_H
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
index 3b4967421a..3be8b664dd 100644
--- a/src/qt/askpassphrasedialog.cpp
+++ b/src/qt/askpassphrasedialog.cpp
@@ -199,6 +199,8 @@ void AskPassphraseDialog::textChanged()
acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
break;
case Unlock: // Old passphrase x1
+ acceptable = !ui->passEdit1->text().isEmpty();
+ break;
case ChangePass: // Old passphrase x1, new passphrase x2
acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
break;
diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp
index 2739b21a9d..2676de96d7 100644
--- a/src/qt/bantablemodel.cpp
+++ b/src/qt/bantablemodel.cpp
@@ -11,6 +11,7 @@
#include <QDateTime>
#include <QList>
+#include <QLocale>
#include <QModelIndex>
#include <QVariant>
@@ -122,7 +123,7 @@ QVariant BanTableModel::data(const QModelIndex &index, int role) const
case Bantime:
QDateTime date = QDateTime::fromMSecsSinceEpoch(0);
date = date.addSecs(rec->banEntry.nBanUntil);
- return date.toString(Qt::SystemLocaleLongDate);
+ return QLocale::system().toString(date, QLocale::LongFormat);
}
}
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 70e76f765b..53ffb27f50 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -43,6 +43,7 @@
#include <QKeyEvent>
#include <QLineEdit>
#include <QList>
+#include <QLocale>
#include <QMenu>
#include <QMouseEvent>
#include <QProgressDialog>
@@ -67,7 +68,7 @@ namespace GUIUtil {
QString dateTimeStr(const QDateTime &date)
{
- return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") + date.toString("hh:mm");
+ return QLocale::system().toString(date.date(), QLocale::ShortFormat) + QString(" ") + date.toString("hh:mm");
}
QString dateTimeStr(qint64 nTime)
diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp
index 4b91c19761..d518a2065c 100644
--- a/src/qt/notificator.cpp
+++ b/src/qt/notificator.cpp
@@ -17,12 +17,7 @@
#include <stdint.h>
#include <QtDBus>
#endif
-// Include ApplicationServices.h after QtDbus to avoid redefinition of check().
-// This affects at least OSX 10.6. See /usr/include/AssertMacros.h for details.
-// Note: This could also be worked around using:
-// #define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
#ifdef Q_OS_MAC
-#include <ApplicationServices/ApplicationServices.h>
#include <qt/macnotificationhandler.h>
#endif
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index 6c0a98cca2..8d8fa185ba 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -731,7 +731,7 @@ enum class ParseScriptContext {
};
/** Parse a key path, being passed a split list of elements (the first element is ignored). */
-NODISCARD bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath& out, std::string& error)
+[[nodiscard]] bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath& out, std::string& error)
{
for (size_t i = 1; i < split.size(); ++i) {
Span<const char> elem = split[i];
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index 173ec5e3d9..6bfcf242d0 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -38,7 +38,7 @@ class CCoinsViewTest : public CCoinsView
std::map<COutPoint, Coin> map_;
public:
- NODISCARD bool GetCoin(const COutPoint& outpoint, Coin& coin) const override
+ [[nodiscard]] bool GetCoin(const COutPoint& outpoint, Coin& coin) const override
{
std::map<COutPoint, Coin>::const_iterator it = map_.find(outpoint);
if (it == map_.end()) {
diff --git a/src/test/fuzz/addition_overflow.cpp b/src/test/fuzz/addition_overflow.cpp
index a455992b13..7350ec7838 100644
--- a/src/test/fuzz/addition_overflow.cpp
+++ b/src/test/fuzz/addition_overflow.cpp
@@ -14,7 +14,7 @@
#if __has_builtin(__builtin_add_overflow)
#define HAVE_BUILTIN_ADD_OVERFLOW
#endif
-#elif defined(__GNUC__) && (__GNUC__ >= 5)
+#elif defined(__GNUC__)
#define HAVE_BUILTIN_ADD_OVERFLOW
#endif
diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp
index 0ceeea2d36..ae595be742 100644
--- a/src/test/fuzz/addrman.cpp
+++ b/src/test/fuzz/addrman.cpp
@@ -22,12 +22,22 @@ void initialize()
SelectParams(CBaseChainParams::REGTEST);
}
+class CAddrManDeterministic : public CAddrMan
+{
+public:
+ void MakeDeterministic(const uint256& random_seed)
+ {
+ insecure_rand = FastRandomContext{random_seed};
+ Clear();
+ }
+};
+
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
-
SetMockTime(ConsumeTime(fuzzed_data_provider));
- CAddrMan addr_man;
+ CAddrManDeterministic addr_man;
+ addr_man.MakeDeterministic(ConsumeUInt256(fuzzed_data_provider));
if (fuzzed_data_provider.ConsumeBool()) {
addr_man.m_asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
if (!SanityCheckASMap(addr_man.m_asmap)) {
diff --git a/src/test/fuzz/multiplication_overflow.cpp b/src/test/fuzz/multiplication_overflow.cpp
index a4b158c18b..08dc660a19 100644
--- a/src/test/fuzz/multiplication_overflow.cpp
+++ b/src/test/fuzz/multiplication_overflow.cpp
@@ -14,7 +14,7 @@
#if __has_builtin(__builtin_mul_overflow)
#define HAVE_BUILTIN_MUL_OVERFLOW
#endif
-#elif defined(__GNUC__) && (__GNUC__ >= 5)
+#elif defined(__GNUC__)
#define HAVE_BUILTIN_MUL_OVERFLOW
#endif
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index e99ed8d72d..cf666a8b93 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -35,23 +35,23 @@
#include <string>
#include <vector>
-NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
{
const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(max_length);
return {s.begin(), s.end()};
}
-NODISCARD inline std::vector<bool> ConsumeRandomLengthBitVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline std::vector<bool> ConsumeRandomLengthBitVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
{
return BytesToBits(ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length));
}
-NODISCARD inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
{
return {ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION};
}
-NODISCARD inline std::vector<std::string> ConsumeRandomLengthStringVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16, const size_t max_string_length = 16) noexcept
+[[nodiscard]] inline std::vector<std::string> ConsumeRandomLengthStringVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16, const size_t max_string_length = 16) noexcept
{
const size_t n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size);
std::vector<std::string> r;
@@ -62,7 +62,7 @@ NODISCARD inline std::vector<std::string> ConsumeRandomLengthStringVector(Fuzzed
}
template <typename T>
-NODISCARD inline std::vector<T> ConsumeRandomLengthIntegralVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16) noexcept
+[[nodiscard]] inline std::vector<T> ConsumeRandomLengthIntegralVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16) noexcept
{
const size_t n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size);
std::vector<T> r;
@@ -73,7 +73,7 @@ NODISCARD inline std::vector<T> ConsumeRandomLengthIntegralVector(FuzzedDataProv
}
template <typename T>
-NODISCARD inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
{
const std::vector<uint8_t> buffer = ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length);
CDataStream ds{buffer, SER_NETWORK, INIT_PROTO_VERSION};
@@ -86,35 +86,36 @@ NODISCARD inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzz
return obj;
}
-NODISCARD inline opcodetype ConsumeOpcodeType(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline opcodetype ConsumeOpcodeType(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return static_cast<opcodetype>(fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, MAX_OPCODE));
}
-NODISCARD inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, MAX_MONEY);
}
-NODISCARD inline int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
- static const int64_t time_min = ParseISO8601DateTime("1970-01-01T00:00:00Z");
+ // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) is a no-op.
+ static const int64_t time_min = ParseISO8601DateTime("1970-01-01T00:00:01Z");
static const int64_t time_max = ParseISO8601DateTime("9999-12-31T23:59:59Z");
return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(time_min, time_max);
}
-NODISCARD inline CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
return {b.begin(), b.end()};
}
-NODISCARD inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
}
-NODISCARD inline uint160 ConsumeUInt160(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline uint160 ConsumeUInt160(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
const std::vector<uint8_t> v160 = fuzzed_data_provider.ConsumeBytes<uint8_t>(160 / 8);
if (v160.size() != 160 / 8) {
@@ -123,7 +124,7 @@ NODISCARD inline uint160 ConsumeUInt160(FuzzedDataProvider& fuzzed_data_provider
return uint160{v160};
}
-NODISCARD inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
const std::vector<uint8_t> v256 = fuzzed_data_provider.ConsumeBytes<uint8_t>(256 / 8);
if (v256.size() != 256 / 8) {
@@ -132,12 +133,12 @@ NODISCARD inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider
return uint256{v256};
}
-NODISCARD inline arith_uint256 ConsumeArithUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline arith_uint256 ConsumeArithUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return UintToArith256(ConsumeUInt256(fuzzed_data_provider));
}
-NODISCARD inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider, const CTransaction& tx) noexcept
+[[nodiscard]] inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider, const CTransaction& tx) noexcept
{
// Avoid:
// policy/feerate.cpp:28:34: runtime error: signed integer overflow: 34873208148477500 * 1000 cannot be represented in type 'long'
@@ -152,7 +153,7 @@ NODISCARD inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzze
return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
}
-NODISCARD inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
CTxDestination tx_destination;
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
@@ -190,7 +191,7 @@ NODISCARD inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_
}
template <typename T>
-NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept
+[[nodiscard]] bool MultiplicationOverflow(const T i, const T j) noexcept
{
static_assert(std::is_integral<T>::value, "Integral required.");
if (std::numeric_limits<T>::is_signed) {
@@ -213,7 +214,7 @@ NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept
}
template <class T>
-NODISCARD bool AdditionOverflow(const T i, const T j) noexcept
+[[nodiscard]] bool AdditionOverflow(const T i, const T j) noexcept
{
static_assert(std::is_integral<T>::value, "Integral required.");
if (std::numeric_limits<T>::is_signed) {
@@ -223,7 +224,7 @@ NODISCARD bool AdditionOverflow(const T i, const T j) noexcept
return std::numeric_limits<T>::max() - i < j;
}
-NODISCARD inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept
+[[nodiscard]] inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept
{
for (const CTxIn& tx_in : tx.vin) {
const Coin& coin = inputs.AccessCoin(tx_in.prevout);
@@ -238,7 +239,7 @@ NODISCARD inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsVie
* Returns a byte vector of specified size regardless of the number of remaining bytes available
* from the fuzzer. Pads with zero value bytes if needed to achieve the specified size.
*/
-NODISCARD inline std::vector<uint8_t> ConsumeFixedLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t length) noexcept
+[[nodiscard]] inline std::vector<uint8_t> ConsumeFixedLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t length) noexcept
{
std::vector<uint8_t> result(length);
const std::vector<uint8_t> random_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(length);
@@ -419,7 +420,7 @@ public:
}
};
-NODISCARD inline FuzzedFileProvider ConsumeFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline FuzzedFileProvider ConsumeFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return {fuzzed_data_provider};
}
@@ -440,7 +441,7 @@ public:
}
};
-NODISCARD inline FuzzedAutoFileProvider ConsumeAutoFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
+[[nodiscard]] inline FuzzedAutoFileProvider ConsumeAutoFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
return {fuzzed_data_provider};
}
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 2d3137e1e2..adf5970206 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -141,8 +141,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
- m_node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator);
- m_node.mempool->setSanityCheck(1.0);
+ m_node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator, 1);
m_node.chainman = &::g_chainman;
m_node.chainman->InitializeChainstate(*m_node.mempool);
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 0c2b731967..d18182c07d 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -331,15 +331,10 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee,
assert(int(nSigOpCostWithAncestors) >= 0);
}
-CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator)
- : nTransactionsUpdated(0), minerPolicyEstimator(estimator), m_epoch(0), m_has_epoch_guard(false)
+CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio)
+ : m_check_ratio(check_ratio), minerPolicyEstimator(estimator)
{
_clear(); //lock free clear
-
- // Sanity checks off by default for performance, because otherwise
- // accepting transactions becomes O(N^2) where N is the number
- // of transactions in the pool
- nCheckFrequency = 0;
}
bool CTxMemPool::isSpent(const COutPoint& outpoint) const
@@ -523,7 +518,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem
if (it2 != mapTx.end())
continue;
const Coin &coin = pcoins->AccessCoin(txin.prevout);
- if (nCheckFrequency != 0) assert(!coin.IsSpent());
+ if (m_check_ratio != 0) assert(!coin.IsSpent());
if (coin.IsSpent() || (coin.IsCoinBase() && ((signed long)nMemPoolHeight) - coin.nHeight < COINBASE_MATURITY)) {
txToRemove.insert(it);
break;
@@ -619,13 +614,11 @@ static void CheckInputsAndUpdateCoins(const CTransaction& tx, CCoinsViewCache& m
void CTxMemPool::check(const CCoinsViewCache *pcoins) const
{
- LOCK(cs);
- if (nCheckFrequency == 0)
- return;
+ if (m_check_ratio == 0) return;
- if (GetRand(std::numeric_limits<uint32_t>::max()) >= nCheckFrequency)
- return;
+ if (GetRand(m_check_ratio) >= 1) return;
+ LOCK(cs);
LogPrint(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
uint64_t checkTotal = 0;
diff --git a/src/txmempool.h b/src/txmempool.h
index f513f14af6..78ad62aae6 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -488,8 +488,8 @@ public:
class CTxMemPool
{
private:
- uint32_t nCheckFrequency GUARDED_BY(cs); //!< Value n means that n times in 2^32 we check.
- std::atomic<unsigned int> nTransactionsUpdated; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
+ const int m_check_ratio; //!< Value n means that 1 times in n we check.
+ std::atomic<unsigned int> nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
CBlockPolicyEstimator* minerPolicyEstimator;
uint64_t totalTxSize; //!< sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discounted. Defined in BIP 141.
@@ -498,8 +498,8 @@ private:
mutable int64_t lastRollingFeeUpdate;
mutable bool blockSinceLastRollingFeeBump;
mutable double rollingMinimumFeeRate; //!< minimum fee to get into the pool, decreases exponentially
- mutable uint64_t m_epoch;
- mutable bool m_has_epoch_guard;
+ mutable uint64_t m_epoch{0};
+ mutable bool m_has_epoch_guard{false};
// In-memory counter for external mempool tracking purposes.
// This number is incremented once every time a transaction
@@ -601,8 +601,14 @@ public:
std::map<uint256, CAmount> mapDeltas;
/** Create a new CTxMemPool.
+ * Sanity checks will be off by default for performance, because otherwise
+ * accepting transactions becomes O(N^2) where N is the number of transactions
+ * in the pool.
+ *
+ * @param[in] estimator is used to estimate appropriate transaction fees.
+ * @param[in] check_ratio is the ratio used to determine how often sanity checks will run.
*/
- explicit CTxMemPool(CBlockPolicyEstimator* estimator = nullptr);
+ explicit CTxMemPool(CBlockPolicyEstimator* estimator = nullptr, int check_ratio = 0);
/**
* If sanity-checking is turned on, check makes sure the pool is
@@ -611,7 +617,6 @@ public:
* check does nothing.
*/
void check(const CCoinsViewCache *pcoins) const;
- void setSanityCheck(double dFrequency = 1.0) { LOCK(cs); nCheckFrequency = static_cast<uint32_t>(dFrequency * 4294967295.0); }
// addUnchecked must updated state for all ancestors of a given transaction,
// to track size/count of descendant transactions. First version of
diff --git a/src/util/bip32.h b/src/util/bip32.h
index 347e83db9e..8f86f2aaa6 100644
--- a/src/util/bip32.h
+++ b/src/util/bip32.h
@@ -10,7 +10,7 @@
#include <vector>
/** Parse an HD keypaths like "m/7/0'/2000". */
-NODISCARD bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath);
+[[nodiscard]] bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath);
/** Write HD keypaths as strings */
std::string WriteHDKeypath(const std::vector<uint32_t>& keypath);
diff --git a/src/util/moneystr.h b/src/util/moneystr.h
index 9d2b6da0fc..da7f673cda 100644
--- a/src/util/moneystr.h
+++ b/src/util/moneystr.h
@@ -19,6 +19,6 @@
*/
std::string FormatMoney(const CAmount& n);
/** Parse an amount denoted in full coins. E.g. "0.0034" supplied on the command line. **/
-NODISCARD bool ParseMoney(const std::string& str, CAmount& nRet);
+[[nodiscard]] bool ParseMoney(const std::string& str, CAmount& nRet);
#endif // BITCOIN_UTIL_MONEYSTR_H
diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp
index 3236184b0b..f3d54a2ac9 100644
--- a/src/util/strencodings.cpp
+++ b/src/util/strencodings.cpp
@@ -280,7 +280,7 @@ std::string DecodeBase32(const std::string& str, bool* pf_invalid)
return std::string((const char*)vchRet.data(), vchRet.size());
}
-NODISCARD static bool ParsePrechecks(const std::string& str)
+[[nodiscard]] static bool ParsePrechecks(const std::string& str)
{
if (str.empty()) // No empty string allowed
return false;
diff --git a/src/util/strencodings.h b/src/util/strencodings.h
index 1a217dd12d..8ee43c620b 100644
--- a/src/util/strencodings.h
+++ b/src/util/strencodings.h
@@ -101,42 +101,42 @@ constexpr inline bool IsSpace(char c) noexcept {
* @returns true if the entire string could be parsed as valid integer,
* false if not the entire string could be parsed or when overflow or underflow occurred.
*/
-NODISCARD bool ParseInt32(const std::string& str, int32_t *out);
+[[nodiscard]] bool ParseInt32(const std::string& str, int32_t *out);
/**
* Convert string to signed 64-bit integer with strict parse error feedback.
* @returns true if the entire string could be parsed as valid integer,
* false if not the entire string could be parsed or when overflow or underflow occurred.
*/
-NODISCARD bool ParseInt64(const std::string& str, int64_t *out);
+[[nodiscard]] bool ParseInt64(const std::string& str, int64_t *out);
/**
* Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
* @returns true if the entire string could be parsed as valid integer,
* false if not the entire string could be parsed or when overflow or underflow occurred.
*/
-NODISCARD bool ParseUInt8(const std::string& str, uint8_t *out);
+[[nodiscard]] bool ParseUInt8(const std::string& str, uint8_t *out);
/**
* Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
* @returns true if the entire string could be parsed as valid integer,
* false if not the entire string could be parsed or when overflow or underflow occurred.
*/
-NODISCARD bool ParseUInt32(const std::string& str, uint32_t *out);
+[[nodiscard]] bool ParseUInt32(const std::string& str, uint32_t *out);
/**
* Convert decimal string to unsigned 64-bit integer with strict parse error feedback.
* @returns true if the entire string could be parsed as valid integer,
* false if not the entire string could be parsed or when overflow or underflow occurred.
*/
-NODISCARD bool ParseUInt64(const std::string& str, uint64_t *out);
+[[nodiscard]] bool ParseUInt64(const std::string& str, uint64_t *out);
/**
* Convert string to double with strict parse error feedback.
* @returns true if the entire string could be parsed as valid double,
* false if not the entire string could be parsed or when overflow or underflow occurred.
*/
-NODISCARD bool ParseDouble(const std::string& str, double *out);
+[[nodiscard]] bool ParseDouble(const std::string& str, double *out);
/**
* Convert a span of bytes to a lower-case hexadecimal string.
@@ -170,7 +170,7 @@ bool TimingResistantEqual(const T& a, const T& b)
* @returns true on success, false on error.
* @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger.
*/
-NODISCARD bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out);
+[[nodiscard]] bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out);
/** Convert from one power-of-2 number base to another. */
template<int frombits, int tobits, bool pad, typename O, typename I>
diff --git a/src/util/string.h b/src/util/string.h
index a0c87bd00c..5ffdc80d88 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -15,7 +15,7 @@
#include <string>
#include <vector>
-NODISCARD inline std::string TrimString(const std::string& str, const std::string& pattern = " \f\n\r\t\v")
+[[nodiscard]] inline std::string TrimString(const std::string& str, const std::string& pattern = " \f\n\r\t\v")
{
std::string::size_type front = str.find_first_not_of(pattern);
if (front == std::string::npos) {
@@ -59,7 +59,7 @@ inline std::string Join(const std::vector<std::string>& list, const std::string&
/**
* Check if a string does not contain any embedded NUL (\0) characters
*/
-NODISCARD inline bool ValidAsCString(const std::string& str) noexcept
+[[nodiscard]] inline bool ValidAsCString(const std::string& str) noexcept
{
return str.size() == strlen(str.c_str());
}
@@ -80,7 +80,7 @@ std::string ToString(const T& t)
* Check whether a container begins with the given prefix.
*/
template <typename T1, size_t PREFIX_LEN>
-NODISCARD inline bool HasPrefix(const T1& obj,
+[[nodiscard]] inline bool HasPrefix(const T1& obj,
const std::array<uint8_t, PREFIX_LEN>& prefix)
{
return obj.size() >= PREFIX_LEN &&
diff --git a/src/util/system.h b/src/util/system.h
index 1df194ca84..2be8bb754b 100644
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -60,7 +60,7 @@ bool FileCommit(FILE *file);
bool TruncateFile(FILE *file, unsigned int length);
int RaiseFileDescriptorLimit(int nMinFD);
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
-bool RenameOver(fs::path src, fs::path dest);
+[[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false);
void UnlockDirectory(const fs::path& directory, const std::string& lockfile_name);
bool DirIsWritable(const fs::path& directory);
@@ -188,7 +188,7 @@ protected:
std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
- NODISCARD bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false);
+ [[nodiscard]] bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false);
/**
* Returns true if settings values from the default section should be used,
@@ -220,8 +220,8 @@ public:
*/
void SelectConfigNetwork(const std::string& network);
- NODISCARD bool ParseParameters(int argc, const char* const argv[], std::string& error);
- NODISCARD bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
+ [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error);
+ [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
/**
* Log warnings for options in m_section_only_args when
diff --git a/src/validation.cpp b/src/validation.cpp
index 5ddee092bf..d8f7bfc913 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -5110,7 +5110,9 @@ bool DumpMempool(const CTxMemPool& pool)
if (!FileCommit(file.Get()))
throw std::runtime_error("FileCommit failed");
file.fclose();
- RenameOver(GetDataDir() / "mempool.dat.new", GetDataDir() / "mempool.dat");
+ if (!RenameOver(GetDataDir() / "mempool.dat.new", GetDataDir() / "mempool.dat")) {
+ throw std::runtime_error("Rename failed");
+ }
int64_t last = GetTimeMicros();
LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*MICRO, (last-mid)*MICRO);
} catch (const std::exception& e) {
diff --git a/src/interfaces/wallet.cpp b/src/wallet/interfaces.cpp
index f68016b557..3fbba9ab92 100644
--- a/src/interfaces/wallet.cpp
+++ b/src/wallet/interfaces.cpp
@@ -31,9 +31,22 @@
#include <utility>
#include <vector>
-namespace interfaces {
-namespace {
+using interfaces::Chain;
+using interfaces::FoundBlock;
+using interfaces::Handler;
+using interfaces::MakeHandler;
+using interfaces::Wallet;
+using interfaces::WalletAddress;
+using interfaces::WalletBalances;
+using interfaces::WalletClient;
+using interfaces::WalletOrderForm;
+using interfaces::WalletTx;
+using interfaces::WalletTxOut;
+using interfaces::WalletTxStatus;
+using interfaces::WalletValueMap;
+namespace wallet {
+namespace {
//! Construct wallet tx struct.
WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx)
{
@@ -561,14 +574,14 @@ public:
std::vector<std::unique_ptr<Handler>> m_rpc_handlers;
std::list<CRPCCommand> m_rpc_commands;
};
-
} // namespace
+} // namespace wallet
-std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet) { return wallet ? MakeUnique<WalletImpl>(wallet) : nullptr; }
+namespace interfaces {
+std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet) { return wallet ? MakeUnique<wallet::WalletImpl>(wallet) : nullptr; }
std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, ArgsManager& args)
{
- return MakeUnique<WalletClientImpl>(chain, args);
+ return MakeUnique<wallet::WalletClientImpl>(chain, args);
}
-
} // namespace interfaces
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index e66377c13c..7ea6a214b2 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2789,7 +2789,7 @@ static RPCHelpMan unloadwallet()
"Unloads the wallet referenced by the request endpoint otherwise unloads the wallet specified in the argument.\n"
"Specifying the wallet name on a wallet endpoint is invalid.",
{
- {"wallet_name", RPCArg::Type::STR, /* default */ "the wallet name from the RPC endpoint", "The name of the wallet to unload. Must be provided in the RPC endpoint or this parameter (but not both)."},
+ {"wallet_name", RPCArg::Type::STR, /* default */ "the wallet name from the RPC endpoint", "The name of the wallet to unload. If provided both here and in the RPC endpoint, the two must be identical."},
{"load_on_startup", RPCArg::Type::BOOL, /* default */ "null", "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},
},
RPCResult{RPCResult::Type::OBJ, "", "", {
@@ -2803,8 +2803,8 @@ static RPCHelpMan unloadwallet()
{
std::string wallet_name;
if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) {
- if (!request.params[0].isNull()) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Both the RPC endpoint wallet and wallet_name parameter were provided (only one allowed)");
+ if (!(request.params[0].isNull() || request.params[0].get_str() == wallet_name)) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "RPC endpoint wallet and wallet_name parameter specify different wallets");
}
} else {
wallet_name = request.params[0].get_str();