merge bitcoin#21866: Farewell, global Chainstate!

This commit is contained in:
Kittywhiskers Van Gogh 2024-06-25 09:44:28 +00:00
parent e3687f790a
commit 0213fbebe6
No known key found for this signature in database
GPG Key ID: 30CD0C065E5C4AAD
43 changed files with 358 additions and 457 deletions

View File

@ -25,7 +25,6 @@ static void DuplicateInputs(benchmark::Bench& bench)
CMutableTransaction coinbaseTx{};
CMutableTransaction naughtyTx{};
assert(std::addressof(::ChainActive()) == std::addressof(testing_setup->m_node.chainman->ActiveChain()));
CBlockIndex* pindexPrev = testing_setup->m_node.chainman->ActiveChain().Tip();
assert(pindexPrev != nullptr);
block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus());

View File

@ -28,6 +28,7 @@ CDSNotificationInterface::CDSNotificationInterface(CConnman& connman,
CMasternodeSync& mn_sync,
CGovernanceManager& govman,
PeerManager& peerman,
const ChainstateManager& chainman,
const CActiveMasternodeManager* const mn_activeman,
const std::unique_ptr<CDeterministicMNManager>& dmnman,
const std::unique_ptr<LLMQContext>& llmq_ctx,
@ -36,6 +37,7 @@ CDSNotificationInterface::CDSNotificationInterface(CConnman& connman,
m_mn_sync(mn_sync),
m_govman(govman),
m_peerman(peerman),
m_chainman(chainman),
m_mn_activeman(mn_activeman),
m_dmnman(dmnman),
m_llmq_ctx(llmq_ctx),
@ -43,8 +45,8 @@ CDSNotificationInterface::CDSNotificationInterface(CConnman& connman,
void CDSNotificationInterface::InitializeCurrentBlockTip()
{
SynchronousUpdatedBlockTip(::ChainActive().Tip(), nullptr, ::ChainstateActive().IsInitialBlockDownload());
UpdatedBlockTip(::ChainActive().Tip(), nullptr, ::ChainstateActive().IsInitialBlockDownload());
SynchronousUpdatedBlockTip(m_chainman.ActiveChain().Tip(), nullptr, m_chainman.ActiveChainstate().IsInitialBlockDownload());
UpdatedBlockTip(m_chainman.ActiveChain().Tip(), nullptr, m_chainman.ActiveChainstate().IsInitialBlockDownload());
}
void CDSNotificationInterface::AcceptedBlockHeader(const CBlockIndex *pindexNew)

View File

@ -11,6 +11,7 @@ class CActiveMasternodeManager;
class CConnman;
class CDeterministicMNManager;
class CGovernanceManager;
class ChainstateManager;
class CMasternodeSync;
class PeerManager;
struct CJContext;
@ -23,6 +24,7 @@ public:
CMasternodeSync& mn_sync,
CGovernanceManager& govman,
PeerManager& peerman,
const ChainstateManager& chainman,
const CActiveMasternodeManager* const mn_activeman,
const std::unique_ptr<CDeterministicMNManager>& dmnman,
const std::unique_ptr<LLMQContext>& llmq_ctx,
@ -50,6 +52,7 @@ private:
CMasternodeSync& m_mn_sync;
CGovernanceManager& m_govman;
PeerManager& m_peerman;
const ChainstateManager& m_chainman;
const CActiveMasternodeManager* const m_mn_activeman;
const std::unique_ptr<CDeterministicMNManager>& m_dmnman;
const std::unique_ptr<LLMQContext>& m_llmq_ctx;

View File

@ -10,7 +10,7 @@
#include <tinyformat.h>
#include <util/thread.h>
#include <util/translation.h>
#include <validation.h> // For g_chainman
#include <validation.h>
#include <warnings.h>
constexpr uint8_t DB_BEST_BLOCK{'B'};
@ -349,7 +349,6 @@ void BaseIndex::Interrupt()
bool BaseIndex::Start(CChainState& active_chainstate)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
m_chainstate = &active_chainstate;
// Need to register this ValidationInterface before running Init(), so that
// callbacks are not missed if Init sets m_synced to true.

View File

@ -402,7 +402,7 @@ void Shutdown(NodeContext& node)
ECC_Stop();
node.mempool.reset();
node.fee_estimator.reset();
node.chainman = nullptr;
node.chainman.reset();
node.scheduler.reset();
try {
@ -883,12 +883,12 @@ static void StartupNotify(const ArgsManager& args)
}
#endif
static void PeriodicStats(ArgsManager& args, const CTxMemPool& mempool)
static void PeriodicStats(ArgsManager& args, ChainstateManager& chainman, const CTxMemPool& mempool)
{
assert(args.GetBoolArg("-statsenabled", DEFAULT_STATSD_ENABLE));
CCoinsStats stats{CoinStatsHashType::NONE};
::ChainstateActive().ForceFlushStateToDisk();
if (WITH_LOCK(cs_main, return GetUTXOStats(&::ChainstateActive().CoinsDB(), std::ref(g_chainman.m_blockman), stats, RpcInterruptionPoint, ::ChainActive().Tip()))) {
chainman.ActiveChainstate().ForceFlushStateToDisk();
if (WITH_LOCK(cs_main, return GetUTXOStats(&chainman.ActiveChainstate().CoinsDB(), std::ref(chainman.m_blockman), stats, RpcInterruptionPoint, chainman.ActiveChain().Tip()))) {
statsClient.gauge("utxoset.tx", stats.nTransactions, 1.0f);
statsClient.gauge("utxoset.txOutputs", stats.nTransactionOutputs, 1.0f);
statsClient.gauge("utxoset.dbSizeBytes", stats.nDiskSize, 1.0f);
@ -902,7 +902,7 @@ static void PeriodicStats(ArgsManager& args, const CTxMemPool& mempool)
}
// short version of GetNetworkHashPS(120, -1);
CBlockIndex *tip = ::ChainActive().Tip();
CBlockIndex *tip = chainman.ActiveChain().Tip();
CBlockIndex *pindex = tip;
int64_t minTime = pindex->GetBlockTime();
int64_t maxTime = minTime;
@ -923,7 +923,7 @@ static void PeriodicStats(ArgsManager& args, const CTxMemPool& mempool)
// No need for cs_main, we never use null tip here
statsClient.gaugeDouble("network.difficulty", (double)GetDifficulty(tip));
statsClient.gauge("transactions.txCacheSize", WITH_LOCK(cs_main, return ::ChainstateActive().CoinsTip().GetCacheSize()), 1.0f);
statsClient.gauge("transactions.txCacheSize", WITH_LOCK(cs_main, return chainman.ActiveChainstate().CoinsTip().GetCacheSize()), 1.0f);
statsClient.gauge("transactions.totalTransactions", tip->nChainTx, 1.0f);
{
@ -1716,8 +1716,8 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), check_ratio);
assert(!node.chainman);
node.chainman = &g_chainman;
ChainstateManager& chainman = *Assert(node.chainman);
node.chainman = std::make_unique<ChainstateManager>();
ChainstateManager& chainman = *node.chainman;
assert(!node.mn_metaman);
node.mn_metaman = std::make_unique<CMasternodeMetaMan>();
@ -1913,7 +1913,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
#endif
pdsNotificationInterface = new CDSNotificationInterface(
*node.connman, *node.mn_sync, *node.govman, *node.peerman, node.mn_activeman.get(), node.dmnman, node.llmq_ctx, node.cj_ctx
*node.connman, *node.mn_sync, *node.govman, *node.peerman, chainman, node.mn_activeman.get(), node.dmnman, node.llmq_ctx, node.cj_ctx
);
RegisterValidationInterface(pdsNotificationInterface);
@ -2016,7 +2016,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
node.llmq_ctx = std::make_unique<LLMQContext>(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.evodb, *node.mn_metaman, *node.mnhf_manager, *node.sporkman,
*node.mempool, node.mn_activeman.get(), *node.mn_sync, node.peerman, /* unit_tests = */ false, /* wipe = */ fReset || fReindexChainState);
// Enable CMNHFManager::{Process, Undo}Block
node.mnhf_manager->ConnectManagers(node.chainman, node.llmq_ctx->qman.get());
node.mnhf_manager->ConnectManagers(node.chainman.get(), node.llmq_ctx->qman.get());
// Have to start it early to let VerifyDB check ChainLock signatures in coinbase
node.llmq_ctx->Start();
@ -2050,12 +2050,12 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
// If the loaded chain has a wrong genesis, bail out immediately
// (we're likely using a testnet datadir, or the other way around).
if (!chainman.BlockIndex().empty() &&
!g_chainman.m_blockman.LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) {
!chainman.m_blockman.LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) {
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
}
if (!chainparams.GetConsensus().hashDevnetGenesisBlock.IsNull() && !chainman.BlockIndex().empty() &&
!g_chainman.m_blockman.LookupBlockIndex(chainparams.GetConsensus().hashDevnetGenesisBlock)) {
!chainman.m_blockman.LookupBlockIndex(chainparams.GetConsensus().hashDevnetGenesisBlock)) {
return InitError(_("Incorrect or no devnet genesis block found. Wrong datadir for devnet specified?"));
}
@ -2088,7 +2088,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
// If we're not mid-reindex (based on disk + args), add a genesis block on disk
// (otherwise we use the one already on disk).
// This is called again in ThreadImport after the reindex completes.
if (!fReindex && !::ChainstateActive().LoadGenesisBlock()) {
if (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock()) {
strLoadError = _("Error initializing block database");
break;
}
@ -2132,7 +2132,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
// TODO: CEvoDB instance should probably be a part of CChainState
// (for multiple chainstates to actually work in parallel)
// and not a global
if (&::ChainstateActive() == chainstate && !node.evodb->CommitRootTransaction()) {
if (&chainman.ActiveChainstate() == chainstate && !node.evodb->CommitRootTransaction()) {
strLoadError = _("Failed to commit EvoDB");
failed_chainstate_init = true;
break;
@ -2210,7 +2210,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
// TODO: CEvoDB instance should probably be a part of CChainState
// (for multiple chainstates to actually work in parallel)
// and not a global
if (&::ChainstateActive() == chainstate && !node.evodb->IsEmpty()) {
if (&chainman.ActiveChainstate() == chainstate && !node.evodb->IsEmpty()) {
// EvoDB processed some blocks earlier but we have no blocks anymore, something is wrong
strLoadError = _("Error initializing block database");
failed_verification = true;
@ -2271,7 +2271,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
// ********************************************************* Step 7d: Setup other Dash services
bool fLoadCacheFiles = !(fReindex || fReindexChainState) && (::ChainActive().Tip() != nullptr);
bool fLoadCacheFiles = !(fReindex || fReindexChainState) && (chainman.ActiveChain().Tip() != nullptr);
if (!node.netfulfilledman->LoadCache(fLoadCacheFiles)) {
auto file_path = (GetDataDir() / "netfulfilled.dat").string();
@ -2302,21 +2302,21 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
// ********************************************************* Step 8: start indexers
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex);
if (!g_txindex->Start(::ChainstateActive())) {
if (!g_txindex->Start(chainman.ActiveChainstate())) {
return false;
}
}
for (const auto& filter_type : g_enabled_filter_types) {
InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex);
if (!GetBlockFilterIndex(filter_type)->Start(::ChainstateActive())) {
if (!GetBlockFilterIndex(filter_type)->Start(chainman.ActiveChainstate())) {
return false;
}
}
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
g_coin_stats_index = std::make_unique<CoinStatsIndex>(/* cache size */ 0, false, fReindex);
if (!g_coin_stats_index->Start(::ChainstateActive())) {
if (!g_coin_stats_index->Start(chainman.ActiveChainstate())) {
return false;
}
}
@ -2383,7 +2383,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
if (args.GetBoolArg("-statsenabled", DEFAULT_STATSD_ENABLE)) {
int nStatsPeriod = std::min(std::max((int)args.GetArg("-statsperiod", DEFAULT_STATSD_PERIOD), MIN_STATSD_PERIOD), MAX_STATSD_PERIOD);
node.scheduler->scheduleEvery(std::bind(&PeriodicStats, std::ref(*node.args), std::cref(*node.mempool)), std::chrono::seconds{nStatsPeriod});
node.scheduler->scheduleEvery(std::bind(&PeriodicStats, std::ref(*node.args), std::ref(chainman), std::cref(*node.mempool)), std::chrono::seconds{nStatsPeriod});
}
// ********************************************************* Step 11: import blocks
@ -2400,7 +2400,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
// Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
// No locking, as this happens before any background thread is started.
boost::signals2::connection block_notify_genesis_wait_connection;
if (::ChainActive().Tip() == nullptr) {
if (chainman.ActiveChain().Tip() == nullptr) {
block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect(std::bind(BlockNotifyGenesisWait, std::placeholders::_2));
} else {
fHaveGenesis = true;
@ -2476,7 +2476,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
tip_info->header_time = ::pindexBestHeader->GetBlockTime();
}
}
LogPrintf("::ChainActive().Height() = %d\n", chain_active_height);
LogPrintf("nBestHeight = %d\n", chain_active_height);
if (node.peerman) node.peerman->SetBestHeight(chain_active_height);
// Map ports with UPnP or NAT-PMP.

View File

@ -132,7 +132,6 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxSigOps.push_back(-1); // updated at end
LOCK2(cs_main, m_mempool.cs);
assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*m_chainstate.m_chain.Tip()));
CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip();
assert(pindexPrev != nullptr);
nHeight = pindexPrev->nHeight + 1;
@ -265,7 +264,6 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(*pblock->vtx[0]);
BlockValidationState state;
assert(std::addressof(::ChainstateActive()) == std::addressof(m_chainstate));
if (!TestBlockValidity(state, m_clhandler, m_evoDb, chainparams, m_chainstate, *pblock, pindexPrev, false, false)) {
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString()));
}

View File

@ -1899,7 +1899,6 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn
m_mn_activeman(mn_activeman),
m_ignore_incoming_txs(ignore_incoming_txs)
{
assert(std::addressof(g_chainman) == std::addressof(m_chainman));
// Stale tip checking and peer eviction are on two different timers, but we
// don't want them to get out of sync due to drift in the scheduler, so we
// combine them in one function and schedule at the quicker (peer-eviction)

View File

@ -210,7 +210,7 @@ void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman,
}
if (mn_activeman != nullptr) {
mn_activeman->Init(::ChainActive().Tip());
mn_activeman->Init(chainman.ActiveTip());
}
g_wallet_init_interface.AutoLockMasternodeCollaterals();

View File

@ -13,7 +13,6 @@ void FindCoins(const NodeContext& node, std::map<COutPoint, Coin>& coins)
assert(node.mempool);
assert(node.chainman);
LOCK2(cs_main, node.mempool->cs);
assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
CCoinsViewCache& chain_view = node.chainman->ActiveChainstate().CoinsTip();
CCoinsViewMemPool mempool_view(&chain_view, *node.mempool);
for (auto& coin : coins) {

View File

@ -113,7 +113,6 @@ static bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats&
if (!pindex) {
LOCK(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
pindex = blockman.LookupBlockIndex(view->GetBestBlock());
}
stats.nHeight = Assert(pindex)->nHeight;

View File

@ -26,6 +26,7 @@
#include <scheduler.h>
#include <spork.h>
#include <txmempool.h>
#include <validation.h>
NodeContext::NodeContext() {}
NodeContext::~NodeContext() {}

View File

@ -58,7 +58,7 @@ struct NodeContext {
std::unique_ptr<CTxMemPool> mempool;
std::unique_ptr<CBlockPolicyEstimator> fee_estimator;
std::unique_ptr<PeerManager> peerman;
ChainstateManager* chainman{nullptr}; // Currently a raw pointer because the memory is not managed by this struct
std::unique_ptr<ChainstateManager> chainman;
std::unique_ptr<BanMan> banman;
ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct
std::unique_ptr<interfaces::Chain> chain;

View File

@ -428,26 +428,16 @@ public:
int getNumBlocks() override
{
LOCK(::cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
return chainman().ActiveChain().Height();
}
uint256 getBestBlockHash() override
{
const CBlockIndex* tip;
{
// TODO: Temporary scope to check correctness of refactored code.
// Should be removed manually after merge of
// https://github.com/bitcoin/bitcoin/pull/20158
LOCK(cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
tip = chainman().ActiveChain().Tip();
}
const CBlockIndex* tip = WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip());
return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
}
int64_t getLastBlockTime() override
{
LOCK(::cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
if (chainman().ActiveChain().Tip()) {
return chainman().ActiveChain().Tip()->GetBlockTime();
}
@ -456,7 +446,6 @@ public:
std::string getLastBlockHash() override
{
LOCK(::cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
if (m_context->chainman->ActiveChain().Tip()) {
return m_context->chainman->ActiveChain().Tip()->GetBlockHash().ToString();
}
@ -467,22 +456,12 @@ public:
const CBlockIndex* tip;
{
LOCK(::cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
tip = chainman().ActiveChain().Tip();
}
return GuessVerificationProgress(Params().TxData(), tip);
}
bool isInitialBlockDownload() override {
const CChainState* active_chainstate;
{
// TODO: Temporary scope to check correctness of refactored code.
// Should be removed manually after merge of
// https://github.com/bitcoin/bitcoin/pull/20158
LOCK(::cs_main);
active_chainstate = &m_context->chainman->ActiveChainstate();
assert(std::addressof(::ChainstateActive()) == std::addressof(*active_chainstate));
}
return active_chainstate->IsInitialBlockDownload();
return chainman().ActiveChainstate().IsInitialBlockDownload();
}
bool isMasternode() override
{
@ -512,7 +491,6 @@ public:
bool getUnspentOutput(const COutPoint& output, Coin& coin) override
{
LOCK(::cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(chainman().ActiveChainstate()));
return chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin);
}
WalletLoader& walletLoader() override
@ -761,8 +739,8 @@ public:
std::optional<int> findFork(const uint256& hash, std::optional<int>* height) override
{
LOCK(cs_main);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
const CBlockIndex* block = g_chainman.m_blockman.LookupBlockIndex(hash);
const CChain& active = chainman().ActiveChain();
const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(hash);
const CBlockIndex* fork = block ? active.FindFork(block) : nullptr;
if (height) {
if (block) {
@ -779,14 +757,12 @@ public:
CBlockLocator getTipLocator() override
{
LOCK(cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
return chainman().ActiveChain().GetLocator();
}
std::optional<int> findLocatorFork(const CBlockLocator& locator) override
{
LOCK(cs_main);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
if (CBlockIndex* fork = m_node.chainman->m_blockman.FindForkInGlobalIndex(active, locator)) {
return fork->nHeight;
}
@ -795,7 +771,6 @@ public:
bool checkFinalTx(const CTransaction& tx) override
{
LOCK(cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(m_node.chainman->ActiveChain()));
return CheckFinalTx(m_node.chainman->ActiveChain().Tip(), tx);
}
bool isInstantSendLockedTx(const uint256& hash) override
@ -810,7 +785,7 @@ public:
}
std::vector<COutPoint> listMNCollaterials(const std::vector<std::pair<const CTransactionRef&, unsigned int>>& outputs) override
{
const CBlockIndex *tip = WITH_LOCK(::cs_main, return ::ChainActive().Tip());
const CBlockIndex *tip = WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip());
CDeterministicMNList mnList{};
if (tip != nullptr && m_node.dmnman != nullptr) {
mnList = m_node.dmnman->GetListForBlock(tip);
@ -828,7 +803,6 @@ public:
{
WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash), block, lock, active);
}
bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override
@ -841,7 +815,6 @@ public:
{
WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
if (const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) {
return FillBlock(ancestor, ancestor_out, lock, active);
@ -853,9 +826,7 @@ public:
{
WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
const CBlockIndex* ancestor = m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr;
return FillBlock(ancestor, ancestor_out, lock, active);
@ -864,9 +835,7 @@ public:
{
WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
const CBlockIndex* block1 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
const CBlockIndex* block2 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
// Using & instead of && below to avoid short circuiting and leaving
@ -880,7 +849,6 @@ public:
double guessVerificationProgress(const uint256& block_hash) override
{
LOCK(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman().m_blockman));
return GuessVerificationProgress(Params().TxData(), chainman().m_blockman.LookupBlockIndex(block_hash));
}
bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override
@ -893,7 +861,6 @@ public:
// used to limit the range, and passing min_height that's too low or
// max_height that's too high will not crash or change the result.
LOCK(::cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman().m_blockman));
if (CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height);
for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) {
@ -976,16 +943,7 @@ public:
}
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); }
bool isInitialBlockDownload() override {
const CChainState* active_chainstate;
{
// TODO: Temporary scope to check correctness of refactored code.
// Should be removed manually after merge of
// https://github.com/bitcoin/bitcoin/pull/20158
LOCK(::cs_main);
active_chainstate = &chainman().ActiveChainstate();
assert(std::addressof(::ChainstateActive()) == std::addressof(*active_chainstate));
}
return active_chainstate->IsInitialBlockDownload();
return chainman().ActiveChainstate().IsInitialBlockDownload();
}
bool shutdownRequested() override { return ShutdownRequested(); }
void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }

View File

@ -42,7 +42,6 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
{ // cs_main scope
assert(node.chainman);
LOCK(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
// If the transaction is already confirmed in the chain, don't do anything
// and return early.
CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();

View File

@ -87,11 +87,6 @@ void AppTests::appTests()
// Reset global state to avoid interfering with later tests.
LogInstance().DisconnectTestLogger();
AbortShutdown();
{
LOCK(cs_main);
UnloadBlockIndex(/* mempool */ nullptr, g_chainman);
g_chainman.Reset();
}
}
//! Entry point for BitcoinGUI tests.

View File

@ -117,14 +117,14 @@ void TestGUI(interfaces::Node& node)
LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
wallet->SetAddressBook(PKHash(test.coinbaseKey.GetPubKey()), "", "receive");
spk_man->AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
wallet->SetLastBlockProcessed(105, ::ChainActive().Tip()->GetBlockHash());
wallet->SetLastBlockProcessed(105, node.context()->chainman->ActiveChain().Tip()->GetBlockHash());
}
{
WalletRescanReserver reserver(*wallet);
reserver.reserve();
CWallet::ScanResult result = wallet->ScanForWalletTransactions(Params().GetConsensus().hashGenesisBlock, 0 /* start_height */, {} /* max_height */, reserver, true /* fUpdate */);
QCOMPARE(result.status, CWallet::ScanResult::SUCCESS);
QCOMPARE(result.last_scanned_block, ::ChainActive().Tip()->GetBlockHash());
QCOMPARE(result.last_scanned_block, node.context()->chainman->ActiveChain().Tip()->GetBlockHash());
QVERIFY(result.last_failed_block.IsNull());
}
wallet->SetBroadcastTransactions(true);

View File

@ -124,7 +124,7 @@ static ChainstateManager* GetChainman(const CoreContext& context, HTTPRequest* r
__FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
return nullptr;
}
return node_context->chainman;
return node_context->chainman.get();
}
static RetFormat ParseDataFormat(std::string& param, const std::string& strReq)

View File

@ -100,7 +100,6 @@ ChainstateManager& EnsureChainman(const NodeContext& node)
if (!node.chainman) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
}
WITH_LOCK(::cs_main, CHECK_NONFATAL(std::addressof(g_chainman) == std::addressof(*node.chainman)));
return *node.chainman;
}

View File

@ -99,9 +99,9 @@ static RPCHelpMan masternode_count()
};
}
static UniValue GetNextMasternodeForPayment(CDeterministicMNManager& dmnman, int heightShift)
static UniValue GetNextMasternodeForPayment(const CChain& active_chain, CDeterministicMNManager& dmnman, int heightShift)
{
const CBlockIndex *tip = WITH_LOCK(::cs_main, return ::ChainActive().Tip());
const CBlockIndex *tip = WITH_LOCK(::cs_main, return active_chain.Tip());
auto mnList = dmnman.GetListForBlock(tip);
auto payees = mnList.GetProjectedMNPayees(tip, heightShift);
if (payees.empty())
@ -136,8 +136,9 @@ static RPCHelpMan masternode_winner()
}
const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman);
return GetNextMasternodeForPayment(*node.dmnman, 10);
return GetNextMasternodeForPayment(chainman.ActiveChain(), *node.dmnman, 10);
},
};
}
@ -156,8 +157,9 @@ static RPCHelpMan masternode_current()
}
const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman);
return GetNextMasternodeForPayment(*node.dmnman, 1);
return GetNextMasternodeForPayment(chainman.ActiveChain(), *node.dmnman, 1);
},
};
}

View File

@ -128,7 +128,6 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t&
{
LOCK(cs_main);
CHECK_NONFATAL(std::addressof(::ChainActive()) == std::addressof(chainman.ActiveChain()));
IncrementExtraNonce(&block, chainman.ActiveChain().Tip(), extra_nonce);
}
@ -164,7 +163,6 @@ static UniValue generateBlocks(ChainstateManager& chainman, const NodeContext& n
{ // Don't keep cs_main locked
LOCK(cs_main);
CHECK_NONFATAL(std::addressof(::ChainActive()) == std::addressof(chainman.ActiveChain()));
nHeight = chainman.ActiveChain().Height();
nHeightEnd = nHeight+nGenerate;
}

View File

@ -55,7 +55,7 @@ static SimpleUTXOMap BuildSimpleUtxoMap(const std::vector<CTransactionRef>& txs)
return utxos;
}
static std::vector<COutPoint> SelectUTXOs(SimpleUTXOMap& utoxs, CAmount amount, CAmount& changeRet)
static std::vector<COutPoint> SelectUTXOs(const CChain& active_chain, SimpleUTXOMap& utoxs, CAmount amount, CAmount& changeRet)
{
changeRet = 0;
@ -64,7 +64,7 @@ static std::vector<COutPoint> SelectUTXOs(SimpleUTXOMap& utoxs, CAmount amount,
while (!utoxs.empty()) {
bool found = false;
for (auto it = utoxs.begin(); it != utoxs.end(); ++it) {
if (::ChainActive().Height() - it->second.first < 101) {
if (active_chain.Height() - it->second.first < 101) {
continue;
}
@ -84,10 +84,10 @@ static std::vector<COutPoint> SelectUTXOs(SimpleUTXOMap& utoxs, CAmount amount,
return selectedUtxos;
}
static void FundTransaction(CMutableTransaction& tx, SimpleUTXOMap& utoxs, const CScript& scriptPayout, CAmount amount)
static void FundTransaction(const CChain& active_chain, CMutableTransaction& tx, SimpleUTXOMap& utoxs, const CScript& scriptPayout, CAmount amount)
{
CAmount change;
auto inputs = SelectUTXOs(utoxs, amount, change);
auto inputs = SelectUTXOs(active_chain, utoxs, amount, change);
for (const auto& input : inputs) {
tx.vin.emplace_back(input);
}
@ -110,7 +110,7 @@ static void SignTransaction(const CTxMemPool& mempool, CMutableTransaction& tx,
}
}
static CMutableTransaction CreateProRegTx(const CTxMemPool& mempool, SimpleUTXOMap& utxos, int port, const CScript& scriptPayout, const CKey& coinbaseKey, CKey& ownerKeyRet, CBLSSecretKey& operatorKeyRet)
static CMutableTransaction CreateProRegTx(const CChain& active_chain, const CTxMemPool& mempool, SimpleUTXOMap& utxos, int port, const CScript& scriptPayout, const CKey& coinbaseKey, CKey& ownerKeyRet, CBLSSecretKey& operatorKeyRet)
{
ownerKeyRet.MakeNewKey(true);
operatorKeyRet.MakeNewKey();
@ -127,7 +127,7 @@ static CMutableTransaction CreateProRegTx(const CTxMemPool& mempool, SimpleUTXOM
CMutableTransaction tx;
tx.nVersion = 3;
tx.nType = TRANSACTION_PROVIDER_REGISTER;
FundTransaction(tx, utxos, scriptPayout, dmn_types::Regular.collat_amount);
FundTransaction(active_chain, tx, utxos, scriptPayout, dmn_types::Regular.collat_amount);
proTx.inputsHash = CalcTxInputsHash(CTransaction(tx));
SetTxPayload(tx, proTx);
SignTransaction(mempool, tx, coinbaseKey);
@ -157,7 +157,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
CKey ownerKey;
CBLSSecretKey operatorKey;
auto utxos = BuildSimpleUtxoMap(m_coinbase_txns);
auto tx = CreateProRegTx(*m_node.mempool, utxos, 1, GenerateRandomAddress(), coinbaseKey, ownerKey, operatorKey);
auto tx = CreateProRegTx(m_node.chainman->ActiveChain(), *m_node.mempool, utxos, 1, GenerateRandomAddress(), coinbaseKey, ownerKey, operatorKey);
CreateAndProcessBlock({tx}, coinbaseKey);

View File

@ -69,7 +69,7 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
const CScript& scriptPubKey)
{
const CChainParams& chainparams = Params();
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(::ChainstateActive(), m_node, *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey);
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(m_node.chainman->ActiveChainstate(), m_node, *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey);
CBlock& block = pblocktemplate->block;
block.hashPrevBlock = prev->GetBlockHash();
block.nTime = prev->nTime + 1;
@ -124,9 +124,9 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
std::vector<BlockFilter> filters;
std::vector<uint256> filter_hashes;
for (const CBlockIndex* block_index = ::ChainActive().Genesis();
for (const CBlockIndex* block_index = m_node.chainman->ActiveChain().Genesis();
block_index != nullptr;
block_index = ::ChainActive().Next(block_index)) {
block_index = m_node.chainman->ActiveChain().Next(block_index)) {
BOOST_CHECK(!filter_index.LookupFilter(block_index, filter));
BOOST_CHECK(!filter_index.LookupFilterHeader(block_index, filter_header));
BOOST_CHECK(!filter_index.LookupFilterRange(block_index->nHeight, block_index, filters));
@ -138,7 +138,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
// BlockUntilSyncedToCurrentChain should return false before index is started.
BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(filter_index.Start(::ChainstateActive()));
BOOST_REQUIRE(filter_index.Start(m_node.chainman->ActiveChainstate()));
// Allow filter index to catch up with the block index.
IndexWaitSynced(filter_index);
@ -147,9 +147,9 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
{
LOCK(cs_main);
const CBlockIndex* block_index;
for (block_index = ::ChainActive().Genesis();
for (block_index = m_node.chainman->ActiveChain().Genesis();
block_index != nullptr;
block_index = ::ChainActive().Next(block_index)) {
block_index = m_node.chainman->ActiveChain().Next(block_index)) {
CheckFilterLookups(filter_index, block_index, last_header);
}
}
@ -158,7 +158,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
const CBlockIndex* tip;
{
LOCK(cs_main);
tip = ::ChainActive().Tip();
tip = m_node.chainman->ActiveChain().Tip();
}
CKey coinbase_key_A, coinbase_key_B;
coinbase_key_A.MakeNewKey(true);
@ -180,7 +180,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
const CBlockIndex* block_index;
{
LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(block->GetHash());
block_index = m_node.chainman->m_blockman.LookupBlockIndex(block->GetHash());
}
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
@ -198,7 +198,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
const CBlockIndex* block_index;
{
LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(block->GetHash());
block_index = m_node.chainman->m_blockman.LookupBlockIndex(block->GetHash());
}
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
@ -212,7 +212,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
const CBlockIndex* block_index;
{
LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(block->GetHash());
block_index = m_node.chainman->m_blockman.LookupBlockIndex(block->GetHash());
}
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
@ -233,14 +233,14 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
{
LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(chainA[i]->GetHash());
block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainA[i]->GetHash());
}
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
CheckFilterLookups(filter_index, block_index, chainA_last_header);
{
LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(chainB[i]->GetHash());
block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainB[i]->GetHash());
}
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
CheckFilterLookups(filter_index, block_index, chainB_last_header);
@ -252,7 +252,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
{
LOCK(cs_main);
tip = ::ChainActive().Tip();
tip = m_node.chainman->ActiveChain().Tip();
}
BOOST_CHECK(filter_index.LookupFilterRange(0, tip, filters));
BOOST_CHECK(filter_index.LookupFilterHashRange(0, tip, filter_hashes));

View File

@ -20,7 +20,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
const CBlockIndex* block_index;
{
LOCK(cs_main);
block_index = ChainActive().Tip();
block_index = m_node.chainman->ActiveChain().Tip();
}
// CoinStatsIndex should not be found before it is started.
@ -30,7 +30,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
// is started.
BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(coin_stats_index.Start(::ChainstateActive()));
BOOST_REQUIRE(coin_stats_index.Start(m_node.chainman->ActiveChainstate()));
IndexWaitSynced(coin_stats_index);
@ -38,7 +38,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
const CBlockIndex* genesis_block_index;
{
LOCK(cs_main);
genesis_block_index = ChainActive().Genesis();
genesis_block_index = m_node.chainman->ActiveChain().Genesis();
}
BOOST_CHECK(coin_stats_index.LookUpStats(genesis_block_index, coin_stats));
@ -56,7 +56,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
const CBlockIndex* new_block_index;
{
LOCK(cs_main);
new_block_index = ChainActive().Tip();
new_block_index = m_node.chainman->ActiveChain().Tip();
}
coin_stats_index.LookUpStats(new_block_index, new_coin_stats);

View File

@ -92,8 +92,8 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
// This test requires that we have a chain with non-zero work.
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip() != nullptr);
BOOST_CHECK(::ChainActive().Tip()->nChainWork > 0);
BOOST_CHECK(m_node.chainman->ActiveChain().Tip() != nullptr);
BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->nChainWork > 0);
}
// Test starts here

View File

@ -55,9 +55,9 @@ struct TestChainDATSetup : public TestChainSetup
}
LOCK(cs_main);
if (expected_lockin) {
BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::LOCKED_IN);
BOOST_CHECK_EQUAL(g_versionbitscache.State(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id), ThresholdState::LOCKED_IN);
} else {
BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
BOOST_CHECK_EQUAL(g_versionbitscache.State(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
}
}
@ -68,8 +68,8 @@ struct TestChainDATSetup : public TestChainSetup
{
LOCK(cs_main);
BOOST_CHECK_EQUAL(::ChainActive().Height(), window - 2);
BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::DEFINED);
BOOST_CHECK_EQUAL(m_node.chainman->ActiveChain().Height(), window - 2);
BOOST_CHECK_EQUAL(g_versionbitscache.State(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id), ThresholdState::DEFINED);
}
CreateAndProcessBlock({}, coinbaseKey);
@ -77,13 +77,13 @@ struct TestChainDATSetup : public TestChainSetup
{
LOCK(cs_main);
// Advance from DEFINED to STARTED at height = window - 1
BOOST_CHECK_EQUAL(::ChainActive().Height(), window - 1);
BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
BOOST_CHECK_EQUAL(g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id).threshold, threshold(0));
BOOST_CHECK_EQUAL(m_node.chainman->ActiveChain().Height(), window - 1);
BOOST_CHECK_EQUAL(g_versionbitscache.State(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
BOOST_CHECK_EQUAL(g_versionbitscache.Statistics(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id).threshold, threshold(0));
// Next block should be signaling by default
const auto pblocktemplate = BlockAssembler(::ChainstateActive(), m_node, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
const auto pblocktemplate = BlockAssembler(m_node.chainman->ActiveChainstate(), m_node, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
const uint32_t bitmask = ((uint32_t)1) << consensus_params.vDeployments[deployment_id].bit;
BOOST_CHECK_EQUAL(::ChainActive().Tip()->nVersion & bitmask, 0);
BOOST_CHECK_EQUAL(m_node.chainman->ActiveChain().Tip()->nVersion & bitmask, 0);
BOOST_CHECK_EQUAL(pblocktemplate->block.nVersion & bitmask, bitmask);
}
@ -94,18 +94,18 @@ struct TestChainDATSetup : public TestChainSetup
{
// Still STARTED but with a (potentially) new threshold
LOCK(cs_main);
BOOST_CHECK_EQUAL(::ChainActive().Height(), window * (i + 2) - 1);
BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
const auto vbts = g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id);
BOOST_CHECK_EQUAL(m_node.chainman->ActiveChain().Height(), window * (i + 2) - 1);
BOOST_CHECK_EQUAL(g_versionbitscache.State(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id), ThresholdState::STARTED);
const auto vbts = g_versionbitscache.Statistics(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id);
BOOST_CHECK_EQUAL(vbts.threshold, threshold(i + 1));
BOOST_CHECK(vbts.threshold <= th_start);
BOOST_CHECK(vbts.threshold >= th_end);
}
}
if (LOCK(cs_main); check_activation_at_min) {
BOOST_CHECK_EQUAL(g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id).threshold, th_end);
BOOST_CHECK_EQUAL(g_versionbitscache.Statistics(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id).threshold, th_end);
} else {
BOOST_CHECK(g_versionbitscache.Statistics(::ChainActive().Tip(), consensus_params, deployment_id).threshold > th_end);
BOOST_CHECK(g_versionbitscache.Statistics(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id).threshold > th_end);
}
// activate
@ -115,7 +115,7 @@ struct TestChainDATSetup : public TestChainSetup
}
{
LOCK(cs_main);
BOOST_CHECK_EQUAL(g_versionbitscache.State(::ChainActive().Tip(), consensus_params, deployment_id), ThresholdState::ACTIVE);
BOOST_CHECK_EQUAL(g_versionbitscache.State(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id), ThresholdState::ACTIVE);
}
}

View File

@ -14,7 +14,7 @@
#include <script/script.h>
#include <script/signingprovider.h>
#include <util/ranges_set.h>
#include <validation.h> // for ::ChainActive()
#include <validation.h>
#include <boost/test/unit_test.hpp>
@ -316,7 +316,7 @@ BOOST_FIXTURE_TEST_CASE(evo_assetunlock, TestChain100Setup)
auto& blockman = Assert(m_node.chainman)->m_blockman;
auto& qman = *Assert(m_node.llmq_ctx)->qman;
const CBlockIndex *block_index = ::ChainActive().Tip();
const CBlockIndex *block_index = m_node.chainman->ActiveChain().Tip();
BOOST_CHECK(!CheckAssetUnlockTx(blockman, qman, CTransaction(tx), block_index, std::nullopt, tx_state));
BOOST_CHECK(tx_state.GetRejectReason() == "bad-assetunlock-quorum-hash");

View File

@ -39,7 +39,7 @@ static SimpleUTXOMap BuildSimpleUtxoMap(const std::vector<CTransactionRef>& txs)
return utxos;
}
static std::vector<COutPoint> SelectUTXOs(SimpleUTXOMap& utoxs, CAmount amount, CAmount& changeRet)
static std::vector<COutPoint> SelectUTXOs(const CChain& active_chain, SimpleUTXOMap& utoxs, CAmount amount, CAmount& changeRet)
{
changeRet = 0;
@ -48,7 +48,7 @@ static std::vector<COutPoint> SelectUTXOs(SimpleUTXOMap& utoxs, CAmount amount,
while (!utoxs.empty()) {
bool found = false;
for (auto it = utoxs.begin(); it != utoxs.end(); ++it) {
if (::ChainActive().Height() - it->second.first < 101) {
if (active_chain.Height() - it->second.first < 101) {
continue;
}
@ -68,10 +68,10 @@ static std::vector<COutPoint> SelectUTXOs(SimpleUTXOMap& utoxs, CAmount amount,
return selectedUtxos;
}
static void FundTransaction(CMutableTransaction& tx, SimpleUTXOMap& utoxs, const CScript& scriptPayout, CAmount amount, const CKey& coinbaseKey)
static void FundTransaction(const CChain& active_chain, CMutableTransaction& tx, SimpleUTXOMap& utoxs, const CScript& scriptPayout, CAmount amount, const CKey& coinbaseKey)
{
CAmount change;
auto inputs = SelectUTXOs(utoxs, amount, change);
auto inputs = SelectUTXOs(active_chain, utoxs, amount, change);
for (size_t i = 0; i < inputs.size(); i++) {
tx.vin.emplace_back(CTxIn(inputs[i]));
}
@ -94,7 +94,7 @@ static void SignTransaction(const CTxMemPool& mempool, CMutableTransaction& tx,
}
}
static CMutableTransaction CreateProRegTx(const CTxMemPool& mempool, SimpleUTXOMap& utxos, int port, const CScript& scriptPayout, const CKey& coinbaseKey, CKey& ownerKeyRet, CBLSSecretKey& operatorKeyRet)
static CMutableTransaction CreateProRegTx(const CChain& active_chain, const CTxMemPool& mempool, SimpleUTXOMap& utxos, int port, const CScript& scriptPayout, const CKey& coinbaseKey, CKey& ownerKeyRet, CBLSSecretKey& operatorKeyRet)
{
ownerKeyRet.MakeNewKey(true);
operatorKeyRet.MakeNewKey();
@ -111,7 +111,7 @@ static CMutableTransaction CreateProRegTx(const CTxMemPool& mempool, SimpleUTXOM
CMutableTransaction tx;
tx.nVersion = 3;
tx.nType = TRANSACTION_PROVIDER_REGISTER;
FundTransaction(tx, utxos, scriptPayout, dmn_types::Regular.collat_amount, coinbaseKey);
FundTransaction(active_chain, tx, utxos, scriptPayout, dmn_types::Regular.collat_amount, coinbaseKey);
proTx.inputsHash = CalcTxInputsHash(CTransaction(tx));
SetTxPayload(tx, proTx);
SignTransaction(mempool, tx, coinbaseKey);
@ -119,7 +119,7 @@ static CMutableTransaction CreateProRegTx(const CTxMemPool& mempool, SimpleUTXOM
return tx;
}
static CMutableTransaction CreateProUpServTx(const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CBLSSecretKey& operatorKey, int port, const CScript& scriptOperatorPayout, const CKey& coinbaseKey)
static CMutableTransaction CreateProUpServTx(const CChain& active_chain, const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CBLSSecretKey& operatorKey, int port, const CScript& scriptOperatorPayout, const CKey& coinbaseKey)
{
CProUpServTx proTx;
proTx.nVersion = CProUpRevTx::GetVersion(!bls::bls_legacy_scheme);
@ -130,7 +130,7 @@ static CMutableTransaction CreateProUpServTx(const CTxMemPool& mempool, SimpleUT
CMutableTransaction tx;
tx.nVersion = 3;
tx.nType = TRANSACTION_PROVIDER_UPDATE_SERVICE;
FundTransaction(tx, utxos, GetScriptForDestination(PKHash(coinbaseKey.GetPubKey())), 1 * COIN, coinbaseKey);
FundTransaction(active_chain, tx, utxos, GetScriptForDestination(PKHash(coinbaseKey.GetPubKey())), 1 * COIN, coinbaseKey);
proTx.inputsHash = CalcTxInputsHash(CTransaction(tx));
proTx.sig = operatorKey.Sign(::SerializeHash(proTx));
SetTxPayload(tx, proTx);
@ -139,7 +139,7 @@ static CMutableTransaction CreateProUpServTx(const CTxMemPool& mempool, SimpleUT
return tx;
}
static CMutableTransaction CreateProUpRegTx(const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CKey& mnKey, const CBLSPublicKey& pubKeyOperator, const CKeyID& keyIDVoting, const CScript& scriptPayout, const CKey& coinbaseKey)
static CMutableTransaction CreateProUpRegTx(const CChain& active_chain, const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CKey& mnKey, const CBLSPublicKey& pubKeyOperator, const CKeyID& keyIDVoting, const CScript& scriptPayout, const CKey& coinbaseKey)
{
CProUpRegTx proTx;
proTx.nVersion = CProUpRegTx::GetVersion(!bls::bls_legacy_scheme);
@ -151,7 +151,7 @@ static CMutableTransaction CreateProUpRegTx(const CTxMemPool& mempool, SimpleUTX
CMutableTransaction tx;
tx.nVersion = 3;
tx.nType = TRANSACTION_PROVIDER_UPDATE_REGISTRAR;
FundTransaction(tx, utxos, GetScriptForDestination(PKHash(coinbaseKey.GetPubKey())), 1 * COIN, coinbaseKey);
FundTransaction(active_chain, tx, utxos, GetScriptForDestination(PKHash(coinbaseKey.GetPubKey())), 1 * COIN, coinbaseKey);
proTx.inputsHash = CalcTxInputsHash(CTransaction(tx));
CHashSigner::SignHash(::SerializeHash(proTx), mnKey, proTx.vchSig);
SetTxPayload(tx, proTx);
@ -160,7 +160,7 @@ static CMutableTransaction CreateProUpRegTx(const CTxMemPool& mempool, SimpleUTX
return tx;
}
static CMutableTransaction CreateProUpRevTx(const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CBLSSecretKey& operatorKey, const CKey& coinbaseKey)
static CMutableTransaction CreateProUpRevTx(const CChain& active_chain, const CTxMemPool& mempool, SimpleUTXOMap& utxos, const uint256& proTxHash, const CBLSSecretKey& operatorKey, const CKey& coinbaseKey)
{
CProUpRevTx proTx;
proTx.nVersion = CProUpRevTx::GetVersion(!bls::bls_legacy_scheme);
@ -169,7 +169,7 @@ static CMutableTransaction CreateProUpRevTx(const CTxMemPool& mempool, SimpleUTX
CMutableTransaction tx;
tx.nVersion = 3;
tx.nType = TRANSACTION_PROVIDER_UPDATE_REVOKE;
FundTransaction(tx, utxos, GetScriptForDestination(PKHash(coinbaseKey.GetPubKey())), 1 * COIN, coinbaseKey);
FundTransaction(active_chain, tx, utxos, GetScriptForDestination(PKHash(coinbaseKey.GetPubKey())), 1 * COIN, coinbaseKey);
proTx.inputsHash = CalcTxInputsHash(CTransaction(tx));
proTx.sig = operatorKey.Sign(::SerializeHash(proTx));
SetTxPayload(tx, proTx);
@ -238,42 +238,44 @@ static bool CheckTransactionSignature(const CTxMemPool& mempool, const CMutableT
void FuncDIP3Activation(TestChainSetup& setup)
{
auto& chainman = *Assert(setup.m_node.chainman.get());
auto& dmnman = *Assert(setup.m_node.dmnman);
auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns);
CKey ownerKey;
CBLSSecretKey operatorKey;
CTxDestination payoutDest = DecodeDestination("yRq1Ky1AfFmf597rnotj7QRxsDUKePVWNF");
auto tx = CreateProRegTx(*(setup.m_node.mempool), utxos, 1, GetScriptForDestination(payoutDest), setup.coinbaseKey, ownerKey, operatorKey);
auto tx = CreateProRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, 1, GetScriptForDestination(payoutDest), setup.coinbaseKey, ownerKey, operatorKey);
std::vector<CMutableTransaction> txns = {tx};
int nHeight = ::ChainActive().Height();
int nHeight = chainman.ActiveChain().Height();
// We start one block before DIP3 activation, so mining a block with a DIP3 transaction should fail
auto block = std::make_shared<CBlock>(setup.CreateBlock(txns, setup.coinbaseKey));
Assert(setup.m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr);
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight);
BOOST_ASSERT(block->GetHash() != ::ChainActive().Tip()->GetBlockHash());
chainman.ProcessNewBlock(Params(), block, true, nullptr);
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight);
BOOST_ASSERT(block->GetHash() != chainman.ActiveChain().Tip()->GetBlockHash());
BOOST_ASSERT(!dmnman.GetListAtChainTip().HasMN(tx.GetHash()));
// This block should activate DIP3
setup.CreateAndProcessBlock({}, setup.coinbaseKey);
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1);
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1);
// Mining a block with a DIP3 transaction should succeed now
block = std::make_shared<CBlock>(setup.CreateBlock(txns, setup.coinbaseKey));
BOOST_ASSERT(Assert(setup.m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 2);
BOOST_CHECK_EQUAL(block->GetHash(), ::ChainActive().Tip()->GetBlockHash());
BOOST_ASSERT(chainman.ProcessNewBlock(Params(), block, true, nullptr));
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 2);
BOOST_CHECK_EQUAL(block->GetHash(), chainman.ActiveChain().Tip()->GetBlockHash());
BOOST_ASSERT(dmnman.GetListAtChainTip().HasMN(tx.GetHash()));
};
void FuncV19Activation(TestChainSetup& setup)
{
BOOST_ASSERT(!DeploymentActiveAfter(::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
auto& chainman = *Assert(setup.m_node.chainman.get());
auto& dmnman = *Assert(setup.m_node.dmnman);
BOOST_ASSERT(!DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
// create
auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns);
CKey owner_key;
@ -281,35 +283,35 @@ void FuncV19Activation(TestChainSetup& setup)
CKey collateral_key;
collateral_key.MakeNewKey(false);
auto collateralScript = GetScriptForDestination(PKHash(collateral_key.GetPubKey()));
auto tx_reg = CreateProRegTx(*(setup.m_node.mempool), utxos, 1, collateralScript, setup.coinbaseKey, owner_key, operator_key);
auto tx_reg = CreateProRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, 1, collateralScript, setup.coinbaseKey, owner_key, operator_key);
auto tx_reg_hash = tx_reg.GetHash();
int nHeight = ::ChainActive().Height();
int nHeight = chainman.ActiveChain().Height();
auto block = std::make_shared<CBlock>(setup.CreateBlock({tx_reg}, setup.coinbaseKey));
BOOST_ASSERT(Assert(setup.m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
BOOST_ASSERT(!DeploymentActiveAfter(::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
BOOST_ASSERT(chainman.ProcessNewBlock(Params(), block, true, nullptr));
BOOST_ASSERT(!DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
++nHeight;
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
dmnman.DoMaintenance();
auto tip_list = dmnman.GetListAtChainTip();
BOOST_ASSERT(tip_list.HasMN(tx_reg_hash));
auto pindex_create = ::ChainActive().Tip();
auto pindex_create = chainman.ActiveChain().Tip();
auto base_list = dmnman.GetListForBlock(pindex_create);
std::vector<CDeterministicMNListDiff> diffs;
// update
CBLSSecretKey operator_key_new;
operator_key_new.MakeNewKey();
auto tx_upreg = CreateProUpRegTx(*(setup.m_node.mempool), utxos, tx_reg_hash, owner_key, operator_key_new.GetPublicKey(), owner_key.GetPubKey().GetID(), collateralScript, setup.coinbaseKey);
auto tx_upreg = CreateProUpRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, tx_reg_hash, owner_key, operator_key_new.GetPublicKey(), owner_key.GetPubKey().GetID(), collateralScript, setup.coinbaseKey);
block = std::make_shared<CBlock>(setup.CreateBlock({tx_upreg}, setup.coinbaseKey));
BOOST_ASSERT(Assert(setup.m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
BOOST_ASSERT(!DeploymentActiveAfter(::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
BOOST_ASSERT(chainman.ProcessNewBlock(Params(), block, true, nullptr));
BOOST_ASSERT(!DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
++nHeight;
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
dmnman.DoMaintenance();
tip_list = dmnman.GetListAtChainTip();
BOOST_ASSERT(tip_list.HasMN(tx_reg_hash));
@ -325,11 +327,11 @@ void FuncV19Activation(TestChainSetup& setup)
signing_provider.AddKeyPubKey(collateral_key, collateral_key.GetPubKey());
BOOST_ASSERT(SignSignature(signing_provider, CTransaction(tx_reg), tx_spend, 0, SIGHASH_ALL));
block = std::make_shared<CBlock>(setup.CreateBlock({tx_spend}, setup.coinbaseKey));
BOOST_ASSERT(Assert(setup.m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
BOOST_ASSERT(!DeploymentActiveAfter(::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
BOOST_ASSERT(chainman.ProcessNewBlock(Params(), block, true, nullptr));
BOOST_ASSERT(!DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
++nHeight;
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
dmnman.DoMaintenance();
diffs.push_back(tip_list.BuildDiff(dmnman.GetListAtChainTip()));
tip_list = dmnman.GetListAtChainTip();
@ -338,10 +340,10 @@ void FuncV19Activation(TestChainSetup& setup)
// mine another block so that it's not the last one before V19
setup.CreateAndProcessBlock({}, setup.coinbaseKey);
BOOST_ASSERT(!DeploymentActiveAfter(::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
BOOST_ASSERT(!DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
++nHeight;
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
dmnman.DoMaintenance();
diffs.push_back(tip_list.BuildDiff(dmnman.GetListAtChainTip()));
tip_list = dmnman.GetListAtChainTip();
@ -350,10 +352,10 @@ void FuncV19Activation(TestChainSetup& setup)
// this block should activate V19
setup.CreateAndProcessBlock({}, setup.coinbaseKey);
BOOST_ASSERT(DeploymentActiveAfter(::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
BOOST_ASSERT(DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
++nHeight;
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
dmnman.DoMaintenance();
diffs.push_back(tip_list.BuildDiff(dmnman.GetListAtChainTip()));
tip_list = dmnman.GetListAtChainTip();
@ -362,7 +364,7 @@ void FuncV19Activation(TestChainSetup& setup)
// check mn list/diff
CDeterministicMNListDiff dummy_diff = base_list.BuildDiff(tip_list);
CDeterministicMNList dummmy_list = base_list.ApplyDiff(::ChainActive().Tip(), dummy_diff);
CDeterministicMNList dummmy_list = base_list.ApplyDiff(chainman.ActiveChain().Tip(), dummy_diff);
// Lists should match
BOOST_ASSERT(dummmy_list == tip_list);
@ -370,9 +372,9 @@ void FuncV19Activation(TestChainSetup& setup)
for (int i = 0; i < 10; ++i)
{
setup.CreateAndProcessBlock({}, setup.coinbaseKey);
BOOST_ASSERT(DeploymentActiveAfter(::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1 + i);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_ASSERT(DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19));
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1 + i);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
dmnman.DoMaintenance();
diffs.push_back(tip_list.BuildDiff(dmnman.GetListAtChainTip()));
tip_list = dmnman.GetListAtChainTip();
@ -381,27 +383,28 @@ void FuncV19Activation(TestChainSetup& setup)
}
// check mn list/diff
const CBlockIndex* v19_index = ::ChainActive().Tip()->GetAncestor(Params().GetConsensus().V19Height);
const CBlockIndex* v19_index = chainman.ActiveChain().Tip()->GetAncestor(Params().GetConsensus().V19Height);
auto v19_list = dmnman.GetListForBlock(v19_index);
dummy_diff = v19_list.BuildDiff(tip_list);
dummmy_list = v19_list.ApplyDiff(::ChainActive().Tip(), dummy_diff);
dummmy_list = v19_list.ApplyDiff(chainman.ActiveChain().Tip(), dummy_diff);
BOOST_ASSERT(dummmy_list == tip_list);
// NOTE: this fails on v19/v19.1 with errors like:
// "RemoveMN: Can't delete a masternode ... with a pubKeyOperator=..."
dummy_diff = base_list.BuildDiff(tip_list);
dummmy_list = base_list.ApplyDiff(::ChainActive().Tip(), dummy_diff);
dummmy_list = base_list.ApplyDiff(chainman.ActiveChain().Tip(), dummy_diff);
BOOST_ASSERT(dummmy_list == tip_list);
dummmy_list = base_list;
for (const auto& diff : diffs) {
dummmy_list = dummmy_list.ApplyDiff(::ChainActive().Tip(), diff);
dummmy_list = dummmy_list.ApplyDiff(chainman.ActiveChain().Tip(), diff);
}
BOOST_ASSERT(dummmy_list == tip_list);
};
void FuncDIP3Protx(TestChainSetup& setup)
{
auto& chainman = *Assert(setup.m_node.chainman.get());
auto& dmnman = *Assert(setup.m_node.dmnman);
CKey sporkKey;
@ -411,7 +414,7 @@ void FuncDIP3Protx(TestChainSetup& setup)
auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns);
int nHeight = ::ChainActive().Height();
int nHeight = chainman.ActiveChain().Height();
int port = 1;
std::vector<uint256> dmnHashes;
@ -422,7 +425,7 @@ void FuncDIP3Protx(TestChainSetup& setup)
for (size_t i = 0; i < 6; i++) {
CKey ownerKey;
CBLSSecretKey operatorKey;
auto tx = CreateProRegTx(*(setup.m_node.mempool), utxos, port++, GenerateRandomAddress(), setup.coinbaseKey, ownerKey, operatorKey);
auto tx = CreateProRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, port++, GenerateRandomAddress(), setup.coinbaseKey, ownerKey, operatorKey);
dmnHashes.emplace_back(tx.GetHash());
ownerKeys.emplace(tx.GetHash(), ownerKey);
operatorKeys.emplace(tx.GetHash(), operatorKey);
@ -436,34 +439,34 @@ void FuncDIP3Protx(TestChainSetup& setup)
// Technically, the payload is still valid...
{
LOCK(cs_main);
BOOST_ASSERT(CheckProRegTx(dmnman, CTransaction(tx), ::ChainActive().Tip(), dummy_state, ::ChainstateActive().CoinsTip(), true));
BOOST_ASSERT(CheckProRegTx(dmnman, CTransaction(tx2), ::ChainActive().Tip(), dummy_state, ::ChainstateActive().CoinsTip(), true));
BOOST_ASSERT(CheckProRegTx(dmnman, CTransaction(tx), chainman.ActiveChain().Tip(), dummy_state, chainman.ActiveChainstate().CoinsTip(), true));
BOOST_ASSERT(CheckProRegTx(dmnman, CTransaction(tx2), chainman.ActiveChain().Tip(), dummy_state, chainman.ActiveChainstate().CoinsTip(), true));
}
// But the signature should not verify anymore
BOOST_ASSERT(CheckTransactionSignature(*(setup.m_node.mempool), tx));
BOOST_ASSERT(!CheckTransactionSignature(*(setup.m_node.mempool), tx2));
setup.CreateAndProcessBlock({tx}, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1);
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1);
BOOST_ASSERT(dmnman.GetListAtChainTip().HasMN(tx.GetHash()));
nHeight++;
}
int DIP0003EnforcementHeightBackup = Params().GetConsensus().DIP0003EnforcementHeight;
const_cast<Consensus::Params&>(Params().GetConsensus()).DIP0003EnforcementHeight = ::ChainActive().Height() + 1;
const_cast<Consensus::Params&>(Params().GetConsensus()).DIP0003EnforcementHeight = chainman.ActiveChain().Height() + 1;
setup.CreateAndProcessBlock({}, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
nHeight++;
// check MN reward payments
for (size_t i = 0; i < 20; i++) {
auto dmnExpectedPayee = dmnman.GetListAtChainTip().GetMNPayee(::ChainActive().Tip());
auto dmnExpectedPayee = dmnman.GetListAtChainTip().GetMNPayee(chainman.ActiveChain().Tip());
CBlock block = setup.CreateAndProcessBlock({}, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_ASSERT(!block.vtx.empty());
auto dmnPayout = FindPayoutDmn(dmnman, block);
@ -479,15 +482,15 @@ void FuncDIP3Protx(TestChainSetup& setup)
for (size_t j = 0; j < 3; j++) {
CKey ownerKey;
CBLSSecretKey operatorKey;
auto tx = CreateProRegTx(*(setup.m_node.mempool), utxos, port++, GenerateRandomAddress(), setup.coinbaseKey, ownerKey, operatorKey);
auto tx = CreateProRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, port++, GenerateRandomAddress(), setup.coinbaseKey, ownerKey, operatorKey);
dmnHashes.emplace_back(tx.GetHash());
ownerKeys.emplace(tx.GetHash(), ownerKey);
operatorKeys.emplace(tx.GetHash(), operatorKey);
txns.emplace_back(tx);
}
setup.CreateAndProcessBlock(txns, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1);
for (size_t j = 0; j < 3; j++) {
BOOST_ASSERT(dmnman.GetListAtChainTip().HasMN(txns[j].GetHash()));
@ -497,20 +500,20 @@ void FuncDIP3Protx(TestChainSetup& setup)
}
// test ProUpServTx
auto tx = CreateProUpServTx(*(setup.m_node.mempool), utxos, dmnHashes[0], operatorKeys[dmnHashes[0]], 1000, CScript(), setup.coinbaseKey);
auto tx = CreateProUpServTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, dmnHashes[0], operatorKeys[dmnHashes[0]], 1000, CScript(), setup.coinbaseKey);
setup.CreateAndProcessBlock({tx}, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1);
nHeight++;
auto dmn = dmnman.GetListAtChainTip().GetMN(dmnHashes[0]);
BOOST_ASSERT(dmn != nullptr && dmn->pdmnState->addr.GetPort() == 1000);
// test ProUpRevTx
tx = CreateProUpRevTx(*(setup.m_node.mempool), utxos, dmnHashes[0], operatorKeys[dmnHashes[0]], setup.coinbaseKey);
tx = CreateProUpRevTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, dmnHashes[0], operatorKeys[dmnHashes[0]], setup.coinbaseKey);
setup.CreateAndProcessBlock({tx}, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1);
nHeight++;
dmn = dmnman.GetListAtChainTip().GetMN(dmnHashes[0]);
@ -518,11 +521,11 @@ void FuncDIP3Protx(TestChainSetup& setup)
// test that the revoked MN does not get paid anymore
for (size_t i = 0; i < 20; i++) {
auto dmnExpectedPayee = dmnman.GetListAtChainTip().GetMNPayee(::ChainActive().Tip());
auto dmnExpectedPayee = dmnman.GetListAtChainTip().GetMNPayee(chainman.ActiveChain().Tip());
BOOST_ASSERT(dmnExpectedPayee->proTxHash != dmnHashes[0]);
CBlock block = setup.CreateAndProcessBlock({}, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_ASSERT(!block.vtx.empty());
auto dmnPayout = FindPayoutDmn(dmnman, block);
@ -536,27 +539,27 @@ void FuncDIP3Protx(TestChainSetup& setup)
CBLSSecretKey newOperatorKey;
newOperatorKey.MakeNewKey();
dmn = dmnman.GetListAtChainTip().GetMN(dmnHashes[0]);
tx = CreateProUpRegTx(*(setup.m_node.mempool), utxos, dmnHashes[0], ownerKeys[dmnHashes[0]], newOperatorKey.GetPublicKey(), ownerKeys[dmnHashes[0]].GetPubKey().GetID(), dmn->pdmnState->scriptPayout, setup.coinbaseKey);
tx = CreateProUpRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, dmnHashes[0], ownerKeys[dmnHashes[0]], newOperatorKey.GetPublicKey(), ownerKeys[dmnHashes[0]].GetPubKey().GetID(), dmn->pdmnState->scriptPayout, setup.coinbaseKey);
// check malleability protection again, but this time by also relying on the signature inside the ProUpRegTx
auto tx2 = MalleateProTxPayout<CProUpRegTx>(tx);
TxValidationState dummy_state;
{
LOCK(cs_main);
BOOST_ASSERT(CheckProUpRegTx(dmnman, CTransaction(tx), ::ChainActive().Tip(), dummy_state, ::ChainstateActive().CoinsTip(), true));
BOOST_ASSERT(!CheckProUpRegTx(dmnman, CTransaction(tx2), ::ChainActive().Tip(), dummy_state, ::ChainstateActive().CoinsTip(), true));
BOOST_ASSERT(CheckProUpRegTx(dmnman, CTransaction(tx), chainman.ActiveChain().Tip(), dummy_state, chainman.ActiveChainstate().CoinsTip(), true));
BOOST_ASSERT(!CheckProUpRegTx(dmnman, CTransaction(tx2), chainman.ActiveChain().Tip(), dummy_state, chainman.ActiveChainstate().CoinsTip(), true));
}
BOOST_ASSERT(CheckTransactionSignature(*(setup.m_node.mempool), tx));
BOOST_ASSERT(!CheckTransactionSignature(*(setup.m_node.mempool), tx2));
// now process the block
setup.CreateAndProcessBlock({tx}, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1);
nHeight++;
tx = CreateProUpServTx(*(setup.m_node.mempool), utxos, dmnHashes[0], newOperatorKey, 100, CScript(), setup.coinbaseKey);
tx = CreateProUpServTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, dmnHashes[0], newOperatorKey, 100, CScript(), setup.coinbaseKey);
setup.CreateAndProcessBlock({tx}, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1);
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1);
nHeight++;
dmn = dmnman.GetListAtChainTip().GetMN(dmnHashes[0]);
@ -566,13 +569,13 @@ void FuncDIP3Protx(TestChainSetup& setup)
// test that the revived MN gets payments again
bool foundRevived = false;
for (size_t i = 0; i < 20; i++) {
auto dmnExpectedPayee = dmnman.GetListAtChainTip().GetMNPayee(::ChainActive().Tip());
auto dmnExpectedPayee = dmnman.GetListAtChainTip().GetMNPayee(chainman.ActiveChain().Tip());
if (dmnExpectedPayee->proTxHash == dmnHashes[0]) {
foundRevived = true;
}
CBlock block = setup.CreateAndProcessBlock({}, setup.coinbaseKey);
dmnman.UpdatedBlockTip(::ChainActive().Tip());
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_ASSERT(!block.vtx.empty());
auto dmnPayout = FindPayoutDmn(dmnman, block);
@ -588,7 +591,9 @@ void FuncDIP3Protx(TestChainSetup& setup)
void FuncTestMempoolReorg(TestChainSetup& setup)
{
int nHeight = ::ChainActive().Height();
auto& chainman = *Assert(setup.m_node.chainman.get());
int nHeight = chainman.ActiveChain().Height();
auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns);
CKey ownerKey;
@ -606,14 +611,14 @@ void FuncTestMempoolReorg(TestChainSetup& setup)
// Create a MN with an external collateral
CMutableTransaction tx_collateral;
FundTransaction(tx_collateral, utxos, scriptCollateral, dmn_types::Regular.collat_amount, setup.coinbaseKey);
FundTransaction(chainman.ActiveChain(), tx_collateral, utxos, scriptCollateral, dmn_types::Regular.collat_amount, setup.coinbaseKey);
SignTransaction(*(setup.m_node.mempool), tx_collateral, setup.coinbaseKey);
auto block = std::make_shared<CBlock>(setup.CreateBlock({tx_collateral}, setup.coinbaseKey));
BOOST_ASSERT(Assert(setup.m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
setup.m_node.dmnman->UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1);
BOOST_CHECK_EQUAL(block->GetHash(), ::ChainActive().Tip()->GetBlockHash());
BOOST_ASSERT(chainman.ProcessNewBlock(Params(), block, true, nullptr));
setup.m_node.dmnman->UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1);
BOOST_CHECK_EQUAL(block->GetHash(), chainman.ActiveChain().Tip()->GetBlockHash());
CProRegTx payload;
payload.nVersion = CProRegTx::GetVersion(!bls::bls_legacy_scheme);
@ -633,7 +638,7 @@ void FuncTestMempoolReorg(TestChainSetup& setup)
CMutableTransaction tx_reg;
tx_reg.nVersion = 3;
tx_reg.nType = TRANSACTION_PROVIDER_REGISTER;
FundTransaction(tx_reg, utxos, scriptPayout, dmn_types::Regular.collat_amount, setup.coinbaseKey);
FundTransaction(chainman.ActiveChain(), tx_reg, utxos, scriptPayout, dmn_types::Regular.collat_amount, setup.coinbaseKey);
payload.inputsHash = CalcTxInputsHash(CTransaction(tx_reg));
CMessageSigner::SignMessage(payload.MakeSignString(), payload.vchSig, collateralKey);
SetTxPayload(tx_reg, payload);
@ -647,7 +652,7 @@ void FuncTestMempoolReorg(TestChainSetup& setup)
LOCK2(cs_main, testPool.cs);
// Create ProUpServ and test block reorg which double-spend ProRegTx
auto tx_up_serv = CreateProUpServTx(*(setup.m_node.mempool), utxos, tx_reg.GetHash(), operatorKey, 2, CScript(), setup.coinbaseKey);
auto tx_up_serv = CreateProUpServTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, tx_reg.GetHash(), operatorKey, 2, CScript(), setup.coinbaseKey);
testPool.addUnchecked(entry.FromTx(tx_up_serv));
// A disconnected block would insert ProRegTx back into mempool
testPool.addUnchecked(entry.FromTx(tx_reg));
@ -668,12 +673,14 @@ void FuncTestMempoolReorg(TestChainSetup& setup)
void FuncTestMempoolDualProregtx(TestChainSetup& setup)
{
auto& chainman = *Assert(setup.m_node.chainman.get());
auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns);
// Create a MN
CKey ownerKey1;
CBLSSecretKey operatorKey1;
auto tx_reg1 = CreateProRegTx(*(setup.m_node.mempool), utxos, 1, GenerateRandomAddress(), setup.coinbaseKey, ownerKey1, operatorKey1);
auto tx_reg1 = CreateProRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, 1, GenerateRandomAddress(), setup.coinbaseKey, ownerKey1, operatorKey1);
// Create a MN with an external collateral that references tx_reg1
CKey ownerKey;
@ -705,7 +712,7 @@ void FuncTestMempoolDualProregtx(TestChainSetup& setup)
CMutableTransaction tx_reg2;
tx_reg2.nVersion = 3;
tx_reg2.nType = TRANSACTION_PROVIDER_REGISTER;
FundTransaction(tx_reg2, utxos, scriptPayout, dmn_types::Regular.collat_amount, setup.coinbaseKey);
FundTransaction(chainman.ActiveChain(), tx_reg2, utxos, scriptPayout, dmn_types::Regular.collat_amount, setup.coinbaseKey);
payload.inputsHash = CalcTxInputsHash(CTransaction(tx_reg2));
CMessageSigner::SignMessage(payload.MakeSignString(), payload.vchSig, collateralKey);
SetTxPayload(tx_reg2, payload);
@ -725,9 +732,10 @@ void FuncTestMempoolDualProregtx(TestChainSetup& setup)
void FuncVerifyDB(TestChainSetup& setup)
{
auto& chainman = *Assert(setup.m_node.chainman.get());
auto& dmnman = *Assert(setup.m_node.dmnman);
int nHeight = ::ChainActive().Height();
int nHeight = chainman.ActiveChain().Height();
auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns);
CKey ownerKey;
@ -745,14 +753,14 @@ void FuncVerifyDB(TestChainSetup& setup)
// Create a MN with an external collateral
CMutableTransaction tx_collateral;
FundTransaction(tx_collateral, utxos, scriptCollateral, dmn_types::Regular.collat_amount, setup.coinbaseKey);
FundTransaction(chainman.ActiveChain(), tx_collateral, utxos, scriptCollateral, dmn_types::Regular.collat_amount, setup.coinbaseKey);
SignTransaction(*(setup.m_node.mempool), tx_collateral, setup.coinbaseKey);
auto block = std::make_shared<CBlock>(setup.CreateBlock({tx_collateral}, setup.coinbaseKey));
BOOST_ASSERT(Assert(setup.m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 1);
BOOST_CHECK_EQUAL(block->GetHash(), ::ChainActive().Tip()->GetBlockHash());
BOOST_ASSERT(chainman.ProcessNewBlock(Params(), block, true, nullptr));
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1);
BOOST_CHECK_EQUAL(block->GetHash(), chainman.ActiveChain().Tip()->GetBlockHash());
CProRegTx payload;
payload.nVersion = CProRegTx::GetVersion(!bls::bls_legacy_scheme);
@ -772,7 +780,7 @@ void FuncVerifyDB(TestChainSetup& setup)
CMutableTransaction tx_reg;
tx_reg.nVersion = 3;
tx_reg.nType = TRANSACTION_PROVIDER_REGISTER;
FundTransaction(tx_reg, utxos, scriptPayout, dmn_types::Regular.collat_amount, setup.coinbaseKey);
FundTransaction(chainman.ActiveChain(), tx_reg, utxos, scriptPayout, dmn_types::Regular.collat_amount, setup.coinbaseKey);
payload.inputsHash = CalcTxInputsHash(CTransaction(tx_reg));
CMessageSigner::SignMessage(payload.MakeSignString(), payload.vchSig, collateralKey);
SetTxPayload(tx_reg, payload);
@ -781,27 +789,27 @@ void FuncVerifyDB(TestChainSetup& setup)
auto tx_reg_hash = tx_reg.GetHash();
block = std::make_shared<CBlock>(setup.CreateBlock({tx_reg}, setup.coinbaseKey));
BOOST_ASSERT(Assert(setup.m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 2);
BOOST_CHECK_EQUAL(block->GetHash(), ::ChainActive().Tip()->GetBlockHash());
BOOST_ASSERT(chainman.ProcessNewBlock(Params(), block, true, nullptr));
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 2);
BOOST_CHECK_EQUAL(block->GetHash(), chainman.ActiveChain().Tip()->GetBlockHash());
BOOST_ASSERT(dmnman.GetListAtChainTip().HasMN(tx_reg_hash));
// Now spend the collateral while updating the same MN
SimpleUTXOMap collateral_utxos;
collateral_utxos.emplace(payload.collateralOutpoint, std::make_pair(1, 1000));
auto proUpRevTx = CreateProUpRevTx(*(setup.m_node.mempool), collateral_utxos, tx_reg_hash, operatorKey, collateralKey);
auto proUpRevTx = CreateProUpRevTx(chainman.ActiveChain(), *(setup.m_node.mempool), collateral_utxos, tx_reg_hash, operatorKey, collateralKey);
block = std::make_shared<CBlock>(setup.CreateBlock({proUpRevTx}, setup.coinbaseKey));
BOOST_ASSERT(Assert(setup.m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
dmnman.UpdatedBlockTip(::ChainActive().Tip());
BOOST_CHECK_EQUAL(::ChainActive().Height(), nHeight + 3);
BOOST_CHECK_EQUAL(block->GetHash(), ::ChainActive().Tip()->GetBlockHash());
BOOST_ASSERT(chainman.ProcessNewBlock(Params(), block, true, nullptr));
dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip());
BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 3);
BOOST_CHECK_EQUAL(block->GetHash(), chainman.ActiveChain().Tip()->GetBlockHash());
BOOST_ASSERT(!dmnman.GetListAtChainTip().HasMN(tx_reg_hash));
// Verify db consistency
LOCK(cs_main);
BOOST_ASSERT(CVerifyDB().VerifyDB(::ChainstateActive(), Params(), ::ChainstateActive().CoinsTip(), *(setup.m_node.evodb), 4, 2));
BOOST_ASSERT(CVerifyDB().VerifyDB(chainman.ActiveChainstate(), Params(), chainman.ActiveChainstate().CoinsTip(), *(setup.m_node.evodb), 4, 2));
}
BOOST_AUTO_TEST_SUITE(evo_dip3_activation_tests)

View File

@ -28,6 +28,7 @@
#include <vector>
namespace {
const TestingSetup* g_setup;
const Coin EMPTY_COIN{};
bool operator==(const Coin& a, const Coin& b)
@ -40,6 +41,7 @@ bool operator==(const Coin& a, const Coin& b)
void initialize_coins_view()
{
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
g_setup = testing_setup.get();
}
FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
@ -268,7 +270,7 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
CCoinsStats stats{CoinStatsHashType::HASH_SERIALIZED};
bool expected_code_path = false;
try {
(void)GetUTXOStats(&coins_view_cache, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats);
(void)GetUTXOStats(&coins_view_cache, WITH_LOCK(::cs_main, return std::ref(g_setup->m_node.chainman->m_blockman)), stats);
} catch (const std::logic_error&) {
expected_code_path = true;
}

View File

@ -13,9 +13,14 @@
#include <cstdint>
#include <vector>
namespace {
const TestingSetup* g_setup;
} // namespace
void initialize_load_external_block_file()
{
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
g_setup = testing_setup.get();
}
FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file)
@ -27,5 +32,5 @@ FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file)
return;
}
FlatFilePos flat_file_pos;
::ChainstateActive().LoadExternalBlockFile(fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
}

View File

@ -14,9 +14,14 @@
#include <cstdint>
#include <vector>
namespace {
const TestingSetup* g_setup;
} // namespace
void initialize_validation_load_mempool()
{
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
g_setup = testing_setup.get();
}
FUZZ_TARGET_INIT(validation_load_mempool, initialize_validation_load_mempool)
@ -29,6 +34,6 @@ FUZZ_TARGET_INIT(validation_load_mempool, initialize_validation_load_mempool)
auto fuzzed_fopen = [&](const fs::path&, const char*) {
return fuzzed_file_provider.open();
};
(void)LoadMempool(pool, ::ChainstateActive(), fuzzed_fopen);
(void)LoadMempool(pool, g_setup->m_node.chainman->ActiveChainstate(), fuzzed_fopen);
(void)DumpMempool(pool, fuzzed_fopen, true);
}

View File

@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(findCommonAncestor)
auto* orig_tip = active.Tip();
for (int i = 0; i < 10; ++i) {
BlockValidationState state;
ChainstateActive().InvalidateBlock(state, active.Tip());
m_node.chainman->ActiveChainstate().InvalidateBlock(state, active.Tip());
}
BOOST_CHECK_EQUAL(active.Height(), orig_tip->nHeight - 10);
coinbaseKey.MakeNewKey(true);

View File

@ -52,7 +52,7 @@ BlockAssembler MinerTestingSetup::AssemblerForTest(const CChainParams& params)
options.nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE;
options.blockMinFeeRate = blockMinFeeRate;
return BlockAssembler(::ChainstateActive(), m_node, *m_node.mempool, params, options);
return BlockAssembler(m_node.chainman->ActiveChainstate(), m_node, *m_node.mempool, params, options);
}
constexpr static struct {
@ -92,11 +92,11 @@ constexpr static struct {
};
constexpr static size_t blockinfo_size = sizeof(blockinfo) / sizeof(blockinfo[0]);
static CBlockIndex CreateBlockIndex(int nHeight) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static CBlockIndex CreateBlockIndex(int nHeight, CBlockIndex* active_chain_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
CBlockIndex index;
index.nHeight = nHeight;
index.pprev = ::ChainActive().Tip();
index.pprev = active_chain_tip;
return index;
}
@ -236,21 +236,21 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
std::vector<CTransactionRef> txFirst;
auto createAndProcessEmptyBlock = [&]() {
int i = ::ChainActive().Height() % blockinfo_size;
int i = m_node.chainman->ActiveChain().Height() % blockinfo_size;
CBlock *pblock = &pemptyblocktemplate->block; // pointer for convenience
{
LOCK(cs_main);
pblock->nVersion = 2;
pblock->nTime = ::ChainActive().Tip()->GetMedianTimePast()+1;
pblock->nTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1;
CMutableTransaction txCoinbase(*pblock->vtx[0]);
txCoinbase.nVersion = 1;
txCoinbase.vin[0].scriptSig = CScript() << (::ChainActive().Height() + 1);
txCoinbase.vin[0].scriptSig = CScript() << (m_node.chainman->ActiveChain().Height() + 1);
txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce);
txCoinbase.vin[0].scriptSig.push_back(::ChainActive().Height());
txCoinbase.vin[0].scriptSig.push_back(m_node.chainman->ActiveChain().Height());
txCoinbase.vout[0].scriptPubKey = CScript();
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
if (txFirst.size() == 0)
baseheight = ::ChainActive().Height();
baseheight = m_node.chainman->ActiveChain().Height();
if (txFirst.size() < 4)
txFirst.push_back(pblock->vtx[0]);
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
@ -387,29 +387,29 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
m_node.mempool->clear();
// subsidy changing
// int nHeight = ::ChainActive().Height();
// int nHeight = m_node.chainman->ActiveChain().Height();
// // Create an actual 209999-long block chain (without valid blocks).
// while (::ChainActive().Tip()->nHeight < 209999) {
// CBlockIndex* prev = ::ChainActive().Tip();
// while (m_node.chainman->ActiveChain().Tip()->nHeight < 209999) {
// CBlockIndex* prev = m_node.chainman->ActiveChain().Tip();
// CBlockIndex* next = new CBlockIndex();
// next->phashBlock = new uint256(InsecureRand256());
// pcoinsTip->SetBestBlock(next->GetBlockHash());
// next->pprev = prev;
// next->nHeight = prev->nHeight + 1;
// next->BuildSkip();
// ::ChainActive().SetTip(next);
// m_node.chainman->ActiveChain().SetTip(next);
// }
//BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey));
// // Extend to a 210000-long block chain.
// while (::ChainActive().Tip()->nHeight < 210000) {
// CBlockIndex* prev = ::ChainActive().Tip();
// while (m_node.chainman->ActiveChain().Tip()->nHeight < 210000) {
// CBlockIndex* prev = m_node.chainman->ActiveChain().Tip();
// CBlockIndex* next = new CBlockIndex();
// next->phashBlock = new uint256(InsecureRand256());
// pcoinsTip->SetBestBlock(next->GetBlockHash());
// next->pprev = prev;
// next->nHeight = prev->nHeight + 1;
// next->BuildSkip();
// ::ChainActive().SetTip(next);
// m_node.chainman->ActiveChain().SetTip(next);
// }
//BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey));
@ -432,16 +432,16 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
m_node.mempool->clear();
// // Delete the dummy blocks again.
// while (::ChainActive().Tip()->nHeight > nHeight) {
// CBlockIndex* del = ::ChainActive().Tip();
// ::ChainActive().SetTip(del->pprev);
// ::ChainstateActive().CoinsTip().SetBestBlock(del->pprev->GetBlockHash());
// while (m_node.chainman->ActiveChain().Tip()->nHeight > nHeight) {
// CBlockIndex* del = m_node.chainman->ActiveChain().Tip();
// m_node.chainman->ActiveChain().SetTip(del->pprev);
// m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(del->pprev->GetBlockHash());
// delete del->phashBlock;
// delete del;
// }
// non-final txs in mempool
SetMockTime(::ChainActive().Tip()->GetMedianTimePast()+1);
SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1);
int flags = LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST;
// height map
std::vector<int> prevheights;
@ -453,7 +453,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); // only 1 transaction
tx.vin[0].prevout.n = 0;
tx.vin[0].scriptSig = CScript() << OP_1;
tx.vin[0].nSequence = ::ChainActive().Tip()->nHeight + 1; // txFirst[0] is the 2nd block
tx.vin[0].nSequence = m_node.chainman->ActiveChain().Tip()->nHeight + 1; // txFirst[0] is the 2nd block
prevheights[0] = baseheight + 1;
tx.vout.resize(1);
tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
@ -461,53 +461,62 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.nLockTime = 0;
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
BOOST_CHECK(CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail
BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 2))); // Sequence locks pass on 2nd block
{
CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip();
BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 2, active_chain_tip))); // Sequence locks pass on 2nd block
}
// relative time locked
tx.vin[0].prevout.hash = txFirst[1]->GetHash();
tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((::ChainActive().Tip()->GetMedianTimePast()+1-::ChainActive()[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block
tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1-m_node.chainman->ActiveChain()[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block
prevheights[0] = baseheight + 2;
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx));
BOOST_CHECK(CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime += 512; // Trick the MedianTimePast
BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 1))); // Sequence locks pass 512 seconds later
m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast
{
CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip();
BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 1, active_chain_tip))); // Sequence locks pass 512 seconds later
}
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime -= 512; //undo tricked MTP
m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime -= 512; //undo tricked MTP
// absolute height locked
tx.vin[0].prevout.hash = txFirst[2]->GetHash();
tx.vin[0].nSequence = CTxIn::SEQUENCE_FINAL - 1;
prevheights[0] = baseheight + 3;
tx.nLockTime = ::ChainActive().Tip()->nHeight + 1;
tx.nLockTime = m_node.chainman->ActiveChain().Tip()->nHeight + 1;
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx));
BOOST_CHECK(!CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime fails
BOOST_CHECK(!CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime fails
BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass
BOOST_CHECK(IsFinalTx(CTransaction(tx), ::ChainActive().Tip()->nHeight + 2, ::ChainActive().Tip()->GetMedianTimePast())); // Locktime passes on 2nd block
BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast())); // Locktime passes on 2nd block
// absolute time locked
tx.vin[0].prevout.hash = txFirst[3]->GetHash();
tx.nLockTime = ::ChainActive().Tip()->GetMedianTimePast();
tx.nLockTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast();
prevheights.resize(1);
prevheights[0] = baseheight + 4;
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx));
BOOST_CHECK(!CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime fails
BOOST_CHECK(!CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime fails
BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass
BOOST_CHECK(IsFinalTx(CTransaction(tx), ::ChainActive().Tip()->nHeight + 2, ::ChainActive().Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later
BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later
// mempool-dependent transactions (not added)
tx.vin[0].prevout.hash = hash;
prevheights[0] = ::ChainActive().Tip()->nHeight + 1;
prevheights[0] = m_node.chainman->ActiveChain().Tip()->nHeight + 1;
tx.nLockTime = 0;
tx.vin[0].nSequence = 0;
BOOST_CHECK(CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass
tx.vin[0].nSequence = 1;
BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail
@ -525,7 +534,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3U);
// However if we advance height by 1 and time by 512, all of them should be mined
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast
m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast
} // unlock cs_main while calling createAndProcessEmptyBlock
@ -535,14 +544,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
{
LOCK(cs_main);
SetMockTime(::ChainActive().Tip()->GetMedianTimePast() + 1);
SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1);
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U);
} // unlock cs_main while calling InvalidateBlock
BlockValidationState state;
::ChainstateActive().InvalidateBlock(state, WITH_LOCK(cs_main, return ::ChainActive().Tip()));
m_node.chainman->ActiveChainstate().InvalidateBlock(state, WITH_LOCK(cs_main, return m_node.chainman->ActiveChain().Tip()));
SetMockTime(0);
m_node.mempool->clear();

View File

@ -28,7 +28,7 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
// BlockUntilSyncedToCurrentChain should return false before txindex is started.
BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(txindex.Start(::ChainstateActive()));
BOOST_REQUIRE(txindex.Start(m_node.chainman->ActiveChainstate()));
// Allow tx index to catch up with the block index.
IndexWaitSynced(txindex);

View File

@ -37,7 +37,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
LOCK(cs_main);
unsigned int initialPoolSize = m_node.mempool->size();
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, MakeTransactionRef(coinbaseTx), true /* bypass_limits */);
const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, MakeTransactionRef(coinbaseTx), true /* bypass_limits */);
BOOST_CHECK(result.m_result_type == MempoolAcceptResult::ResultType::INVALID);

View File

@ -27,7 +27,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
const auto ToMemPool = [this](const CMutableTransaction& tx) {
LOCK(cs_main);
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, MakeTransactionRef(tx), true /* bypass_limits */);
const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, MakeTransactionRef(tx), true /* bypass_limits */);
return result.m_result_type == MempoolAcceptResult::ResultType::VALID;
};
@ -58,7 +58,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
block = CreateAndProcessBlock(spends, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() != block.GetHash());
}
// Test 2: ... and should be rejected if spend1 is in the memory pool
@ -66,7 +66,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
block = CreateAndProcessBlock(spends, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() != block.GetHash());
}
m_node.mempool->clear();
@ -75,7 +75,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
block = CreateAndProcessBlock(spends, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() != block.GetHash());
}
m_node.mempool->clear();
@ -86,7 +86,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
block = CreateAndProcessBlock(oneSpend, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash());
BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() == block.GetHash());
}
// spends[1] should have been removed from the mempool when the
// block with spends[0] is accepted:
@ -104,7 +104,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
// should fail.
// Capture this interaction with the upgraded_nop argument: set it when evaluating
// any script flag that is implemented as an upgraded NOP code.
static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t failing_flags, bool add_to_cache) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t failing_flags, bool add_to_cache, CCoinsViewCache& active_coins_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
PrecomputedTransactionData txdata;
@ -122,7 +122,7 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
// script/interpreter.cpp
test_flags |= SCRIPT_VERIFY_P2SH;
}
bool ret = CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, nullptr);
bool ret = CheckInputScripts(tx, state, &active_coins_tip, test_flags, true, add_to_cache, txdata, nullptr);
// CheckInputScripts should succeed iff test_flags doesn't intersect with
// failing_flags
bool expected_return_value = !(test_flags & failing_flags);
@ -132,13 +132,13 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
if (ret && add_to_cache) {
// Check that we get a cache hit if the tx was valid
std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK(CheckInputScripts(tx, state, &active_coins_tip, test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK(scriptchecks.empty());
} else {
// Check that we get script executions to check, if the transaction
// was invalid, or we didn't add to cache.
std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK(CheckInputScripts(tx, state, &active_coins_tip, test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size());
}
}
@ -200,20 +200,20 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
TxValidationState state;
PrecomputedTransactionData ptd_spend_tx;
BOOST_CHECK(!CheckInputScripts(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
BOOST_CHECK(!CheckInputScripts(CTransaction(spend_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
// If we call again asking for scriptchecks (as happens in
// ConnectBlock), we should add a script check object for this -- we're
// not caching invalidity (if that changes, delete this test case).
std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputScripts(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
BOOST_CHECK(CheckInputScripts(CTransaction(spend_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
BOOST_CHECK_EQUAL(scriptchecks.size(), 1U);
// Test that CheckInputScripts returns true iff DERSIG-enforcing flags are
// not present. Don't add these checks to the cache, so that we can
// test later that block validation works fine in the absence of cached
// successes.
ValidateCheckInputsForAllFlags(CTransaction(spend_tx), SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false);
ValidateCheckInputsForAllFlags(CTransaction(spend_tx), SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false, m_node.chainman->ActiveChainstate().CoinsTip());
}
// And if we produce a block with this tx, it should be valid (DERSIG not
@ -222,8 +222,8 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey);
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash());
BOOST_CHECK(::ChainstateActive().CoinsTip().GetBestBlock() == block.GetHash());
BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() == block.GetHash());
BOOST_CHECK(m_node.chainman->ActiveChainstate().CoinsTip().GetBestBlock() == block.GetHash());
// Test P2SH: construct a transaction that is valid without P2SH, and
// then test validity with P2SH.
@ -239,7 +239,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
std::vector<unsigned char> vchSig2(p2pk_scriptPubKey.begin(), p2pk_scriptPubKey.end());
invalid_under_p2sh_tx.vin[0].scriptSig << vchSig2;
ValidateCheckInputsForAllFlags(CTransaction(invalid_under_p2sh_tx), SCRIPT_VERIFY_P2SH, true);
ValidateCheckInputsForAllFlags(CTransaction(invalid_under_p2sh_tx), SCRIPT_VERIFY_P2SH, true, m_node.chainman->ActiveChainstate().CoinsTip());
}
// Test CHECKLOCKTIMEVERIFY
@ -262,13 +262,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
vchSig.push_back((unsigned char)SIGHASH_ALL);
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101;
ValidateCheckInputsForAllFlags(CTransaction(invalid_with_cltv_tx), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true);
ValidateCheckInputsForAllFlags(CTransaction(invalid_with_cltv_tx), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, m_node.chainman->ActiveChainstate().CoinsTip());
// Make it valid, and check again
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
TxValidationState state;
PrecomputedTransactionData txdata;
BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_cltv_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_cltv_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
}
// TEST CHECKSEQUENCEVERIFY
@ -290,13 +290,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
vchSig.push_back((unsigned char)SIGHASH_ALL);
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101;
ValidateCheckInputsForAllFlags(CTransaction(invalid_with_csv_tx), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true);
ValidateCheckInputsForAllFlags(CTransaction(invalid_with_csv_tx), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, m_node.chainman->ActiveChainstate().CoinsTip());
// Make it valid, and check again
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
TxValidationState state;
PrecomputedTransactionData txdata;
BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_csv_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
}
// TODO: add tests for remaining script flags

View File

@ -49,11 +49,11 @@ std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coi
{
assert(node.mempool);
auto block = std::make_shared<CBlock>(
BlockAssembler{::ChainstateActive(), node, *node.mempool, Params()}
BlockAssembler{node.chainman->ActiveChainstate(), node, *node.mempool, Params()}
.CreateNewBlock(coinbase_scriptPubKey)
->block);
block->nTime = ::ChainActive().Tip()->GetMedianTimePast() + 1;
block->nTime = Assert(node.chainman)->ActiveChain().Tip()->GetMedianTimePast() + 1;
block->hashMerkleRoot = BlockMerkleRoot(*block);
return block;

View File

@ -119,7 +119,7 @@ void DashTestSetup(NodeContext& node, const CChainParams& chainparams)
#endif // ENABLE_WALLET
node.llmq_ctx = std::make_unique<LLMQContext>(chainstate, *node.connman, *node.dmnman, *node.evodb, *node.mn_metaman, *node.mnhf_manager, *node.sporkman, *node.mempool,
/* mn_activeman = */ nullptr, *node.mn_sync, node.peerman, /* unit_tests = */ true, /* wipe = */ false);
Assert(node.mnhf_manager)->ConnectManagers(node.chainman, node.llmq_ctx->qman.get());
Assert(node.mnhf_manager)->ConnectManagers(node.chainman.get(), node.llmq_ctx->qman.get());
node.chain_helper = std::make_unique<CChainstateHelper>(*node.cpoolman, *node.dmnman, *node.mnhf_manager, *node.govman, *(node.llmq_ctx->quorum_block_processor), *node.chainman,
chainparams.GetConsensus(), *node.mn_sync, *node.sporkman, *(node.llmq_ctx->clhandler), *(node.llmq_ctx->qman));
}
@ -229,7 +229,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>();
m_node.mempool = std::make_unique<CTxMemPool>(m_node.fee_estimator.get(), 1);
m_node.chainman = &::g_chainman;
m_node.chainman = std::make_unique<ChainstateManager>();
m_node.connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman); // Deterministic randomness for tests.
@ -263,7 +263,7 @@ ChainTestingSetup::~ChainTestingSetup()
m_node.mempool.reset();
m_node.scheduler.reset();
m_node.chainman->Reset();
m_node.chainman = nullptr;
m_node.chainman.reset();
pblocktree.reset();
}
@ -276,12 +276,12 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
RegisterAllCoreRPCCommands(tableRPC);
m_node.chainman->InitializeChainstate(m_node.mempool.get(), *m_node.evodb, m_node.chain_helper, llmq::chainLocksHandler, llmq::quorumInstantSendManager);
::ChainstateActive().InitCoinsDB(
m_node.chainman->ActiveChainstate().InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
assert(!::ChainstateActive().CanFlushToDisk());
::ChainstateActive().InitCoinsCache(1 << 23);
assert(::ChainstateActive().CanFlushToDisk());
if (!::ChainstateActive().LoadGenesisBlock()) {
assert(!m_node.chainman->ActiveChainstate().CanFlushToDisk());
m_node.chainman->ActiveChainstate().InitCoinsCache(1 << 23);
assert(m_node.chainman->ActiveChainstate().CanFlushToDisk());
if (!m_node.chainman->ActiveChainstate().LoadGenesisBlock()) {
throw std::runtime_error("LoadGenesisBlock failed.");
}
@ -299,7 +299,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
DashTestSetup(m_node, chainparams);
BlockValidationState state;
if (!::ChainstateActive().ActivateBestChain(state)) {
if (!m_node.chainman->ActiveChainstate().ActivateBestChain(state)) {
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString()));
}
}
@ -362,7 +362,7 @@ void TestChainSetup::mineBlocks(int num_blocks)
}
g_txindex = std::make_unique<TxIndex>(1 << 20, true);
assert(g_txindex->Start(::ChainstateActive()));
assert(g_txindex->Start(m_node.chainman->ActiveChainstate()));
// Allow tx index to catch up with the block index.
IndexWaitSynced(*g_txindex);
@ -389,7 +389,7 @@ CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns,
{
const CChainParams& chainparams = Params();
CTxMemPool empty_pool;
CBlock block = BlockAssembler(::ChainstateActive(), m_node, empty_pool, chainparams).CreateNewBlock(scriptPubKey)->block;
CBlock block = BlockAssembler(m_node.chainman->ActiveChainstate(), m_node, empty_pool, chainparams).CreateNewBlock(scriptPubKey)->block;
std::vector<CTransactionRef> llmqCommitments;
for (const auto& tx : block.vtx) {
@ -414,10 +414,10 @@ CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns,
auto cbTx = GetTxPayload<CCbTx>(*block.vtx[0]);
BOOST_ASSERT(cbTx.has_value());
BlockValidationState state;
if (!CalcCbTxMerkleRootMNList(block, ::ChainActive().Tip(), cbTx->merkleRootMNList, *m_node.dmnman, state, ::ChainstateActive().CoinsTip())) {
if (!CalcCbTxMerkleRootMNList(block, m_node.chainman->ActiveChain().Tip(), cbTx->merkleRootMNList, *m_node.dmnman, state, m_node.chainman->ActiveChainstate().CoinsTip())) {
BOOST_ASSERT(false);
}
if (!CalcCbTxMerkleRootQuorums(block, ::ChainActive().Tip(), *m_node.llmq_ctx->quorum_block_processor, cbTx->merkleRootQuorums, state)) {
if (!CalcCbTxMerkleRootQuorums(block, m_node.chainman->ActiveChain().Tip(), *m_node.llmq_ctx->quorum_block_processor, cbTx->merkleRootQuorums, state)) {
BOOST_ASSERT(false);
}
CMutableTransaction tmpTx{*block.vtx[0]};
@ -429,7 +429,7 @@ CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns,
{
LOCK(cs_main);
unsigned int extraNonce = 0;
IncrementExtraNonce(&block, ::ChainActive().Tip(), extraNonce);
IncrementExtraNonce(&block, m_node.chainman->ActiveChain().Tip(), extraNonce);
}
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
@ -487,7 +487,7 @@ CMutableTransaction TestChainSetup::CreateValidMempoolTransaction(CTransactionRe
// If submit=true, add transaction to the mempool.
if (submit) {
LOCK(cs_main);
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, MakeTransactionRef(mempool_txn), /* bypass_limits */ false);
const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, MakeTransactionRef(mempool_txn), /* bypass_limits */ false);
assert(result.m_result_type == MempoolAcceptResult::ResultType::VALID);
}
@ -530,14 +530,14 @@ CBlock getBlock13b8a()
TestChainV19Setup::TestChainV19Setup() : TestChainSetup(899)
{
bool v19_just_activated{DeploymentActiveAfter(::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19) &&
!DeploymentActiveAt(*::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
bool v19_just_activated{DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19) &&
!DeploymentActiveAt(*m_node.chainman->ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
assert(v19_just_activated);
}
// 5 blocks earlier
TestChainV19BeforeActivationSetup::TestChainV19BeforeActivationSetup() : TestChainSetup(894)
{
bool v19_active{DeploymentActiveAfter(::ChainActive().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
bool v19_active{DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
assert(!v19_active);
}

View File

@ -71,7 +71,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
static int i = 0;
static uint64_t time = Params().GenesisBlock().nTime;
auto ptemplate = BlockAssembler(::ChainstateActive(), m_node, *m_node.mempool, Params()).CreateNewBlock(CScript{} << i++ << OP_TRUE);
auto ptemplate = BlockAssembler(m_node.chainman->ActiveChainstate(), m_node, *m_node.mempool, Params()).CreateNewBlock(CScript{} << i++ << OP_TRUE);
auto pblock = std::make_shared<CBlock>(ptemplate->block);
pblock->hashPrevBlock = prev_hash;
pblock->nTime = ++time;
@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
const CBlockIndex* initial_tip = nullptr;
{
LOCK(cs_main);
initial_tip = ::ChainActive().Tip();
initial_tip = m_node.chainman->ActiveChain().Tip();
}
auto sub = std::make_shared<TestSubscriber>(initial_tip->GetBlockHash());
RegisterSharedValidationInterface(sub);
@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
UnregisterSharedValidationInterface(sub);
LOCK(cs_main);
BOOST_CHECK_EQUAL(sub->m_expected_tip, ::ChainActive().Tip()->GetBlockHash());
BOOST_CHECK_EQUAL(sub->m_expected_tip, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
/**
@ -238,7 +238,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
// Run the test multiple times
for (int test_runs = 3; test_runs > 0; --test_runs) {
BOOST_CHECK_EQUAL(last_mined->GetHash(), ::ChainActive().Tip()->GetBlockHash());
BOOST_CHECK_EQUAL(last_mined->GetHash(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
// Later on split from here
const uint256 split_hash{last_mined->hashPrevBlock};
@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
{
LOCK(cs_main);
for (const auto& tx : txs) {
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, tx, false /* bypass_limits */);
const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, tx, false /* bypass_limits */);
BOOST_REQUIRE(result.m_result_type == MempoolAcceptResult::ResultType::VALID);
}
}
@ -319,7 +319,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
}
LOCK(cs_main);
// We are done with the reorg, so the tip must have changed
assert(tip_init != ::ChainActive().Tip()->GetBlockHash());
assert(tip_init != m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}};
// Submit the reorg in this thread to invalidate and remove the txs from the tx pool
@ -327,7 +327,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
ProcessBlock(b);
}
// Check that the reorg was eventually successful
BOOST_CHECK_EQUAL(last_mined->GetHash(), ::ChainActive().Tip()->GetBlockHash());
BOOST_CHECK_EQUAL(last_mined->GetHash(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
// We can join the other thread, which returns when the reorg was successful
rpc_thread.join();

View File

@ -752,7 +752,6 @@ void CTxMemPool::removeForReorg(CChainState& active_chainstate, int flags) EXCLU
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
const CTransaction& tx = it->GetTx();
LockPoints lp = it->GetLockPoints();
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
bool validLP = TestLockPointValidity(active_chainstate.m_chain, &lp);
CCoinsViewMemPool view_mempool(&active_chainstate.CoinsTip(), *this);
if (!CheckFinalTx(active_chainstate.m_chain.Tip(), tx, flags)
@ -1064,10 +1063,8 @@ void CTxMemPool::check(CChainState& active_chainstate) const
uint64_t innerUsage = 0;
CCoinsViewCache& active_coins_tip = active_chainstate.CoinsTip();
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(active_coins_tip)); // TODO: REVIEW-ONLY, REMOVE IN FUTURE COMMIT
CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip));
const int64_t spendheight = active_chainstate.m_chain.Height() + 1;
assert(g_chainman.m_blockman.GetSpendHeight(mempoolDuplicate) == spendheight); // TODO: REVIEW-ONLY, REMOVE IN FUTURE COMMIT
std::list<const CTxMemPoolEntry*> waitingOnDependants;
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {

View File

@ -115,21 +115,6 @@ bool CBlockIndexWorkComparator::operator()(const CBlockIndex* pa, const CBlockIn
return false;
}
ChainstateManager g_chainman;
CChainState& ChainstateActive()
{
LOCK(::cs_main);
assert(g_chainman.m_active_chainstate);
return *g_chainman.m_active_chainstate;
}
CChain& ChainActive()
{
LOCK(::cs_main);
return ::ChainstateActive().m_chain;
}
/**
* Mutex to guard access to validation specific variables, such as reading
* or changing the chainstate.
@ -191,7 +176,6 @@ namespace {
CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const
{
AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.BlockIndex()) == std::addressof(m_block_index));
BlockMap::const_iterator it = m_block_index.find(hash);
return it == m_block_index.end() ? nullptr : it->second;
}
@ -200,7 +184,6 @@ CBlockIndex* BlockManager::FindForkInGlobalIndex(const CChain& chain, const CBlo
{
AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(*this));
// Find the latest block common to locator and chain - we expect that
// locator.vHave is sorted descending by height.
for (const uint256& hash : locator.vHave) {
@ -224,7 +207,6 @@ bool CheckFinalTx(const CBlockIndex* active_chain_tip, const CTransaction &tx, i
{
AssertLockHeld(cs_main);
assert(active_chain_tip); // TODO: Make active_chain_tip a reference
assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*active_chain_tip));
// By convention a negative value for flags indicates that the
// current network-enforced consensus rules should be used. In
@ -263,7 +245,6 @@ bool TestLockPointValidity(CChain& active_chain, const LockPoints* lp)
if (lp->maxInputBlock) {
// Check whether ::ChainActive() is an extension of the block at which the LockPoints
// calculation was valid. If not LockPoints are no longer valid
assert(std::addressof(::ChainActive()) == std::addressof(active_chain));
if (!active_chain.Contains(lp->maxInputBlock)) {
return false;
}
@ -417,7 +398,6 @@ static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, siz
std::vector<COutPoint> vNoSpendsRemaining;
pool.TrimToSize(limit, &vNoSpendsRemaining);
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(coins_cache));
for (const COutPoint& removed : vNoSpendsRemaining)
coins_cache.Uncache(removed);
}
@ -425,7 +405,6 @@ static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, siz
static bool IsCurrentForFeeEstimation(CChainState& active_chainstate) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (active_chainstate.IsInitialBlockDownload())
return false;
if (active_chainstate.m_chain.Tip()->GetBlockTime() < count_seconds(GetTime<std::chrono::seconds>() - MAX_FEE_ESTIMATION_TIP_AGE))
@ -443,7 +422,6 @@ void CChainState::MaybeUpdateMempoolForReorg(
AssertLockHeld(cs_main);
AssertLockHeld(m_mempool->cs);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
std::vector<uint256> vHashUpdate;
// disconnectpool's insertion_order index sorts the entries from
// oldest to newest, but the oldest entry will be the last tx from the
@ -514,7 +492,6 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, TxValidationS
assert(txFrom->vout.size() > txin.prevout.n);
assert(txFrom->vout[txin.prevout.n] == coin.out);
} else {
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(coins_tip));
const Coin& coinFromUTXOSet = coins_tip.AccessCoin(txin.prevout);
assert(!coinFromUTXOSet.IsSpent());
assert(coinFromUTXOSet.out == coin.out);
@ -540,7 +517,6 @@ public:
m_limit_ancestor_size(gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000),
m_limit_descendants(gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)),
m_limit_descendant_size(gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000) {
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
}
// We put the arguments we're handed into a struct, so we can pass them
@ -660,7 +636,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
return false; // state filled in by CheckTransaction
}
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
if (!ContextualCheckTransaction(tx, state, chainparams.GetConsensus(), m_active_chainstate.m_chain.Tip()))
return error("%s: ContextualCheckTransaction: %s, %s", __func__, hash.ToString(), state.ToString());
@ -726,7 +701,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
LockPoints lp;
m_view.SetBackend(m_viewmempool);
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
const CCoinsViewCache& coins_cache = m_active_chainstate.CoinsTip();
// do all inputs exist?
for (const CTxIn& txin : tx.vin) {
@ -764,11 +738,9 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// be mined yet.
// Pass in m_view which has all of the relevant inputs cached. Note that, since m_view's
// backend was removed, it no longer pulls coins from the mempool.
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
if (!CheckSequenceLocks(m_active_chainstate.m_chain.Tip(), m_view, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-BIP68-final");
assert(std::addressof(g_chainman.m_blockman) == std::addressof(m_active_chainstate.m_blockman));
if (!Consensus::CheckTxInputs(tx, state, m_view, m_active_chainstate.m_blockman.GetSpendHeight(m_view), ws.m_base_fees)) {
return false; // state filled in by CheckTxInputs
}
@ -794,7 +766,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
}
}
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
entry.reset(new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(),
fSpendsCoinbase, nSigOps, lp));
unsigned int nSize = entry->GetTxSize();
@ -885,9 +856,7 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws, P
// There is a similar check in CreateNewBlock() to prevent creating
// invalid blocks (using TestBlockValidity), however allowing such
// transactions into the mempool can be exploited as a DoS attack.
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(m_active_chainstate.m_chain.Tip(), chainparams.GetConsensus());
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags, txdata, m_active_chainstate.CoinsTip())) {
return error("%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s",
__func__, hash.ToString(), state.ToString());
@ -912,7 +881,6 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
// - the node is not behind
// - the transaction is not dependent on any other transactions in the mempool
// - the transaction is not a zero fee transaction
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
bool validForFeeEstimation = (nModifiedFees != 0) && !bypass_limits && IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
// Store transaction in memory
@ -937,7 +905,6 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
}
if (!bypass_limits) {
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(), gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, std::chrono::hours{gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
if (!m_pool.exists(hash))
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full");
@ -1043,7 +1010,6 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
std::vector<COutPoint> coins_to_uncache;
MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache, test_accept };
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
const MempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptSingleTransaction(tx, args);
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID || test_accept) {
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
@ -1066,7 +1032,6 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
MempoolAcceptResult AcceptToMemoryPool(CChainState& active_chainstate, CTxMemPool& pool, const CTransactionRef &tx, bool bypass_limits, bool test_accept)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
return AcceptToMemoryPoolWithTime(Params(), pool, active_chainstate, tx, GetTime(), bypass_limits, test_accept);
}
@ -1081,7 +1046,6 @@ PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTx
std::vector<COutPoint> coins_to_uncache;
const CChainParams& chainparams = Params();
MemPoolAccept::ATMPArgs args { chainparams, GetTime(), /* bypass_limits */ false, coins_to_uncache, test_accept };
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
const PackageMempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptMultipleTransactions(package, args);
// Uncache coins pertaining to transactions that were not submitted to the mempool.
@ -1417,7 +1381,6 @@ static void AlertNotify(const std::string& strMessage)
void CChainState::CheckForkWarningConditions()
{
AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
// Before we get past initial download, we cannot reliably alert about forks
// (we assume we don't get stuck on a fork before finishing our initial sync)
@ -1436,7 +1399,6 @@ void CChainState::CheckForkWarningConditions()
// Called both upon regular invalid block discovery *and* InvalidateBlock
void CChainState::InvalidChainFound(CBlockIndex* pindexNew)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
statsClient.inc("warnings.InvalidChainFound", 1.0f);
@ -1459,7 +1421,6 @@ void CChainState::InvalidChainFound(CBlockIndex* pindexNew)
void CChainState::ConflictingChainFound(CBlockIndex* pindexNew)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
statsClient.inc("warnings.ConflictingChainFound", 1.0f);
@ -1518,7 +1479,6 @@ bool CScriptCheck::operator()() {
int BlockManager::GetSpendHeight(const CCoinsViewCache& inputs)
{
AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(*this));
CBlockIndex* pindexPrev = LookupBlockIndex(inputs.GetBestBlock());
return pindexPrev->nHeight + 1;
}
@ -2758,7 +2718,6 @@ void CChainState::UpdateTip(const CBlockIndex* pindexNew)
}
bilingual_str warning_messages;
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (!this->IsInitialBlockDownload())
{
const CBlockIndex* pindex = pindexNew;
@ -2775,7 +2734,6 @@ void CChainState::UpdateTip(const CBlockIndex* pindexNew)
}
}
}
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo) evodb_cache=%.1fMiB%s\n", __func__,
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
log(pindexNew->nChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx,
@ -3055,7 +3013,6 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, CBlockIndex
{
AssertLockHeld(cs_main);
if (m_mempool) AssertLockHeld(m_mempool->cs);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
const CBlockIndex* pindexOldTip = m_chain.Tip();
const CBlockIndex* pindexFork = m_chain.FindFork(pindexMostWork);
@ -3155,7 +3112,6 @@ static bool NotifyHeaderTip(CChainState& chainstate) LOCKS_EXCLUDED(cs_main) {
if (pindexHeader != pindexHeaderOld) {
fNotify = true;
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
fInitialBlockDownload = chainstate.IsInitialBlockDownload();
pindexHeaderOld = pindexHeader;
}
@ -3384,7 +3340,6 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind
// transactions back to the mempool if disconnecting was successful,
// and we're not doing a very deep invalidation (in which case
// keeping the mempool up to date is probably futile anyway).
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
MaybeUpdateMempoolForReorg(disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret);
if (!ret) return false;
assert(invalid_walk_tip->pprev == m_chain.Tip());
@ -3473,7 +3428,6 @@ void CChainState::EnforceBlock(BlockValidationState& state, const CBlockIndex *p
AssertLockNotHeld(::cs_main);
LOCK2(m_cs_chainstate, ::cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
const CBlockIndex* pindex_walk = pindex;
@ -3503,7 +3457,6 @@ void CChainState::EnforceBlock(BlockValidationState& state, const CBlockIndex *p
bool CChainState::MarkConflictingBlock(BlockValidationState& state, CBlockIndex *pindex)
{
AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
// We first disconnect backwards and then mark the blocks as conflicting.
@ -3737,7 +3690,6 @@ bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight,
// 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) {
@ -3897,7 +3849,6 @@ CBlockIndex* BlockManager::GetLastCheckpoint(const CCheckpointData& data)
for (const MapCheckpoints::value_type& i : reverse_iterate(checkpoints))
{
const uint256& hash = i.second;
assert(std::addressof(g_chainman.m_blockman) == std::addressof(*this));
CBlockIndex* pindex = LookupBlockIndex(hash);
if (pindex) {
return pindex;
@ -3942,7 +3893,6 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
// Don't accept any forks from the main chain prior to last checkpoint.
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
// BlockIndex().
assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
@ -4157,7 +4107,6 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
// Exposed wrapper for AcceptBlockHeader
bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(ActiveChainstate()));
AssertLockNotHeld(cs_main);
{
LOCK(cs_main);
@ -4253,7 +4202,6 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
// Write block to history file
if (fNewBlock) *fNewBlock = true;
assert(std::addressof(::ChainActive()) == std::addressof(m_chain));
try {
FlatFilePos blockPos = SaveBlockToDisk(block, pindex->nHeight, m_chain, m_params, dbp);
if (blockPos.IsNull()) {
@ -4281,7 +4229,6 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool* fNewBlock)
{
AssertLockNotHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(ActiveChainstate()));
{
CBlockIndex *pindex = nullptr;
@ -4329,7 +4276,6 @@ bool TestBlockValidity(BlockValidationState& state,
bool fCheckMerkleRoot)
{
AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
assert(pindexPrev && pindexPrev == chainstate.m_chain.Tip());
auto bls_legacy_scheme = bls::bls_legacy_scheme.load();
@ -4351,7 +4297,6 @@ bool TestBlockValidity(BlockValidationState& state,
auto dbTx = evoDb.BeginTransaction();
// NOTE: CheckBlockHeader is called by CheckBlock
assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainstate.m_blockman));
if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainparams, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
@ -4460,7 +4405,6 @@ void BlockManager::FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nM
void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeight)
{
BlockValidationState state;
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (!active_chainstate.FlushStateToDisk(state, FlushStateMode::NONE, nManualPruneHeight)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
}
@ -4643,7 +4587,6 @@ void BlockManager::Unload() {
bool CChainState::LoadBlockIndexDB()
{
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (!m_blockman.LoadBlockIndex(
m_params.GetConsensus(), *pblocktree,
setBlockIndexCandidates)) {
@ -4713,7 +4656,6 @@ void CChainState::LoadMempool(const ArgsManager& args)
{
if (!m_mempool) return;
if (args.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
::LoadMempool(*m_mempool, *this);
}
m_mempool->SetIsLoaded(!ShutdownRequested());
@ -4766,7 +4708,6 @@ bool CVerifyDB::VerifyDB(
{
AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr)
return true;
@ -5116,7 +5057,6 @@ bool ChainstateManager::LoadBlockIndex()
bool CChainState::AddGenesisBlock(const CBlock& block, BlockValidationState& state)
{
assert(std::addressof(::ChainActive()) == std::addressof(m_chain));
FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, m_params, nullptr);
if (blockPos.IsNull())
return error("%s: writing genesis block to disk failed (%s)", __func__, state.ToString());
@ -5209,7 +5149,6 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
{
LOCK(cs_main);
// detect out of order blocks, and store them for later
assert(std::addressof(g_chainman.m_blockman) == std::addressof(m_blockman));
if (hash != m_params.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(block.hashPrevBlock)) {
LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
block.hashPrevBlock.ToString());
@ -5219,11 +5158,9 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
}
// process in case the block isn't known yet
assert(std::addressof(g_chainman.m_blockman) == std::addressof(m_blockman));
CBlockIndex* pindex = m_blockman.LookupBlockIndex(hash);
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
BlockValidationState state;
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (AcceptBlock(pblock, state, nullptr, true, dbp, nullptr)) {
nLoaded++;
}
@ -5237,14 +5174,12 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
// Activate the genesis block so normal node progress can continue
if (hash == m_params.GetConsensus().hashGenesisBlock) {
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
BlockValidationState state;
if (!ActivateBestChain(state, nullptr)) {
break;
}
}
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
NotifyHeaderTip(*this);
// Recursively process earlier encountered successors of this block
@ -5261,7 +5196,6 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
LogPrint(BCLog::REINDEX, "%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
head.ToString());
LOCK(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
BlockValidationState dummy;
if (AcceptBlock(pblockrecursive, dummy, nullptr, true, &it->second, nullptr)) {
nLoaded++;
@ -5270,7 +5204,6 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
}
range.first++;
mapBlocksUnknownParent.erase(it);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
NotifyHeaderTip(*this);
}
}
@ -5568,7 +5501,6 @@ bool LoadMempool(CTxMemPool& pool, CChainState& active_chainstate, FopenFn mocka
}
if (nTime > nNow - nExpiryTimeout) {
LOCK(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (AcceptToMemoryPoolWithTime(chainparams, pool, active_chainstate, tx, nTime, false /* bypass_limits */,
false /* test_accept */).m_result_type == MempoolAcceptResult::ResultType::VALID) {
++count;

View File

@ -989,10 +989,6 @@ private:
CAutoFile& coins_file,
const SnapshotMetadata& metadata);
// For access to m_active_chainstate.
friend CChainState& ChainstateActive();
friend CChain& ChainActive();
public:
std::thread m_load_block;
//! A single BlockManager instance is shared across each constructed
@ -1127,17 +1123,14 @@ public:
//! Check to see if caches are out of balance and if so, call
//! ResizeCoinsCaches() as needed.
void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
~ChainstateManager() {
LOCK(::cs_main);
UnloadBlockIndex(/* mempool */ nullptr, *this);
Reset();
}
};
/** DEPRECATED! Please use node.chainman instead. May only be used in validation.cpp internally */
extern ChainstateManager g_chainman GUARDED_BY(::cs_main);
/** Please prefer the identical ChainstateManager::ActiveChainstate */
CChainState& ChainstateActive();
/** Please prefer the identical ChainstateManager::ActiveChain */
CChain& ChainActive();
/** Global variable that points to the active block tree (protected by cs_main) */
extern std::unique_ptr<CBlockTreeDB> pblocktree;

View File

@ -138,10 +138,10 @@ public:
{
LOCK2(wallet->cs_wallet, cs_main);
wallet->GetLegacyScriptPubKeyMan()->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
WalletRescanReserver reserver(*wallet);
reserver.reserve();
CWallet::ScanResult result = wallet->ScanForWalletTransactions(::ChainActive().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, true /* fUpdate */);
CWallet::ScanResult result = wallet->ScanForWalletTransactions(m_node.chainman->ActiveChain().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, true /* fUpdate */);
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
}
}
@ -165,8 +165,8 @@ public:
}
CreateAndProcessBlock({blocktx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
LOCK2(wallet->cs_wallet, cs_main);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 1);
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash(), 1);
it->second.m_confirm = confirm;
return it->second;
}

View File

@ -95,10 +95,10 @@ static void AddKey(CWallet& wallet, const CKey& key)
BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
{
// Cap last block file size, and mine new block in a new block file.
CBlockIndex* oldTip = ::ChainActive().Tip();
CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip();
GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE;
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
CBlockIndex* newTip = ::ChainActive().Tip();
CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip();
// Verify ScanForWalletTransactions fails to read an unknown start block.
{
@ -106,7 +106,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
wallet.SetupLegacyScriptPubKeyMan();
{
LOCK(wallet.cs_wallet);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet);
@ -125,7 +125,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
CWallet wallet(m_node.chain.get(), m_node.coinjoin_loader.get(), "", CreateDummyWalletDatabase());
{
LOCK(wallet.cs_wallet);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet);
@ -151,7 +151,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
CWallet wallet(m_node.chain.get(), m_node.coinjoin_loader.get(), "", CreateDummyWalletDatabase());
{
LOCK(wallet.cs_wallet);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet);
@ -176,7 +176,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
CWallet wallet(m_node.chain.get(), m_node.coinjoin_loader.get(), "", CreateDummyWalletDatabase());
{
LOCK(wallet.cs_wallet);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet);
@ -193,10 +193,10 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
{
// Cap last block file size, and mine new block in a new block file.
CBlockIndex* oldTip = ::ChainActive().Tip();
CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip();
GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE;
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
CBlockIndex* newTip = ::ChainActive().Tip();
CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip();
// Prune the older block file.
{
@ -256,7 +256,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
{
// Create two blocks with same timestamp to verify that importwallet rescan
// will pick up both blocks, not just the first.
const int64_t BLOCK_TIME = ::ChainActive().Tip()->GetBlockTimeMax() + 5;
const int64_t BLOCK_TIME = m_node.chainman->ActiveChain().Tip()->GetBlockTimeMax() + 5;
SetMockTime(BLOCK_TIME);
m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
@ -279,7 +279,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
AddWallet(wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
CoreContext context{m_node};
JSONRPCRequest request(context);
@ -303,7 +303,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
request.params.setArray();
request.params.push_back(backup_file);
AddWallet(wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
::importwallet().HandleRequest(request);
RemoveWallet(wallet, std::nullopt);
@ -406,9 +406,9 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
CWalletTx wtx(&wallet, m_coinbase_txns.back());
LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 0);
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash(), 0);
wtx.m_confirm = confirm;
// Call GetImmatureCredit() once before adding the key to the wallet to
@ -576,17 +576,17 @@ public:
wallet = std::make_unique<CWallet>(m_node.chain.get(), m_node.coinjoin_loader.get(), "", CreateMockWalletDatabase());
{
LOCK(wallet->cs_wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
bool firstRun;
wallet->LoadWallet(firstRun);
AddKey(*wallet, coinbaseKey);
WalletRescanReserver reserver(*wallet);
reserver.reserve();
CWallet::ScanResult result = wallet->ScanForWalletTransactions(::ChainActive().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */);
CWallet::ScanResult result = wallet->ScanForWalletTransactions(m_node.chainman->ActiveChain().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */);
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
BOOST_CHECK_EQUAL(result.last_scanned_block, ::ChainActive().Tip()->GetBlockHash());
BOOST_CHECK_EQUAL(*result.last_scanned_height, ::ChainActive().Height());
BOOST_CHECK_EQUAL(result.last_scanned_block, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
BOOST_CHECK_EQUAL(*result.last_scanned_height, m_node.chainman->ActiveChain().Height());
BOOST_CHECK(result.last_failed_block.IsNull());
}
@ -613,10 +613,10 @@ public:
CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
LOCK(wallet->cs_wallet);
wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, ::ChainActive().Tip()->GetBlockHash());
wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
auto it = wallet->mapWallet.find(tx->GetHash());
BOOST_CHECK(it != wallet->mapWallet.end());
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 1);
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash(), 1);
it->second.m_confirm = confirm;
return it->second;
}
@ -720,9 +720,9 @@ public:
reserver.reserve();
{
LOCK(wallet->cs_wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
CWallet::ScanResult result = wallet->ScanForWalletTransactions(::ChainActive().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */);
CWallet::ScanResult result = wallet->ScanForWalletTransactions(m_node.chainman->ActiveChain().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */);
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
}
@ -822,8 +822,8 @@ public:
LOCK(wallet->cs_wallet);
auto it = wallet->mapWallet.find(tx->GetHash());
BOOST_CHECK(it != wallet->mapWallet.end());
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 1);
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash(), 1);
it->second.m_confirm = confirm;
std::vector<COutPoint> vecOutpoints;
@ -1160,13 +1160,13 @@ BOOST_FIXTURE_TEST_CASE(select_coins_grouped_by_addresses, ListCoinsTestingSetup
CreateAndProcessBlock({CMutableTransaction(*tx2)}, GetScriptForRawPubKey({}));
{
LOCK(wallet->cs_wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}
// Reveal the mined tx, it should conflict with the one we have in the wallet already.
WalletRescanReserver reserver(*wallet);
reserver.reserve();
auto result = wallet->ScanForWalletTransactions(::ChainActive().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */);
auto result = wallet->ScanForWalletTransactions(m_node.chainman->ActiveChain().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */);
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
{
LOCK(wallet->cs_wallet);