From 9f6bb539359b98d5b39482ab8a28a68608f0c645 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Sat, 12 Jun 2021 10:52:40 -0400 Subject: [PATCH] validation: add chainman ref to CChainState Add an upwards reference to chainstate instances to the owning ChainstateManager. This is necessary because there are a number of `this_chainstate == chainman.ActiveChainstate()` checks that will happen (as a result of assumeutxo) in functions that otherwise don't have an easily-accessible reference to the chainstate's ChainManager. --- src/test/validation_flush_tests.cpp | 4 ++-- src/validation.cpp | 14 ++++++++++---- src/validation.h | 6 ++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/test/validation_flush_tests.cpp b/src/test/validation_flush_tests.cpp index 22aafcaa6c..9136c497ea 100644 --- a/src/test/validation_flush_tests.cpp +++ b/src/test/validation_flush_tests.cpp @@ -9,7 +9,7 @@ #include -BOOST_FIXTURE_TEST_SUITE(validation_flush_tests, BasicTestingSetup) +BOOST_FIXTURE_TEST_SUITE(validation_flush_tests, ChainTestingSetup) //! Test utilities for detecting when we need to flush the coins cache based //! on estimated memory usage. @@ -20,7 +20,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate) { CTxMemPool mempool; BlockManager blockman{}; - CChainState chainstate{&mempool, blockman}; + CChainState chainstate{&mempool, blockman, *Assert(m_node.chainman)}; chainstate.InitCoinsDB(/*cache_size_bytes*/ 1 << 10, /*in_memory*/ true, /*should_wipe*/ false); WITH_LOCK(::cs_main, chainstate.InitCoinsCache(1 << 10)); diff --git a/src/validation.cpp b/src/validation.cpp index 26333d7026..756e2ba905 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1209,10 +1209,15 @@ void CoinsViews::InitCache() m_cacheview = std::make_unique(&m_catcherview); } -CChainState::CChainState(CTxMemPool* mempool, BlockManager& blockman, std::optional from_snapshot_blockhash) +CChainState::CChainState( + CTxMemPool* mempool, + BlockManager& blockman, + ChainstateManager& chainman, + std::optional from_snapshot_blockhash) : m_mempool(mempool), m_params(::Params()), m_blockman(blockman), + m_chainman(chainman), m_from_snapshot_blockhash(from_snapshot_blockhash) {} void CChainState::InitCoinsDB( @@ -4699,7 +4704,7 @@ CChainState& ChainstateManager::InitializeChainstate( if (to_modify) { throw std::logic_error("should not be overwriting a chainstate"); } - to_modify.reset(new CChainState(mempool, m_blockman, snapshot_blockhash)); + to_modify.reset(new CChainState(mempool, m_blockman, *this, snapshot_blockhash)); // Snapshot chainstates and initial IBD chaintates always become active. if (is_snapshot || (!is_snapshot && !m_active_chainstate)) { @@ -4768,8 +4773,9 @@ bool ChainstateManager::ActivateSnapshot( static_cast(current_coinsdb_cache_size * IBD_CACHE_PERC)); } - auto snapshot_chainstate = WITH_LOCK(::cs_main, return std::make_unique( - /* mempool */ nullptr, m_blockman, base_blockhash)); + auto snapshot_chainstate = WITH_LOCK(::cs_main, + return std::make_unique( + /* mempool */ nullptr, m_blockman, *this, base_blockhash)); { LOCK(::cs_main); diff --git a/src/validation.h b/src/validation.h index 9a2be3ad97..b024699fe8 100644 --- a/src/validation.h +++ b/src/validation.h @@ -601,9 +601,15 @@ public: //! CChainState instances. BlockManager& m_blockman; + //! The chainstate manager that owns this chainstate. The reference is + //! necessary so that this instance can check whether it is the active + //! chainstate within deeply nested method calls. + ChainstateManager& m_chainman; + explicit CChainState( CTxMemPool* mempool, BlockManager& blockman, + ChainstateManager& chainman, std::optional from_snapshot_blockhash = std::nullopt); /**