mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-05-14 16:04:03 +02:00
Replace hard-coded MiB byte conversions (e.g. `1024*1024`, `1<<20`, `1048576`) with the existing `_MiB` literal to improve readability and avoid repeating constants.
In the few spots where arithmetic involves signed values, the result is identical to the previous code assuming those quantities never turn negative.
Also switch to brace init on every declaration assigned from `_MiB`/`_GiB` literals so a future oversized value (e.g. `unsigned int x{4096_MiB}`) becomes a compile error through the C++11 narrowing check instead of silently truncating.
Extend unit tests to cover the 32-bit `size_t` overflow boundary and to assert equivalence for integer and floating-point conversions.
Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
Co-authored-by: w0xlt <94266259+w0xlt@users.noreply.github.com>
114 lines
4.1 KiB
C++
114 lines
4.1 KiB
C++
// Copyright (c) 2020-present The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include <chainparams.h>
|
|
#include <index/coinstatsindex.h>
|
|
#include <interfaces/chain.h>
|
|
#include <kernel/coinstats.h>
|
|
#include <kernel/types.h>
|
|
#include <test/util/setup_common.h>
|
|
#include <test/util/validation.h>
|
|
#include <util/byte_units.h>
|
|
#include <validation.h>
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
using kernel::ChainstateRole;
|
|
|
|
BOOST_AUTO_TEST_SUITE(coinstatsindex_tests)
|
|
|
|
BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
|
|
{
|
|
CoinStatsIndex coin_stats_index{interfaces::MakeChain(m_node), 1_MiB, true};
|
|
BOOST_REQUIRE(coin_stats_index.Init());
|
|
|
|
const CBlockIndex* block_index;
|
|
{
|
|
LOCK(cs_main);
|
|
block_index = m_node.chainman->ActiveChain().Tip();
|
|
}
|
|
|
|
// CoinStatsIndex should not be found before it is started.
|
|
BOOST_CHECK(!coin_stats_index.LookUpStats(*block_index));
|
|
|
|
// BlockUntilSyncedToCurrentChain should return false before CoinStatsIndex
|
|
// is started.
|
|
BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain());
|
|
|
|
coin_stats_index.Sync();
|
|
|
|
// Check that CoinStatsIndex works for genesis block.
|
|
const CBlockIndex* genesis_block_index;
|
|
{
|
|
LOCK(cs_main);
|
|
genesis_block_index = m_node.chainman->ActiveChain().Genesis();
|
|
}
|
|
BOOST_CHECK(coin_stats_index.LookUpStats(*genesis_block_index));
|
|
|
|
// Check that CoinStatsIndex updates with new blocks.
|
|
BOOST_CHECK(coin_stats_index.LookUpStats(*block_index));
|
|
|
|
const CScript script_pub_key{CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG};
|
|
std::vector<CMutableTransaction> noTxns;
|
|
CreateAndProcessBlock(noTxns, script_pub_key);
|
|
|
|
// Let the CoinStatsIndex to catch up again.
|
|
BOOST_CHECK(coin_stats_index.BlockUntilSyncedToCurrentChain());
|
|
|
|
const CBlockIndex* new_block_index;
|
|
{
|
|
LOCK(cs_main);
|
|
new_block_index = m_node.chainman->ActiveChain().Tip();
|
|
}
|
|
BOOST_CHECK(coin_stats_index.LookUpStats(*new_block_index));
|
|
|
|
BOOST_CHECK(block_index != new_block_index);
|
|
|
|
// Shutdown sequence (c.f. Shutdown() in init.cpp)
|
|
coin_stats_index.Stop();
|
|
}
|
|
|
|
// Test shutdown between BlockConnected and ChainStateFlushed notifications,
|
|
// make sure index is not corrupted and is able to reload.
|
|
BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup)
|
|
{
|
|
Chainstate& chainstate = Assert(m_node.chainman)->ActiveChainstate();
|
|
const CChainParams& params = Params();
|
|
{
|
|
CoinStatsIndex index{interfaces::MakeChain(m_node), 1_MiB};
|
|
BOOST_REQUIRE(index.Init());
|
|
index.Sync();
|
|
std::shared_ptr<const CBlock> new_block;
|
|
CBlockIndex* new_block_index = nullptr;
|
|
{
|
|
const CScript script_pub_key{CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG};
|
|
const CBlock block = this->CreateBlock({}, script_pub_key, chainstate);
|
|
|
|
new_block = std::make_shared<CBlock>(block);
|
|
|
|
LOCK(cs_main);
|
|
BlockValidationState state;
|
|
BOOST_CHECK(CheckBlock(block, state, params.GetConsensus()));
|
|
BOOST_CHECK(m_node.chainman->AcceptBlock(new_block, state, &new_block_index, true, nullptr, nullptr, true));
|
|
CCoinsViewCache view(&chainstate.CoinsTip());
|
|
BOOST_CHECK(chainstate.ConnectBlock(block, state, new_block_index, view));
|
|
}
|
|
// Send block connected notification, then stop the index without
|
|
// sending a chainstate flushed notification. Prior to #24138, this
|
|
// would cause the index to be corrupted and fail to reload.
|
|
ValidationInterfaceTest::BlockConnected(ChainstateRole{}, index, new_block, new_block_index);
|
|
index.Stop();
|
|
}
|
|
|
|
{
|
|
CoinStatsIndex index{interfaces::MakeChain(m_node), 1_MiB};
|
|
BOOST_REQUIRE(index.Init());
|
|
// Make sure the index can be loaded.
|
|
BOOST_REQUIRE(index.StartBackgroundSync());
|
|
index.Stop();
|
|
}
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|