aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.test.include13
-rw-r--r--src/bech32.cpp4
-rw-r--r--src/bitcoin-cli.cpp5
-rw-r--r--src/bitcoin-tx.cpp2
-rw-r--r--src/chainparams.cpp13
-rw-r--r--src/coins.h4
-rw-r--r--src/cuckoocache.h6
-rw-r--r--src/dbwrapper.cpp2
-rw-r--r--src/httpserver.cpp8
-rw-r--r--src/init.cpp50
-rw-r--r--src/net.cpp16
-rw-r--r--src/net.h2
-rw-r--r--src/net_processing.cpp4
-rw-r--r--src/net_processing.h2
-rw-r--r--src/noui.cpp7
-rw-r--r--src/noui.h12
-rw-r--r--src/qt/bitcoin.cpp7
-rw-r--r--src/qt/bitcoingui.cpp11
-rw-r--r--src/qt/peertablemodel.cpp2
-rw-r--r--src/qt/sendcoinsdialog.cpp2
-rw-r--r--src/qt/splashscreen.cpp2
-rw-r--r--src/qt/test/util.h2
-rw-r--r--src/qt/trafficgraphwidget.cpp4
-rw-r--r--src/qt/transactiondesc.cpp4
-rw-r--r--src/qt/transactionrecord.cpp4
-rw-r--r--src/random.cpp7
-rw-r--r--src/rest.cpp2
-rw-r--r--src/rpc/blockchain.cpp14
-rw-r--r--src/rpc/blockchain.h3
-rw-r--r--src/rpc/client.cpp2
-rw-r--r--src/rpc/mining.cpp6
-rw-r--r--src/rpc/misc.cpp35
-rw-r--r--src/rpc/net.cpp4
-rw-r--r--src/rpc/rawtransaction.cpp118
-rw-r--r--src/rpc/server.cpp2
-rw-r--r--src/scheduler.h2
-rw-r--r--src/script/descriptor.cpp4
-rw-r--r--src/script/descriptor.h51
-rw-r--r--src/streams.h2
-rw-r--r--src/support/lockedpool.cpp4
-rw-r--r--src/sync.cpp8
-rw-r--r--src/sync.h112
-rw-r--r--src/test/checkqueue_tests.cpp4
-rw-r--r--src/test/coins_tests.cpp18
-rw-r--r--src/test/cuckoocache_tests.cpp6
-rw-r--r--src/test/dbwrapper_tests.cpp12
-rw-r--r--src/test/gen/crypto_gen.cpp19
-rw-r--r--src/test/gen/crypto_gen.h63
-rw-r--r--src/test/getarg_tests.cpp2
-rw-r--r--src/test/key_io_tests.cpp2
-rw-r--r--src/test/key_properties.cpp53
-rw-r--r--src/test/net_tests.cpp4
-rw-r--r--src/test/scheduler_tests.cpp6
-rw-r--r--src/test/skiplist_tests.cpp2
-rw-r--r--src/test/sync_tests.cpp52
-rw-r--r--src/test/test_bitcoin.cpp2
-rw-r--r--src/test/transaction_tests.cpp2
-rw-r--r--src/test/util_tests.cpp4
-rw-r--r--src/threadinterrupt.cpp6
-rw-r--r--src/threadinterrupt.h4
-rw-r--r--src/threadsafety.h2
-rw-r--r--src/timedata.cpp4
-rw-r--r--src/txmempool.cpp48
-rw-r--r--src/txmempool.h12
-rw-r--r--src/univalue/gen/gen.cpp2
-rw-r--r--src/univalue/include/univalue.h68
-rw-r--r--src/univalue/lib/univalue.cpp16
-rw-r--r--src/univalue/lib/univalue_read.cpp12
-rw-r--r--src/univalue/lib/univalue_write.cpp18
-rw-r--r--src/univalue/test/unitester.cpp15
-rw-r--r--src/util.cpp23
-rw-r--r--src/utilstrencodings.cpp2
-rw-r--r--src/validation.cpp33
-rw-r--r--src/validation.h4
-rw-r--r--src/wallet/crypter.cpp2
-rw-r--r--src/wallet/db.cpp4
-rw-r--r--src/wallet/rpcdump.cpp44
-rw-r--r--src/wallet/rpcwallet.cpp5
-rw-r--r--src/wallet/test/wallet_tests.cpp16
-rw-r--r--src/wallet/wallet.cpp40
-rw-r--r--src/wallet/wallet.h2
-rw-r--r--src/wallet/walletdb.cpp6
82 files changed, 614 insertions, 589 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index abfd66efad..c4ee5f5fcc 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -8,6 +8,7 @@ TEST_SRCDIR = test
TEST_BINARY=test/test_bitcoin$(EXEEXT)
JSON_TEST_FILES = \
+ test/data/script_tests.json \
test/data/base58_encode_decode.json \
test/data/blockfilters.json \
test/data/key_io_valid.json \
@@ -83,6 +84,7 @@ BITCOIN_TESTS =\
test/sigopcount_tests.cpp \
test/skiplist_tests.cpp \
test/streams_tests.cpp \
+ test/sync_tests.cpp \
test/timedata_tests.cpp \
test/torcontrol_tests.cpp \
test/transaction_tests.cpp \
@@ -94,6 +96,15 @@ BITCOIN_TESTS =\
test/validation_block_tests.cpp \
test/versionbits_tests.cpp
+if ENABLE_PROPERTY_TESTS
+BITCOIN_TESTS += \
+ test/key_properties.cpp
+
+BITCOIN_TEST_SUITE += \
+ test/gen/crypto_gen.cpp \
+ test/gen/crypto_gen.h
+endif
+
if ENABLE_WALLET
BITCOIN_TESTS += \
wallet/test/psbt_wallet_tests.cpp \
@@ -117,7 +128,7 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
-test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
+test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(RAPIDCHECK_LIBS)
test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
if ENABLE_ZMQ
diff --git a/src/bech32.cpp b/src/bech32.cpp
index c55f22b9b7..d6b29391a9 100644
--- a/src/bech32.cpp
+++ b/src/bech32.cpp
@@ -62,7 +62,7 @@ uint32_t PolyMod(const data& v)
// v, it corresponds to x^2 + v0*x + v1 mod g(x). As 1 mod g(x) = 1, that is the starting value
// for `c`.
uint32_t c = 1;
- for (auto v_i : v) {
+ for (const auto v_i : v) {
// We want to update `c` to correspond to a polynomial with one extra term. If the initial
// value of `c` consists of the coefficients of c(x) = f(x) mod g(x), we modify it to
// correspond to c'(x) = (f(x) * x + v_i) mod g(x), where v_i is the next input to
@@ -149,7 +149,7 @@ std::string Encode(const std::string& hrp, const data& values) {
data combined = Cat(values, checksum);
std::string ret = hrp + '1';
ret.reserve(ret.size() + combined.size());
- for (auto c : combined) {
+ for (const auto c : combined) {
ret += CHARSET[c];
}
return ret;
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index c9414e67c7..53c3821ce5 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -35,6 +35,7 @@ static void SetupCliArgs()
{
const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
+ const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST);
gArgs.AddArg("-?", "This help message", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-version", "Print version and exit", false, OptionsCategory::OPTIONS);
@@ -45,9 +46,9 @@ static void SetupCliArgs()
gArgs.AddArg("-named", strprintf("Pass named instead of positional arguments (default: %s)", DEFAULT_NAMED), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcclienttimeout=<n>", strprintf("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)", DEFAULT_HTTP_CLIENT_TIMEOUT), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcconnect=<ip>", strprintf("Send commands to node running on <ip> (default: %s)", DEFAULT_RPCCONNECT), false, OptionsCategory::OPTIONS);
- gArgs.AddArg("-rpccookiefile=<loc>", _("Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)"), false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", false, OptionsCategory::OPTIONS);
- gArgs.AddArg("-rpcport=<port>", strprintf("Connect to JSON-RPC on <port> (default: %u or testnet: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()), false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-rpcport=<port>", strprintf("Connect to JSON-RPC on <port> (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcwait", "Wait for RPC server to start", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-rpcwallet=<walletname>", "Send RPC for non-default wallet on RPC server (needs to exactly match corresponding -wallet option passed to bitcoind)", false, OptionsCategory::OPTIONS);
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 20f0218ac1..9ee3e8eee7 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -385,7 +385,7 @@ static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& s
CScript scriptPubKey = GetScriptForMultisig(required, pubkeys);
if (bSegWit) {
- for (CPubKey& pubkey : pubkeys) {
+ for (const CPubKey& pubkey : pubkeys) {
if (!pubkey.IsCompressed()) {
throw std::runtime_error("Uncompressed pubkeys are not useable for SegWit outputs");
}
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 93bb3e7647..b80cc2c259 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -4,16 +4,15 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
-#include <consensus/merkle.h>
+#include <chainparamsseeds.h>
+#include <consensus/merkle.h>
#include <tinyformat.h>
#include <util.h>
#include <utilstrencodings.h>
#include <assert.h>
-#include <chainparamsseeds.h>
-
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
CMutableTransaction txNew;
@@ -62,14 +61,6 @@ void CChainParams::UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64
/**
* Main network
*/
-/**
- * What makes a good checkpoint block?
- * + Is surrounded by blocks with reasonable timestamps
- * (no blocks before with a timestamp after, none after with
- * timestamp before)
- * + Contains no strange transactions
- */
-
class CMainParams : public CChainParams {
public:
CMainParams() {
diff --git a/src/coins.h b/src/coins.h
index 41a422f485..3867a37b39 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -285,8 +285,8 @@ public:
* Note that lightweight clients may not know anything besides the hash of previous transactions,
* so may not be able to calculate this.
*
- * @param[in] tx transaction for which we are checking input total
- * @return Sum of value of all inputs (scriptSigs)
+ * @param[in] tx transaction for which we are checking input total
+ * @return Sum of value of all inputs (scriptSigs)
*/
CAmount GetValueIn(const CTransaction& tx) const;
diff --git a/src/cuckoocache.h b/src/cuckoocache.h
index 15f6873961..4d0b094fa2 100644
--- a/src/cuckoocache.h
+++ b/src/cuckoocache.h
@@ -397,7 +397,7 @@ public:
std::array<uint32_t, 8> locs = compute_hashes(e);
// Make sure we have not already inserted this element
// If we have, make sure that it does not get deleted
- for (uint32_t loc : locs)
+ for (const uint32_t loc : locs)
if (table[loc] == e) {
please_keep(loc);
epoch_flags[loc] = last_epoch;
@@ -405,7 +405,7 @@ public:
}
for (uint8_t depth = 0; depth < depth_limit; ++depth) {
// First try to insert to an empty slot, if one exists
- for (uint32_t loc : locs) {
+ for (const uint32_t loc : locs) {
if (!collection_flags.bit_is_set(loc))
continue;
table[loc] = std::move(e);
@@ -467,7 +467,7 @@ public:
inline bool contains(const Element& e, const bool erase) const
{
std::array<uint32_t, 8> locs = compute_hashes(e);
- for (uint32_t loc : locs)
+ for (const uint32_t loc : locs)
if (table[loc] == e) {
if (erase)
allow_erase(loc);
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
index f5fb715800..58d8cc2c9d 100644
--- a/src/dbwrapper.cpp
+++ b/src/dbwrapper.cpp
@@ -78,7 +78,7 @@ static void SetMaxOpenFiles(leveldb::Options *options) {
// do not interfere with select() loops. On 64-bit Unix hosts this value is
// also OK, because up to that amount LevelDB will use an mmap
// implementation that does not use extra file descriptors (the fds are
- // closed after being mmaped).
+ // closed after being mmap'ed).
//
// Increasing the value beyond the default is dangerous because LevelDB will
// fall back to a non-mmap implementation when the file count is too large.
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index 0fdc3e5ff3..326f7f6b64 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -69,7 +69,7 @@ class WorkQueue
{
private:
/** Mutex protects entire object */
- std::mutex cs;
+ Mutex cs;
std::condition_variable cond;
std::deque<std::unique_ptr<WorkItem>> queue;
bool running;
@@ -88,7 +88,7 @@ public:
/** Enqueue a work item */
bool Enqueue(WorkItem* item)
{
- std::unique_lock<std::mutex> lock(cs);
+ LOCK(cs);
if (queue.size() >= maxDepth) {
return false;
}
@@ -102,7 +102,7 @@ public:
while (true) {
std::unique_ptr<WorkItem> i;
{
- std::unique_lock<std::mutex> lock(cs);
+ WAIT_LOCK(cs, lock);
while (running && queue.empty())
cond.wait(lock);
if (!running)
@@ -116,7 +116,7 @@ public:
/** Interrupt and exit loops */
void Interrupt()
{
- std::unique_lock<std::mutex> lock(cs);
+ LOCK(cs);
running = false;
cond.notify_all();
}
diff --git a/src/init.cpp b/src/init.cpp
index bd330459f6..86a82ccaf6 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -343,8 +343,10 @@ void SetupServerArgs()
{
const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
+ const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST);
const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN);
const auto testnetChainParams = CreateChainParams(CBaseChainParams::TESTNET);
+ const auto regtestChainParams = CreateChainParams(CBaseChainParams::REGTEST);
// Hidden Options
std::vector<std::string> hidden_args = {"-rpcssl", "-benchmark", "-h", "-help", "-socks", "-tor", "-debugnet", "-whitelistalwaysrelay",
@@ -366,7 +368,7 @@ void SetupServerArgs()
gArgs.AddArg("-datadir=<dir>", "Specify data directory", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize), true, OptionsCategory::OPTIONS);
gArgs.AddArg("-dbcache=<n>", strprintf("Set database cache size in megabytes (%d to %d, default: %d)", nMinDbCache, nMaxDbCache, nDefaultDbCache), false, OptionsCategory::OPTIONS);
- gArgs.AddArg("-debuglogfile=<file>", strprintf("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (0 to disable; default: %s)", DEFAULT_DEBUGLOGFILE), false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-debuglogfile=<file>", strprintf("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (-nodebuglogfile to disable; default: %s)", DEFAULT_DEBUGLOGFILE), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER), true, OptionsCategory::OPTIONS);
gArgs.AddArg("-includeconf=<file>", "Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-loadblock=<file>", "Imports blocks from external blk000??.dat file on startup", false, OptionsCategory::OPTIONS);
@@ -386,7 +388,7 @@ void SetupServerArgs()
"Warning: Reverting this setting requires re-downloading the entire blockchain. "
"(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >=%u = automatically prune block files to stay under the specified target size in MiB)", MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-reindex", "Rebuild chain state and block index from the blk*.dat files on disk", false, OptionsCategory::OPTIONS);
- gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks", false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks. When in pruning mode or if blocks on disk might be corrupted, use full -reindex instead.", false, OptionsCategory::OPTIONS);
#ifndef WIN32
gArgs.AddArg("-sysperms", "Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)", false, OptionsCategory::OPTIONS);
#else
@@ -398,7 +400,7 @@ void SetupServerArgs()
gArgs.AddArg("-banscore=<n>", strprintf("Threshold for disconnecting misbehaving peers (default: %u)", DEFAULT_BANSCORE_THRESHOLD), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-bantime=<n>", strprintf("Number of seconds to keep misbehaving peers from reconnecting (default: %u)", DEFAULT_MISBEHAVING_BANTIME), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-bind=<addr>", "Bind to given address and always listen on it. Use [host]:port notation for IPv6", false, OptionsCategory::CONNECTION);
- gArgs.AddArg("-connect=<ip>", "Connect only to the specified node; -connect=0 disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", false, OptionsCategory::CONNECTION);
+ gArgs.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", false, OptionsCategory::CONNECTION);
gArgs.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", false, OptionsCategory::CONNECTION);
gArgs.AddArg("-dns", strprintf("Allow DNS lookups for -addnode, -seednode and -connect (default: %u)", DEFAULT_NAME_LOOKUP), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-dnsseed", "Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect used)", false, OptionsCategory::CONNECTION);
@@ -412,12 +414,12 @@ void SetupServerArgs()
gArgs.AddArg("-maxsendbuffer=<n>", strprintf("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-maxtimeadjustment", strprintf("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)", DEFAULT_MAX_TIME_ADJUSTMENT), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-maxuploadtarget=<n>", strprintf("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)", DEFAULT_MAX_UPLOAD_TARGET), false, OptionsCategory::CONNECTION);
- gArgs.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)", false, OptionsCategory::CONNECTION);
+ gArgs.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor hidden services, set -noonion to disable (default: -proxy)", false, OptionsCategory::CONNECTION);
gArgs.AddArg("-onlynet=<net>", "Make outgoing connections only through network <net> (ipv4, ipv6 or onion). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks.", false, OptionsCategory::CONNECTION);
gArgs.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), false, OptionsCategory::CONNECTION);
- gArgs.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u or testnet: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort()), false, OptionsCategory::CONNECTION);
- gArgs.AddArg("-proxy=<ip:port>", "Connect through SOCKS5 proxy", false, OptionsCategory::CONNECTION);
+ gArgs.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet: %u, regtest: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), false, OptionsCategory::CONNECTION);
+ gArgs.AddArg("-proxy=<ip:port>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled)", false, OptionsCategory::CONNECTION);
gArgs.AddArg("-proxyrandomize", strprintf("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)", DEFAULT_PROXYRANDOMIZE), false, OptionsCategory::CONNECTION);
gArgs.AddArg("-seednode=<ip>", "Connect to a node to retrieve peer addresses, and disconnect. This option can be specified multiple times to connect to multiple nodes.", false, OptionsCategory::CONNECTION);
gArgs.AddArg("-timeout=<n>", strprintf("Specify connection timeout in milliseconds (minimum: 1, default: %d)", DEFAULT_CONNECT_TIMEOUT), false, OptionsCategory::CONNECTION);
@@ -452,8 +454,8 @@ void SetupServerArgs()
gArgs.AddArg("-checkblocks=<n>", strprintf("How many blocks to check at startup (default: %u, 0 = all)", DEFAULT_CHECKBLOCKS), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-checklevel=<n>", strprintf("How thorough the block verification of -checkblocks is (0-4, default: %u)", DEFAULT_CHECKLEVEL), true, OptionsCategory::DEBUG_TEST);
- gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. (default: %u)", defaultChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
- gArgs.AddArg("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u)", defaultChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
+ gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
+ gArgs.AddArg("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-deprecatedrpc=<method>", "Allows deprecated RPC method(s) to be used", true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages", true, OptionsCategory::DEBUG_TEST);
@@ -465,7 +467,7 @@ void SetupServerArgs()
gArgs.AddArg("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-addrmantest", "Allows to test address relay on localhost", true, OptionsCategory::DEBUG_TEST);
- gArgs.AddArg("-debug=<category>", strprintf("Output debugging information (default: %u, supplying <category> is optional)", 0) + ". " +
+ gArgs.AddArg("-debug=<category>", "Output debugging information (default: -nodebug, supplying <category> is optional). "
"If <category> is not supplied or if <category> = 1, output all debugging information. <category> can be: " + ListLogCategories() + ".", false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-debugexclude=<category>", strprintf("Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories."), false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-help-debug", "Show all debugging options (usage: --help -help-debug)", false, OptionsCategory::DEBUG_TEST);
@@ -478,7 +480,7 @@ void SetupServerArgs()
gArgs.AddArg("-maxtxfee=<amt>", strprintf("Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE)), false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-printpriority", strprintf("Log transaction fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY), true, OptionsCategory::DEBUG_TEST);
- gArgs.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -daemon. To disable logging to file, set debuglogfile=0)", false, OptionsCategory::DEBUG_TEST);
+ gArgs.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -daemon. To disable logging to file, set -nodebuglogfile)", false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-shrinkdebugfile", "Shrink debug.log file on client startup (default: 1 when no -debug)", false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-uacomment=<cmt>", "Append comment to the user agent string", false, OptionsCategory::DEBUG_TEST);
@@ -507,7 +509,7 @@ void SetupServerArgs()
gArgs.AddArg("-rpcbind=<addr>[:port]", "Bind to given address to listen for JSON-RPC connections. This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost, or if -rpcallowip has been specified, 0.0.0.0 and :: i.e., all addresses)", false, OptionsCategory::RPC);
gArgs.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", false, OptionsCategory::RPC);
gArgs.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", false, OptionsCategory::RPC);
- gArgs.AddArg("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()), false, OptionsCategory::RPC);
+ gArgs.AddArg("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), false, OptionsCategory::RPC);
gArgs.AddArg("-rpcserialversion", strprintf("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)", DEFAULT_RPC_SERIALIZE_VERSION), false, OptionsCategory::RPC);
gArgs.AddArg("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT), true, OptionsCategory::RPC);
gArgs.AddArg("-rpcthreads=<n>", strprintf("Set the number of threads to service RPC calls (default: %d)", DEFAULT_HTTP_THREADS), false, OptionsCategory::RPC);
@@ -561,17 +563,17 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex
}
static bool fHaveGenesis = false;
-static CWaitableCriticalSection cs_GenesisWait;
-static CConditionVariable condvar_GenesisWait;
+static Mutex g_genesis_wait_mutex;
+static std::condition_variable g_genesis_wait_cv;
static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex)
{
if (pBlockIndex != nullptr) {
{
- WaitableLock lock_GenesisWait(cs_GenesisWait);
+ LOCK(g_genesis_wait_mutex);
fHaveGenesis = true;
}
- condvar_GenesisWait.notify_all();
+ g_genesis_wait_cv.notify_all();
}
}
@@ -1243,7 +1245,19 @@ bool AppInitMain()
LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime()));
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
LogPrintf("Using data directory %s\n", GetDataDir().string());
- LogPrintf("Using config file %s\n", GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string());
+
+ // Only log conf file usage message if conf file actually exists.
+ fs::path config_file_path = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
+ if (fs::exists(config_file_path)) {
+ LogPrintf("Config file: %s\n", config_file_path.string());
+ } else if (gArgs.IsArgSet("-conf")) {
+ // Warn if no conf file exists at path provided by user
+ InitWarning(strprintf(_("The specified config file %s does not exist\n"), config_file_path.string()));
+ } else {
+ // Not categorizing as "Warning" because it's the default behavior
+ LogPrintf("Config file: %s (not found, skipping)\n", config_file_path.string());
+ }
+
LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);
// Warn about relative -datadir path.
@@ -1661,12 +1675,12 @@ bool AppInitMain()
// Wait for genesis block to be processed
{
- WaitableLock lock(cs_GenesisWait);
+ WAIT_LOCK(g_genesis_wait_mutex, lock);
// We previously could hang here if StartShutdown() is called prior to
// ThreadImport getting started, so instead we just wait on a timer to
// check ShutdownRequested() regularly.
while (!fHaveGenesis && !ShutdownRequested()) {
- condvar_GenesisWait.wait_for(lock, std::chrono::milliseconds(500));
+ g_genesis_wait_cv.wait_for(lock, std::chrono::milliseconds(500));
}
uiInterface.NotifyBlockTip_disconnect(BlockNotifyGenesisWait);
}
diff --git a/src/net.cpp b/src/net.cpp
index df2cb54b7a..f83f39a67d 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -344,7 +344,7 @@ CNode* CConnman::FindNode(const CService& addr)
bool CConnman::CheckIncomingNonce(uint64_t nonce)
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes) {
+ for (const CNode* pnode : vNodes) {
if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
return false;
}
@@ -1227,7 +1227,7 @@ void CConnman::ThreadSocketHandler()
if(vNodesSize != nPrevNodeCount) {
nPrevNodeCount = vNodesSize;
if(clientInterface)
- clientInterface->NotifyNumConnectionsChanged(nPrevNodeCount);
+ clientInterface->NotifyNumConnectionsChanged(vNodesSize);
}
//
@@ -1614,7 +1614,7 @@ void CConnman::ThreadDNSAddressSeed()
LOCK(cs_vNodes);
int nRelevant = 0;
- for (auto pnode : vNodes) {
+ for (const CNode* pnode : vNodes) {
nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
}
if (nRelevant >= 2) {
@@ -1733,7 +1733,7 @@ int CConnman::GetExtraOutboundCount()
int nOutbound = 0;
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes) {
+ for (const CNode* pnode : vNodes) {
if (!pnode->fInbound && !pnode->m_manual_connection && !pnode->fFeeler && !pnode->fDisconnect && !pnode->fOneShot && pnode->fSuccessfullyConnected) {
++nOutbound;
}
@@ -1803,7 +1803,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
std::set<std::vector<unsigned char> > setConnected;
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes) {
+ for (const CNode* pnode : vNodes) {
if (!pnode->fInbound && !pnode->m_manual_connection) {
// Netgroups for inbound and addnode peers are not excluded because our goal here
// is to not use multiple of our limited outbound slots on a single netgroup
@@ -2065,7 +2065,7 @@ void CConnman::ThreadMessageHandler()
pnode->Release();
}
- std::unique_lock<std::mutex> lock(mutexMsgProc);
+ WAIT_LOCK(mutexMsgProc, lock);
if (!fMoreWork) {
condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this] { return fMsgProcWake; });
}
@@ -2167,7 +2167,7 @@ void Discover()
}
}
}
-#else
+#elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
// Get local host ip
struct ifaddrs* myaddrs;
if (getifaddrs(&myaddrs) == 0)
@@ -2347,7 +2347,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
flagInterruptMsgProc = false;
{
- std::unique_lock<std::mutex> lock(mutexMsgProc);
+ LOCK(mutexMsgProc);
fMsgProcWake = false;
}
diff --git a/src/net.h b/src/net.h
index edd2f8cf0d..9f6c426ab7 100644
--- a/src/net.h
+++ b/src/net.h
@@ -427,7 +427,7 @@ private:
bool fMsgProcWake;
std::condition_variable condMsgProc;
- std::mutex mutexMsgProc;
+ Mutex mutexMsgProc;
std::atomic<bool> flagInterruptMsgProc;
CThreadInterrupt interruptNet;
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 9f950831c4..b48a3bd221 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -882,7 +882,7 @@ void PeerLogicValidation::BlockConnected(const std::shared_ptr<const CBlock>& pb
// Erase orphan transactions included or precluded by this block
if (vOrphanErase.size()) {
int nErased = 0;
- for (uint256 &orphanHash : vOrphanErase) {
+ for (const uint256& orphanHash : vOrphanErase) {
nErased += EraseOrphanTx(orphanHash);
}
LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx included or conflicted by block\n", nErased);
@@ -2288,7 +2288,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
}
}
- for (uint256 hash : vEraseQueue)
+ for (const uint256& hash : vEraseQueue)
EraseOrphanTx(hash);
}
else if (fMissingInputs)
diff --git a/src/net_processing.h b/src/net_processing.h
index f16d00032e..496c3c7b0d 100644
--- a/src/net_processing.h
+++ b/src/net_processing.h
@@ -15,7 +15,7 @@ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
/** Default number of orphan+recently-replaced txn to keep around for block reconstruction */
static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN = 100;
/** Default for BIP61 (sending reject messages) */
-static constexpr bool DEFAULT_ENABLE_BIP61 = true;
+static constexpr bool DEFAULT_ENABLE_BIP61{false};
class PeerLogicValidation final : public CValidationInterface, public NetEventsInterface {
private:
diff --git a/src/noui.cpp b/src/noui.cpp
index 3a1ec2d050..df4bfabb66 100644
--- a/src/noui.cpp
+++ b/src/noui.cpp
@@ -14,7 +14,7 @@
#include <boost/signals2/connection.hpp>
-static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
+bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
{
bool fSecure = style & CClientUIInterface::SECURE;
style &= ~CClientUIInterface::SECURE;
@@ -41,19 +41,18 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str
return false;
}
-static bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style)
+bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style)
{
return noui_ThreadSafeMessageBox(message, caption, style);
}
-static void noui_InitMessage(const std::string& message)
+void noui_InitMessage(const std::string& message)
{
LogPrintf("init message: %s\n", message);
}
void noui_connect()
{
- // Connect bitcoind signal handlers
uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox);
uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion);
uiInterface.InitMessage_connect(noui_InitMessage);
diff --git a/src/noui.h b/src/noui.h
index ff16cc9aa8..169c2bbd7f 100644
--- a/src/noui.h
+++ b/src/noui.h
@@ -5,6 +5,16 @@
#ifndef BITCOIN_NOUI_H
#define BITCOIN_NOUI_H
-extern void noui_connect();
+#include <string>
+
+/** Non-GUI handler, which logs and prints messages. */
+bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style);
+/** Non-GUI handler, which logs and prints questions. */
+bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style);
+/** Non-GUI handler, which only logs a message. */
+void noui_InitMessage(const std::string& message);
+
+/** Connect all bitcoind signal handlers */
+void noui_connect();
#endif // BITCOIN_NOUI_H
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 712d20b71e..87282a961f 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -28,6 +28,7 @@
#include <interfaces/handler.h>
#include <interfaces/node.h>
+#include <noui.h>
#include <rpc/server.h>
#include <ui_interface.h>
#include <uint256.h>
@@ -71,9 +72,9 @@ Q_DECLARE_METATYPE(bool*)
Q_DECLARE_METATYPE(CAmount)
Q_DECLARE_METATYPE(uint256)
-static void InitMessage(const std::string &message)
+static void InitMessage(const std::string& message)
{
- LogPrintf("init message: %s\n", message);
+ noui_InitMessage(message);
}
/** Translate string to current locale using Qt. */
@@ -416,7 +417,7 @@ void BitcoinApplication::requestShutdown()
#ifdef ENABLE_WALLET
window->removeAllWallets();
- for (WalletModel *walletModel : m_wallet_models) {
+ for (const WalletModel* walletModel : m_wallet_models) {
delete walletModel;
}
m_wallet_models.clear();
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 5321cd94fd..51aff08c42 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -31,6 +31,7 @@
#include <chainparams.h>
#include <interfaces/handler.h>
#include <interfaces/node.h>
+#include <noui.h>
#include <ui_interface.h>
#include <util.h>
@@ -614,8 +615,11 @@ void BitcoinGUI::createTrayIconMenu()
#endif
// Configuration of the tray icon (or dock icon) icon menu
+#ifndef Q_OS_MAC
+ // Note: On Mac, the dock icon's menu already has show / hide action.
trayIconMenu->addAction(toggleHideAction);
trayIconMenu->addSeparator();
+#endif
trayIconMenu->addAction(sendCoinsMenuAction);
trayIconMenu->addAction(receiveCoinsMenuAction);
trayIconMenu->addSeparator();
@@ -1214,8 +1218,11 @@ void BitcoinGUI::showModalOverlay()
modalOverlay->toggleVisibility();
}
-static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style)
+static bool ThreadSafeMessageBox(BitcoinGUI* gui, const std::string& message, const std::string& caption, unsigned int style)
{
+ // Redundantly log and print message in non-gui fashion
+ noui_ThreadSafeMessageBox(message, caption, style);
+
bool modal = (style & CClientUIInterface::MODAL);
// The SECURE flag has no effect in the Qt GUI.
// bool secure = (style & CClientUIInterface::SECURE);
@@ -1273,7 +1280,7 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event)
void UnitDisplayStatusBarControl::createContextMenu()
{
menu = new QMenu(this);
- for (BitcoinUnits::Unit u : BitcoinUnits::availableUnits())
+ for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits())
{
QAction *menuAction = new QAction(QString(BitcoinUnits::longName(u)), this);
menuAction->setData(QVariant(u));
diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp
index 59a751fb12..8cfedca57f 100644
--- a/src/qt/peertablemodel.cpp
+++ b/src/qt/peertablemodel.cpp
@@ -65,7 +65,7 @@ public:
interfaces::Node::NodesStats nodes_stats;
node.getNodesStats(nodes_stats);
cachedNodeStats.reserve(nodes_stats.size());
- for (auto& node_stats : nodes_stats)
+ for (const auto& node_stats : nodes_stats)
{
CNodeCombinedStats stats;
stats.nodeStats = std::get<0>(node_stats);
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index eed71397ab..6f66bc19e1 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -348,7 +348,7 @@ void SendCoinsDialog::on_sendButton_clicked()
questionString.append("<hr />");
CAmount totalAmount = currentTransaction.getTotalTransactionAmount() + txFee;
QStringList alternativeUnits;
- for (BitcoinUnits::Unit u : BitcoinUnits::availableUnits())
+ for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits())
{
if(u != model->getOptionsModel()->getDisplayUnit())
alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount));
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index 0b111cc6d7..1eff4f6b65 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -200,7 +200,7 @@ void SplashScreen::unsubscribeFromCoreSignals()
// Disconnect signals from client
m_handler_init_message->disconnect();
m_handler_show_progress->disconnect();
- for (auto& handler : m_connected_wallet_handlers) {
+ for (const auto& handler : m_connected_wallet_handlers) {
handler->disconnect();
}
m_connected_wallet_handlers.clear();
diff --git a/src/qt/test/util.h b/src/qt/test/util.h
index 324386c139..5363c94547 100644
--- a/src/qt/test/util.h
+++ b/src/qt/test/util.h
@@ -5,7 +5,7 @@
* Press "Ok" button in message box dialog.
*
* @param text - Optionally store dialog text.
- * @param msec - Number of miliseconds to pause before triggering the callback.
+ * @param msec - Number of milliseconds to pause before triggering the callback.
*/
void ConfirmMessage(QString* text = nullptr, int msec = 0);
diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp
index f087e7569c..3aed3f2b97 100644
--- a/src/qt/trafficgraphwidget.cpp
+++ b/src/qt/trafficgraphwidget.cpp
@@ -141,10 +141,10 @@ void TrafficGraphWidget::updateRates()
}
float tmax = 0.0f;
- for (float f : vSamplesIn) {
+ for (const float f : vSamplesIn) {
if(f > tmax) tmax = f;
}
- for (float f : vSamplesOut) {
+ for (const float f : vSamplesOut) {
if(f > tmax) tmax = f;
}
fMax = tmax;
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index 6286ddc0e0..59332be754 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -152,13 +152,13 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall
else
{
isminetype fAllFromMe = ISMINE_SPENDABLE;
- for (isminetype mine : wtx.txin_is_mine)
+ for (const isminetype mine : wtx.txin_is_mine)
{
if(fAllFromMe > mine) fAllFromMe = mine;
}
isminetype fAllToMe = ISMINE_SPENDABLE;
- for (isminetype mine : wtx.txout_is_mine)
+ for (const isminetype mine : wtx.txout_is_mine)
{
if(fAllToMe > mine) fAllToMe = mine;
}
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index c767de5eda..d1a7527ac7 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -77,14 +77,14 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const interface
{
bool involvesWatchAddress = false;
isminetype fAllFromMe = ISMINE_SPENDABLE;
- for (isminetype mine : wtx.txin_is_mine)
+ for (const isminetype mine : wtx.txin_is_mine)
{
if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
if(fAllFromMe > mine) fAllFromMe = mine;
}
isminetype fAllToMe = ISMINE_SPENDABLE;
- for (isminetype mine : wtx.txout_is_mine)
+ for (const isminetype mine : wtx.txout_is_mine)
{
if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
if(fAllToMe > mine) fAllToMe = mine;
diff --git a/src/random.cpp b/src/random.cpp
index 6c5ad5ac96..503d5b3636 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -12,6 +12,7 @@
#include <wincrypt.h>
#endif
#include <logging.h> // for LogPrint()
+#include <sync.h> // for WAIT_LOCK
#include <utiltime.h> // for GetTime()
#include <stdlib.h>
@@ -295,7 +296,7 @@ void RandAddSeedSleep()
}
-static std::mutex cs_rng_state;
+static Mutex cs_rng_state;
static unsigned char rng_state[32] = {0};
static uint64_t rng_counter = 0;
@@ -305,7 +306,7 @@ static void AddDataToRng(void* data, size_t len) {
hasher.Write((const unsigned char*)data, len);
unsigned char buf[64];
{
- std::unique_lock<std::mutex> lock(cs_rng_state);
+ WAIT_LOCK(cs_rng_state, lock);
hasher.Write(rng_state, sizeof(rng_state));
hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter));
++rng_counter;
@@ -337,7 +338,7 @@ void GetStrongRandBytes(unsigned char* out, int num)
// Combine with and update state
{
- std::unique_lock<std::mutex> lock(cs_rng_state);
+ WAIT_LOCK(cs_rng_state, lock);
hasher.Write(rng_state, sizeof(rng_state));
hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter));
++rng_counter;
diff --git a/src/rest.cpp b/src/rest.cpp
index 12358cf50d..6ba15172fa 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -464,7 +464,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
oss >> fCheckMemPool;
oss >> vOutPoints;
}
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
// abort in case of unreadable binary data
return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
}
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index a77fea8ea8..9a3ec27d6d 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -50,7 +50,7 @@ struct CUpdatedBlock
int height;
};
-static std::mutex cs_blockchange;
+static Mutex cs_blockchange;
static std::condition_variable cond_blockchange;
static CUpdatedBlock latestblock;
@@ -225,7 +225,7 @@ static UniValue waitfornewblock(const JSONRPCRequest& request)
CUpdatedBlock block;
{
- std::unique_lock<std::mutex> lock(cs_blockchange);
+ WAIT_LOCK(cs_blockchange, lock);
block = latestblock;
if(timeout)
cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
@@ -267,7 +267,7 @@ static UniValue waitforblock(const JSONRPCRequest& request)
CUpdatedBlock block;
{
- std::unique_lock<std::mutex> lock(cs_blockchange);
+ WAIT_LOCK(cs_blockchange, lock);
if(timeout)
cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();});
else
@@ -310,7 +310,7 @@ static UniValue waitforblockheight(const JSONRPCRequest& request)
CUpdatedBlock block;
{
- std::unique_lock<std::mutex> lock(cs_blockchange);
+ WAIT_LOCK(cs_blockchange, lock);
if(timeout)
cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();});
else
@@ -426,7 +426,7 @@ static void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCK
UniValue spent(UniValue::VARR);
const CTxMemPool::txiter &it = mempool.mapTx.find(tx.GetHash());
const CTxMemPool::setEntries &setChildren = mempool.GetMemPoolChildren(it);
- for (const CTxMemPool::txiter &childiter : setChildren) {
+ for (CTxMemPool::txiter childiter : setChildren) {
spent.push_back(childiter->GetTx().GetHash().ToString());
}
@@ -2058,7 +2058,7 @@ UniValue scantxoutset(const JSONRPCRequest& request)
"or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n"
"unhardened or hardened child keys.\n"
"In the latter case, a range needs to be specified by below if different from 1000.\n"
- "For more information on output descriptors, see the documentation at TODO\n"
+ "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n"
"\nArguments:\n"
"1. \"action\" (string, required) The action to execute\n"
" \"start\" for starting a scan\n"
@@ -2192,6 +2192,7 @@ UniValue scantxoutset(const JSONRPCRequest& request)
return result;
}
+// clang-format off
static const CRPCCommand commands[] =
{ // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ----------
@@ -2227,6 +2228,7 @@ static const CRPCCommand commands[] =
{ "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} },
{ "hidden", "syncwithvalidationinterfacequeue", &syncwithvalidationinterfacequeue, {} },
};
+// clang-format on
void RegisterBlockchainRPCCommands(CRPCTable &t)
{
diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h
index 544bc62c36..add335eb8a 100644
--- a/src/rpc/blockchain.h
+++ b/src/rpc/blockchain.h
@@ -16,8 +16,7 @@ class UniValue;
static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
/**
- * Get the difficulty of the net wrt to the given block index, or the chain tip if
- * not provided.
+ * Get the difficulty of the net wrt to the given block index.
*
* @return A floating point number that is a multiple of the main net minimum
* difficulty (4295032833 hashes).
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 784d6416cf..f4d44fc809 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -18,6 +18,7 @@ public:
std::string paramName; //!< parameter name
};
+// clang-format off
/**
* Specify a (method, idx, name) here if the argument is a non-string RPC
* argument and needs to be converted from JSON.
@@ -163,6 +164,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "rescanblockchain", 1, "stop_height"},
{ "createwallet", 1, "disable_private_keys"},
};
+// clang-format on
class CRPCConvertTable
{
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 623b0bd86a..885ad834cf 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -470,7 +470,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
{
checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1);
- WaitableLock lock(g_best_block_mutex);
+ WAIT_LOCK(g_best_block_mutex, lock);
while (g_best_block == hashWatchedChain && IsRPCRunning())
{
if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout)
@@ -922,7 +922,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
UniValue result(UniValue::VOBJ);
- for (FeeEstimateHorizon horizon : {FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}) {
+ for (const FeeEstimateHorizon horizon : {FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}) {
CFeeRate feeRate;
EstimationResult buckets;
@@ -968,6 +968,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
return result;
}
+// clang-format off
static const CRPCCommand commands[] =
{ // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ----------
@@ -986,6 +987,7 @@ static const CRPCCommand commands[] =
{ "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} },
};
+// clang-format on
void RegisterMiningRPCCommands(CRPCTable &t)
{
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 40418545c1..0f3b601414 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -19,11 +19,6 @@
#include <timedata.h>
#include <util.h>
#include <utilstrencodings.h>
-#ifdef ENABLE_WALLET
-#include <wallet/rpcwallet.h>
-#include <wallet/wallet.h>
-#include <wallet/walletdb.h>
-#endif
#include <warnings.h>
#include <stdint.h>
@@ -67,29 +62,18 @@ static UniValue validateaddress(const JSONRPCRequest& request)
ret.pushKV("isvalid", isValid);
if (isValid)
{
+ std::string currentAddress = EncodeDestination(dest);
+ ret.pushKV("address", currentAddress);
-#ifdef ENABLE_WALLET
- if (HasWallets() && IsDeprecatedRPCEnabled("validateaddress")) {
- ret.pushKVs(getaddressinfo(request));
- }
-#endif
- if (ret["address"].isNull()) {
- std::string currentAddress = EncodeDestination(dest);
- ret.pushKV("address", currentAddress);
-
- CScript scriptPubKey = GetScriptForDestination(dest);
- ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
+ CScript scriptPubKey = GetScriptForDestination(dest);
+ ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
- UniValue detail = DescribeAddress(dest);
- ret.pushKVs(detail);
- }
+ UniValue detail = DescribeAddress(dest);
+ ret.pushKVs(detail);
}
return ret;
}
-// Needed even with !ENABLE_WALLET, to pass (ignored) pointers around
-class CWallet;
-
static UniValue createmultisig(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
@@ -130,8 +114,7 @@ static UniValue createmultisig(const JSONRPCRequest& request)
if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) {
pubkeys.push_back(HexToPubKey(keys[i].get_str()));
} else {
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\nNote that from v0.16, createmultisig no longer accepts addresses."
- " Users must use addmultisigaddress to create multisig addresses with addresses known to the wallet.", keys[i].get_str()));
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\n.", keys[i].get_str()));
}
}
@@ -456,12 +439,13 @@ static UniValue echo(const JSONRPCRequest& request)
return request.params;
}
+// clang-format off
static const CRPCCommand commands[] =
{ // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ----------
{ "control", "getmemoryinfo", &getmemoryinfo, {"mode"} },
{ "control", "logging", &logging, {"include", "exclude"}},
- { "util", "validateaddress", &validateaddress, {"address"} }, /* uses wallet if enabled */
+ { "util", "validateaddress", &validateaddress, {"address"} },
{ "util", "createmultisig", &createmultisig, {"nrequired","keys"} },
{ "util", "verifymessage", &verifymessage, {"address","signature","message"} },
{ "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} },
@@ -471,6 +455,7 @@ static const CRPCCommand commands[] =
{ "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
{ "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
};
+// clang-format on
void RegisterMiscRPCCommands(CRPCTable &t)
{
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 343b7d3b05..099a7cf1da 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -164,7 +164,7 @@ static UniValue getpeerinfo(const JSONRPCRequest& request)
obj.pushKV("synced_headers", statestats.nSyncHeight);
obj.pushKV("synced_blocks", statestats.nCommonHeight);
UniValue heights(UniValue::VARR);
- for (int height : statestats.vHeightInFlight) {
+ for (const int height : statestats.vHeightInFlight) {
heights.push_back(height);
}
obj.pushKV("inflight", heights);
@@ -626,6 +626,7 @@ static UniValue setnetworkactive(const JSONRPCRequest& request)
return g_connman->GetNetworkActive();
}
+// clang-format off
static const CRPCCommand commands[] =
{ // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ----------
@@ -642,6 +643,7 @@ static const CRPCCommand commands[] =
{ "network", "clearbanned", &clearbanned, {} },
{ "network", "setnetworkactive", &setnetworkactive, {"state"} },
};
+// clang-format on
void RegisterNetRPCCommands(CRPCTable &t)
{
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 248b963c0b..798d54f35d 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -27,9 +27,6 @@
#include <txmempool.h>
#include <uint256.h>
#include <utilstrencodings.h>
-#ifdef ENABLE_WALLET
-#include <wallet/rpcwallet.h>
-#endif
#include <future>
#include <stdint.h>
@@ -824,8 +821,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
view.AddCoin(out, std::move(newcoin), true);
}
- // if redeemScript given and not using the local wallet (private keys
- // given), add redeemScript to the keystore so it can be signed:
+ // if redeemScript and private keys were given, add redeemScript to the keystore so it can be signed
if (is_temp_keystore && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) {
RPCTypeCheckObj(prevOut,
{
@@ -980,102 +976,10 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
UniValue signrawtransaction(const JSONRPCRequest& request)
{
-#ifdef ENABLE_WALLET
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- CWallet* const pwallet = wallet.get();
-#endif
-
- if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
- throw std::runtime_error(
- "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
- "\nDEPRECATED. Sign inputs for raw transaction (serialized, hex-encoded).\n"
- "The second optional argument (may be null) is an array of previous transaction outputs that\n"
- "this transaction depends on but may not yet be in the block chain.\n"
- "The third optional argument (may be null) is an array of base58-encoded private\n"
- "keys that, if given, will be the only keys used to sign the transaction.\n"
-#ifdef ENABLE_WALLET
- + HelpRequiringPassphrase(pwallet) + "\n"
-#endif
- "\nArguments:\n"
- "1. \"hexstring\" (string, required) The transaction hex string\n"
- "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
- " [ (json array of json objects, or 'null' if none provided)\n"
- " {\n"
- " \"txid\":\"id\", (string, required) The transaction id\n"
- " \"vout\":n, (numeric, required) The output number\n"
- " \"scriptPubKey\": \"hex\", (string, required) script key\n"
- " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n"
- " \"amount\": value (numeric, required) The amount spent\n"
- " }\n"
- " ,...\n"
- " ]\n"
- "3. \"privkeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
- " [ (json array of strings, or 'null' if none provided)\n"
- " \"privatekey\" (string) private key in base58-encoding\n"
- " ,...\n"
- " ]\n"
- "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
- " \"ALL\"\n"
- " \"NONE\"\n"
- " \"SINGLE\"\n"
- " \"ALL|ANYONECANPAY\"\n"
- " \"NONE|ANYONECANPAY\"\n"
- " \"SINGLE|ANYONECANPAY\"\n"
-
- "\nResult:\n"
- "{\n"
- " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
- " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
- " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
- " {\n"
- " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
- " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
- " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
- " \"sequence\" : n, (numeric) Script sequence number\n"
- " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
- " }\n"
- " ,...\n"
- " ]\n"
- "}\n"
-
- "\nExamples:\n"
- + HelpExampleCli("signrawtransaction", "\"myhex\"")
- + HelpExampleRpc("signrawtransaction", "\"myhex\"")
- );
-
- if (!IsDeprecatedRPCEnabled("signrawtransaction")) {
- throw JSONRPCError(RPC_METHOD_DEPRECATED, "signrawtransaction is deprecated and will be fully removed in v0.18. "
- "To use signrawtransaction in v0.17, restart bitcoind with -deprecatedrpc=signrawtransaction.\n"
- "Projects should transition to using signrawtransactionwithkey and signrawtransactionwithwallet before upgrading to v0.18");
- }
-
- RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
-
- // Make a JSONRPCRequest to pass on to the right signrawtransaction* command
- JSONRPCRequest new_request;
- new_request.id = request.id;
- new_request.params.setArray();
-
- // For signing with private keys
- if (!request.params[2].isNull()) {
- new_request.params.push_back(request.params[0]);
- // Note: the prevtxs and privkeys are reversed for signrawtransactionwithkey
- new_request.params.push_back(request.params[2]);
- new_request.params.push_back(request.params[1]);
- new_request.params.push_back(request.params[3]);
- return signrawtransactionwithkey(new_request);
- } else {
-#ifdef ENABLE_WALLET
- // Otherwise sign with the wallet which does not take a privkeys parameter
- new_request.params.push_back(request.params[0]);
- new_request.params.push_back(request.params[1]);
- new_request.params.push_back(request.params[3]);
- return signrawtransactionwithwallet(new_request);
-#else
- // If we have made it this far, then wallet is disabled and no private keys were given, so fail here.
- throw JSONRPCError(RPC_INVALID_PARAMETER, "No private keys available.");
-#endif
- }
+ // This method should be removed entirely in V0.19, along with the entries in the
+ // CRPCCommand table and rpc/client.cpp.
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "signrawtransaction was removed in v0.18.\n"
+ "Clients should transition to using signrawtransactionwithkey and signrawtransactionwithwallet");
}
static UniValue sendrawtransaction(const JSONRPCRequest& request)
@@ -1084,7 +988,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
throw std::runtime_error(
"sendrawtransaction \"hexstring\" ( allowhighfees )\n"
"\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
- "\nAlso see createrawtransaction and signrawtransaction calls.\n"
+ "\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n"
"\nArguments:\n"
"1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
"2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
@@ -1094,7 +998,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
"\nCreate a transaction\n"
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
"Sign the transaction, and get back the hex\n"
- + HelpExampleCli("signrawtransaction", "\"myhex\"") +
+ + HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") +
"\nSend the transaction (signed hex)\n"
+ HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
"\nAs a json rpc call\n"
@@ -1199,7 +1103,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
"\nCreate a transaction\n"
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
"Sign the transaction, and get back the hex\n"
- + HelpExampleCli("signrawtransaction", "\"myhex\"") +
+ + HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") +
"\nTest acceptance of the transaction (signed hex)\n"
+ HelpExampleCli("testmempoolaccept", "\"signedhex\"") +
"\nAs a json rpc call\n"
@@ -1740,7 +1644,7 @@ UniValue converttopsbt(const JSONRPCRequest& request)
" will continue. If false, RPC will fail if any signatures are present.\n"
"3. iswitness (boolean, optional) Whether the transaction hex is a serialized witness transaction.\n"
" If iswitness is not present, heuristic tests will be used in decoding. If true, only witness deserializaion\n"
- " will be tried. If false, only non-witness deserialization wil be tried. Only has an effect if\n"
+ " will be tried. If false, only non-witness deserialization will be tried. Only has an effect if\n"
" permitsigdata is true.\n"
"\nResult:\n"
" \"psbt\" (string) The resulting raw transaction (base64-encoded string)\n"
@@ -1791,6 +1695,7 @@ UniValue converttopsbt(const JSONRPCRequest& request)
return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size());
}
+// clang-format off
static const CRPCCommand commands[] =
{ // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ----------
@@ -1800,7 +1705,7 @@ static const CRPCCommand commands[] =
{ "rawtransactions", "decodescript", &decodescript, {"hexstring"} },
{ "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees"} },
{ "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} },
- { "rawtransactions", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
+ { "hidden", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} },
{ "rawtransactions", "signrawtransactionwithkey", &signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} },
{ "rawtransactions", "testmempoolaccept", &testmempoolaccept, {"rawtxs","allowhighfees"} },
{ "rawtransactions", "decodepsbt", &decodepsbt, {"psbt"} },
@@ -1812,6 +1717,7 @@ static const CRPCCommand commands[] =
{ "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} },
{ "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} },
};
+// clang-format on
void RegisterRawTransactionRPCCommands(CRPCTable &t)
{
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 7d7e83fea8..8f3fe31ce8 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -252,6 +252,7 @@ static UniValue uptime(const JSONRPCRequest& jsonRequest)
return GetTime() - GetStartupTime();
}
+// clang-format off
/**
* Call Table
*/
@@ -263,6 +264,7 @@ static const CRPCCommand vRPCCommands[] =
{ "control", "stop", &stop, {} },
{ "control", "uptime", &uptime, {} },
};
+// clang-format on
CRPCTable::CRPCTable()
{
diff --git a/src/scheduler.h b/src/scheduler.h
index 0c2551cf4f..953d6c37de 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -111,7 +111,7 @@ public:
/**
* Add a callback to be executed. Callbacks are executed serially
* and memory is release-acquire consistent between callback executions.
- * Practially, this means that callbacks can behave as if they are executed
+ * Practically, this means that callbacks can behave as if they are executed
* in order by a single thread.
*/
void AddToProcessQueue(std::function<void (void)> func);
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index f366b99ec3..45b097dde6 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -373,7 +373,7 @@ enum class ParseScriptContext {
P2WSH,
};
-/** Parse a constant. If succesful, sp is updated to skip the constant and return true. */
+/** Parse a constant. If successful, sp is updated to skip the constant and return true. */
bool Const(const std::string& str, Span<const char>& sp)
{
if ((size_t)sp.size() >= str.size() && std::equal(str.begin(), str.end(), sp.begin())) {
@@ -383,7 +383,7 @@ bool Const(const std::string& str, Span<const char>& sp)
return false;
}
-/** Parse a function call. If succesful, sp is updated to be the function's argument(s). */
+/** Parse a function call. If successful, sp is updated to be the function's argument(s). */
bool Func(const std::string& str, Span<const char>& sp)
{
if ((size_t)sp.size() >= str.size() + 2 && sp[str.size()] == '(' && sp[sp.size() - 1] == ')' && std::equal(str.begin(), str.end(), sp.begin())) {
diff --git a/src/script/descriptor.h b/src/script/descriptor.h
index e079c72e92..87e07369c7 100644
--- a/src/script/descriptor.h
+++ b/src/script/descriptor.h
@@ -22,55 +22,8 @@
// they can be included inside by changing public keys to private keys (WIF
// format), and changing xpubs by xprvs.
//
-// 1. Examples
-//
-// A P2PK descriptor with a fixed public key:
-// - pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)
-//
-// A P2SH-P2WSH-P2PKH descriptor with a fixed public key:
-// - sh(wsh(pkh(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13)))
-//
-// A bare 1-of-2 multisig descriptor:
-// - multi(1,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)
-//
-// A chain of P2PKH outputs (this needs the corresponding private key to derive):
-// - pkh(xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw/1'/2/*)
-//
-// 2. Grammar description:
-//
-// X: xpub or xprv encoded extended key
-// I: decimal encoded integer
-// H: Hex encoded byte array
-// A: Address in P2PKH, P2SH, or Bech32 encoding
-//
-// S (Scripts):
-// * pk(P): Pay-to-pubkey (P2PK) output for public key P.
-// * pkh(P): Pay-to-pubkey-hash (P2PKH) output for public key P.
-// * wpkh(P): Pay-to-witness-pubkey-hash (P2WPKH) output for public key P.
-// * sh(S): Pay-to-script-hash (P2SH) output for script S
-// * wsh(S): Pay-to-witness-script-hash (P2WSH) output for script S
-// * combo(P): combination of P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH for public key P.
-// * multi(I,L): k-of-n multisig for given public keys
-// * addr(A): Output to address
-// * raw(H): scriptPubKey with raw bytes
-//
-// P (Public keys):
-// * H: fixed public key (or WIF-encoded private key)
-// * E: extended public key
-// * E/*: (ranged) all unhardened direct children of an extended public key
-// * E/*': (ranged) all hardened direct children of an extended public key
-//
-// L (Comma-separated lists of public keys):
-// * P
-// * L,P
-//
-// E (Extended public keys):
-// * X
-// * E/I: unhardened child
-// * E/I': hardened child
-// * E/Ih: hardened child (alternative notation)
-//
-// The top level is S.
+// Reference documentation about the descriptor language can be found in
+// doc/descriptors.md.
/** Interface for parsed descriptor objects. */
struct Descriptor {
diff --git a/src/streams.h b/src/streams.h
index d4a309be3c..dc20f7a9da 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -529,7 +529,7 @@ public:
explicit BitStreamReader(IStream& istream) : m_istream(istream) {}
/** Read the specified number of bits from the stream. The data is returned
- * in the nbits least signficant bits of a 64-bit uint.
+ * in the nbits least significant bits of a 64-bit uint.
*/
uint64_t Read(int nbits) {
if (nbits < 0 || nbits > 64) {
diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp
index 070b3ed80e..8d577cf521 100644
--- a/src/support/lockedpool.cpp
+++ b/src/support/lockedpool.cpp
@@ -75,7 +75,7 @@ void* Arena::alloc(size_t size)
// Create the used-chunk, taking its space from the end of the free-chunk
const size_t size_remaining = size_ptr_it->first - size;
- auto alloced = chunks_used.emplace(size_ptr_it->second + size_remaining, size).first;
+ auto allocated = chunks_used.emplace(size_ptr_it->second + size_remaining, size).first;
chunks_free_end.erase(size_ptr_it->second + size_ptr_it->first);
if (size_ptr_it->first == size) {
// whole chunk is used up
@@ -88,7 +88,7 @@ void* Arena::alloc(size_t size)
}
size_to_free_chunk.erase(size_ptr_it);
- return reinterpret_cast<void*>(alloced->first);
+ return reinterpret_cast<void*>(allocated->first);
}
void Arena::free(void *ptr)
diff --git a/src/sync.cpp b/src/sync.cpp
index 255eb4f00b..c9aa98dcd6 100644
--- a/src/sync.cpp
+++ b/src/sync.cpp
@@ -100,7 +100,11 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch,
}
LogPrintf(" %s\n", i.second.ToString());
}
- assert(false);
+ if (g_debug_lockorder_abort) {
+ fprintf(stderr, "Assertion failed: detected inconsistent lock order at %s:%i, details in debug log.\n", __FILE__, __LINE__);
+ abort();
+ }
+ throw std::logic_error("potential deadlock detected");
}
static void push_lock(void* c, const CLockLocation& locklocation)
@@ -189,4 +193,6 @@ void DeleteLock(void* cs)
}
}
+bool g_debug_lockorder_abort = true;
+
#endif /* DEBUG_LOCKORDER */
diff --git a/src/sync.h b/src/sync.h
index 11c1253757..40709bdd7f 100644
--- a/src/sync.h
+++ b/src/sync.h
@@ -46,14 +46,42 @@ LEAVE_CRITICAL_SECTION(mutex); // no RAII
// //
///////////////////////////////
+#ifdef DEBUG_LOCKORDER
+void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
+void LeaveCritical();
+std::string LocksHeld();
+void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) ASSERT_EXCLUSIVE_LOCK(cs);
+void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs);
+void DeleteLock(void* cs);
+
/**
- * Template mixin that adds -Wthread-safety locking
- * annotations to a subset of the mutex API.
+ * Call abort() if a potential lock order deadlock bug is detected, instead of
+ * just logging information and throwing a logic_error. Defaults to true, and
+ * set to false in DEBUG_LOCKORDER unit tests.
+ */
+extern bool g_debug_lockorder_abort;
+#else
+void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {}
+void static inline LeaveCritical() {}
+void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) ASSERT_EXCLUSIVE_LOCK(cs) {}
+void static inline AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) {}
+void static inline DeleteLock(void* cs) {}
+#endif
+#define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
+#define AssertLockNotHeld(cs) AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs)
+
+/**
+ * Template mixin that adds -Wthread-safety locking annotations and lock order
+ * checking to a subset of the mutex API.
*/
template <typename PARENT>
class LOCKABLE AnnotatedMixin : public PARENT
{
public:
+ ~AnnotatedMixin() {
+ DeleteLock((void*)this);
+ }
+
void lock() EXCLUSIVE_LOCK_FUNCTION()
{
PARENT::lock();
@@ -68,64 +96,36 @@ public:
{
return PARENT::try_lock();
}
-};
-#ifdef DEBUG_LOCKORDER
-void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
-void LeaveCritical();
-std::string LocksHeld();
-void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) ASSERT_EXCLUSIVE_LOCK(cs);
-void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs);
-void DeleteLock(void* cs);
-#else
-void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {}
-void static inline LeaveCritical() {}
-void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) ASSERT_EXCLUSIVE_LOCK(cs) {}
-void static inline AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) {}
-void static inline DeleteLock(void* cs) {}
-#endif
-#define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
-#define AssertLockNotHeld(cs) AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs)
+ using UniqueLock = std::unique_lock<PARENT>;
+};
/**
* Wrapped mutex: supports recursive locking, but no waiting
* TODO: We should move away from using the recursive lock by default.
*/
-class CCriticalSection : public AnnotatedMixin<std::recursive_mutex>
-{
-public:
- ~CCriticalSection() {
- DeleteLock((void*)this);
- }
-};
+typedef AnnotatedMixin<std::recursive_mutex> CCriticalSection;
/** Wrapped mutex: supports waiting but not recursive locking */
-typedef AnnotatedMixin<std::mutex> CWaitableCriticalSection;
-
-/** Just a typedef for std::condition_variable, can be wrapped later if desired */
-typedef std::condition_variable CConditionVariable;
-
-/** Just a typedef for std::unique_lock, can be wrapped later if desired */
-typedef std::unique_lock<std::mutex> WaitableLock;
+typedef AnnotatedMixin<std::mutex> Mutex;
#ifdef DEBUG_LOCKCONTENTION
void PrintLockContention(const char* pszName, const char* pszFile, int nLine);
#endif
-/** Wrapper around std::unique_lock<CCriticalSection> */
-class SCOPED_LOCKABLE CCriticalBlock
+/** Wrapper around std::unique_lock style lock for Mutex. */
+template <typename Mutex, typename Base = typename Mutex::UniqueLock>
+class SCOPED_LOCKABLE UniqueLock : public Base
{
private:
- std::unique_lock<CCriticalSection> lock;
-
void Enter(const char* pszName, const char* pszFile, int nLine)
{
- EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()));
+ EnterCritical(pszName, pszFile, nLine, (void*)(Base::mutex()));
#ifdef DEBUG_LOCKCONTENTION
- if (!lock.try_lock()) {
+ if (!Base::try_lock()) {
PrintLockContention(pszName, pszFile, nLine);
#endif
- lock.lock();
+ Base::lock();
#ifdef DEBUG_LOCKCONTENTION
}
#endif
@@ -133,15 +133,15 @@ private:
bool TryEnter(const char* pszName, const char* pszFile, int nLine)
{
- EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true);
- lock.try_lock();
- if (!lock.owns_lock())
+ EnterCritical(pszName, pszFile, nLine, (void*)(Base::mutex()), true);
+ Base::try_lock();
+ if (!Base::owns_lock())
LeaveCritical();
- return lock.owns_lock();
+ return Base::owns_lock();
}
public:
- CCriticalBlock(CCriticalSection& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : lock(mutexIn, std::defer_lock)
+ UniqueLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock)
{
if (fTry)
TryEnter(pszName, pszFile, nLine);
@@ -149,35 +149,41 @@ public:
Enter(pszName, pszFile, nLine);
}
- CCriticalBlock(CCriticalSection* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
+ UniqueLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
{
if (!pmutexIn) return;
- lock = std::unique_lock<CCriticalSection>(*pmutexIn, std::defer_lock);
+ *static_cast<Base*>(this) = Base(*pmutexIn, std::defer_lock);
if (fTry)
TryEnter(pszName, pszFile, nLine);
else
Enter(pszName, pszFile, nLine);
}
- ~CCriticalBlock() UNLOCK_FUNCTION()
+ ~UniqueLock() UNLOCK_FUNCTION()
{
- if (lock.owns_lock())
+ if (Base::owns_lock())
LeaveCritical();
}
operator bool()
{
- return lock.owns_lock();
+ return Base::owns_lock();
}
};
+template<typename MutexArg>
+using DebugLock = UniqueLock<typename std::remove_reference<typename std::remove_pointer<MutexArg>::type>::type>;
+
#define PASTE(x, y) x ## y
#define PASTE2(x, y) PASTE(x, y)
-#define LOCK(cs) CCriticalBlock PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__)
-#define LOCK2(cs1, cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__), criticalblock2(cs2, #cs2, __FILE__, __LINE__)
-#define TRY_LOCK(cs, name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true)
+#define LOCK(cs) DebugLock<decltype(cs)> PASTE2(criticalblock, __COUNTER__)(cs, #cs, __FILE__, __LINE__)
+#define LOCK2(cs1, cs2) \
+ DebugLock<decltype(cs1)> criticalblock1(cs1, #cs1, __FILE__, __LINE__); \
+ DebugLock<decltype(cs2)> criticalblock2(cs2, #cs2, __FILE__, __LINE__);
+#define TRY_LOCK(cs, name) DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__, true)
+#define WAIT_LOCK(cs, name) DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__)
#define ENTER_CRITICAL_SECTION(cs) \
{ \
diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp
index 39d0061c1c..2732598b4f 100644
--- a/src/test/checkqueue_tests.cpp
+++ b/src/test/checkqueue_tests.cpp
@@ -155,7 +155,7 @@ static void Correct_Queue_range(std::vector<size_t> range)
}
// Make vChecks here to save on malloc (this test can be slow...)
std::vector<FakeCheckCheckCompletion> vChecks;
- for (auto i : range) {
+ for (const size_t i : range) {
size_t total = i;
FakeCheckCheckCompletion::n_calls = 0;
CCheckQueueControl<FakeCheckCheckCompletion> control(small_queue.get());
@@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Recovers_From_Failure)
}
for (auto times = 0; times < 10; ++times) {
- for (bool end_fails : {true, false}) {
+ for (const bool end_fails : {true, false}) {
CCheckQueueControl<FailingCheck> control(fail_queue.get());
{
std::vector<FailingCheck> vChecks;
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index 63b91b74c0..6f4b5ecd26 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -508,7 +508,7 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization)
Coin cc4;
ss4 >> cc4;
BOOST_CHECK_MESSAGE(false, "We should have thrown");
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
}
// Very large scriptPubKey (3*10^9 bytes) past the end of the stream
@@ -521,7 +521,7 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization)
Coin cc5;
ss5 >> cc5;
BOOST_CHECK_MESSAGE(false, "We should have thrown");
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
}
}
@@ -719,7 +719,7 @@ static void CheckAddCoinBase(CAmount base_value, CAmount cache_value, CAmount mo
test.cache.AddCoin(OUTPOINT, Coin(std::move(output), 1, coinbase), coinbase);
test.cache.SelfTest();
GetCoinsMapEntry(test.cache.map(), result_value, result_flags);
- } catch (std::logic_error& e) {
+ } catch (std::logic_error&) {
result_value = FAIL;
result_flags = NO_ENTRY;
}
@@ -736,7 +736,7 @@ static void CheckAddCoinBase(CAmount base_value, CAmount cache_value, CAmount mo
template <typename... Args>
static void CheckAddCoin(Args&&... args)
{
- for (CAmount base_value : {ABSENT, PRUNED, VALUE1})
+ for (const CAmount base_value : {ABSENT, PRUNED, VALUE1})
CheckAddCoinBase(base_value, std::forward<Args>(args)...);
}
@@ -780,7 +780,7 @@ void CheckWriteCoins(CAmount parent_value, CAmount child_value, CAmount expected
WriteCoinsViewEntry(test.cache, child_value, child_flags);
test.cache.SelfTest();
GetCoinsMapEntry(test.cache.map(), result_value, result_flags);
- } catch (std::logic_error& e) {
+ } catch (std::logic_error&) {
result_value = FAIL;
result_flags = NO_ENTRY;
}
@@ -848,10 +848,10 @@ BOOST_AUTO_TEST_CASE(ccoins_write)
// they would be too repetitive (the parent cache is never updated in these
// cases). The loop below covers these cases and makes sure the parent cache
// is always left unchanged.
- for (CAmount parent_value : {ABSENT, PRUNED, VALUE1})
- for (CAmount child_value : {ABSENT, PRUNED, VALUE2})
- for (char parent_flags : parent_value == ABSENT ? ABSENT_FLAGS : FLAGS)
- for (char child_flags : child_value == ABSENT ? ABSENT_FLAGS : CLEAN_FLAGS)
+ for (const CAmount parent_value : {ABSENT, PRUNED, VALUE1})
+ for (const CAmount child_value : {ABSENT, PRUNED, VALUE2})
+ for (const char parent_flags : parent_value == ABSENT ? ABSENT_FLAGS : FLAGS)
+ for (const char child_flags : child_value == ABSENT ? ABSENT_FLAGS : CLEAN_FLAGS)
CheckWriteCoins(parent_value, child_value, parent_value, parent_flags, child_flags, parent_flags);
}
diff --git a/src/test/cuckoocache_tests.cpp b/src/test/cuckoocache_tests.cpp
index ec7aba34ca..dbceb9d2e0 100644
--- a/src/test/cuckoocache_tests.cpp
+++ b/src/test/cuckoocache_tests.cpp
@@ -82,11 +82,11 @@ static double test_cache(size_t megabytes, double load)
*/
std::vector<uint256> hashes_insert_copy = hashes;
/** Do the insert */
- for (uint256& h : hashes_insert_copy)
+ for (const uint256& h : hashes_insert_copy)
set.insert(h);
/** Count the hits */
uint32_t count = 0;
- for (uint256& h : hashes)
+ for (const uint256& h : hashes)
count += set.contains(h, false);
double hit_rate = ((double)count) / ((double)n_insert);
return hit_rate;
@@ -323,7 +323,7 @@ static void test_cache_generations()
reads.push_back(inserts[i]);
for (uint32_t i = n_insert - (n_insert / 4); i < n_insert; ++i)
reads.push_back(inserts[i]);
- for (auto h : inserts)
+ for (const auto& h : inserts)
c.insert(h);
}
};
diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp
index 4dff1e5c72..9957ac074b 100644
--- a/src/test/dbwrapper_tests.cpp
+++ b/src/test/dbwrapper_tests.cpp
@@ -26,7 +26,7 @@ BOOST_FIXTURE_TEST_SUITE(dbwrapper_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(dbwrapper)
{
// Perform tests both obfuscated and non-obfuscated.
- for (bool obfuscate : {false, true}) {
+ for (const bool obfuscate : {false, true}) {
fs::path ph = SetDataDir(std::string("dbwrapper").append(obfuscate ? "_true" : "_false"));
CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
char key = 'k';
@@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper)
BOOST_AUTO_TEST_CASE(dbwrapper_batch)
{
// Perform tests both obfuscated and non-obfuscated.
- for (bool obfuscate : {false, true}) {
+ for (const bool obfuscate : {false, true}) {
fs::path ph = SetDataDir(std::string("dbwrapper_batch").append(obfuscate ? "_true" : "_false"));
CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
@@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch)
BOOST_AUTO_TEST_CASE(dbwrapper_iterator)
{
// Perform tests both obfuscated and non-obfuscated.
- for (bool obfuscate : {false, true}) {
+ for (const bool obfuscate : {false, true}) {
fs::path ph = SetDataDir(std::string("dbwrapper_iterator").append(obfuscate ? "_true" : "_false"));
CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
@@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(iterator_ordering)
if (x & 1) BOOST_CHECK(dbw.Write(key, value));
}
- for (int seek_start : {0x00, 0x80}) {
+ for (const int seek_start : {0x00, 0x80}) {
it->Seek((uint8_t)seek_start);
for (unsigned int x=seek_start; x<255; ++x) {
uint8_t key;
@@ -262,7 +262,7 @@ struct StringContentsSerializer {
try {
READWRITE(c);
str.push_back(c);
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
break;
}
}
@@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering)
}
std::unique_ptr<CDBIterator> it(const_cast<CDBWrapper&>(dbw).NewIterator());
- for (int seek_start : {0, 5}) {
+ for (const int seek_start : {0, 5}) {
snprintf(buf, sizeof(buf), "%d", seek_start);
StringContentsSerializer seek_key(buf);
it->Seek(seek_key);
diff --git a/src/test/gen/crypto_gen.cpp b/src/test/gen/crypto_gen.cpp
new file mode 100644
index 0000000000..ca8c65806f
--- /dev/null
+++ b/src/test/gen/crypto_gen.cpp
@@ -0,0 +1,19 @@
+// Copyright (c) 2018 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 <test/gen/crypto_gen.h>
+
+#include <key.h>
+
+#include <rapidcheck/gen/Arbitrary.h>
+#include <rapidcheck/Gen.h>
+#include <rapidcheck/gen/Predicate.h>
+#include <rapidcheck/gen/Container.h>
+
+/** Generates 1 to 20 keys for OP_CHECKMULTISIG */
+rc::Gen<std::vector<CKey>> MultisigKeys()
+{
+ return rc::gen::suchThat(rc::gen::arbitrary<std::vector<CKey>>(), [](const std::vector<CKey>& keys) {
+ return keys.size() >= 1 && keys.size() <= 15;
+ });
+};
diff --git a/src/test/gen/crypto_gen.h b/src/test/gen/crypto_gen.h
new file mode 100644
index 0000000000..7c2fb0350f
--- /dev/null
+++ b/src/test/gen/crypto_gen.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_TEST_GEN_CRYPTO_GEN_H
+#define BITCOIN_TEST_GEN_CRYPTO_GEN_H
+
+#include <key.h>
+#include <random.h>
+#include <uint256.h>
+#include <rapidcheck/gen/Arbitrary.h>
+#include <rapidcheck/Gen.h>
+#include <rapidcheck/gen/Create.h>
+#include <rapidcheck/gen/Numeric.h>
+
+/** Generates 1 to 15 keys for OP_CHECKMULTISIG */
+rc::Gen<std::vector<CKey>> MultisigKeys();
+
+namespace rc
+{
+/** Generator for a new CKey */
+template <>
+struct Arbitrary<CKey> {
+ static Gen<CKey> arbitrary()
+ {
+ return rc::gen::map<int>([](int x) {
+ CKey key;
+ key.MakeNewKey(true);
+ return key;
+ });
+ };
+};
+
+/** Generator for a CPrivKey */
+template <>
+struct Arbitrary<CPrivKey> {
+ static Gen<CPrivKey> arbitrary()
+ {
+ return gen::map(gen::arbitrary<CKey>(), [](const CKey& key) {
+ return key.GetPrivKey();
+ });
+ };
+};
+
+/** Generator for a new CPubKey */
+template <>
+struct Arbitrary<CPubKey> {
+ static Gen<CPubKey> arbitrary()
+ {
+ return gen::map(gen::arbitrary<CKey>(), [](const CKey& key) {
+ return key.GetPubKey();
+ });
+ };
+};
+/** Generates a arbitrary uint256 */
+template <>
+struct Arbitrary<uint256> {
+ static Gen<uint256> arbitrary()
+ {
+ return rc::gen::just(GetRandHash());
+ };
+};
+} //namespace rc
+#endif
diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp
index eec7b38af7..7592330b10 100644
--- a/src/test/getarg_tests.cpp
+++ b/src/test/getarg_tests.cpp
@@ -24,7 +24,7 @@ static void ResetArgs(const std::string& strArg)
// Convert to char*:
std::vector<const char*> vecChar;
- for (std::string& s : vecArg)
+ for (const std::string& s : vecArg)
vecChar.push_back(s.c_str());
std::string error;
diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp
index 7e475ac610..a0c10d8ddd 100644
--- a/src/test/key_io_tests.cpp
+++ b/src/test/key_io_tests.cpp
@@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(key_io_invalid)
std::string exp_base58string = test[0].get_str();
// must be invalid as public and as private key
- for (auto chain : { CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::REGTEST }) {
+ for (const auto& chain : { CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::REGTEST }) {
SelectParams(chain);
destination = DecodeDestination(exp_base58string);
BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid pubkey in mainnet:" + strTest);
diff --git a/src/test/key_properties.cpp b/src/test/key_properties.cpp
new file mode 100644
index 0000000000..14e3c85359
--- /dev/null
+++ b/src/test/key_properties.cpp
@@ -0,0 +1,53 @@
+// Copyright (c) 2018 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 <key.h>
+
+#include <base58.h>
+#include <script/script.h>
+#include <uint256.h>
+#include <util.h>
+#include <utilstrencodings.h>
+#include <test/test_bitcoin.h>
+#include <string>
+#include <vector>
+
+#include <boost/test/unit_test.hpp>
+#include <rapidcheck/boost_test.h>
+#include <rapidcheck/gen/Arbitrary.h>
+#include <rapidcheck/Gen.h>
+
+#include <test/gen/crypto_gen.h>
+
+BOOST_FIXTURE_TEST_SUITE(key_properties, BasicTestingSetup)
+
+/** Check CKey uniqueness */
+RC_BOOST_PROP(key_uniqueness, (const CKey& key1, const CKey& key2))
+{
+ RC_ASSERT(!(key1 == key2));
+}
+
+/** Verify that a private key generates the correct public key */
+RC_BOOST_PROP(key_generates_correct_pubkey, (const CKey& key))
+{
+ CPubKey pubKey = key.GetPubKey();
+ RC_ASSERT(key.VerifyPubKey(pubKey));
+}
+
+/** Create a CKey using the 'Set' function must give us the same key */
+RC_BOOST_PROP(key_set_symmetry, (const CKey& key))
+{
+ CKey key1;
+ key1.Set(key.begin(), key.end(), key.IsCompressed());
+ RC_ASSERT(key1 == key);
+}
+
+/** Create a CKey, sign a piece of data, then verify it with the public key */
+RC_BOOST_PROP(key_sign_symmetry, (const CKey& key, const uint256& hash))
+{
+ std::vector<unsigned char> vchSig;
+ key.Sign(hash, vchSig, 0);
+ const CPubKey& pubKey = key.GetPubKey();
+ RC_ASSERT(pubKey.Verify(hash, vchSig));
+}
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index 4c56938ec9..eaa8b16182 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read)
unsigned char pchMsgTmp[4];
ssPeers1 >> pchMsgTmp;
ssPeers1 >> addrman1;
- } catch (const std::exception& e) {
+ } catch (const std::exception&) {
exceptionThrown = true;
}
@@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted)
unsigned char pchMsgTmp[4];
ssPeers1 >> pchMsgTmp;
ssPeers1 >> addrman1;
- } catch (const std::exception& e) {
+ } catch (const std::exception&) {
exceptionThrown = true;
}
// Even through de-serialization failed addrman is not left in a clean state.
diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp
index 814459c2bc..12ec00ce02 100644
--- a/src/test/scheduler_tests.cpp
+++ b/src/test/scheduler_tests.cpp
@@ -138,11 +138,13 @@ BOOST_AUTO_TEST_CASE(singlethreadedscheduler_ordered)
// the callbacks should run in exactly the order in which they were enqueued
for (int i = 0; i < 100; ++i) {
queue1.AddToProcessQueue([i, &counter1]() {
- assert(i == counter1++);
+ bool expectation = i == counter1++;
+ assert(expectation);
});
queue2.AddToProcessQueue([i, &counter2]() {
- assert(i == counter2++);
+ bool expectation = i == counter2++;
+ assert(expectation);
});
}
diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp
index bcd2a9c7b6..c0754618fb 100644
--- a/src/test/skiplist_tests.cpp
+++ b/src/test/skiplist_tests.cpp
@@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(findearliestatleast_test)
BOOST_AUTO_TEST_CASE(findearliestatleast_edge_test)
{
std::list<CBlockIndex> blocks;
- for (unsigned int timeMax : {100, 100, 100, 200, 200, 200, 300, 300, 300}) {
+ for (const unsigned int timeMax : {100, 100, 100, 200, 200, 200, 300, 300, 300}) {
CBlockIndex* prev = blocks.empty() ? nullptr : &blocks.back();
blocks.emplace_back();
blocks.back().nHeight = prev ? prev->nHeight + 1 : 0;
diff --git a/src/test/sync_tests.cpp b/src/test/sync_tests.cpp
new file mode 100644
index 0000000000..df0380546e
--- /dev/null
+++ b/src/test/sync_tests.cpp
@@ -0,0 +1,52 @@
+// Copyright (c) 2012-2017 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 <sync.h>
+#include <test/test_bitcoin.h>
+
+#include <boost/test/unit_test.hpp>
+
+namespace {
+template <typename MutexType>
+void TestPotentialDeadLockDetected(MutexType& mutex1, MutexType& mutex2)
+{
+ {
+ LOCK2(mutex1, mutex2);
+ }
+ bool error_thrown = false;
+ try {
+ LOCK2(mutex2, mutex1);
+ } catch (const std::logic_error& e) {
+ BOOST_CHECK_EQUAL(e.what(), "potential deadlock detected");
+ error_thrown = true;
+ }
+ #ifdef DEBUG_LOCKORDER
+ BOOST_CHECK(error_thrown);
+ #else
+ BOOST_CHECK(!error_thrown);
+ #endif
+}
+} // namespace
+
+BOOST_FIXTURE_TEST_SUITE(sync_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(potential_deadlock_detected)
+{
+ #ifdef DEBUG_LOCKORDER
+ bool prev = g_debug_lockorder_abort;
+ g_debug_lockorder_abort = false;
+ #endif
+
+ CCriticalSection rmutex1, rmutex2;
+ TestPotentialDeadLockDetected(rmutex1, rmutex2);
+
+ Mutex mutex1, mutex2;
+ TestPotentialDeadLockDetected(mutex1, mutex2);
+
+ #ifdef DEBUG_LOCKORDER
+ g_debug_lockorder_abort = prev;
+ #endif
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index a89bf785f1..0d7c9f0abf 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -29,7 +29,7 @@ void CConnmanTest::AddNode(CNode& node)
void CConnmanTest::ClearNodes()
{
LOCK(g_connman->cs_vNodes);
- for (CNode* node : g_connman->vNodes) {
+ for (const CNode* node : g_connman->vNodes) {
delete node;
}
g_connman->vNodes.clear();
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 33f0a83b7e..c527ad448c 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -65,7 +65,7 @@ unsigned int ParseScriptFlags(std::string strFlags)
std::vector<std::string> words;
boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(","));
- for (std::string word : words)
+ for (const std::string& word : words)
{
if (!mapFlagNames.count(word))
BOOST_ERROR("Bad test: unknown verification flag '" << word << "'");
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 8e2f5abe66..c74eb7531a 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArg)
testArgs.ParseParameters(7, (char**)argv_test, error);
// Each letter should be set.
- for (char opt : "abcdef")
+ for (const char opt : "abcdef")
BOOST_CHECK(testArgs.IsArgSet({'-', opt}) || !opt);
// Nothing else should be in the map
@@ -394,7 +394,7 @@ BOOST_AUTO_TEST_CASE(util_ReadConfigStream)
&& test_args.GetArg("-iii", "xxx") == "xxx"
);
- for (bool def : {false, true}) {
+ for (const bool def : {false, true}) {
BOOST_CHECK(test_args.GetBoolArg("-a", def)
&& test_args.GetBoolArg("-b", def)
&& !test_args.GetBoolArg("-ccc", def)
diff --git a/src/threadinterrupt.cpp b/src/threadinterrupt.cpp
index d08d52e4a9..340106ed99 100644
--- a/src/threadinterrupt.cpp
+++ b/src/threadinterrupt.cpp
@@ -5,6 +5,8 @@
#include <threadinterrupt.h>
+#include <sync.h>
+
CThreadInterrupt::CThreadInterrupt() : flag(false) {}
CThreadInterrupt::operator bool() const
@@ -20,7 +22,7 @@ void CThreadInterrupt::reset()
void CThreadInterrupt::operator()()
{
{
- std::unique_lock<std::mutex> lock(mut);
+ LOCK(mut);
flag.store(true, std::memory_order_release);
}
cond.notify_all();
@@ -28,7 +30,7 @@ void CThreadInterrupt::operator()()
bool CThreadInterrupt::sleep_for(std::chrono::milliseconds rel_time)
{
- std::unique_lock<std::mutex> lock(mut);
+ WAIT_LOCK(mut, lock);
return !cond.wait_for(lock, rel_time, [this]() { return flag.load(std::memory_order_acquire); });
}
diff --git a/src/threadinterrupt.h b/src/threadinterrupt.h
index c30bd3d657..9c6fccfcde 100644
--- a/src/threadinterrupt.h
+++ b/src/threadinterrupt.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_THREADINTERRUPT_H
#define BITCOIN_THREADINTERRUPT_H
+#include <sync.h>
+
#include <atomic>
#include <chrono>
#include <condition_variable>
@@ -28,7 +30,7 @@ public:
private:
std::condition_variable cond;
- std::mutex mut;
+ Mutex mut;
std::atomic<bool> flag;
};
diff --git a/src/threadsafety.h b/src/threadsafety.h
index a2f45e5fce..47e6b2ea38 100644
--- a/src/threadsafety.h
+++ b/src/threadsafety.h
@@ -10,7 +10,7 @@
// TL;DR Add GUARDED_BY(mutex) to member variables. The others are
// rarely necessary. Ex: int nFoo GUARDED_BY(cs_foo);
//
-// See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety
+// See https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
// for documentation. The clang compiler can do advanced static analysis
// of locking when given the -Wthread-safety option.
#define LOCKABLE __attribute__((lockable))
diff --git a/src/timedata.cpp b/src/timedata.cpp
index 1599508306..291111feb2 100644
--- a/src/timedata.cpp
+++ b/src/timedata.cpp
@@ -94,7 +94,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
{
// If nobody has a time different than ours but within 5 minutes of ours, give a warning
bool fMatch = false;
- for (int64_t nOffset : vSorted)
+ for (const int64_t nOffset : vSorted)
if (nOffset != 0 && abs64(nOffset) < 5 * 60)
fMatch = true;
@@ -109,7 +109,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
}
if (LogAcceptCategory(BCLog::NET)) {
- for (int64_t n : vSorted) {
+ for (const int64_t n : vSorted) {
LogPrint(BCLog::NET, "%+d ", n); /* Continued */
}
LogPrint(BCLog::NET, "| "); /* Continued */
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 05217149e3..3ad93342c4 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -156,9 +156,9 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntr
// GetMemPoolParents() is only valid for entries in the mempool, so we
// iterate mapTx to find parents.
for (unsigned int i = 0; i < tx.vin.size(); i++) {
- txiter piter = mapTx.find(tx.vin[i].prevout.hash);
- if (piter != mapTx.end()) {
- parentHashes.insert(piter);
+ boost::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash);
+ if (piter) {
+ parentHashes.insert(*piter);
if (parentHashes.size() + 1 > limitAncestorCount) {
errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
return false;
@@ -193,7 +193,7 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntr
}
const setEntries & setMemPoolParents = GetMemPoolParents(stageit);
- for (const txiter &phash : setMemPoolParents) {
+ for (txiter phash : setMemPoolParents) {
// If this is a new ancestor, add it.
if (setAncestors.count(phash) == 0) {
parentHashes.insert(phash);
@@ -364,12 +364,10 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
// Update transaction for any feeDelta created by PrioritiseTransaction
// TODO: refactor so that the fee delta is calculated before inserting
// into mapTx.
- std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(entry.GetTx().GetHash());
- if (pos != mapDeltas.end()) {
- const CAmount &delta = pos->second;
- if (delta) {
+ CAmount delta{0};
+ ApplyDelta(entry.GetTx().GetHash(), delta);
+ if (delta) {
mapTx.modify(newit, update_fee_delta(delta));
- }
}
// Update cachedInnerUsage to include contained transaction's usage.
@@ -391,11 +389,8 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
// to clean up the mess we're leaving here.
// Update ancestors with information about this tx
- for (const uint256 &phash : setParentTransactions) {
- txiter pit = mapTx.find(phash);
- if (pit != mapTx.end()) {
+ for (const auto& pit : GetIterSet(setParentTransactions)) {
UpdateParent(newit, pit, true);
- }
}
UpdateAncestorsOf(true, newit, setAncestors);
UpdateEntryForAncestors(newit, setAncestors);
@@ -454,7 +449,7 @@ void CTxMemPool::CalculateDescendants(txiter entryit, setEntries& setDescendants
stage.erase(it);
const setEntries &setChildren = GetMemPoolChildren(it);
- for (const txiter &childiter : setChildren) {
+ for (txiter childiter : setChildren) {
if (!setDescendants.count(childiter)) {
stage.insert(childiter);
}
@@ -864,6 +859,29 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash)
mapDeltas.erase(hash);
}
+const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const
+{
+ const auto it = mapNextTx.find(prevout);
+ return it == mapNextTx.end() ? nullptr : it->second;
+}
+
+boost::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const uint256& txid) const
+{
+ auto it = mapTx.find(txid);
+ if (it != mapTx.end()) return it;
+ return boost::optional<txiter>{};
+}
+
+CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set<uint256>& hashes) const
+{
+ CTxMemPool::setEntries ret;
+ for (const auto& h : hashes) {
+ const auto mi = GetIter(h);
+ if (mi) ret.insert(*mi);
+ }
+ return ret;
+}
+
bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
{
for (unsigned int i = 0; i < tx.vin.size(); i++)
@@ -899,7 +917,7 @@ size_t CTxMemPool::DynamicMemoryUsage() const {
void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) {
AssertLockHeld(cs);
UpdateForRemoveFromMempool(stage, updateDescendants);
- for (const txiter& it : stage) {
+ for (txiter it : stage) {
removeUnchecked(it, reason);
}
}
diff --git a/src/txmempool.h b/src/txmempool.h
index 2163b5eb21..913501fd66 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -566,7 +566,15 @@ public:
void ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const;
void ClearPrioritisation(const uint256 hash);
-public:
+ /** Get the transaction in the pool that spends the same prevout */
+ const CTransaction* GetConflictTx(const COutPoint& prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs);
+
+ /** Returns an iterator to the given hash, if found */
+ boost::optional<txiter> GetIter(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs);
+
+ /** Translate a set of hashes into a set of pool iterators to avoid repeated lookups */
+ setEntries GetIterSet(const std::set<uint256>& hashes) const EXCLUSIVE_LOCKS_REQUIRED(cs);
+
/** Remove a set of transactions from the mempool.
* If a transaction is in this set, then all in-mempool descendants must
* also be in the set, unless this transaction is being removed for being
@@ -639,7 +647,7 @@ public:
return totalTxSize;
}
- bool exists(uint256 hash) const
+ bool exists(const uint256& hash) const
{
LOCK(cs);
return (mapTx.count(hash) != 0);
diff --git a/src/univalue/gen/gen.cpp b/src/univalue/gen/gen.cpp
index 17f361941d..85fe20924a 100644
--- a/src/univalue/gen/gen.cpp
+++ b/src/univalue/gen/gen.cpp
@@ -12,8 +12,6 @@
#include <string.h>
#include "univalue.h"
-using namespace std;
-
static bool initEscapes;
static std::string escapes[256];
diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h
index c15b2f051e..91b104e56e 100644
--- a/src/univalue/include/univalue.h
+++ b/src/univalue/include/univalue.h
@@ -15,7 +15,6 @@
#include <cassert>
#include <sstream> // .get_int64()
-#include <utility> // std::pair
class UniValue {
public:
@@ -177,76 +176,9 @@ public:
const UniValue& get_array() const;
enum VType type() const { return getType(); }
- bool push_back(std::pair<std::string,UniValue> pear) {
- return pushKV(pear.first, pear.second);
- }
friend const UniValue& find_value( const UniValue& obj, const std::string& name);
};
-//
-// The following were added for compatibility with json_spirit.
-// Most duplicate other methods, and should be removed.
-//
-static inline std::pair<std::string,UniValue> Pair(const char *cKey, const char *cVal)
-{
- std::string key(cKey);
- UniValue uVal(cVal);
- return std::make_pair(key, uVal);
-}
-
-static inline std::pair<std::string,UniValue> Pair(const char *cKey, std::string strVal)
-{
- std::string key(cKey);
- UniValue uVal(strVal);
- return std::make_pair(key, uVal);
-}
-
-static inline std::pair<std::string,UniValue> Pair(const char *cKey, uint64_t u64Val)
-{
- std::string key(cKey);
- UniValue uVal(u64Val);
- return std::make_pair(key, uVal);
-}
-
-static inline std::pair<std::string,UniValue> Pair(const char *cKey, int64_t i64Val)
-{
- std::string key(cKey);
- UniValue uVal(i64Val);
- return std::make_pair(key, uVal);
-}
-
-static inline std::pair<std::string,UniValue> Pair(const char *cKey, bool iVal)
-{
- std::string key(cKey);
- UniValue uVal(iVal);
- return std::make_pair(key, uVal);
-}
-
-static inline std::pair<std::string,UniValue> Pair(const char *cKey, int iVal)
-{
- std::string key(cKey);
- UniValue uVal(iVal);
- return std::make_pair(key, uVal);
-}
-
-static inline std::pair<std::string,UniValue> Pair(const char *cKey, double dVal)
-{
- std::string key(cKey);
- UniValue uVal(dVal);
- return std::make_pair(key, uVal);
-}
-
-static inline std::pair<std::string,UniValue> Pair(const char *cKey, const UniValue& uVal)
-{
- std::string key(cKey);
- return std::make_pair(key, uVal);
-}
-
-static inline std::pair<std::string,UniValue> Pair(std::string key, const UniValue& uVal)
-{
- return std::make_pair(key, uVal);
-}
-
enum jtokentype {
JTOK_ERR = -1,
JTOK_NONE = 0, // eof
diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp
index d8ad7c4b90..4c9c15d63e 100644
--- a/src/univalue/lib/univalue.cpp
+++ b/src/univalue/lib/univalue.cpp
@@ -10,8 +10,6 @@
#include "univalue.h"
-using namespace std;
-
const UniValue NullUniValue;
void UniValue::clear()
@@ -37,15 +35,15 @@ bool UniValue::setBool(bool val_)
return true;
}
-static bool validNumStr(const string& s)
+static bool validNumStr(const std::string& s)
{
- string tokenVal;
+ std::string tokenVal;
unsigned int consumed;
enum jtokentype tt = getJsonToken(tokenVal, consumed, s.data(), s.data() + s.size());
return (tt == JTOK_NUMBER);
}
-bool UniValue::setNumStr(const string& val_)
+bool UniValue::setNumStr(const std::string& val_)
{
if (!validNumStr(val_))
return false;
@@ -58,7 +56,7 @@ bool UniValue::setNumStr(const string& val_)
bool UniValue::setInt(uint64_t val_)
{
- ostringstream oss;
+ std::ostringstream oss;
oss << val_;
@@ -67,7 +65,7 @@ bool UniValue::setInt(uint64_t val_)
bool UniValue::setInt(int64_t val_)
{
- ostringstream oss;
+ std::ostringstream oss;
oss << val_;
@@ -76,7 +74,7 @@ bool UniValue::setInt(int64_t val_)
bool UniValue::setFloat(double val_)
{
- ostringstream oss;
+ std::ostringstream oss;
oss << std::setprecision(16) << val_;
@@ -85,7 +83,7 @@ bool UniValue::setFloat(double val_)
return ret;
}
-bool UniValue::setStr(const string& val_)
+bool UniValue::setStr(const std::string& val_)
{
clear();
typ = VSTR;
diff --git a/src/univalue/lib/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp
index ae75cb462a..14834db24d 100644
--- a/src/univalue/lib/univalue_read.cpp
+++ b/src/univalue/lib/univalue_read.cpp
@@ -8,8 +8,6 @@
#include "univalue.h"
#include "univalue_utffilter.h"
-using namespace std;
-
static bool json_isdigit(int ch)
{
return ((ch >= '0') && (ch <= '9'));
@@ -42,7 +40,7 @@ static const char *hatoui(const char *first, const char *last,
return first;
}
-enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
+enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed,
const char *raw, const char *end)
{
tokenVal.clear();
@@ -114,7 +112,7 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
case '8':
case '9': {
// part 1: int
- string numStr;
+ std::string numStr;
const char *first = raw;
@@ -174,7 +172,7 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
case '"': {
raw++; // skip "
- string valStr;
+ std::string valStr;
JSONUTF8StringFilter writer(valStr);
while (true) {
@@ -255,9 +253,9 @@ bool UniValue::read(const char *raw, size_t size)
clear();
uint32_t expectMask = 0;
- vector<UniValue*> stack;
+ std::vector<UniValue*> stack;
- string tokenVal;
+ std::string tokenVal;
unsigned int consumed;
enum jtokentype tok = JTOK_NONE;
enum jtokentype last_tok = JTOK_NONE;
diff --git a/src/univalue/lib/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp
index cf27835991..827eb9b271 100644
--- a/src/univalue/lib/univalue_write.cpp
+++ b/src/univalue/lib/univalue_write.cpp
@@ -8,11 +8,9 @@
#include "univalue.h"
#include "univalue_escapes.h"
-using namespace std;
-
-static string json_escape(const string& inS)
+static std::string json_escape(const std::string& inS)
{
- string outS;
+ std::string outS;
outS.reserve(inS.size() * 2);
for (unsigned int i = 0; i < inS.size(); i++) {
@@ -28,10 +26,10 @@ static string json_escape(const string& inS)
return outS;
}
-string UniValue::write(unsigned int prettyIndent,
- unsigned int indentLevel) const
+std::string UniValue::write(unsigned int prettyIndent,
+ unsigned int indentLevel) const
{
- string s;
+ std::string s;
s.reserve(1024);
unsigned int modIndent = indentLevel;
@@ -62,12 +60,12 @@ string UniValue::write(unsigned int prettyIndent,
return s;
}
-static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, string& s)
+static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, std::string& s)
{
s.append(prettyIndent * indentLevel, ' ');
}
-void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, string& s) const
+void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const
{
s += "[";
if (prettyIndent)
@@ -89,7 +87,7 @@ void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, s
s += "]";
}
-void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, string& s) const
+void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const
{
s += "{";
if (prettyIndent)
diff --git a/src/univalue/test/unitester.cpp b/src/univalue/test/unitester.cpp
index 2c37794a4b..75c0dc225a 100644
--- a/src/univalue/test/unitester.cpp
+++ b/src/univalue/test/unitester.cpp
@@ -17,8 +17,7 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
-using namespace std;
-string srcdir(JSON_TEST_SRC);
+std::string srcdir(JSON_TEST_SRC);
static bool test_failed = false;
#define d_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", filename.c_str()); } }
@@ -30,9 +29,9 @@ static std::string rtrim(std::string s)
return s;
}
-static void runtest(string filename, const string& jdata)
+static void runtest(std::string filename, const std::string& jdata)
{
- string prefix = filename.substr(0, 4);
+ std::string prefix = filename.substr(0, 4);
bool wantPass = (prefix == "pass") || (prefix == "roun");
bool wantFail = (prefix == "fail");
@@ -56,19 +55,19 @@ static void runtest(string filename, const string& jdata)
static void runtest_file(const char *filename_)
{
- string basename(filename_);
- string filename = srcdir + "/" + basename;
+ std::string basename(filename_);
+ std::string filename = srcdir + "/" + basename;
FILE *f = fopen(filename.c_str(), "r");
assert(f != NULL);
- string jdata;
+ std::string jdata;
char buf[4096];
while (!feof(f)) {
int bread = fread(buf, 1, sizeof(buf), f);
assert(!ferror(f));
- string s(buf, bread);
+ std::string s(buf, bread);
jdata += s;
}
diff --git a/src/util.cpp b/src/util.cpp
index 3bb52e9b3d..84d8175389 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -818,11 +818,11 @@ static std::string TrimString(const std::string& str, const std::string& pattern
return str.substr(front, end - front + 1);
}
-static std::vector<std::pair<std::string, std::string>> GetConfigOptions(std::istream& stream)
+static bool GetConfigOptions(std::istream& stream, std::string& error, std::vector<std::pair<std::string, std::string>> &options)
{
- std::vector<std::pair<std::string, std::string>> options;
std::string str, prefix;
std::string::size_type pos;
+ int linenr = 1;
while (std::getline(stream, str)) {
if ((pos = str.find('#')) != std::string::npos) {
str = str.substr(0, pos);
@@ -832,21 +832,34 @@ static std::vector<std::pair<std::string, std::string>> GetConfigOptions(std::is
if (!str.empty()) {
if (*str.begin() == '[' && *str.rbegin() == ']') {
prefix = str.substr(1, str.size() - 2) + '.';
+ } else if (*str.begin() == '-') {
+ error = strprintf("parse error on line %i: %s, options in configuration file must be specified without leading -", linenr, str);
+ return false;
} else if ((pos = str.find('=')) != std::string::npos) {
std::string name = prefix + TrimString(str.substr(0, pos), pattern);
std::string value = TrimString(str.substr(pos + 1), pattern);
options.emplace_back(name, value);
+ } else {
+ error = strprintf("parse error on line %i: %s", linenr, str);
+ if (str.size() >= 2 && str.substr(0, 2) == "no") {
+ error += strprintf(", if you intended to specify a negated option, use %s=1 instead", str);
+ }
+ return false;
}
}
+ ++linenr;
}
- return options;
+ return true;
}
bool ArgsManager::ReadConfigStream(std::istream& stream, std::string& error, bool ignore_invalid_keys)
{
LOCK(cs_args);
-
- for (const std::pair<std::string, std::string>& option : GetConfigOptions(stream)) {
+ std::vector<std::pair<std::string, std::string>> options;
+ if (!GetConfigOptions(stream, error, options)) {
+ return false;
+ }
+ for (const std::pair<std::string, std::string>& option : options) {
std::string strKey = std::string("-") + option.first;
std::string strValue = option.second;
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
index 2326383586..4940267bae 100644
--- a/src/utilstrencodings.cpp
+++ b/src/utilstrencodings.cpp
@@ -72,7 +72,7 @@ bool IsHexNumber(const std::string& str)
if (str.size() > 2 && *str.begin() == '0' && *(str.begin()+1) == 'x') {
starting_location = 2;
}
- for (auto c : str.substr(starting_location)) {
+ for (const char c : str.substr(starting_location)) {
if (HexDigit(c) < 0) return false;
}
// Return false for empty string or "0x".
diff --git a/src/validation.cpp b/src/validation.cpp
index f6257ffaed..2ad2422618 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -217,8 +217,8 @@ CCriticalSection cs_main;
BlockMap& mapBlockIndex = g_chainstate.mapBlockIndex;
CChain& chainActive = g_chainstate.chainActive;
CBlockIndex *pindexBestHeader = nullptr;
-CWaitableCriticalSection g_best_block_mutex;
-CConditionVariable g_best_block_cv;
+Mutex g_best_block_mutex;
+std::condition_variable g_best_block_cv;
uint256 g_best_block;
int nScriptCheckThreads = 0;
std::atomic_bool fImporting(false);
@@ -421,7 +421,7 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool
// lock on a mempool input, so we can use the return value of
// CheckSequenceLocks to indicate the LockPoints validity
int maxInputHeight = 0;
- for (int height : prevheights) {
+ for (const int height : prevheights) {
// Can ignore mempool inputs since we'll fail if they had non-zero locks
if (height != tip->nHeight+1) {
maxInputHeight = std::max(maxInputHeight, height);
@@ -602,10 +602,8 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
std::set<uint256> setConflicts;
for (const CTxIn &txin : tx.vin)
{
- auto itConflicting = pool.mapNextTx.find(txin.prevout);
- if (itConflicting != pool.mapNextTx.end())
- {
- const CTransaction *ptxConflicting = itConflicting->second;
+ const CTransaction* ptxConflicting = pool.GetConflictTx(txin.prevout);
+ if (ptxConflicting) {
if (!setConflicts.count(ptxConflicting->GetHash()))
{
// Allow opt-out of transaction replacement by setting
@@ -786,16 +784,8 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
CFeeRate newFeeRate(nModifiedFees, nSize);
std::set<uint256> setConflictsParents;
const int maxDescendantsToVisit = 100;
- CTxMemPool::setEntries setIterConflicting;
- for (const uint256 &hashConflicting : setConflicts)
- {
- CTxMemPool::txiter mi = pool.mapTx.find(hashConflicting);
- if (mi == pool.mapTx.end())
- continue;
-
- // Save these to avoid repeated lookups
- setIterConflicting.insert(mi);
-
+ const CTxMemPool::setEntries setIterConflicting = pool.GetIterSet(setConflicts);
+ for (const auto& mi : setIterConflicting) {
// Don't allow the replacement to reduce the feerate of the
// mempool.
//
@@ -861,11 +851,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
// Rather than check the UTXO set - potentially expensive -
// it's cheaper to just check if the new input refers to a
// tx that's in the mempool.
- if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end())
+ if (pool.exists(tx.vin[j].prevout.hash)) {
return state.DoS(0, false,
REJECT_NONSTANDARD, "replacement-adds-unconfirmed", false,
strprintf("replacement %s adds unconfirmed input, idx %d",
hash.ToString(), j));
+ }
}
}
@@ -2239,7 +2230,7 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar
mempool.AddTransactionsUpdated(1);
{
- WaitableLock lock(g_best_block_mutex);
+ LOCK(g_best_block_mutex);
g_best_block = pindexNew->GetBlockHash();
g_best_block_cv.notify_all();
}
@@ -4291,7 +4282,7 @@ void UnloadBlockIndex()
warningcache[b].clear();
}
- for (BlockMap::value_type& entry : mapBlockIndex) {
+ for (const BlockMap::value_type& entry : mapBlockIndex) {
delete entry.second;
}
mapBlockIndex.clear();
@@ -4492,7 +4483,7 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
// Build forward-pointing map of the entire block tree.
std::multimap<CBlockIndex*,CBlockIndex*> forward;
- for (auto& entry : mapBlockIndex) {
+ for (const std::pair<const uint256, CBlockIndex*>& entry : mapBlockIndex) {
forward.insert(std::make_pair(entry.second->pprev, entry.second));
}
diff --git a/src/validation.h b/src/validation.h
index c4c9b8b5ba..3df6456eca 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -151,8 +151,8 @@ extern BlockMap& mapBlockIndex;
extern uint64_t nLastBlockTx;
extern uint64_t nLastBlockWeight;
extern const std::string strMessageMagic;
-extern CWaitableCriticalSection g_best_block_mutex;
-extern CConditionVariable g_best_block_cv;
+extern Mutex g_best_block_mutex;
+extern std::condition_variable g_best_block_cv;
extern uint256 g_best_block;
extern std::atomic_bool fImporting;
extern std::atomic_bool fReindex;
diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp
index 4fa9603011..729e4e39b0 100644
--- a/src/wallet/crypter.cpp
+++ b/src/wallet/crypter.cpp
@@ -311,7 +311,7 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
return false;
fUseCrypto = true;
- for (KeyMap::value_type& mKey : mapKeys)
+ for (const KeyMap::value_type& mKey : mapKeys)
{
const CKey &key = mKey.second;
CPubKey vchPubKey = key.GetPubKey();
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index d0fe51801e..dfd60ae5eb 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -72,7 +72,7 @@ BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& data
database_filename = "wallet.dat";
}
LOCK(cs_db);
- // Note: An ununsed temporary BerkeleyEnvironment object may be created inside the
+ // Note: An unused temporary BerkeleyEnvironment object may be created inside the
// emplace function if the key already exists. This is a little inefficient,
// but not a big concern since the map will be changed in the future to hold
// pointers instead of objects, anyway.
@@ -503,7 +503,7 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo
// be implemented, so no equality checks are needed at all. (Newer
// versions of BDB have an set_lk_exclusive method for this
// purpose, but the older version we use does not.)
- for (auto& env : g_dbenvs) {
+ for (const auto& env : g_dbenvs) {
CheckUniqueFileid(env.second, strFilename, *pdb_temp);
}
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 60f14e5886..c82d0e97d4 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -41,7 +41,7 @@ int64_t static DecodeDumpTime(const std::string &str) {
std::string static EncodeDumpString(const std::string &str) {
std::stringstream ret;
- for (unsigned char c : str) {
+ for (const unsigned char c : str) {
if (c <= 32 || c >= 128 || c == '%') {
ret << '%' << HexStr(&c, &c + 1);
} else {
@@ -849,6 +849,9 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
std::vector<unsigned char> vData(ParseHex(output));
script = CScript(vData.begin(), vData.end());
+ if (!ExtractDestination(script, dest) && !internal) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal must be set to true for nonstandard scriptPubKey imports.");
+ }
}
// Watchonly and private keys
@@ -861,11 +864,6 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
throw JSONRPCError(RPC_INVALID_PARAMETER, "Incompatibility found between internal and label");
}
- // Not having Internal + Script
- if (!internal && isScript) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal must be set for hex scriptPubKey");
- }
-
// Keys / PubKeys size check.
if (!isP2SH && (keys.size() > 1 || pubKeys.size() > 1)) { // Address / scriptPubKey
throw JSONRPCError(RPC_INVALID_PARAMETER, "More than private key given for one address");
@@ -969,21 +967,10 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
CTxDestination pubkey_dest = pubKey.GetID();
// Consistency check.
- if (!isScript && !(pubkey_dest == dest)) {
+ if (!(pubkey_dest == dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
}
- // Consistency check.
- if (isScript) {
- CTxDestination destination;
-
- if (ExtractDestination(script, destination)) {
- if (!(destination == pubkey_dest)) {
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
- }
- }
- }
-
CScript pubKeyScript = GetScriptForDestination(pubkey_dest);
if (::IsMine(*pwallet, pubKeyScript) == ISMINE_SPENDABLE) {
@@ -1034,21 +1021,10 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
CTxDestination pubkey_dest = pubKey.GetID();
// Consistency check.
- if (!isScript && !(pubkey_dest == dest)) {
+ if (!(pubkey_dest == dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
}
- // Consistency check.
- if (isScript) {
- CTxDestination destination;
-
- if (ExtractDestination(script, destination)) {
- if (!(destination == pubkey_dest)) {
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
- }
- }
- }
-
CKeyID vchAddress = pubKey.GetID();
pwallet->MarkDirty();
pwallet->SetAddressBook(vchAddress, label, "receive");
@@ -1080,11 +1056,9 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
}
- if (scriptPubKey.getType() == UniValue::VOBJ) {
- // add to address book or update label
- if (IsValidDestination(dest)) {
- pwallet->SetAddressBook(dest, label, "receive");
- }
+ // add to address book or update label
+ if (IsValidDestination(dest)) {
+ pwallet->SetAddressBook(dest, label, "receive");
}
success = true;
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 66ec070982..15f3e5947e 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -278,7 +278,6 @@ static UniValue setlabel(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
}
- std::string old_label = pwallet->mapAddressBook[dest].name;
std::string label = LabelFromValue(request.params[1]);
if (IsMine(*pwallet, dest)) {
@@ -2338,7 +2337,7 @@ static UniValue listlockunspent(const JSONRPCRequest& request)
UniValue ret(UniValue::VARR);
- for (COutPoint &outpt : vOutpts) {
+ for (const COutPoint& outpt : vOutpts) {
UniValue o(UniValue::VOBJ);
o.pushKV("txid", outpt.hash.GetHex());
@@ -4066,6 +4065,7 @@ UniValue importprunedfunds(const JSONRPCRequest& request);
UniValue removeprunedfunds(const JSONRPCRequest& request);
UniValue importmulti(const JSONRPCRequest& request);
+// clang-format off
static const CRPCCommand commands[] =
{ // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ----------
@@ -4126,6 +4126,7 @@ static const CRPCCommand commands[] =
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, {"oldpassphrase","newpassphrase"} },
{ "wallet", "walletprocesspsbt", &walletprocesspsbt, {"psbt","sign","sighashtype","bip32derivs"} },
};
+// clang-format on
void RegisterWalletRPCCommands(CRPCTable &t)
{
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index b436efc276..3a8e6f751a 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -320,7 +320,11 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
// Confirm ListCoins initially returns 1 coin grouped under coinbaseKey
// address.
- auto list = wallet->ListCoins();
+ std::map<CTxDestination, std::vector<COutput>> list;
+ {
+ LOCK2(cs_main, wallet->cs_wallet);
+ list = wallet->ListCoins();
+ }
BOOST_CHECK_EQUAL(list.size(), 1U);
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
BOOST_CHECK_EQUAL(list.begin()->second.size(), 1U);
@@ -333,7 +337,10 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
// coinbaseKey pubkey, even though the change address has a different
// pubkey.
AddTx(CRecipient{GetScriptForRawPubKey({}), 1 * COIN, false /* subtract fee */});
- list = wallet->ListCoins();
+ {
+ LOCK2(cs_main, wallet->cs_wallet);
+ list = wallet->ListCoins();
+ }
BOOST_CHECK_EQUAL(list.size(), 1U);
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);
@@ -359,7 +366,10 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
}
// Confirm ListCoins still returns same result as before, despite coins
// being locked.
- list = wallet->ListCoins();
+ {
+ LOCK2(cs_main, wallet->cs_wallet);
+ list = wallet->ListCoins();
+ }
BOOST_CHECK_EQUAL(list.size(), 1U);
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index d3ccd2dfaa..de707a09f4 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -687,6 +687,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
{
encrypted_batch->TxnAbort();
delete encrypted_batch;
+ encrypted_batch = nullptr;
// We now probably have half of our keys encrypted in memory, and half not...
// die and let the user reload the unencrypted wallet.
assert(false);
@@ -697,6 +698,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
if (!encrypted_batch->TxnCommit()) {
delete encrypted_batch;
+ encrypted_batch = nullptr;
// We now have keys encrypted in memory, but not on disk...
// die to avoid confusion and let the user reload the unencrypted wallet.
assert(false);
@@ -1484,7 +1486,7 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wall
// Look up the inputs. We should have already checked that this transaction
// IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our
// wallet, with a valid index into the vout array, and the ability to sign.
- for (auto& input : tx.vin) {
+ for (const CTxIn& input : tx.vin) {
const auto mi = wallet->mapWallet.find(input.prevout.hash);
if (mi == wallet->mapWallet.end()) {
return -1;
@@ -1723,7 +1725,7 @@ void CWallet::ReacceptWalletTransactions()
}
// Try to add wallet transactions to memory pool
- for (std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
+ for (const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
CWalletTx& wtx = *(item.second);
CValidationState state;
wtx.AcceptToMemoryPool(maxTxFee, state);
@@ -1969,7 +1971,7 @@ std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime, CCon
continue;
mapSorted.insert(std::make_pair(wtx.nTimeReceived, &wtx));
}
- for (std::pair<const unsigned int, CWalletTx*>& item : mapSorted)
+ for (const std::pair<const unsigned int, CWalletTx*>& item : mapSorted)
{
CWalletTx& wtx = *item.second;
if (wtx.RelayWalletTransaction(connman))
@@ -2252,23 +2254,15 @@ void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const
std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins() const
{
- // TODO: Add AssertLockHeld(cs_wallet) here.
- //
- // Because the return value from this function contains pointers to
- // CWalletTx objects, callers to this function really should acquire the
- // cs_wallet lock before calling it. However, the current caller doesn't
- // acquire this lock yet. There was an attempt to add the missing lock in
- // https://github.com/bitcoin/bitcoin/pull/10340, but that change has been
- // postponed until after https://github.com/bitcoin/bitcoin/pull/10244 to
- // avoid adding some extra complexity to the Qt code.
+ AssertLockHeld(cs_main);
+ AssertLockHeld(cs_wallet);
std::map<CTxDestination, std::vector<COutput>> result;
std::vector<COutput> availableCoins;
- LOCK2(cs_main, cs_wallet);
AvailableCoins(availableCoins);
- for (auto& coin : availableCoins) {
+ for (const COutput& coin : availableCoins) {
CTxDestination address;
if (coin.fSpendable &&
ExtractDestination(FindNonChangeParentOutput(*coin.tx->tx, coin.i).scriptPubKey, address)) {
@@ -2278,7 +2272,7 @@ std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins() const
std::vector<COutPoint> lockedCoins;
ListLockedCoins(lockedCoins);
- for (const auto& output : lockedCoins) {
+ for (const COutPoint& output : lockedCoins) {
auto it = mapWallet.find(output.hash);
if (it != mapWallet.end()) {
int depth = it->second.GetDepthInMainChain();
@@ -3154,17 +3148,17 @@ bool CWallet::NewKeyPool()
LOCK(cs_wallet);
WalletBatch batch(*database);
- for (int64_t nIndex : setInternalKeyPool) {
+ for (const int64_t nIndex : setInternalKeyPool) {
batch.ErasePool(nIndex);
}
setInternalKeyPool.clear();
- for (int64_t nIndex : setExternalKeyPool) {
+ for (const int64_t nIndex : setExternalKeyPool) {
batch.ErasePool(nIndex);
}
setExternalKeyPool.clear();
- for (int64_t nIndex : set_pre_split_keypool) {
+ for (const int64_t nIndex : set_pre_split_keypool) {
batch.ErasePool(nIndex);
}
set_pre_split_keypool.clear();
@@ -3441,7 +3435,7 @@ std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
{
bool any_mine = false;
// group all input addresses with each other
- for (CTxIn txin : pcoin->tx->vin)
+ for (const CTxIn& txin : pcoin->tx->vin)
{
CTxDestination address;
if(!IsMine(txin)) /* If this input isn't mine, ignore it */
@@ -3455,7 +3449,7 @@ std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
// group change with input addresses
if (any_mine)
{
- for (CTxOut txout : pcoin->tx->vout)
+ for (const CTxOut& txout : pcoin->tx->vout)
if (IsChange(txout))
{
CTxDestination txoutAddr;
@@ -3491,7 +3485,7 @@ std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
// make a set of all the groups hit by this new group
std::set< std::set<CTxDestination>* > hits;
std::map< CTxDestination, std::set<CTxDestination>* >::iterator it;
- for (CTxDestination address : _grouping)
+ for (const CTxDestination& address : _grouping)
if ((it = setmap.find(address)) != setmap.end())
hits.insert((*it).second);
@@ -3506,12 +3500,12 @@ std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
uniqueGroupings.insert(merged);
// update setmap
- for (CTxDestination element : *merged)
+ for (const CTxDestination& element : *merged)
setmap[element] = merged;
}
std::set< std::set<CTxDestination> > ret;
- for (std::set<CTxDestination>* uniqueGrouping : uniqueGroupings)
+ for (const std::set<CTxDestination>* uniqueGrouping : uniqueGroupings)
{
ret.insert(*uniqueGrouping);
delete uniqueGrouping;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 05ae9a1bbf..da326517c0 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -764,7 +764,7 @@ public:
/**
* Return list of available coins and locked coins grouped by non-change output address.
*/
- std::map<CTxDestination, std::vector<COutput>> ListCoins() const;
+ std::map<CTxDestination, std::vector<COutput>> ListCoins() const EXCLUSIVE_LOCKS_REQUIRED(cs_main, cs_wallet);
/**
* Find non-change parent output.
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 5ce4d080e5..5e85151358 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -520,7 +520,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta)
pwallet->UpdateTimeFirstKey(1);
- for (uint256 hash : wss.vWalletUpgrade)
+ for (const uint256& hash : wss.vWalletUpgrade)
WriteTx(pwallet->mapWallet.at(hash));
// Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
@@ -611,7 +611,7 @@ DBErrors WalletBatch::ZapSelectTx(std::vector<uint256>& vTxHashIn, std::vector<u
// erase each matching wallet TX
bool delerror = false;
std::vector<uint256>::iterator it = vTxHashIn.begin();
- for (uint256 hash : vTxHash) {
+ for (const uint256& hash : vTxHash) {
while (it < vTxHashIn.end() && (*it) < hash) {
it++;
}
@@ -642,7 +642,7 @@ DBErrors WalletBatch::ZapWalletTx(std::vector<CWalletTx>& vWtx)
return err;
// erase each wallet TX
- for (uint256& hash : vTxHash) {
+ for (const uint256& hash : vTxHash) {
if (!EraseTx(hash))
return DBErrors::CORRUPT;
}