aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bench/block_assemble.cpp15
-rw-r--r--src/chainparamsseeds.h8
-rw-r--r--src/compressor.cpp2
-rw-r--r--src/dbwrapper.cpp7
-rw-r--r--src/index/base.cpp2
-rw-r--r--src/index/blockfilterindex.cpp12
-rw-r--r--src/index/coinstatsindex.cpp10
-rw-r--r--src/index/txindex.cpp18
-rw-r--r--src/init.cpp45
-rw-r--r--src/key.cpp4
-rw-r--r--src/key.h2
-rw-r--r--src/node/blockstorage.cpp326
-rw-r--r--src/node/blockstorage.h41
-rw-r--r--src/node/utxo_snapshot.h9
-rw-r--r--src/pubkey.cpp2
-rw-r--r--src/pubkey.h4
-rw-r--r--src/qt/test/rpcnestedtests.cpp6
-rw-r--r--src/qt/walletmodel.cpp2
-rw-r--r--src/random.cpp2
-rw-r--r--src/rpc/net.cpp4
-rw-r--r--src/script/descriptor.cpp4
-rw-r--r--src/script/interpreter.cpp2
-rw-r--r--src/script/sigcache.cpp4
-rw-r--r--src/script/sign.cpp2
-rw-r--r--src/test/compress_tests.cpp10
-rw-r--r--src/test/crypto_tests.cpp8
-rw-r--r--src/test/data/tx_invalid.json4
-rw-r--r--src/test/fuzz/rpc.cpp32
-rw-r--r--src/test/fuzz/script_assets_test_minimizer.cpp17
-rw-r--r--src/test/fuzz/tx_pool.cpp75
-rw-r--r--src/test/fuzz/util.cpp13
-rw-r--r--src/test/fuzz/util.h23
-rw-r--r--src/test/script_standard_tests.cpp34
-rw-r--r--src/test/script_tests.cpp26
-rw-r--r--src/test/validation_chainstatemanager_tests.cpp6
-rw-r--r--src/validation.cpp287
-rw-r--r--src/validation.h35
-rw-r--r--src/wallet/crypter.cpp6
-rw-r--r--src/wallet/rpcdump.cpp8
-rw-r--r--src/wallet/salvage.cpp4
-rw-r--r--src/wallet/scriptpubkeyman.cpp2
-rw-r--r--src/wallet/test/wallet_tests.cpp1
-rw-r--r--src/wallet/wallet.cpp4
-rw-r--r--src/zmq/zmqpublishnotifier.cpp2
44 files changed, 598 insertions, 532 deletions
diff --git a/src/bench/block_assemble.cpp b/src/bench/block_assemble.cpp
index 67ab02a5b3..aa72981cb4 100644
--- a/src/bench/block_assemble.cpp
+++ b/src/bench/block_assemble.cpp
@@ -6,6 +6,7 @@
#include <consensus/validation.h>
#include <crypto/sha256.h>
#include <test/util/mining.h>
+#include <test/util/script.h>
#include <test/util/setup_common.h>
#include <test/util/wallet.h>
#include <txmempool.h>
@@ -18,23 +19,17 @@ static void AssembleBlock(benchmark::Bench& bench)
{
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
- const std::vector<unsigned char> op_true{OP_TRUE};
CScriptWitness witness;
- witness.stack.push_back(op_true);
-
- uint256 witness_program;
- CSHA256().Write(&op_true[0], op_true.size()).Finalize(witness_program.begin());
-
- const CScript SCRIPT_PUB{CScript(OP_0) << std::vector<unsigned char>{witness_program.begin(), witness_program.end()}};
+ witness.stack.push_back(WITNESS_STACK_ELEM_OP_TRUE);
// Collect some loose transactions that spend the coinbases of our mined blocks
constexpr size_t NUM_BLOCKS{200};
std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs;
for (size_t b{0}; b < NUM_BLOCKS; ++b) {
CMutableTransaction tx;
- tx.vin.push_back(MineBlock(test_setup->m_node, SCRIPT_PUB));
+ tx.vin.push_back(MineBlock(test_setup->m_node, P2WSH_OP_TRUE));
tx.vin.back().scriptWitness = witness;
- tx.vout.emplace_back(1337, SCRIPT_PUB);
+ tx.vout.emplace_back(1337, P2WSH_OP_TRUE);
if (NUM_BLOCKS - b >= COINBASE_MATURITY)
txs.at(b) = MakeTransactionRef(tx);
}
@@ -48,7 +43,7 @@ static void AssembleBlock(benchmark::Bench& bench)
}
bench.run([&] {
- PrepareBlock(test_setup->m_node, SCRIPT_PUB);
+ PrepareBlock(test_setup->m_node, P2WSH_OP_TRUE);
});
}
diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h
index cd7b806621..2e31daea83 100644
--- a/src/chainparamsseeds.h
+++ b/src/chainparamsseeds.h
@@ -1195,6 +1195,14 @@ static const uint8_t chainparams_seed_main[] = {
0x04,0x20,0x98,0xc6,0x44,0x27,0x90,0x41,0xa6,0x98,0xf9,0x25,0x6c,0x59,0x0f,0x06,0x6d,0x44,0x59,0x0e,0xb2,0x46,0xb0,0xa4,0x37,0x88,0x69,0x8f,0xc1,0x32,0xcd,0x9f,0x15,0xd7,0x20,0x8d,
0x04,0x20,0xaa,0x3a,0x16,0x86,0xea,0x59,0x09,0x04,0x78,0xe5,0x10,0x92,0xe1,0x1d,0xad,0xf7,0x56,0x2b,0xac,0xb0,0x97,0x29,0x63,0x30,0xf4,0x1b,0xcf,0xde,0xf3,0x28,0x0a,0x29,0x20,0x8d,
0x04,0x20,0xbc,0x27,0xae,0x89,0xc1,0x67,0x73,0x0a,0x08,0x02,0xdf,0xb7,0xcc,0x94,0xc7,0x9f,0xf4,0x72,0x7a,0x9b,0x20,0x0c,0x5c,0x11,0x3d,0x22,0xd6,0x13,0x88,0x66,0x74,0xbf,0x20,0x8d,
+ 0x05,0x20,0xfe,0x97,0xba,0x09,0x2a,0xa4,0x85,0x10,0xa1,0x04,0x7b,0x88,0x7a,0x5a,0x06,0x53,0x71,0x93,0x3b,0xf9,0xa2,0x2f,0xd9,0xe3,0x8f,0xa5,0xa2,0xac,0x1e,0x6c,0x6c,0x8c,0x20,0x8d,
+ 0x05,0x20,0x17,0x0c,0x56,0xce,0x72,0xa5,0xa0,0xe6,0x23,0x06,0xa3,0xc7,0x08,0x43,0x18,0xee,0x3a,0x46,0x35,0x5d,0x17,0xf6,0x78,0x96,0xa0,0x9c,0x51,0xef,0xbe,0x23,0xfd,0x71,0x20,0x8d,
+ 0x05,0x20,0x31,0x0f,0x30,0x0b,0x9d,0x70,0x0c,0x7c,0xf7,0x98,0x7e,0x1c,0xf4,0x33,0xdc,0x64,0x17,0xf7,0x00,0x7a,0x0c,0x04,0xb5,0x83,0xfc,0x5f,0xa6,0x52,0x39,0x79,0x63,0x87,0x20,0x8d,
+ 0x05,0x20,0x3e,0xe3,0xe0,0xa9,0xbc,0xf4,0x2e,0x59,0xd9,0x20,0xee,0xdf,0x74,0x61,0x4d,0x99,0x0c,0x5c,0x15,0x30,0x9b,0x72,0x16,0x79,0x15,0xf4,0x7a,0xca,0x34,0xcc,0x81,0x99,0x20,0x8d,
+ 0x05,0x20,0x3b,0x42,0x1c,0x25,0xf7,0xbf,0x79,0xed,0x6d,0x7d,0xef,0x65,0x30,0x7d,0xee,0x16,0x37,0x22,0x72,0x43,0x33,0x28,0x40,0xa3,0xaa,0xf4,0x48,0x49,0x67,0xb1,0x4b,0xfd,0x20,0x8d,
+ 0x05,0x20,0x7a,0x65,0xf7,0x47,0x42,0x9d,0x66,0x42,0x3b,0xb3,0xa7,0x03,0x6c,0x46,0x78,0x19,0x28,0x78,0x1e,0xa3,0x7c,0x67,0x44,0xb7,0x83,0x05,0xe3,0xfe,0xa5,0xe4,0x0a,0x6e,0x20,0x8d,
+ 0x05,0x20,0xb5,0x83,0x6f,0xb6,0x11,0xd8,0x0e,0xa8,0x57,0xda,0x15,0x20,0x5b,0x1a,0x6d,0x21,0x15,0x5a,0xbd,0xb4,0x17,0x11,0xc2,0xfb,0x0e,0xfc,0xde,0xe8,0x26,0x56,0xa8,0xac,0x20,0x8d,
+ 0x05,0x20,0xcc,0xaf,0x6c,0x3b,0xd0,0x13,0x76,0x23,0xc3,0x36,0xbb,0x64,0x4a,0x4a,0x06,0x93,0x69,0x6d,0xb0,0x10,0x6e,0x66,0xa4,0x61,0xf8,0x2d,0xe7,0x80,0x72,0x4d,0x53,0x94,0x20,0x8d,
};
static const uint8_t chainparams_seed_test[] = {
diff --git a/src/compressor.cpp b/src/compressor.cpp
index ef3135e7a5..a161c42866 100644
--- a/src/compressor.cpp
+++ b/src/compressor.cpp
@@ -124,7 +124,7 @@ bool DecompressScript(CScript& script, unsigned int nSize, const CompressedScrip
unsigned char vch[33] = {};
vch[0] = nSize - 2;
memcpy(&vch[1], in.data(), 32);
- CPubKey pubkey(&vch[0], &vch[33]);
+ CPubKey pubkey{vch};
if (!pubkey.Decompress())
return false;
assert(pubkey.size() == 65);
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
index d7694108f5..3a1086bf4c 100644
--- a/src/dbwrapper.cpp
+++ b/src/dbwrapper.cpp
@@ -220,10 +220,9 @@ const unsigned int CDBWrapper::OBFUSCATE_KEY_NUM_BYTES = 8;
*/
std::vector<unsigned char> CDBWrapper::CreateObfuscateKey() const
{
- unsigned char buff[OBFUSCATE_KEY_NUM_BYTES];
- GetRandBytes(buff, OBFUSCATE_KEY_NUM_BYTES);
- return std::vector<unsigned char>(&buff[0], &buff[OBFUSCATE_KEY_NUM_BYTES]);
-
+ std::vector<uint8_t> ret(OBFUSCATE_KEY_NUM_BYTES);
+ GetRandBytes(ret.data(), OBFUSCATE_KEY_NUM_BYTES);
+ return ret;
}
bool CDBWrapper::IsEmpty()
diff --git a/src/index/base.cpp b/src/index/base.cpp
index 9e637c9c6f..357c4fbaf9 100644
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -13,7 +13,7 @@
#include <validation.h> // For g_chainman
#include <warnings.h>
-constexpr char DB_BEST_BLOCK = 'B';
+constexpr uint8_t DB_BEST_BLOCK{'B'};
constexpr int64_t SYNC_LOG_INTERVAL = 30; // seconds
constexpr int64_t SYNC_LOCATOR_WRITE_INTERVAL = 30; // seconds
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
index 154d7a7027..b82b9915d5 100644
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -24,9 +24,9 @@
* as big-endian so that sequential reads of filters by height are fast.
* Keys for the hash index have the type [DB_BLOCK_HASH, uint256].
*/
-constexpr char DB_BLOCK_HASH = 's';
-constexpr char DB_BLOCK_HEIGHT = 't';
-constexpr char DB_FILTER_POS = 'P';
+constexpr uint8_t DB_BLOCK_HASH{'s'};
+constexpr uint8_t DB_BLOCK_HEIGHT{'t'};
+constexpr uint8_t DB_FILTER_POS{'P'};
constexpr unsigned int MAX_FLTR_FILE_SIZE = 0x1000000; // 16 MiB
/** The pre-allocation chunk size for fltr?????.dat files */
@@ -63,7 +63,7 @@ struct DBHeightKey {
template<typename Stream>
void Unserialize(Stream& s)
{
- char prefix = ser_readdata8(s);
+ const uint8_t prefix{ser_readdata8(s)};
if (prefix != DB_BLOCK_HEIGHT) {
throw std::ios_base::failure("Invalid format for block filter index DB height key");
}
@@ -77,7 +77,7 @@ struct DBHashKey {
explicit DBHashKey(const uint256& hash_in) : hash(hash_in) {}
SERIALIZE_METHODS(DBHashKey, obj) {
- char prefix = DB_BLOCK_HASH;
+ uint8_t prefix{DB_BLOCK_HASH};
READWRITE(prefix);
if (prefix != DB_BLOCK_HASH) {
throw std::ios_base::failure("Invalid format for block filter index DB hash key");
@@ -149,7 +149,7 @@ bool BlockFilterIndex::ReadFilterFromDisk(const FlatFilePos& pos, BlockFilter& f
}
uint256 block_hash;
- std::vector<unsigned char> encoded_filter;
+ std::vector<uint8_t> encoded_filter;
try {
filein >> block_hash >> encoded_filter;
filter = BlockFilter(GetFilterType(), block_hash, std::move(encoded_filter));
diff --git a/src/index/coinstatsindex.cpp b/src/index/coinstatsindex.cpp
index c7c1f4b533..7c8b2b186e 100644
--- a/src/index/coinstatsindex.cpp
+++ b/src/index/coinstatsindex.cpp
@@ -12,9 +12,9 @@
#include <undo.h>
#include <validation.h>
-static constexpr char DB_BLOCK_HASH = 's';
-static constexpr char DB_BLOCK_HEIGHT = 't';
-static constexpr char DB_MUHASH = 'M';
+static constexpr uint8_t DB_BLOCK_HASH{'s'};
+static constexpr uint8_t DB_BLOCK_HEIGHT{'t'};
+static constexpr uint8_t DB_MUHASH{'M'};
namespace {
@@ -66,7 +66,7 @@ struct DBHeightKey {
template <typename Stream>
void Unserialize(Stream& s)
{
- char prefix{static_cast<char>(ser_readdata8(s))};
+ const uint8_t prefix{ser_readdata8(s)};
if (prefix != DB_BLOCK_HEIGHT) {
throw std::ios_base::failure("Invalid format for coinstatsindex DB height key");
}
@@ -81,7 +81,7 @@ struct DBHashKey {
SERIALIZE_METHODS(DBHashKey, obj)
{
- char prefix{DB_BLOCK_HASH};
+ uint8_t prefix{DB_BLOCK_HASH};
READWRITE(prefix);
if (prefix != DB_BLOCK_HASH) {
throw std::ios_base::failure("Invalid format for coinstatsindex DB hash key");
diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp
index f41985c344..3feefe8619 100644
--- a/src/index/txindex.cpp
+++ b/src/index/txindex.cpp
@@ -4,20 +4,20 @@
#include <index/disktxpos.h>
#include <index/txindex.h>
+#include <node/blockstorage.h>
#include <node/ui_interface.h>
#include <shutdown.h>
#include <util/system.h>
#include <util/translation.h>
#include <validation.h>
-constexpr char DB_BEST_BLOCK = 'B';
-constexpr char DB_TXINDEX = 't';
-constexpr char DB_TXINDEX_BLOCK = 'T';
+constexpr uint8_t DB_BEST_BLOCK{'B'};
+constexpr uint8_t DB_TXINDEX{'t'};
+constexpr uint8_t DB_TXINDEX_BLOCK{'T'};
std::unique_ptr<TxIndex> g_txindex;
-
/** Access to the txindex database (indexes/txindex/) */
class TxIndex::DB : public BaseIndex::DB
{
@@ -60,8 +60,8 @@ bool TxIndex::DB::WriteTxs(const std::vector<std::pair<uint256, CDiskTxPos>>& v_
*/
static void WriteTxIndexMigrationBatches(CDBWrapper& newdb, CDBWrapper& olddb,
CDBBatch& batch_newdb, CDBBatch& batch_olddb,
- const std::pair<unsigned char, uint256>& begin_key,
- const std::pair<unsigned char, uint256>& end_key)
+ const std::pair<uint8_t, uint256>& begin_key,
+ const std::pair<uint8_t, uint256>& end_key)
{
// Sync new DB changes to disk before deleting from old DB.
newdb.WriteBatch(batch_newdb, /*fSync=*/ true);
@@ -113,9 +113,9 @@ bool TxIndex::DB::MigrateData(CBlockTreeDB& block_tree_db, const CBlockLocator&
CDBBatch batch_newdb(*this);
CDBBatch batch_olddb(block_tree_db);
- std::pair<unsigned char, uint256> key;
- std::pair<unsigned char, uint256> begin_key{DB_TXINDEX, uint256()};
- std::pair<unsigned char, uint256> prev_key = begin_key;
+ std::pair<uint8_t, uint256> key;
+ std::pair<uint8_t, uint256> begin_key{DB_TXINDEX, uint256()};
+ std::pair<uint8_t, uint256> prev_key = begin_key;
bool interrupted = false;
std::unique_ptr<CDBIterator> cursor(block_tree_db.NewIterator());
diff --git a/src/init.cpp b/src/init.cpp
index 10404f9887..dbc4ea30c5 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -420,7 +420,7 @@ void SetupServerArgs(NodeContext& node)
" If <type> is not supplied or if <type> = 1, indexes for all known types are enabled.",
ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
- argsman.AddArg("-addnode=<ip>", "Add a node to connect to and attempt to keep the connection open (see the `addnode` RPC command help for more info). This option can be specified multiple times to add multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
+ argsman.AddArg("-addnode=<ip>", strprintf("Add a node to connect to and attempt to keep the connection open (see the addnode RPC help for more info). This option can be specified multiple times to add multiple nodes; connections are limited to %u at a time and are counted separately from the -maxconnections limit.", MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), signetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
@@ -433,7 +433,7 @@ void SetupServerArgs(NodeContext& node)
argsman.AddArg("-forcednsseed", strprintf("Always query for peer addresses via DNS lookup (default: %u)", DEFAULT_FORCEDNSSEED), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-listen", "Accept connections from outside (default: 1 if no -proxy or -connect)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-listenonion", strprintf("Automatically create Tor onion service (default: %d)", DEFAULT_LISTEN_ONION), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
- argsman.AddArg("-maxconnections=<n>", strprintf("Maintain at most <n> connections to peers (default: %u)", DEFAULT_MAX_PEER_CONNECTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
+ argsman.AddArg("-maxconnections=<n>", strprintf("Maintain at most <n> connections to peers (default: %u). This limit does not apply to connections manually added via -addnode or the addnode RPC, which have a separate limit of %u.", DEFAULT_MAX_PEER_CONNECTIONS, MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxreceivebuffer=<n>", strprintf("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXRECEIVEBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxsendbuffer=<n>", strprintf("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.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), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
@@ -602,47 +602,6 @@ static void BlockNotifyGenesisWait(const CBlockIndex* pBlockIndex)
}
}
-// If we're using -prune with -reindex, then delete block files that will be ignored by the
-// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
-// is missing, do the same here to delete any later block files after a gap. Also delete all
-// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
-// is in sync with what's actually on disk by the time we start downloading, so that pruning
-// works correctly.
-static void CleanupBlockRevFiles()
-{
- std::map<std::string, fs::path> mapBlockFiles;
-
- // Glob all blk?????.dat and rev?????.dat files from the blocks directory.
- // Remove the rev files immediately and insert the blk file paths into an
- // ordered map keyed by block file index.
- LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
- fs::path blocksdir = gArgs.GetBlocksDirPath();
- for (fs::directory_iterator it(blocksdir); it != fs::directory_iterator(); it++) {
- if (fs::is_regular_file(*it) &&
- it->path().filename().string().length() == 12 &&
- it->path().filename().string().substr(8,4) == ".dat")
- {
- if (it->path().filename().string().substr(0,3) == "blk")
- mapBlockFiles[it->path().filename().string().substr(3,5)] = it->path();
- else if (it->path().filename().string().substr(0,3) == "rev")
- remove(it->path());
- }
- }
-
- // Remove all block files that aren't part of a contiguous set starting at
- // zero by walking the ordered map (keys are block file indices) by
- // keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
- // start removing block files.
- int nContigCounter = 0;
- for (const std::pair<const std::string, fs::path>& item : mapBlockFiles) {
- if (atoi(item.first) == nContigCounter) {
- nContigCounter++;
- continue;
- }
- remove(item.second);
- }
-}
-
#if HAVE_SYSTEM
static void StartupNotify(const ArgsManager& args)
{
diff --git a/src/key.cpp b/src/key.cpp
index 1e59b301cb..5666adebb8 100644
--- a/src/key.cpp
+++ b/src/key.cpp
@@ -293,7 +293,7 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const
bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const {
out.nDepth = nDepth + 1;
CKeyID id = key.GetPubKey().GetID();
- memcpy(&out.vchFingerprint[0], &id, 4);
+ memcpy(out.vchFingerprint, &id, 4);
out.nChild = _nChild;
return key.Derive(out.key, out.chaincode, _nChild, chaincode);
}
@@ -312,7 +312,7 @@ void CExtKey::SetSeed(const unsigned char *seed, unsigned int nSeedLen) {
CExtPubKey CExtKey::Neuter() const {
CExtPubKey ret;
ret.nDepth = nDepth;
- memcpy(&ret.vchFingerprint[0], &vchFingerprint[0], 4);
+ memcpy(ret.vchFingerprint, vchFingerprint, 4);
ret.nChild = nChild;
ret.pubkey = key.GetPubKey();
ret.chaincode = chaincode;
diff --git a/src/key.h b/src/key.h
index 206322956c..3ee49a778b 100644
--- a/src/key.h
+++ b/src/key.h
@@ -151,7 +151,7 @@ struct CExtKey {
friend bool operator==(const CExtKey& a, const CExtKey& b)
{
return a.nDepth == b.nDepth &&
- memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], sizeof(vchFingerprint)) == 0 &&
+ memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
a.nChild == b.nChild &&
a.chaincode == b.chaincode &&
a.key == b.key;
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index daed6605e8..6c66c565ad 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -6,17 +6,310 @@
#include <chain.h>
#include <chainparams.h>
+#include <clientversion.h>
+#include <consensus/validation.h>
#include <flatfile.h>
#include <fs.h>
+#include <hash.h>
#include <pow.h>
#include <shutdown.h>
#include <signet.h>
#include <streams.h>
+#include <undo.h>
#include <util/system.h>
#include <validation.h>
-// From validation. TODO move here
-bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false);
+std::atomic_bool fImporting(false);
+std::atomic_bool fReindex(false);
+bool fHavePruned = false;
+bool fPruneMode = false;
+uint64_t nPruneTarget = 0;
+
+// TODO make namespace {
+RecursiveMutex cs_LastBlockFile;
+std::vector<CBlockFileInfo> vinfoBlockFile;
+int nLastBlockFile = 0;
+/** Global flag to indicate we should check to see if there are
+* block/undo files that should be deleted. Set on startup
+* or if we allocate more file space when we're in prune mode
+*/
+bool fCheckForPruning = false;
+
+/** Dirty block index entries. */
+std::set<CBlockIndex*> setDirtyBlockIndex;
+
+/** Dirty block file entries. */
+std::set<int> setDirtyFileInfo;
+// } // namespace
+
+static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false);
+static FlatFileSeq BlockFileSeq();
+static FlatFileSeq UndoFileSeq();
+
+bool IsBlockPruned(const CBlockIndex* pblockindex)
+{
+ return (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0);
+}
+
+// If we're using -prune with -reindex, then delete block files that will be ignored by the
+// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
+// is missing, do the same here to delete any later block files after a gap. Also delete all
+// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
+// is in sync with what's actually on disk by the time we start downloading, so that pruning
+// works correctly.
+void CleanupBlockRevFiles()
+{
+ std::map<std::string, fs::path> mapBlockFiles;
+
+ // Glob all blk?????.dat and rev?????.dat files from the blocks directory.
+ // Remove the rev files immediately and insert the blk file paths into an
+ // ordered map keyed by block file index.
+ LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
+ fs::path blocksdir = gArgs.GetBlocksDirPath();
+ for (fs::directory_iterator it(blocksdir); it != fs::directory_iterator(); it++) {
+ if (fs::is_regular_file(*it) &&
+ it->path().filename().string().length() == 12 &&
+ it->path().filename().string().substr(8,4) == ".dat")
+ {
+ if (it->path().filename().string().substr(0, 3) == "blk") {
+ mapBlockFiles[it->path().filename().string().substr(3, 5)] = it->path();
+ } else if (it->path().filename().string().substr(0, 3) == "rev") {
+ remove(it->path());
+ }
+ }
+ }
+
+ // Remove all block files that aren't part of a contiguous set starting at
+ // zero by walking the ordered map (keys are block file indices) by
+ // keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
+ // start removing block files.
+ int nContigCounter = 0;
+ for (const std::pair<const std::string, fs::path>& item : mapBlockFiles) {
+ if (atoi(item.first) == nContigCounter) {
+ nContigCounter++;
+ continue;
+ }
+ remove(item.second);
+ }
+}
+
+std::string CBlockFileInfo::ToString() const
+{
+ return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast));
+}
+
+CBlockFileInfo* GetBlockFileInfo(size_t n)
+{
+ LOCK(cs_LastBlockFile);
+
+ return &vinfoBlockFile.at(n);
+}
+
+static bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
+{
+ // Open history file to append
+ CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
+ if (fileout.IsNull()) {
+ return error("%s: OpenUndoFile failed", __func__);
+ }
+
+ // Write index header
+ unsigned int nSize = GetSerializeSize(blockundo, fileout.GetVersion());
+ fileout << messageStart << nSize;
+
+ // Write undo data
+ long fileOutPos = ftell(fileout.Get());
+ if (fileOutPos < 0) {
+ return error("%s: ftell failed", __func__);
+ }
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << blockundo;
+
+ // calculate & write checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << blockundo;
+ fileout << hasher.GetHash();
+
+ return true;
+}
+
+bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
+{
+ FlatFilePos pos = pindex->GetUndoPos();
+ if (pos.IsNull()) {
+ return error("%s: no undo data available", __func__);
+ }
+
+ // Open history file to read
+ CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull()) {
+ return error("%s: OpenUndoFile failed", __func__);
+ }
+
+ // Read block
+ uint256 hashChecksum;
+ CHashVerifier<CAutoFile> verifier(&filein); // We need a CHashVerifier as reserializing may lose data
+ try {
+ verifier << pindex->pprev->GetBlockHash();
+ verifier >> blockundo;
+ filein >> hashChecksum;
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ }
+
+ // Verify checksum
+ if (hashChecksum != verifier.GetHash()) {
+ return error("%s: Checksum mismatch", __func__);
+ }
+
+ return true;
+}
+
+static void FlushUndoFile(int block_file, bool finalize = false)
+{
+ FlatFilePos undo_pos_old(block_file, vinfoBlockFile[block_file].nUndoSize);
+ if (!UndoFileSeq().Flush(undo_pos_old, finalize)) {
+ AbortNode("Flushing undo file to disk failed. This is likely the result of an I/O error.");
+ }
+}
+
+void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false)
+{
+ LOCK(cs_LastBlockFile);
+ FlatFilePos block_pos_old(nLastBlockFile, vinfoBlockFile[nLastBlockFile].nSize);
+ if (!BlockFileSeq().Flush(block_pos_old, fFinalize)) {
+ AbortNode("Flushing block file to disk failed. This is likely the result of an I/O error.");
+ }
+ // we do not always flush the undo file, as the chain tip may be lagging behind the incoming blocks,
+ // e.g. during IBD or a sync after a node going offline
+ if (!fFinalize || finalize_undo) FlushUndoFile(nLastBlockFile, finalize_undo);
+}
+
+uint64_t CalculateCurrentUsage()
+{
+ LOCK(cs_LastBlockFile);
+
+ uint64_t retval = 0;
+ for (const CBlockFileInfo& file : vinfoBlockFile) {
+ retval += file.nSize + file.nUndoSize;
+ }
+ return retval;
+}
+
+void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune)
+{
+ for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
+ FlatFilePos pos(*it, 0);
+ fs::remove(BlockFileSeq().FileName(pos));
+ fs::remove(UndoFileSeq().FileName(pos));
+ LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
+ }
+}
+
+static FlatFileSeq BlockFileSeq()
+{
+ return FlatFileSeq(gArgs.GetBlocksDirPath(), "blk", gArgs.GetBoolArg("-fastprune", false) ? 0x4000 /* 16kb */ : BLOCKFILE_CHUNK_SIZE);
+}
+
+static FlatFileSeq UndoFileSeq()
+{
+ return FlatFileSeq(gArgs.GetBlocksDirPath(), "rev", UNDOFILE_CHUNK_SIZE);
+}
+
+FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly)
+{
+ return BlockFileSeq().Open(pos, fReadOnly);
+}
+
+/** Open an undo file (rev?????.dat) */
+static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly)
+{
+ return UndoFileSeq().Open(pos, fReadOnly);
+}
+
+fs::path GetBlockPosFilename(const FlatFilePos& pos)
+{
+ return BlockFileSeq().FileName(pos);
+}
+
+bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false)
+{
+ LOCK(cs_LastBlockFile);
+
+ unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
+ if (vinfoBlockFile.size() <= nFile) {
+ vinfoBlockFile.resize(nFile + 1);
+ }
+
+ bool finalize_undo = false;
+ if (!fKnown) {
+ while (vinfoBlockFile[nFile].nSize + nAddSize >= (gArgs.GetBoolArg("-fastprune", false) ? 0x10000 /* 64kb */ : MAX_BLOCKFILE_SIZE)) {
+ // when the undo file is keeping up with the block file, we want to flush it explicitly
+ // when it is lagging behind (more blocks arrive than are being connected), we let the
+ // undo block write case handle it
+ assert(std::addressof(::ChainActive()) == std::addressof(active_chain));
+ finalize_undo = (vinfoBlockFile[nFile].nHeightLast == (unsigned int)active_chain.Tip()->nHeight);
+ nFile++;
+ if (vinfoBlockFile.size() <= nFile) {
+ vinfoBlockFile.resize(nFile + 1);
+ }
+ }
+ pos.nFile = nFile;
+ pos.nPos = vinfoBlockFile[nFile].nSize;
+ }
+
+ if ((int)nFile != nLastBlockFile) {
+ if (!fKnown) {
+ LogPrint(BCLog::VALIDATION, "Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString());
+ }
+ FlushBlockFile(!fKnown, finalize_undo);
+ nLastBlockFile = nFile;
+ }
+
+ vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
+ if (fKnown) {
+ vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
+ } else {
+ vinfoBlockFile[nFile].nSize += nAddSize;
+ }
+
+ if (!fKnown) {
+ bool out_of_space;
+ size_t bytes_allocated = BlockFileSeq().Allocate(pos, nAddSize, out_of_space);
+ if (out_of_space) {
+ return AbortNode("Disk space is too low!", _("Disk space is too low!"));
+ }
+ if (bytes_allocated != 0 && fPruneMode) {
+ fCheckForPruning = true;
+ }
+ }
+
+ setDirtyFileInfo.insert(nFile);
+ return true;
+}
+
+static bool FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize)
+{
+ pos.nFile = nFile;
+
+ LOCK(cs_LastBlockFile);
+
+ pos.nPos = vinfoBlockFile[nFile].nUndoSize;
+ vinfoBlockFile[nFile].nUndoSize += nAddSize;
+ setDirtyFileInfo.insert(nFile);
+
+ bool out_of_space;
+ size_t bytes_allocated = UndoFileSeq().Allocate(pos, nAddSize, out_of_space);
+ if (out_of_space) {
+ return AbortNode(state, "Disk space is too low!", _("Disk space is too low!"));
+ }
+ if (bytes_allocated != 0 && fPruneMode) {
+ fCheckForPruning = true;
+ }
+
+ return true;
+}
static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart)
{
@@ -41,6 +334,35 @@ static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessa
return true;
}
+bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams)
+{
+ // Write undo information to disk
+ if (pindex->GetUndoPos().IsNull()) {
+ FlatFilePos _pos;
+ if (!FindUndoPos(state, pindex->nFile, _pos, ::GetSerializeSize(blockundo, CLIENT_VERSION) + 40)) {
+ return error("ConnectBlock(): FindUndoPos failed");
+ }
+ if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart())) {
+ return AbortNode(state, "Failed to write undo data");
+ }
+ // rev files are written in block height order, whereas blk files are written as blocks come in (often out of order)
+ // we want to flush the rev (undo) file once we've written the last block, which is indicated by the last height
+ // in the block file info as below; note that this does not catch the case where the undo writes are keeping up
+ // with the block writes (usually when a synced up node is getting newly mined blocks) -- this case is caught in
+ // the FindBlockPos function
+ if (_pos.nFile < nLastBlockFile && static_cast<uint32_t>(pindex->nHeight) == vinfoBlockFile[_pos.nFile].nHeightLast) {
+ FlushUndoFile(_pos.nFile, true);
+ }
+
+ // update nUndoPos in block index
+ pindex->nUndoPos = _pos.nPos;
+ pindex->nStatus |= BLOCK_HAVE_UNDO;
+ setDirtyBlockIndex.insert(pindex);
+ }
+
+ return true;
+}
+
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams)
{
block.SetNull();
diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h
index 3b546f0719..faf99dea81 100644
--- a/src/node/blockstorage.h
+++ b/src/node/blockstorage.h
@@ -12,7 +12,9 @@
#include <protocol.h> // For CMessageHeader::MessageStartChars
class ArgsManager;
+class BlockValidationState;
class CBlock;
+class CBlockFileInfo;
class CBlockIndex;
class CBlockUndo;
class CChain;
@@ -25,6 +27,44 @@ struct Params;
static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false};
+/** The pre-allocation chunk size for blk?????.dat files (since 0.8) */
+static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
+/** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
+static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
+/** The maximum size of a blk?????.dat file (since 0.8) */
+static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
+
+extern std::atomic_bool fImporting;
+extern std::atomic_bool fReindex;
+/** Pruning-related variables and constants */
+/** True if any block files have ever been pruned. */
+extern bool fHavePruned;
+/** True if we're running in -prune mode. */
+extern bool fPruneMode;
+/** Number of MiB of block files that we're trying to stay below. */
+extern uint64_t nPruneTarget;
+
+//! Check whether the block associated with this index entry is pruned or not.
+bool IsBlockPruned(const CBlockIndex* pblockindex);
+
+void CleanupBlockRevFiles();
+
+/** Open a block file (blk?????.dat) */
+FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false);
+/** Translation to a filesystem path */
+fs::path GetBlockPosFilename(const FlatFilePos& pos);
+
+/** Get block file info entry for one block file */
+CBlockFileInfo* GetBlockFileInfo(size_t n);
+
+/** Calculate the amount of disk space the block & undo files currently use */
+uint64_t CalculateCurrentUsage();
+
+/**
+ * Actually unlink the specified files
+ */
+void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune);
+
/** Functions for disk access for blocks */
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams);
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
@@ -32,6 +72,7 @@ bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, c
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start);
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
+bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams);
FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp);
diff --git a/src/node/utxo_snapshot.h b/src/node/utxo_snapshot.h
index fe78cb46bd..61292cdcc5 100644
--- a/src/node/utxo_snapshot.h
+++ b/src/node/utxo_snapshot.h
@@ -22,20 +22,15 @@ public:
//! during snapshot load to estimate progress of UTXO set reconstruction.
uint64_t m_coins_count = 0;
- //! Necessary to "fake" the base nChainTx so that we can estimate progress during
- //! initial block download for the assumeutxo chainstate.
- unsigned int m_nchaintx = 0;
-
SnapshotMetadata() { }
SnapshotMetadata(
const uint256& base_blockhash,
uint64_t coins_count,
unsigned int nchaintx) :
m_base_blockhash(base_blockhash),
- m_coins_count(coins_count),
- m_nchaintx(nchaintx) { }
+ m_coins_count(coins_count) { }
- SERIALIZE_METHODS(SnapshotMetadata, obj) { READWRITE(obj.m_base_blockhash, obj.m_coins_count, obj.m_nchaintx); }
+ SERIALIZE_METHODS(SnapshotMetadata, obj) { READWRITE(obj.m_base_blockhash, obj.m_coins_count); }
};
#endif // BITCOIN_NODE_UTXO_SNAPSHOT_H
diff --git a/src/pubkey.cpp b/src/pubkey.cpp
index fc1624af25..a89988cc90 100644
--- a/src/pubkey.cpp
+++ b/src/pubkey.cpp
@@ -293,7 +293,7 @@ void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
out.nDepth = nDepth + 1;
CKeyID id = pubkey.GetID();
- memcpy(&out.vchFingerprint[0], &id, 4);
+ memcpy(out.vchFingerprint, &id, 4);
out.nChild = _nChild;
return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
}
diff --git a/src/pubkey.h b/src/pubkey.h
index 12514fc3c9..b653c202fc 100644
--- a/src/pubkey.h
+++ b/src/pubkey.h
@@ -101,7 +101,7 @@ public:
}
//! Construct a public key from a byte vector.
- explicit CPubKey(const std::vector<unsigned char>& _vch)
+ explicit CPubKey(Span<const uint8_t> _vch)
{
Set(_vch.begin(), _vch.end());
}
@@ -247,7 +247,7 @@ struct CExtPubKey {
friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
{
return a.nDepth == b.nDepth &&
- memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], sizeof(vchFingerprint)) == 0 &&
+ memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
a.nChild == b.nChild &&
a.chaincode == b.chaincode &&
a.pubkey == b.pubkey;
diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp
index 9e6e98b274..df3b85ea71 100644
--- a/src/qt/test/rpcnestedtests.cpp
+++ b/src/qt/test/rpcnestedtests.cpp
@@ -35,14 +35,16 @@ static RPCHelpMan rpcNestedTest_rpc()
}
static const CRPCCommand vRPCCommands[] = {
- {"test", &rpcNestedTest_rpc},
+ {"rpcNestedTest", &rpcNestedTest_rpc},
};
void RPCNestedTests::rpcNestedTests()
{
// do some test setup
// could be moved to a more generic place when we add more tests on QT level
- tableRPC.appendCommand("rpcNestedTest", &vRPCCommands[0]);
+ for (const auto& c : vRPCCommands) {
+ tableRPC.appendCommand(c.name, &c);
+ }
TestingSetup test;
m_node.setContext(&test.m_node);
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index c6dd0c2ad6..cc6db8d33e 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -248,7 +248,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << *newTx;
- transaction_array.append((const char*)&(ssTx[0]), ssTx.size());
+ transaction_array.append((const char*)ssTx.data(), ssTx.size());
}
// Add addresses / update labels that we've sent to the address book,
diff --git a/src/random.cpp b/src/random.cpp
index 9900825abb..174f4cef31 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -628,7 +628,7 @@ std::vector<unsigned char> FastRandomContext::randbytes(size_t len)
if (requires_seed) RandomSeed();
std::vector<unsigned char> ret(len);
if (len > 0) {
- rng.Keystream(&ret[0], len);
+ rng.Keystream(ret.data(), len);
}
return ret;
}
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 2bfcaeafc9..382c6f11ff 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -277,7 +277,9 @@ static RPCHelpMan addnode()
"\nAttempts to add or remove a node from the addnode list.\n"
"Or try a connection to a node once.\n"
"Nodes added using addnode (or -connect) are protected from DoS disconnection and are not required to be\n"
- "full nodes/support SegWit as other outbound peers are (though such peers will not be synced from).\n",
+ "full nodes/support SegWit as other outbound peers are (though such peers will not be synced from).\n" +
+ strprintf("Addnode connections are limited to %u at a time", MAX_ADDNODE_CONNECTIONS) +
+ " and are counted separately from the -maxconnections limit.\n",
{
{"node", RPCArg::Type::STR, RPCArg::Optional::NO, "The node (see getpeerinfo for nodes)"},
{"command", RPCArg::Type::STR, RPCArg::Optional::NO, "'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once"},
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index e433ed6764..b54ba204f0 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -1098,7 +1098,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
TxoutType txntype = Solver(script, data);
if (txntype == TxoutType::PUBKEY) {
- CPubKey pubkey(data[0].begin(), data[0].end());
+ CPubKey pubkey(data[0]);
if (pubkey.IsValid()) {
return std::make_unique<PKDescriptor>(InferPubkey(pubkey, ctx, provider));
}
@@ -1122,7 +1122,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
if (txntype == TxoutType::MULTISIG) {
std::vector<std::unique_ptr<PubkeyProvider>> providers;
for (size_t i = 1; i + 1 < data.size(); ++i) {
- CPubKey pubkey(data[i].begin(), data[i].end());
+ CPubKey pubkey(data[i]);
providers.push_back(InferPubkey(pubkey, ctx, provider));
}
return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers));
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 7e119bb3c4..dc0f165be0 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1890,7 +1890,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
const valtype& script_bytes = SpanPopBack(stack);
exec_script = CScript(script_bytes.begin(), script_bytes.end());
uint256 hash_exec_script;
- CSHA256().Write(&exec_script[0], exec_script.size()).Finalize(hash_exec_script.begin());
+ CSHA256().Write(exec_script.data(), exec_script.size()).Finalize(hash_exec_script.begin());
if (memcmp(hash_exec_script.begin(), program.data(), 32)) {
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
}
diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp
index c6d898a25a..65867c1c14 100644
--- a/src/script/sigcache.cpp
+++ b/src/script/sigcache.cpp
@@ -53,14 +53,14 @@ public:
ComputeEntryECDSA(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) const
{
CSHA256 hasher = m_salted_hasher_ecdsa;
- hasher.Write(hash.begin(), 32).Write(&pubkey[0], pubkey.size()).Write(&vchSig[0], vchSig.size()).Finalize(entry.begin());
+ hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(vchSig.data(), vchSig.size()).Finalize(entry.begin());
}
void
ComputeEntrySchnorr(uint256& entry, const uint256 &hash, Span<const unsigned char> sig, const XOnlyPubKey& pubkey) const
{
CSHA256 hasher = m_salted_hasher_schnorr;
- hasher.Write(hash.begin(), 32).Write(&pubkey[0], pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin());
+ hasher.Write(hash.begin(), 32).Write(pubkey.data(), pubkey.size()).Write(sig.data(), sig.size()).Finalize(entry.begin());
}
bool
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index 4d9026427e..da0092f9e3 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -167,7 +167,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
return true;
case TxoutType::WITNESS_V0_SCRIPTHASH:
- CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin());
+ CRIPEMD160().Write(vSolutions[0].data(), vSolutions[0].size()).Finalize(h160.begin());
if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
return true;
diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp
index 7b661a0d1d..b7ba46bd30 100644
--- a/src/test/compress_tests.cpp
+++ b/src/test/compress_tests.cpp
@@ -79,7 +79,7 @@ BOOST_AUTO_TEST_CASE(compress_script_to_ckey_id)
// Check compressed script
BOOST_CHECK_EQUAL(out.size(), 21U);
BOOST_CHECK_EQUAL(out[0], 0x00);
- BOOST_CHECK_EQUAL(memcmp(&out[1], &script[3], 20), 0); // compare the 20 relevant chars of the CKeyId in the script
+ BOOST_CHECK_EQUAL(memcmp(out.data() + 1, script.data() + 3, 20), 0); // compare the 20 relevant chars of the CKeyId in the script
}
BOOST_AUTO_TEST_CASE(compress_script_to_cscript_id)
@@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(compress_script_to_cscript_id)
// Check compressed script
BOOST_CHECK_EQUAL(out.size(), 21U);
BOOST_CHECK_EQUAL(out[0], 0x01);
- BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 20), 0); // compare the 20 relevant chars of the CScriptId in the script
+ BOOST_CHECK_EQUAL(memcmp(out.data() + 1, script.data() + 2, 20), 0); // compare the 20 relevant chars of the CScriptId in the script
}
BOOST_AUTO_TEST_CASE(compress_script_to_compressed_pubkey_id)
@@ -113,8 +113,8 @@ BOOST_AUTO_TEST_CASE(compress_script_to_compressed_pubkey_id)
// Check compressed script
BOOST_CHECK_EQUAL(out.size(), 33U);
- BOOST_CHECK_EQUAL(memcmp(&out[0], &script[1], 1), 0);
- BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 32), 0); // compare the 32 chars of the compressed CPubKey
+ BOOST_CHECK_EQUAL(memcmp(out.data(), script.data() + 1, 1), 0);
+ BOOST_CHECK_EQUAL(memcmp(out.data() + 1, script.data() + 2, 32), 0); // compare the 32 chars of the compressed CPubKey
}
BOOST_AUTO_TEST_CASE(compress_script_to_uncompressed_pubkey_id)
@@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE(compress_script_to_uncompressed_pubkey_id)
// Check compressed script
BOOST_CHECK_EQUAL(out.size(), 33U);
- BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 32), 0); // first 32 chars of CPubKey are copied into out[1:]
+ BOOST_CHECK_EQUAL(memcmp(out.data() + 1, script.data() + 2, 32), 0); // first 32 chars of CPubKey are copied into out[1:]
BOOST_CHECK_EQUAL(out[0], 0x04 | (script[65] & 0x01)); // least significant bit (lsb) of last char of pubkey is mapped into out[0]
}
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
index 7358b246b6..edec5f0a31 100644
--- a/src/test/crypto_tests.cpp
+++ b/src/test/crypto_tests.cpp
@@ -33,7 +33,7 @@ static void TestVector(const Hasher &h, const In &in, const Out &out) {
hash.resize(out.size());
{
// Test that writing the whole input string at once works.
- Hasher(h).Write((unsigned char*)&in[0], in.size()).Finalize(&hash[0]);
+ Hasher(h).Write((const uint8_t*)in.data(), in.size()).Finalize(hash.data());
BOOST_CHECK(hash == out);
}
for (int i=0; i<32; i++) {
@@ -42,15 +42,15 @@ static void TestVector(const Hasher &h, const In &in, const Out &out) {
size_t pos = 0;
while (pos < in.size()) {
size_t len = InsecureRandRange((in.size() - pos + 1) / 2 + 1);
- hasher.Write((unsigned char*)&in[pos], len);
+ hasher.Write((const uint8_t*)in.data() + pos, len);
pos += len;
if (pos > 0 && pos + 2 * out.size() > in.size() && pos < in.size()) {
// Test that writing the rest at once to a copy of a hasher works.
- Hasher(hasher).Write((unsigned char*)&in[pos], in.size() - pos).Finalize(&hash[0]);
+ Hasher(hasher).Write((const uint8_t*)in.data() + pos, in.size() - pos).Finalize(hash.data());
BOOST_CHECK(hash == out);
}
}
- hasher.Finalize(&hash[0]);
+ hasher.Finalize(hash.data());
BOOST_CHECK(hash == out);
}
}
diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json
index 41bebab2a0..a47bc8f366 100644
--- a/src/test/data/tx_invalid.json
+++ b/src/test/data/tx_invalid.json
@@ -311,6 +311,10 @@
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x34b6c399093e06cf9f0f7f660a1abcfe78fcf7b576f43993208edd9518a0ae9b", 1000]],
"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015101045102010100000000", "P2SH,WITNESS"],
+["P2WSH with an empty redeem should fail due to empty stack"],
+[[["3d4da21b04a67a54c8a58df1c53a0534b0a7f0864fb3d19abd43b8f6934e785f", 0, "0x00 0x20 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 1337]],
+"020000000001015f784e93f6b843bd9ad1b34f86f0a7b034053ac5f18da5c8547aa6041ba24d3d0000000000ffffffff013905000000000000220020e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855010000000000", "P2SH,WITNESS"],
+
["33 bytes push should be considered a witness scriptPubKey"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x21 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff", 1000]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"],
diff --git a/src/test/fuzz/rpc.cpp b/src/test/fuzz/rpc.cpp
index dae6f6b6a7..cf32a79932 100644
--- a/src/test/fuzz/rpc.cpp
+++ b/src/test/fuzz/rpc.cpp
@@ -3,9 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <base58.h>
-#include <chainparamsbase.h>
#include <core_io.h>
-#include <interfaces/chain.h>
#include <key.h>
#include <key_io.h>
#include <node/context.h>
@@ -70,18 +68,15 @@ const std::vector<std::string> RPC_COMMANDS_NOT_SAFE_FOR_FUZZING{
"addpeeraddress", // avoid DNS lookups
"analyzepsbt", // avoid signed integer overflow in CFeeRate::GetFee(unsigned long) (https://github.com/bitcoin/bitcoin/issues/20607)
"dumptxoutset", // avoid writing to disk
-#ifdef ENABLE_WALLET
"dumpwallet", // avoid writing to disk
-#endif
- "echoipc", // avoid assertion failure (Assertion `"EnsureAnyNodeContext(request.context).init" && check' failed.)
- "generatetoaddress", // avoid timeout
- "gettxoutproof", // avoid slow execution
-#ifdef ENABLE_WALLET
+ "echoipc", // avoid assertion failure (Assertion `"EnsureAnyNodeContext(request.context).init" && check' failed.)
+ "generatetoaddress", // avoid prohibitively slow execution (when `num_blocks` is large)
+ "generatetodescriptor", // avoid prohibitively slow execution (when `nblocks` is large)
+ "gettxoutproof", // avoid prohibitively slow execution
"importwallet", // avoid reading from disk
"loadwallet", // avoid reading from disk
-#endif
- "mockscheduler", // avoid assertion failure (Assertion `delta_seconds.count() > 0 && delta_seconds < std::chrono::hours{1}' failed.)
"prioritisetransaction", // avoid signed integer overflow in CTxMemPool::PrioritiseTransaction(uint256 const&, long const&) (https://github.com/bitcoin/bitcoin/issues/20626)
+ "savemempool", // disabled as a precautionary measure: may take a file path argument in the future
"setban", // avoid DNS lookups
"stop", // avoid shutdown state
};
@@ -107,7 +102,6 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
"finalizepsbt",
"generate",
"generateblock",
- "generatetodescriptor",
"getaddednodeinfo",
"getbestblockhash",
"getblock",
@@ -145,11 +139,11 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
"joinpsbts",
"listbanned",
"logging",
+ "mockscheduler",
"ping",
"preciousblock",
"pruneblockchain",
"reconsiderblock",
- "savemempool",
"scantxoutset",
"sendrawtransaction",
"setmocktime",
@@ -334,20 +328,6 @@ void initialize_rpc()
std::terminate();
}
}
- for (const std::string& rpc_command : RPC_COMMANDS_SAFE_FOR_FUZZING) {
- const bool supported_rpc_command = std::find(supported_rpc_commands.begin(), supported_rpc_commands.end(), rpc_command) != supported_rpc_commands.end();
- if (!supported_rpc_command) {
- std::cerr << "Error: Unknown RPC command \"" << rpc_command << "\" found in RPC_COMMANDS_SAFE_FOR_FUZZING. Please update " << __FILE__ << ".\n";
- std::terminate();
- }
- }
- for (const std::string& rpc_command : RPC_COMMANDS_NOT_SAFE_FOR_FUZZING) {
- const bool supported_rpc_command = std::find(supported_rpc_commands.begin(), supported_rpc_commands.end(), rpc_command) != supported_rpc_commands.end();
- if (!supported_rpc_command) {
- std::cerr << "Error: Unknown RPC command \"" << rpc_command << "\" found in RPC_COMMANDS_NOT_SAFE_FOR_FUZZING. Please update " << __FILE__ << ".\n";
- std::terminate();
- }
- }
const char* limit_to_rpc_command_env = std::getenv("LIMIT_TO_RPC_COMMAND");
if (limit_to_rpc_command_env != nullptr) {
g_limit_to_rpc_command = std::string{limit_to_rpc_command_env};
diff --git a/src/test/fuzz/script_assets_test_minimizer.cpp b/src/test/fuzz/script_assets_test_minimizer.cpp
index cec5212f42..a80338b965 100644
--- a/src/test/fuzz/script_assets_test_minimizer.cpp
+++ b/src/test/fuzz/script_assets_test_minimizer.cpp
@@ -133,8 +133,7 @@ unsigned int ParseScriptFlags(const std::string& str)
std::vector<std::string> words;
boost::algorithm::split(words, str, boost::algorithm::is_any_of(","));
- for (const std::string& word : words)
- {
+ for (const std::string& word : words) {
auto it = FLAG_NAMES.find(word);
if (it == FLAG_NAMES.end()) throw std::runtime_error("Unknown verification flag " + word);
flags |= it->second;
@@ -186,15 +185,19 @@ void Test(const std::string& str)
}
}
-ECCVerifyHandle handle;
-
-} // namespace
+void test_init()
+{
+ static ECCVerifyHandle handle;
+}
-FUZZ_TARGET_INIT_HIDDEN(script_assets_test_minimizer, FuzzFrameworkEmptyInitFun, /* hidden */ true)
+FUZZ_TARGET_INIT_HIDDEN(script_assets_test_minimizer, test_init, /* hidden */ true)
{
if (buffer.size() < 2 || buffer.back() != '\n' || buffer[buffer.size() - 2] != ',') return;
const std::string str((const char*)buffer.data(), buffer.size() - 2);
try {
Test(str);
- } catch (const std::runtime_error&) {}
+ } catch (const std::runtime_error&) {
+ }
}
+
+} // namespace
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index fe8d17b24a..59229987ba 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <consensus/validation.h>
+#include <miner.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
@@ -77,13 +78,44 @@ void SetMempoolConstraints(ArgsManager& args, FuzzedDataProvider& fuzzed_data_pr
ToString(fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 999)));
}
+void Finish(FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, CChainState& chainstate)
+{
+ WITH_LOCK(::cs_main, tx_pool.check(chainstate));
+ {
+ BlockAssembler::Options options;
+ options.nBlockMaxWeight = fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BLOCK_WEIGHT);
+ options.blockMinFeeRate = CFeeRate{ConsumeMoney(fuzzed_data_provider)};
+ auto assembler = BlockAssembler{chainstate, *static_cast<CTxMemPool*>(&tx_pool), ::Params(), options};
+ auto block_template = assembler.CreateNewBlock(CScript{} << OP_TRUE);
+ Assert(block_template->block.vtx.size() >= 1);
+ }
+ const auto info_all = tx_pool.infoAll();
+ if (!info_all.empty()) {
+ const auto& tx_to_remove = *PickValue(fuzzed_data_provider, info_all).tx;
+ WITH_LOCK(tx_pool.cs, tx_pool.removeRecursive(tx_to_remove, /* dummy */ MemPoolRemovalReason::BLOCK));
+ std::vector<uint256> all_txids;
+ tx_pool.queryHashes(all_txids);
+ assert(all_txids.size() < info_all.size());
+ WITH_LOCK(::cs_main, tx_pool.check(chainstate));
+ }
+ SyncWithValidationInterfaceQueue();
+}
+
+void MockTime(FuzzedDataProvider& fuzzed_data_provider, const CChainState& chainstate)
+{
+ const auto time = ConsumeTime(fuzzed_data_provider,
+ chainstate.m_chain.Tip()->GetMedianTimePast() + 1,
+ std::numeric_limits<decltype(chainstate.m_chain.Tip()->nTime)>::max());
+ SetMockTime(time);
+}
+
FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const auto& node = g_setup->m_node;
auto& chainstate = node.chainman->ActiveChainstate();
- SetMockTime(ConsumeTime(fuzzed_data_provider));
+ MockTime(fuzzed_data_provider, chainstate);
SetMempoolConstraints(*node.args, fuzzed_data_provider);
// All RBF-spendable outpoints
@@ -163,7 +195,7 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool)
}();
if (fuzzed_data_provider.ConsumeBool()) {
- SetMockTime(ConsumeTime(fuzzed_data_provider));
+ MockTime(fuzzed_data_provider, chainstate);
}
if (fuzzed_data_provider.ConsumeBool()) {
SetMempoolConstraints(*node.args, fuzzed_data_provider);
@@ -237,23 +269,17 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool)
}
}
}
- WITH_LOCK(::cs_main, tx_pool.check(chainstate));
- const auto info_all = tx_pool.infoAll();
- if (!info_all.empty()) {
- const auto& tx_to_remove = *PickValue(fuzzed_data_provider, info_all).tx;
- WITH_LOCK(tx_pool.cs, tx_pool.removeRecursive(tx_to_remove, /* dummy */ MemPoolRemovalReason::BLOCK));
- std::vector<uint256> all_txids;
- tx_pool.queryHashes(all_txids);
- assert(all_txids.size() < info_all.size());
- WITH_LOCK(::cs_main, tx_pool.check(chainstate));
- }
- SyncWithValidationInterfaceQueue();
+ Finish(fuzzed_data_provider, tx_pool, chainstate);
}
FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const auto& node = g_setup->m_node;
+ auto& chainstate = node.chainman->ActiveChainstate();
+
+ MockTime(fuzzed_data_provider, chainstate);
+ SetMempoolConstraints(*node.args, fuzzed_data_provider);
std::vector<uint256> txids;
for (const auto& outpoint : g_outpoints_coinbase_init_mature) {
@@ -265,11 +291,29 @@ FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool)
txids.push_back(ConsumeUInt256(fuzzed_data_provider));
}
- CTxMemPool tx_pool{/* estimator */ nullptr, /* check_ratio */ 1};
+ CTxMemPool tx_pool_{/* estimator */ nullptr, /* check_ratio */ 1};
+ MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_);
while (fuzzed_data_provider.ConsumeBool()) {
const auto mut_tx = ConsumeTransaction(fuzzed_data_provider, txids);
+ if (fuzzed_data_provider.ConsumeBool()) {
+ MockTime(fuzzed_data_provider, chainstate);
+ }
+ if (fuzzed_data_provider.ConsumeBool()) {
+ SetMempoolConstraints(*node.args, fuzzed_data_provider);
+ }
+ if (fuzzed_data_provider.ConsumeBool()) {
+ tx_pool.RollingFeeUpdate();
+ }
+ if (fuzzed_data_provider.ConsumeBool()) {
+ const auto& txid = fuzzed_data_provider.ConsumeBool() ?
+ mut_tx.GetHash() :
+ PickValue(fuzzed_data_provider, txids);
+ const auto delta = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-50 * COIN, +50 * COIN);
+ tx_pool.PrioritiseTransaction(txid, delta);
+ }
+
const auto tx = MakeTransactionRef(mut_tx);
const bool bypass_limits = fuzzed_data_provider.ConsumeBool();
::fRequireStandard = fuzzed_data_provider.ConsumeBool();
@@ -278,8 +322,7 @@ FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool)
if (accepted) {
txids.push_back(tx->GetHash());
}
-
- SyncWithValidationInterfaceQueue();
}
+ Finish(fuzzed_data_provider, tx_pool, chainstate);
}
} // namespace
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp
index b8d846a995..574b694d1a 100644
--- a/src/test/fuzz/util.cpp
+++ b/src/test/fuzz/util.cpp
@@ -5,6 +5,7 @@
#include <test/fuzz/util.h>
#include <test/util/script.h>
#include <util/rbf.h>
+#include <util/time.h>
#include <version.h>
FuzzedSock::FuzzedSock(FuzzedDataProvider& fuzzed_data_provider)
@@ -216,6 +217,14 @@ void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_v
}
}
+int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min, const std::optional<int64_t>& max) noexcept
+{
+ // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime.
+ static const int64_t time_min = ParseISO8601DateTime("1970-01-01T00:00:01Z");
+ static const int64_t time_max = ParseISO8601DateTime("9999-12-31T23:59:59Z");
+ return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(min.value_or(time_min), max.value_or(time_max));
+}
+
CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<uint256>>& prevout_txids, const int max_num_in, const int max_num_out) noexcept
{
CMutableTransaction tx_mut;
@@ -267,13 +276,13 @@ CScriptWitness ConsumeScriptWitness(FuzzedDataProvider& fuzzed_data_provider, co
return ret;
}
-CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length, const bool maybe_p2wsh) noexcept
+CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length, const bool maybe_p2wsh) noexcept
{
const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length);
CScript r_script{b.begin(), b.end()};
if (maybe_p2wsh && fuzzed_data_provider.ConsumeBool()) {
uint256 script_hash;
- CSHA256().Write(&r_script[0], r_script.size()).Finalize(script_hash.begin());
+ CSHA256().Write(r_script.data(), r_script.size()).Finalize(script_hash.begin());
r_script.clear();
r_script << OP_0 << ToByteVector(script_hash);
}
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 8f4f87fbdc..1a83f7a57a 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -26,7 +26,6 @@
#include <test/util/net.h>
#include <txmempool.h>
#include <uint256.h>
-#include <util/time.h>
#include <version.h>
#include <algorithm>
@@ -58,18 +57,20 @@ auto& PickValue(FuzzedDataProvider& fuzzed_data_provider, Collection& col)
return *it;
}
-[[nodiscard]] inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length = std::nullopt) noexcept
{
- const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(max_length);
+ const std::string s = max_length ?
+ fuzzed_data_provider.ConsumeRandomLengthString(*max_length) :
+ fuzzed_data_provider.ConsumeRandomLengthString();
return {s.begin(), s.end()};
}
-[[nodiscard]] inline std::vector<bool> ConsumeRandomLengthBitVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline std::vector<bool> ConsumeRandomLengthBitVector(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length = std::nullopt) noexcept
{
return BytesToBits(ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length));
}
-[[nodiscard]] inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length = std::nullopt) noexcept
{
return CDataStream{ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION};
}
@@ -96,7 +97,7 @@ template <typename T>
}
template <typename T>
-[[nodiscard]] inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+[[nodiscard]] inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length = std::nullopt) noexcept
{
const std::vector<uint8_t> buffer = ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length);
CDataStream ds{buffer, SER_NETWORK, INIT_PROTO_VERSION};
@@ -127,19 +128,13 @@ template <typename WeakEnumType, size_t size>
return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, MAX_MONEY);
}
-[[nodiscard]] inline int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider) noexcept
-{
- // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) is a no-op.
- static const int64_t time_min = ParseISO8601DateTime("1970-01-01T00:00:01Z");
- static const int64_t time_max = ParseISO8601DateTime("9999-12-31T23:59:59Z");
- return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(time_min, time_max);
-}
+[[nodiscard]] int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min = std::nullopt, const std::optional<int64_t>& max = std::nullopt) noexcept;
[[nodiscard]] CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<uint256>>& prevout_txids, const int max_num_in = 10, const int max_num_out = 10) noexcept;
[[nodiscard]] CScriptWitness ConsumeScriptWitness(FuzzedDataProvider& fuzzed_data_provider, const size_t max_stack_elem_size = 32) noexcept;
-[[nodiscard]] CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096, const bool maybe_p2wsh = false) noexcept;
+[[nodiscard]] CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length = std::nullopt, const bool maybe_p2wsh = false) noexcept;
[[nodiscard]] uint32_t ConsumeSequence(FuzzedDataProvider& fuzzed_data_provider) noexcept;
diff --git a/src/test/script_standard_tests.cpp b/src/test/script_standard_tests.cpp
index 4dc0dd5f51..44fbfa5970 100644
--- a/src/test/script_standard_tests.cpp
+++ b/src/test/script_standard_tests.cpp
@@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
// TxoutType::WITNESS_V0_SCRIPTHASH
uint256 scriptHash;
- CSHA256().Write(&redeemScript[0], redeemScript.size())
+ CSHA256().Write(redeemScript.data(), redeemScript.size())
.Finalize(scriptHash.begin());
s.clear();
@@ -199,23 +199,20 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
s.clear();
s << ToByteVector(pubkey) << OP_CHECKSIG;
BOOST_CHECK(ExtractDestination(s, address));
- BOOST_CHECK(std::get_if<PKHash>(&address) &&
- *std::get_if<PKHash>(&address) == PKHash(pubkey));
+ BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));
// TxoutType::PUBKEYHASH
s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(ExtractDestination(s, address));
- BOOST_CHECK(std::get_if<PKHash>(&address) &&
- *std::get_if<PKHash>(&address) == PKHash(pubkey));
+ BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));
// TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script
s.clear();
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
BOOST_CHECK(ExtractDestination(s, address));
- BOOST_CHECK(std::get_if<ScriptHash>(&address) &&
- *std::get_if<ScriptHash>(&address) == ScriptHash(redeemScript));
+ BOOST_CHECK(std::get<ScriptHash>(address) == ScriptHash(redeemScript));
// TxoutType::MULTISIG
s.clear();
@@ -233,7 +230,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
BOOST_CHECK(ExtractDestination(s, address));
WitnessV0KeyHash keyhash;
CHash160().Write(pubkey).Finalize(keyhash);
- BOOST_CHECK(std::get_if<WitnessV0KeyHash>(&address) && *std::get_if<WitnessV0KeyHash>(&address) == keyhash);
+ BOOST_CHECK(std::get<WitnessV0KeyHash>(address) == keyhash);
// TxoutType::WITNESS_V0_SCRIPTHASH
s.clear();
@@ -241,7 +238,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
CSHA256().Write(redeemScript.data(), redeemScript.size()).Finalize(scripthash.begin());
s << OP_0 << ToByteVector(scripthash);
BOOST_CHECK(ExtractDestination(s, address));
- BOOST_CHECK(std::get_if<WitnessV0ScriptHash>(&address) && *std::get_if<WitnessV0ScriptHash>(&address) == scripthash);
+ BOOST_CHECK(std::get<WitnessV0ScriptHash>(address) == scripthash);
// TxoutType::WITNESS_UNKNOWN with unknown version
s.clear();
@@ -251,7 +248,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
unk.length = 33;
unk.version = 1;
std::copy(pubkey.begin(), pubkey.end(), unk.program);
- BOOST_CHECK(std::get_if<WitnessUnknown>(&address) && *std::get_if<WitnessUnknown>(&address) == unk);
+ BOOST_CHECK(std::get<WitnessUnknown>(address) == unk);
}
BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
@@ -275,8 +272,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEY);
BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
- BOOST_CHECK(std::get_if<PKHash>(&addresses[0]) &&
- *std::get_if<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
+ BOOST_CHECK(std::get<PKHash>(addresses[0]) == PKHash(pubkeys[0]));
// TxoutType::PUBKEYHASH
s.clear();
@@ -285,8 +281,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEYHASH);
BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
- BOOST_CHECK(std::get_if<PKHash>(&addresses[0]) &&
- *std::get_if<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
+ BOOST_CHECK(std::get<PKHash>(addresses[0]) == PKHash(pubkeys[0]));
// TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script
@@ -296,8 +291,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK_EQUAL(whichType, TxoutType::SCRIPTHASH);
BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
- BOOST_CHECK(std::get_if<ScriptHash>(&addresses[0]) &&
- *std::get_if<ScriptHash>(&addresses[0]) == ScriptHash(redeemScript));
+ BOOST_CHECK(std::get<ScriptHash>(addresses[0]) == ScriptHash(redeemScript));
// TxoutType::MULTISIG
s.clear();
@@ -309,10 +303,8 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK_EQUAL(whichType, TxoutType::MULTISIG);
BOOST_CHECK_EQUAL(addresses.size(), 2U);
BOOST_CHECK_EQUAL(nRequired, 2);
- BOOST_CHECK(std::get_if<PKHash>(&addresses[0]) &&
- *std::get_if<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
- BOOST_CHECK(std::get_if<PKHash>(&addresses[1]) &&
- *std::get_if<PKHash>(&addresses[1]) == PKHash(pubkeys[1]));
+ BOOST_CHECK(std::get<PKHash>(addresses[0]) == PKHash(pubkeys[0]));
+ BOOST_CHECK(std::get<PKHash>(addresses[1]) == PKHash(pubkeys[1]));
// TxoutType::NULL_DATA
s.clear();
@@ -378,7 +370,7 @@ BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
witnessScript << OP_1 << ToByteVector(pubkeys[0]) << OP_1 << OP_CHECKMULTISIG;
uint256 scriptHash;
- CSHA256().Write(&witnessScript[0], witnessScript.size())
+ CSHA256().Write(witnessScript.data(), witnessScript.size())
.Finalize(scriptHash.begin());
expected.clear();
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 14cfadf75d..171234f745 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -155,10 +155,10 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
if (libconsensus_flags == flags) {
int expectedSuccessCode = expect ? 1 : 0;
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
- BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
+ BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
} else {
- BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
- BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
+ BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
+ BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
}
}
#endif
@@ -224,7 +224,7 @@ struct KeyData
pubkey0 = key0.GetPubKey();
pubkey0H = key0.GetPubKey();
pubkey0C = key0C.GetPubKey();
- *const_cast<unsigned char*>(&pubkey0H[0]) = 0x06 | (pubkey0H[64] & 1);
+ *const_cast<unsigned char*>(pubkey0H.data()) = 0x06 | (pubkey0H[64] & 1);
key1.Set(vchKey1, vchKey1 + 32, false);
key1C.Set(vchKey1, vchKey1 + 32, true);
@@ -290,7 +290,7 @@ public:
} else if (wm == WitnessMode::SH) {
witscript = scriptPubKey;
uint256 hash;
- CSHA256().Write(&witscript[0], witscript.size()).Finalize(hash.begin());
+ CSHA256().Write(witscript.data(), witscript.size()).Finalize(hash.begin());
scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
}
if (P2SH) {
@@ -774,7 +774,7 @@ BOOST_AUTO_TEST_CASE(script_build)
{
CScript witscript = CScript() << ToByteVector(keys.pubkey0);
uint256 hash;
- CSHA256().Write(&witscript[0], witscript.size()).Finalize(hash.begin());
+ CSHA256().Write(witscript.data(), witscript.size()).Finalize(hash.begin());
std::vector<unsigned char> hashBytes = ToByteVector(hash);
hashBytes.pop_back();
tests.push_back(TestBuilder(CScript() << OP_0 << hashBytes,
@@ -1520,7 +1520,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_returns_true)
stream << spendTx;
bitcoinconsensus_error err;
- int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
+ int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 1);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_OK);
}
@@ -1543,7 +1543,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_index_err)
stream << spendTx;
bitcoinconsensus_error err;
- int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
+ int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_INDEX);
}
@@ -1566,7 +1566,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_size)
stream << spendTx;
bitcoinconsensus_error err;
- int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size() * 2, nIn, libconsensus_flags, &err);
+ int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size() * 2, nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
}
@@ -1589,7 +1589,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_serialization)
stream << 0xffffffff;
bitcoinconsensus_error err;
- int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
+ int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_DESERIALIZE);
}
@@ -1612,7 +1612,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_amount_required_err)
stream << spendTx;
bitcoinconsensus_error err;
- int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
+ int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
}
@@ -1635,7 +1635,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_invalid_flags)
stream << spendTx;
bitcoinconsensus_error err;
- int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
+ int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_INVALID_FLAGS);
}
@@ -1733,7 +1733,7 @@ BOOST_AUTO_TEST_CASE(script_assets_test)
size_t length = file.tellg();
file.seekg(0, std::ios::beg);
std::string data(length, '\0');
- file.read(&data[0], data.size());
+ file.read(data.data(), data.size());
UniValue tests = read_json(data);
BOOST_CHECK(tests.isArray());
BOOST_CHECK(tests.size() > 0);
diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp
index ab31662f97..82e70b5cdc 100644
--- a/src/test/validation_chainstatemanager_tests.cpp
+++ b/src/test/validation_chainstatemanager_tests.cpp
@@ -233,6 +233,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
// Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can
// be found.
+ constexpr int snapshot_height = 110;
mineBlocks(10);
initial_size += 10;
initial_total_coins += 10;
@@ -273,6 +274,11 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
chainman.ActiveChainstate().m_from_snapshot_blockhash,
*chainman.SnapshotBlockhash());
+ const AssumeutxoData& au_data = *ExpectedAssumeutxo(snapshot_height, ::Params());
+ const CBlockIndex* tip = chainman.ActiveTip();
+
+ BOOST_CHECK_EQUAL(tip->nChainTx, au_data.nChainTx);
+
// To be checked against later when we try loading a subsequent snapshot.
uint256 loaded_snapshot_blockhash{*chainman.SnapshotBlockhash()};
diff --git a/src/validation.cpp b/src/validation.cpp
index bf774a0791..52bdee699c 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -66,10 +66,6 @@
static const unsigned int EXTRA_DESCENDANT_TX_SIZE_LIMIT = 10000;
/** Maximum kilobytes for transactions to store for processing during reorg */
static const unsigned int MAX_DISCONNECTED_TX_POOL_SIZE = 20000;
-/** The pre-allocation chunk size for blk?????.dat files (since 0.8) */
-static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
-/** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
-static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
/** Time to wait between writing blocks/block index to disk. */
static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL{1};
/** Time to wait between flushing chainstate to disk. */
@@ -135,14 +131,9 @@ Mutex g_best_block_mutex;
std::condition_variable g_best_block_cv;
uint256 g_best_block;
bool g_parallel_script_checks{false};
-std::atomic_bool fImporting(false);
-std::atomic_bool fReindex(false);
-bool fHavePruned = false;
-bool fPruneMode = false;
bool fRequireStandard = true;
bool fCheckBlockIndex = false;
bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
-uint64_t nPruneTarget = 0;
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
uint256 hashAssumeValid;
@@ -153,22 +144,17 @@ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
// Internal stuff
namespace {
CBlockIndex* pindexBestInvalid = nullptr;
-
- RecursiveMutex cs_LastBlockFile;
- std::vector<CBlockFileInfo> vinfoBlockFile;
- int nLastBlockFile = 0;
- /** Global flag to indicate we should check to see if there are
- * block/undo files that should be deleted. Set on startup
- * or if we allocate more file space when we're in prune mode
- */
- bool fCheckForPruning = false;
-
- /** Dirty block index entries. */
- std::set<CBlockIndex*> setDirtyBlockIndex;
-
- /** Dirty block file entries. */
- std::set<int> setDirtyFileInfo;
-} // anon namespace
+} // namespace
+
+// Internal stuff from blockstorage ...
+extern RecursiveMutex cs_LastBlockFile;
+extern std::vector<CBlockFileInfo> vinfoBlockFile;
+extern int nLastBlockFile;
+extern bool fCheckForPruning;
+extern std::set<CBlockIndex*> setDirtyBlockIndex;
+extern std::set<int> setDirtyFileInfo;
+void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false);
+// ... TODO move fully to blockstorage
CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const
{
@@ -205,9 +191,6 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
bool cacheFullScriptStore, PrecomputedTransactionData& txdata,
std::vector<CScriptCheck>* pvChecks = nullptr)
EXCLUSIVE_LOCKS_REQUIRED(cs_main);
-static FILE* OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false);
-static FlatFileSeq BlockFileSeq();
-static FlatFileSeq UndoFileSeq();
bool CheckFinalTx(const CBlockIndex* active_chain_tip, const CTransaction &tx, int flags)
{
@@ -1462,65 +1445,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
return true;
}
-static bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
-{
- // Open history file to append
- CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
- if (fileout.IsNull())
- return error("%s: OpenUndoFile failed", __func__);
-
- // Write index header
- unsigned int nSize = GetSerializeSize(blockundo, fileout.GetVersion());
- fileout << messageStart << nSize;
-
- // Write undo data
- long fileOutPos = ftell(fileout.Get());
- if (fileOutPos < 0)
- return error("%s: ftell failed", __func__);
- pos.nPos = (unsigned int)fileOutPos;
- fileout << blockundo;
-
- // calculate & write checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << blockundo;
- fileout << hasher.GetHash();
-
- return true;
-}
-
-bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
-{
- FlatFilePos pos = pindex->GetUndoPos();
- if (pos.IsNull()) {
- return error("%s: no undo data available", __func__);
- }
-
- // Open history file to read
- CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
- if (filein.IsNull())
- return error("%s: OpenUndoFile failed", __func__);
-
- // Read block
- uint256 hashChecksum;
- CHashVerifier<CAutoFile> verifier(&filein); // We need a CHashVerifier as reserializing may lose data
- try {
- verifier << pindex->pprev->GetBlockHash();
- verifier >> blockundo;
- filein >> hashChecksum;
- }
- catch (const std::exception& e) {
- return error("%s: Deserialize or I/O error - %s", __func__, e.what());
- }
-
- // Verify checksum
- if (hashChecksum != verifier.GetHash())
- return error("%s: Checksum mismatch", __func__);
-
- return true;
-}
-
-static bool AbortNode(BlockValidationState& state, const std::string& strMessage, const bilingual_str& userMessage = bilingual_str())
+bool AbortNode(BlockValidationState& state, const std::string& strMessage, const bilingual_str& userMessage)
{
AbortNode(strMessage, userMessage);
return state.Error(strMessage);
@@ -1620,55 +1545,6 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
}
-static void FlushUndoFile(int block_file, bool finalize = false)
-{
- FlatFilePos undo_pos_old(block_file, vinfoBlockFile[block_file].nUndoSize);
- if (!UndoFileSeq().Flush(undo_pos_old, finalize)) {
- AbortNode("Flushing undo file to disk failed. This is likely the result of an I/O error.");
- }
-}
-
-static void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false)
-{
- LOCK(cs_LastBlockFile);
- FlatFilePos block_pos_old(nLastBlockFile, vinfoBlockFile[nLastBlockFile].nSize);
- if (!BlockFileSeq().Flush(block_pos_old, fFinalize)) {
- AbortNode("Flushing block file to disk failed. This is likely the result of an I/O error.");
- }
- // we do not always flush the undo file, as the chain tip may be lagging behind the incoming blocks,
- // e.g. during IBD or a sync after a node going offline
- if (!fFinalize || finalize_undo) FlushUndoFile(nLastBlockFile, finalize_undo);
-}
-
-static bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize);
-
-static bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams)
-{
- // Write undo information to disk
- if (pindex->GetUndoPos().IsNull()) {
- FlatFilePos _pos;
- if (!FindUndoPos(state, pindex->nFile, _pos, ::GetSerializeSize(blockundo, CLIENT_VERSION) + 40))
- return error("ConnectBlock(): FindUndoPos failed");
- if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
- return AbortNode(state, "Failed to write undo data");
- // rev files are written in block height order, whereas blk files are written as blocks come in (often out of order)
- // we want to flush the rev (undo) file once we've written the last block, which is indicated by the last height
- // in the block file info as below; note that this does not catch the case where the undo writes are keeping up
- // with the block writes (usually when a synced up node is getting newly mined blocks) -- this case is caught in
- // the FindBlockPos function
- if (_pos.nFile < nLastBlockFile && static_cast<uint32_t>(pindex->nHeight) == vinfoBlockFile[_pos.nFile].nHeightLast) {
- FlushUndoFile(_pos.nFile, true);
- }
-
- // update nUndoPos in block index
- pindex->nUndoPos = _pos.nPos;
- pindex->nStatus |= BLOCK_HAVE_UNDO;
- setDirtyBlockIndex.insert(pindex);
- }
-
- return true;
-}
-
static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
void StartScriptCheckWorkerThreads(int threads_num)
@@ -3102,84 +2978,6 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
}
}
-// TODO move to blockstorage
-bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false)
-{
- LOCK(cs_LastBlockFile);
-
- unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
- if (vinfoBlockFile.size() <= nFile) {
- vinfoBlockFile.resize(nFile + 1);
- }
-
- bool finalize_undo = false;
- if (!fKnown) {
- while (vinfoBlockFile[nFile].nSize + nAddSize >= (gArgs.GetBoolArg("-fastprune", false) ? 0x10000 /* 64kb */ : MAX_BLOCKFILE_SIZE)) {
- // when the undo file is keeping up with the block file, we want to flush it explicitly
- // when it is lagging behind (more blocks arrive than are being connected), we let the
- // undo block write case handle it
- assert(std::addressof(::ChainActive()) == std::addressof(active_chain));
- finalize_undo = (vinfoBlockFile[nFile].nHeightLast == (unsigned int)active_chain.Tip()->nHeight);
- nFile++;
- if (vinfoBlockFile.size() <= nFile) {
- vinfoBlockFile.resize(nFile + 1);
- }
- }
- pos.nFile = nFile;
- pos.nPos = vinfoBlockFile[nFile].nSize;
- }
-
- if ((int)nFile != nLastBlockFile) {
- if (!fKnown) {
- LogPrint(BCLog::VALIDATION, "Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString());
- }
- FlushBlockFile(!fKnown, finalize_undo);
- nLastBlockFile = nFile;
- }
-
- vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
- if (fKnown)
- vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
- else
- vinfoBlockFile[nFile].nSize += nAddSize;
-
- if (!fKnown) {
- bool out_of_space;
- size_t bytes_allocated = BlockFileSeq().Allocate(pos, nAddSize, out_of_space);
- if (out_of_space) {
- return AbortNode("Disk space is too low!", _("Disk space is too low!"));
- }
- if (bytes_allocated != 0 && fPruneMode) {
- fCheckForPruning = true;
- }
- }
-
- setDirtyFileInfo.insert(nFile);
- return true;
-}
-
-static bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize)
-{
- pos.nFile = nFile;
-
- LOCK(cs_LastBlockFile);
-
- pos.nPos = vinfoBlockFile[nFile].nUndoSize;
- vinfoBlockFile[nFile].nUndoSize += nAddSize;
- setDirtyFileInfo.insert(nFile);
-
- bool out_of_space;
- size_t bytes_allocated = UndoFileSeq().Allocate(pos, nAddSize, out_of_space);
- if (out_of_space) {
- return AbortNode(state, "Disk space is too low!", _("Disk space is too low!"));
- }
- if (bytes_allocated != 0 && fPruneMode) {
- fCheckForPruning = true;
- }
-
- return true;
-}
-
static bool CheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true)
{
// Check proof of work matches claimed amount
@@ -3737,18 +3535,6 @@ bool TestBlockValidity(BlockValidationState& state,
* BLOCK PRUNING CODE
*/
-/* Calculate the amount of disk space the block & undo files currently use */
-uint64_t CalculateCurrentUsage()
-{
- LOCK(cs_LastBlockFile);
-
- uint64_t retval = 0;
- for (const CBlockFileInfo &file : vinfoBlockFile) {
- retval += file.nSize + file.nUndoSize;
- }
- return retval;
-}
-
void BlockManager::PruneOneBlockFile(const int fileNumber)
{
AssertLockHeld(cs_main);
@@ -3783,17 +3569,6 @@ void BlockManager::PruneOneBlockFile(const int fileNumber)
setDirtyFileInfo.insert(fileNumber);
}
-
-void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune)
-{
- for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
- FlatFilePos pos(*it, 0);
- fs::remove(BlockFileSeq().FileName(pos));
- fs::remove(UndoFileSeq().FileName(pos));
- LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
- }
-}
-
void BlockManager::FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight, int chain_tip_height)
{
assert(fPruneMode && nManualPruneHeight > 0);
@@ -3888,30 +3663,6 @@ void BlockManager::FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPr
nLastBlockWeCanPrune, count);
}
-static FlatFileSeq BlockFileSeq()
-{
- return FlatFileSeq(gArgs.GetBlocksDirPath(), "blk", gArgs.GetBoolArg("-fastprune", false) ? 0x4000 /* 16kb */ : BLOCKFILE_CHUNK_SIZE);
-}
-
-static FlatFileSeq UndoFileSeq()
-{
- return FlatFileSeq(gArgs.GetBlocksDirPath(), "rev", UNDOFILE_CHUNK_SIZE);
-}
-
-FILE* OpenBlockFile(const FlatFilePos &pos, bool fReadOnly) {
- return BlockFileSeq().Open(pos, fReadOnly);
-}
-
-/** Open an undo file (rev?????.dat) */
-static FILE* OpenUndoFile(const FlatFilePos &pos, bool fReadOnly) {
- return UndoFileSeq().Open(pos, fReadOnly);
-}
-
-fs::path GetBlockPosFilename(const FlatFilePos &pos)
-{
- return BlockFileSeq().FileName(pos);
-}
-
CBlockIndex * BlockManager::InsertBlockIndex(const uint256& hash)
{
AssertLockHeld(cs_main);
@@ -4744,18 +4495,6 @@ bool CChainState::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
return ret;
}
-std::string CBlockFileInfo::ToString() const
-{
- return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast));
-}
-
-CBlockFileInfo* GetBlockFileInfo(size_t n)
-{
- LOCK(cs_LastBlockFile);
-
- return &vinfoBlockFile.at(n);
-}
-
static const uint64_t MEMPOOL_DUMP_VERSION = 1;
bool LoadMempool(CTxMemPool& pool, CChainState& active_chainstate, FopenFn mockable_fopen_function)
@@ -5236,7 +4975,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
}
assert(index);
- index->nChainTx = metadata.m_nchaintx;
+ index->nChainTx = au_data.nChainTx;
snapshot_chainstate.setBlockIndexCandidates.insert(snapshot_start_block);
LogPrintf("[snapshot] validated snapshot (%.2f MB)\n",
diff --git a/src/validation.h b/src/validation.h
index 63a8bdc096..8fa45c3f77 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -27,6 +27,7 @@
#include <serialize.h>
#include <util/check.h>
#include <util/hasher.h>
+#include <util/translation.h>
#include <atomic>
#include <map>
@@ -70,8 +71,6 @@ static const unsigned int DEFAULT_DESCENDANT_LIMIT = 25;
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 101;
/** Default for -mempoolexpiry, expiration time for mempool transactions in hours */
static const unsigned int DEFAULT_MEMPOOL_EXPIRY = 336;
-/** The maximum size of a blk?????.dat file (since 0.8) */
-static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
/** Maximum number of dedicated script-checking threads allowed */
static const int MAX_SCRIPTCHECK_THREADS = 15;
/** -par default (number of script-checking threads, 0 = auto) */
@@ -113,8 +112,6 @@ typedef std::unordered_map<uint256, CBlockIndex*, BlockHasher> BlockMap;
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;
/** Whether there are dedicated script-checking threads running.
* False indicates all script checking is done on the main threadMessageHandler thread.
*/
@@ -136,20 +133,9 @@ extern arith_uint256 nMinimumChainWork;
/** Best header we've seen so far (used for getheaders queries' starting points). */
extern CBlockIndex *pindexBestHeader;
-/** Pruning-related variables and constants */
-/** True if any block files have ever been pruned. */
-extern bool fHavePruned;
-/** True if we're running in -prune mode. */
-extern bool fPruneMode;
-/** Number of MiB of block files that we're trying to stay below. */
-extern uint64_t nPruneTarget;
/** Documentation for argument 'checklevel'. */
extern const std::vector<std::string> CHECKLEVEL_DOC;
-/** Open a block file (blk?????.dat) */
-FILE* OpenBlockFile(const FlatFilePos &pos, bool fReadOnly = false);
-/** Translation to a filesystem path */
-fs::path GetBlockPosFilename(const FlatFilePos &pos);
/** Unload database information */
void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman);
/** Run instances of script checking worker threads */
@@ -171,17 +157,11 @@ void StopScriptCheckWorkerThreads();
CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock);
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
+bool AbortNode(BlockValidationState& state, const std::string& strMessage, const bilingual_str& userMessage = bilingual_str{});
+
/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex* pindex);
-/** Calculate the amount of disk space the block & undo files currently use */
-uint64_t CalculateCurrentUsage();
-
-/**
- * Actually unlink the specified files
- */
-void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune);
-
/** Prune block files up to a given height */
void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeight);
@@ -1009,9 +989,6 @@ extern VersionBitsCache versionbitscache;
*/
int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params);
-/** Get block file info entry for one block file */
-CBlockFileInfo* GetBlockFileInfo(size_t n);
-
using FopenFn = std::function<FILE*(const fs::path&, const char*)>;
/** Dump the mempool to disk. */
@@ -1020,12 +997,6 @@ bool DumpMempool(const CTxMemPool& pool, FopenFn mockable_fopen_function = fsbri
/** Load the mempool from disk. */
bool LoadMempool(CTxMemPool& pool, CChainState& active_chainstate, FopenFn mockable_fopen_function = fsbridge::fopen);
-//! Check whether the block associated with this index entry is pruned or not.
-inline bool IsBlockPruned(const CBlockIndex* pblockindex)
-{
- return (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0);
-}
-
/**
* Return the expected assumeutxo value for a given height, if one exists.
*
diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp
index b50f00e7d1..251778e401 100644
--- a/src/wallet/crypter.cpp
+++ b/src/wallet/crypter.cpp
@@ -78,7 +78,7 @@ bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned
vchCiphertext.resize(vchPlaintext.size() + AES_BLOCKSIZE);
AES256CBCEncrypt enc(vchKey.data(), vchIV.data(), true);
- size_t nLen = enc.Encrypt(&vchPlaintext[0], vchPlaintext.size(), vchCiphertext.data());
+ size_t nLen = enc.Encrypt(vchPlaintext.data(), vchPlaintext.size(), vchCiphertext.data());
if(nLen < vchPlaintext.size())
return false;
vchCiphertext.resize(nLen);
@@ -97,7 +97,7 @@ bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingM
vchPlaintext.resize(nLen);
AES256CBCDecrypt dec(vchKey.data(), vchIV.data(), true);
- nLen = dec.Decrypt(vchCiphertext.data(), vchCiphertext.size(), &vchPlaintext[0]);
+ nLen = dec.Decrypt(vchCiphertext.data(), vchCiphertext.size(), vchPlaintext.data());
if(nLen == 0)
return false;
vchPlaintext.resize(nLen);
@@ -121,7 +121,7 @@ bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned
memcpy(chIV.data(), &nIV, WALLET_CRYPTO_IV_SIZE);
if(!cKeyCrypter.SetKey(vMasterKey, chIV))
return false;
- return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
+ return cKeyCrypter.Decrypt(vchCiphertext, vchPlaintext);
}
bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key)
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 653dbdfc1d..a851765c57 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -469,7 +469,7 @@ RPCHelpMan importpubkey()
if (!IsHex(request.params[0].get_str()))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string");
std::vector<unsigned char> data(ParseHex(request.params[0].get_str()));
- CPubKey pubKey(data.begin(), data.end());
+ CPubKey pubKey(data);
if (!pubKey.IsFullyValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key");
@@ -871,7 +871,7 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
switch (script_type) {
case TxoutType::PUBKEY: {
- CPubKey pubkey(solverdata[0].begin(), solverdata[0].end());
+ CPubKey pubkey(solverdata[0]);
import_data.used_keys.emplace(pubkey.GetID(), false);
return "";
}
@@ -893,7 +893,7 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
}
case TxoutType::MULTISIG: {
for (size_t i = 1; i + 1< solverdata.size(); ++i) {
- CPubKey pubkey(solverdata[i].begin(), solverdata[i].end());
+ CPubKey pubkey(solverdata[i]);
import_data.used_keys.emplace(pubkey.GetID(), false);
}
return "";
@@ -997,7 +997,7 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey \"" + str + "\" must be a hex string");
}
auto parsed_pubkey = ParseHex(str);
- CPubKey pubkey(parsed_pubkey.begin(), parsed_pubkey.end());
+ CPubKey pubkey(parsed_pubkey);
if (!pubkey.IsFullyValid()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey \"" + str + "\" is not a valid public key");
}
diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp
index 6d912be019..ea045eb6d8 100644
--- a/src/wallet/salvage.cpp
+++ b/src/wallet/salvage.cpp
@@ -154,8 +154,8 @@ bool RecoverDatabaseFile(const fs::path& file_path, bilingual_str& error, std::v
warnings.push_back(strprintf(Untranslated("WARNING: WalletBatch::Recover skipping %s: %s"), strType, strErr));
continue;
}
- Dbt datKey(&row.first[0], row.first.size());
- Dbt datValue(&row.second[0], row.second.size());
+ Dbt datKey(row.first.data(), row.first.size());
+ Dbt datValue(row.second.data(), row.second.size());
int ret2 = pdbCopy->put(ptxn, &datKey, &datValue, DB_NOOVERWRITE);
if (ret2 > 0)
fSuccess = false;
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index 149549410c..2eb9ca5c6d 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -162,7 +162,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
break;
}
uint160 hash;
- CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(hash.begin());
+ CRIPEMD160().Write(vSolutions[0].data(), vSolutions[0].size()).Finalize(hash.begin());
CScriptID scriptID = CScriptID(hash);
CScript subscript;
if (keystore.GetCScript(scriptID, subscript)) {
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 011d59ecaf..c8e3c8f819 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -11,6 +11,7 @@
#include <vector>
#include <interfaces/chain.h>
+#include <node/blockstorage.h>
#include <node/context.h>
#include <policy/policy.h>
#include <rpc/server.h>
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index f0aaee7e4e..3d0ef9f8c0 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -603,12 +603,12 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
CKeyingMaterial _vMasterKey;
_vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
- GetStrongRandBytes(&_vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
+ GetStrongRandBytes(_vMasterKey.data(), WALLET_CRYPTO_KEY_SIZE);
CMasterKey kMasterKey;
kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
- GetStrongRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
+ GetStrongRandBytes(kMasterKey.vchSalt.data(), WALLET_CRYPTO_SALT_SIZE);
CCrypter crypter;
int64_t nStartTime = GetTimeMillis();
diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp
index 25afa94d0f..6ae866cc07 100644
--- a/src/zmq/zmqpublishnotifier.cpp
+++ b/src/zmq/zmqpublishnotifier.cpp
@@ -168,7 +168,7 @@ bool CZMQAbstractPublishNotifier::SendZmqMessage(const char *command, const void
/* send three parts, command & data & a LE 4byte sequence number */
unsigned char msgseq[sizeof(uint32_t)];
- WriteLE32(&msgseq[0], nSequence);
+ WriteLE32(msgseq, nSequence);
int rc = zmq_send_multipart(psocket, command, strlen(command), data, size, msgseq, (size_t)sizeof(uint32_t), nullptr);
if (rc == -1)
return false;