Skip to content

Commit

Permalink
refactor: reduce usage of chainstate globals in Dash-specific logic (#…
Browse files Browse the repository at this point in the history
…5531)

Co-authored-by: Kittywhiskers Van Gogh <[email protected]>
  • Loading branch information
kwvg and kwvg authored Aug 23, 2023
1 parent 3443630 commit 96d0ce2
Show file tree
Hide file tree
Showing 23 changed files with 209 additions and 160 deletions.
4 changes: 2 additions & 2 deletions src/coinjoin/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ void CCoinJoinServer::CommitFinalTransaction()
TRY_LOCK(cs_main, lockMain);
TxValidationState validationState;
mempool.PrioritiseTransaction(hashTx, 0.1 * COIN);
if (!lockMain || !AcceptToMemoryPool(::ChainstateActive(), mempool, validationState, finalTransaction, false /* bypass_limits */, DEFAULT_MAX_RAW_TX_FEE /* nAbsurdFee */)) {
if (!lockMain || !AcceptToMemoryPool(m_chainstate, mempool, validationState, finalTransaction, false /* bypass_limits */, DEFAULT_MAX_RAW_TX_FEE /* nAbsurdFee */)) {
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CommitFinalTransaction -- AcceptToMemoryPool() error: Transaction not valid\n");
WITH_LOCK(cs_coinjoin, SetNull());
// not much we can do in this case, just notify clients
Expand Down Expand Up @@ -455,7 +455,7 @@ void CCoinJoinServer::ConsumeCollateral(const CTransactionRef& txref) const
{
LOCK(cs_main);
TxValidationState validationState;
if (!AcceptToMemoryPool(::ChainstateActive(), mempool, validationState, txref, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
if (!AcceptToMemoryPool(m_chainstate, mempool, validationState, txref, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
LogPrint(BCLog::COINJOIN, "%s -- AcceptToMemoryPool failed\n", __func__);
} else {
connman.RelayTransaction(*txref);
Expand Down
9 changes: 6 additions & 3 deletions src/coinjoin/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <coinjoin/coinjoin.h>
#include <net.h>

class CChainState;
class CCoinJoinServer;
class CTxMemPool;
class PeerManager;
Expand All @@ -22,8 +23,9 @@ extern std::unique_ptr<CCoinJoinServer> coinJoinServer;
class CCoinJoinServer : public CCoinJoinBaseSession, public CCoinJoinBaseManager
{
private:
CTxMemPool& mempool;
CChainState& m_chainstate;
CConnman& connman;
CTxMemPool& mempool;
const CMasternodeSync& m_mn_sync;

// Mixing uses collateral transactions to trust parties entering the pool
Expand Down Expand Up @@ -79,9 +81,10 @@ class CCoinJoinServer : public CCoinJoinBaseSession, public CCoinJoinBaseManager
void SetNull() EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin);

public:
explicit CCoinJoinServer(CTxMemPool& mempool, CConnman& _connman, const CMasternodeSync& mn_sync) :
mempool(mempool),
explicit CCoinJoinServer(CChainState& chainstate, CConnman& _connman, CTxMemPool& mempool, const CMasternodeSync& mn_sync) :
m_chainstate(chainstate),
connman(_connman),
mempool(mempool),
m_mn_sync(mn_sync),
vecSessionCollaterals(),
fUnitTest(false)
Expand Down
32 changes: 16 additions & 16 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded()

LogPrintf("CDeterministicMNManager::%s -- upgrading DB to migrate MN type\n", __func__);

if (::ChainActive().Tip() == nullptr) {
if (m_chainstate.m_chain.Tip() == nullptr) {
// should have no records
LogPrintf("CDeterministicMNManager::%s -- Chain empty. evoDB:%d.\n", __func__, m_evoDb.IsEmpty());
return m_evoDb.IsEmpty();
Expand All @@ -1203,7 +1203,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded()
return true;
}

if (::ChainActive().Tip()->pprev != nullptr && llmq::utils::IsV19Active(::ChainActive().Tip()->pprev)) {
if (m_chainstate.m_chain.Tip()->pprev != nullptr && llmq::utils::IsV19Active(m_chainstate.m_chain.Tip()->pprev)) {
// too late
LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__);
return false;
Expand All @@ -1212,25 +1212,25 @@ bool CDeterministicMNManager::MigrateDBIfNeeded()
// Removing the old EVODB_BEST_BLOCK value early results in older version to crash immediately, even if the upgrade
// process is cancelled in-between. But if the new version sees that the old EVODB_BEST_BLOCK is already removed,
// then we must assume that the upgrade process was already running before but was interrupted.
if (::ChainActive().Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) {
if (m_chainstate.m_chain.Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) {
LogPrintf("CDeterministicMNManager::%s -- previous migration attempt failed.\n", __func__);
return false;
}
m_evoDb.GetRawDB().Erase(DB_OLD_BEST_BLOCK);

if (::ChainActive().Height() < Params().GetConsensus().DIP0003Height) {
if (m_chainstate.m_chain.Height() < Params().GetConsensus().DIP0003Height) {
// not reached DIP3 height yet, so no upgrade needed
LogPrintf("CDeterministicMNManager::%s -- migration not needed. dip3 not reached\n", __func__);
auto dbTx = m_evoDb.BeginTransaction();
m_evoDb.WriteBestBlock(::ChainActive().Tip()->GetBlockHash());
m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash());
dbTx->Commit();
return true;
}

CDBBatch batch(m_evoDb.GetRawDB());

for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, ::ChainActive().Height() + 1)) {
auto pindex = ::ChainActive()[nHeight];
for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, m_chainstate.m_chain.Height() + 1)) {
auto pindex = m_chainstate.m_chain[nHeight];
// Unserialise CDeterministicMNListDiff using MN_OLD_FORMAT and set it's type to the default value TYPE_REGULAR_MASTERNODE
// It will be later written with format MN_CURRENT_FORMAT which includes the type field and MN state bls version.
CDataStream diff_data(SER_DISK, CLIENT_VERSION);
Expand Down Expand Up @@ -1258,7 +1258,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded()

// Writing EVODB_BEST_BLOCK (which is b_b4 now) marks the DB as upgraded
auto dbTx = m_evoDb.BeginTransaction();
m_evoDb.WriteBestBlock(::ChainActive().Tip()->GetBlockHash());
m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash());
dbTx->Commit();

LogPrintf("CDeterministicMNManager::%s -- done migrating\n", __func__);
Expand Down Expand Up @@ -1291,7 +1291,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2()

LogPrintf("CDeterministicMNManager::%s -- upgrading DB to migrate MN state bls version\n", __func__);

if (::ChainActive().Tip() == nullptr) {
if (m_chainstate.m_chain.Tip() == nullptr) {
// should have no records
LogPrintf("CDeterministicMNManager::%s -- Chain empty. evoDB:%d.\n", __func__, m_evoDb.IsEmpty());
return m_evoDb.IsEmpty();
Expand All @@ -1302,7 +1302,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2()
return true;
}

if (::ChainActive().Tip()->pprev != nullptr && llmq::utils::IsV19Active(::ChainActive().Tip()->pprev)) {
if (m_chainstate.m_chain.Tip()->pprev != nullptr && llmq::utils::IsV19Active(m_chainstate.m_chain.Tip()->pprev)) {
// too late
LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__);
return false;
Expand All @@ -1311,25 +1311,25 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2()
// Removing the old EVODB_BEST_BLOCK value early results in older version to crash immediately, even if the upgrade
// process is cancelled in-between. But if the new version sees that the old EVODB_BEST_BLOCK is already removed,
// then we must assume that the upgrade process was already running before but was interrupted.
if (::ChainActive().Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) {
if (m_chainstate.m_chain.Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) {
LogPrintf("CDeterministicMNManager::%s -- previous migration attempt failed.\n", __func__);
return false;
}
m_evoDb.GetRawDB().Erase(DB_OLD_BEST_BLOCK);

if (::ChainActive().Height() < Params().GetConsensus().DIP0003Height) {
if (m_chainstate.m_chain.Height() < Params().GetConsensus().DIP0003Height) {
// not reached DIP3 height yet, so no upgrade needed
LogPrintf("CDeterministicMNManager::%s -- migration not needed. dip3 not reached\n", __func__);
auto dbTx = m_evoDb.BeginTransaction();
m_evoDb.WriteBestBlock(::ChainActive().Tip()->GetBlockHash());
m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash());
dbTx->Commit();
return true;
}

CDBBatch batch(m_evoDb.GetRawDB());

for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, ::ChainActive().Height() + 1)) {
auto pindex = ::ChainActive()[nHeight];
for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, m_chainstate.m_chain.Height() + 1)) {
auto pindex = m_chainstate.m_chain[nHeight];
// Unserialise CDeterministicMNListDiff using MN_TYPE_FORMAT and set MN state bls version to LEGACY_BLS_VERSION.
// It will be later written with format MN_CURRENT_FORMAT which includes the type field.
CDataStream diff_data(SER_DISK, CLIENT_VERSION);
Expand Down Expand Up @@ -1357,7 +1357,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2()

// Writing EVODB_BEST_BLOCK (which is b_b4 now) marks the DB as upgraded
auto dbTx = m_evoDb.BeginTransaction();
m_evoDb.WriteBestBlock(::ChainActive().Tip()->GetBlockHash());
m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash());
dbTx->Commit();

LogPrintf("CDeterministicMNManager::%s -- done migrating\n", __func__);
Expand Down
10 changes: 6 additions & 4 deletions src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
#include <unordered_map>
#include <utility>

class CConnman;
class CBlock;
class CBlockIndex;
class CChainState;
class CConnman;
class TxValidationState;

extern RecursiveMutex cs_main;
Expand Down Expand Up @@ -583,17 +584,18 @@ class CDeterministicMNManager
// Main thread has indicated we should perform cleanup up to this height
std::atomic<int> to_cleanup {0};

CEvoDB& m_evoDb;
CChainState& m_chainstate;
CConnman& connman;
CEvoDB& m_evoDb;

std::unordered_map<uint256, CDeterministicMNList, StaticSaltedHasher> mnListsCache GUARDED_BY(cs);
std::unordered_map<uint256, CDeterministicMNListDiff, StaticSaltedHasher> mnListDiffsCache GUARDED_BY(cs);
const CBlockIndex* tipIndex GUARDED_BY(cs) {nullptr};
const CBlockIndex* m_initial_snapshot_index GUARDED_BY(cs) {nullptr};

public:
explicit CDeterministicMNManager(CEvoDB& evoDb, CConnman& _connman) :
m_evoDb(evoDb), connman(_connman) {}
explicit CDeterministicMNManager(CChainState& chainstate, CConnman& _connman, CEvoDB& evoDb) :
m_chainstate(chainstate), connman(_connman), m_evoDb(evoDb) {}
~CDeterministicMNManager() = default;

bool ProcessBlock(const CBlock& block, const CBlockIndex* pindex, BlockValidationState& state,
Expand Down
7 changes: 4 additions & 3 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1937,12 +1937,13 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc

// Same logic as above with pblocktree
deterministicMNManager.reset();
deterministicMNManager.reset(new CDeterministicMNManager(*node.evodb, *node.connman));
deterministicMNManager.reset(new CDeterministicMNManager(chainman.ActiveChainstate(), *node.connman, *node.evodb));
creditPoolManager.reset();
creditPoolManager.reset(new CCreditPoolManager(*node.evodb));
llmq::quorumSnapshotManager.reset();
llmq::quorumSnapshotManager.reset(new llmq::CQuorumSnapshotManager(*node.evodb));
node.llmq_ctx.reset();
node.llmq_ctx.reset(new LLMQContext(*node.evodb, *node.mempool, *node.connman, *::sporkManager, node.peerman, false, fReset || fReindexChainState));
node.llmq_ctx.reset(new LLMQContext(chainman.ActiveChainstate(), *node.connman, *node.evodb, *::sporkManager, *node.mempool, node.peerman, false, fReset || fReindexChainState));

if (fReset) {
pblocktree->WriteReindexing(true);
Expand Down Expand Up @@ -2248,7 +2249,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc

// ********************************************************* Step 10a: Setup CoinJoin

::coinJoinServer = std::make_unique<CCoinJoinServer>(*node.mempool, *node.connman, *::masternodeSync);
::coinJoinServer = std::make_unique<CCoinJoinServer>(chainman.ActiveChainstate(), *node.connman, *node.mempool, *::masternodeSync);
#ifdef ENABLE_WALLET
if (!ignores_incoming_txs) {
::coinJoinClientQueueManager = std::make_unique<CCoinJoinClientQueueManager>(*node.connman, *::masternodeSync);
Expand Down
36 changes: 18 additions & 18 deletions src/llmq/blockprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT_Q_INDEXED = "q_m

static const std::string DB_BEST_BLOCK_UPGRADE = "q_bbu2";

CQuorumBlockProcessor::CQuorumBlockProcessor(CEvoDB& evoDb, CConnman& _connman, const std::unique_ptr<PeerManager>& peerman) :
m_evoDb(evoDb), connman(_connman), m_peerman(peerman)
CQuorumBlockProcessor::CQuorumBlockProcessor(CChainState& chainstate, CConnman& _connman, CEvoDB& evoDb, const std::unique_ptr<PeerManager>& peerman) :
m_chainstate(chainstate), connman(_connman), m_evoDb(evoDb), m_peerman(peerman)
{
utils::InitQuorumsCache(mapHasMinedCommitmentCache);
}
Expand Down Expand Up @@ -82,15 +82,15 @@ void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view m
const CBlockIndex* pQuorumBaseBlockIndex;
{
LOCK(cs_main);
pQuorumBaseBlockIndex = g_chainman.m_blockman.LookupBlockIndex(qc.quorumHash);
pQuorumBaseBlockIndex = m_chainstate.m_blockman.LookupBlockIndex(qc.quorumHash);
if (pQuorumBaseBlockIndex == nullptr) {
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- unknown block %s in commitment, peer=%d\n", __func__,
qc.quorumHash.ToString(), peer.GetId());
// can't really punish the node here, as we might simply be the one that is on the wrong chain or not
// fully synced
return;
}
if (::ChainActive().Tip()->GetAncestor(pQuorumBaseBlockIndex->nHeight) != pQuorumBaseBlockIndex) {
if (m_chainstate.m_chain.Tip()->GetAncestor(pQuorumBaseBlockIndex->nHeight) != pQuorumBaseBlockIndex) {
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s not in active chain, peer=%d\n", __func__,
qc.quorumHash.ToString(), peer.GetId());
// same, can't punish
Expand All @@ -103,7 +103,7 @@ void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view m
m_peerman->Misbehaving(peer.GetId(), 100);
return;
}
if (pQuorumBaseBlockIndex->nHeight < (::ChainActive().Height() - llmq_params_opt->dkgInterval)) {
if (pQuorumBaseBlockIndex->nHeight < (m_chainstate.m_chain.Height() - llmq_params_opt->dkgInterval)) {
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s is too old, peer=%d\n", __func__,
qc.quorumHash.ToString(), peer.GetId());
// TODO: enable punishment in some future version when all/most nodes are running with this fix
Expand Down Expand Up @@ -171,7 +171,7 @@ bool CQuorumBlockProcessor::ProcessBlock(const CBlock& block, const CBlockIndex*
// Note: must only check quorums that were enabled at the _previous_ block height to match mining logic
for (const Consensus::LLMQParams& params : utils::GetEnabledQuorumParams(pindex->pprev)) {
// skip these checks when replaying blocks after the crash
if (::ChainActive().Tip() == nullptr) {
if (m_chainstate.m_chain.Tip() == nullptr) {
break;
}

Expand Down Expand Up @@ -234,7 +234,7 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH
nHeight, ToUnderlying(qc.llmqType), qc.quorumIndex, quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers(), qc.quorumPublicKey.ToString(), fJustCheck);

// skip `bad-qc-block` checks below when replaying blocks after the crash
if (::ChainActive().Tip() == nullptr) {
if (m_chainstate.m_chain.Tip() == nullptr) {
quorumHash = qc.quorumHash;
}

Expand Down Expand Up @@ -268,7 +268,7 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-height");
}

const auto* pQuorumBaseBlockIndex = g_chainman.m_blockman.LookupBlockIndex(qc.quorumHash);
const auto* pQuorumBaseBlockIndex = m_chainstate.m_blockman.LookupBlockIndex(qc.quorumHash);

if (!qc.Verify(pQuorumBaseBlockIndex, fBLSChecks)) {
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s height=%d, type=%d, quorumIndex=%d, quorumHash=%s, signers=%s, validMembers=%d, quorumPublicKey=%s qc verify failed.\n", __func__,
Expand Down Expand Up @@ -358,20 +358,20 @@ bool CQuorumBlockProcessor::UpgradeDB()
{
LOCK(cs_main);

if (::ChainActive().Tip() == nullptr) {
if (m_chainstate.m_chain.Tip() == nullptr) {
// should have no records
return m_evoDb.IsEmpty();
}

uint256 bestBlock;
if (m_evoDb.GetRawDB().Read(DB_BEST_BLOCK_UPGRADE, bestBlock) && bestBlock == ::ChainActive().Tip()->GetBlockHash()) {
if (m_evoDb.GetRawDB().Read(DB_BEST_BLOCK_UPGRADE, bestBlock) && bestBlock == m_chainstate.m_chain.Tip()->GetBlockHash()) {
return true;
}

LogPrintf("CQuorumBlockProcessor::%s -- Upgrading DB...\n", __func__);

if (::ChainActive().Height() >= Params().GetConsensus().DIP0003EnforcementHeight) {
const auto* pindex = ::ChainActive()[Params().GetConsensus().DIP0003EnforcementHeight];
if (m_chainstate.m_chain.Height() >= Params().GetConsensus().DIP0003EnforcementHeight) {
const auto* pindex = m_chainstate.m_chain[Params().GetConsensus().DIP0003EnforcementHeight];
while (pindex != nullptr) {
if (fPruneMode && ((pindex->nStatus & BLOCK_HAVE_DATA) == 0)) {
// Too late, we already pruned blocks we needed to reprocess commitments
Expand All @@ -390,7 +390,7 @@ bool CQuorumBlockProcessor::UpgradeDB()
if (qc.IsNull()) {
continue;
}
const auto* pQuorumBaseBlockIndex = g_chainman.m_blockman.LookupBlockIndex(qc.quorumHash);
const auto* pQuorumBaseBlockIndex = m_chainstate.m_blockman.LookupBlockIndex(qc.quorumHash);
m_evoDb.GetRawDB().Write(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(qc.llmqType, qc.quorumHash)), std::make_pair(qc, pindex->GetBlockHash()));
const auto& llmq_params_opt = GetLLMQParams(qc.llmqType);
assert(llmq_params_opt.has_value());
Expand All @@ -403,7 +403,7 @@ bool CQuorumBlockProcessor::UpgradeDB()

m_evoDb.GetRawDB().Write(DB_BEST_BLOCK_UPGRADE, pindex->GetBlockHash());

pindex = ::ChainActive().Next(pindex);
pindex = m_chainstate.m_chain.Next(pindex);
}
}

Expand Down Expand Up @@ -479,8 +479,8 @@ size_t CQuorumBlockProcessor::GetNumCommitmentsRequired(const Consensus::LLMQPar
if (!IsMiningPhase(llmqParams, nHeight)) return 0;

// Note: This function can be called for new blocks
assert(nHeight <= ::ChainActive().Height() + 1);
const auto *const pindex = ::ChainActive().Height() < nHeight ? ::ChainActive().Tip() : ::ChainActive().Tip()->GetAncestor(nHeight);
assert(nHeight <= m_chainstate.m_chain.Height() + 1);
const auto *const pindex = m_chainstate.m_chain.Height() < nHeight ? m_chainstate.m_chain.Tip() : m_chainstate.m_chain.Tip()->GetAncestor(nHeight);

bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams, pindex);
size_t quorums_num = rotation_enabled ? llmqParams.signingActiveQuorumCount : 1;
Expand Down Expand Up @@ -763,8 +763,8 @@ std::optional<std::vector<CFinalCommitment>> CQuorumBlockProcessor::GetMineableC
}

// Note: This function can be called for new blocks
assert(nHeight <= ::ChainActive().Height() + 1);
const auto *const pindex = ::ChainActive().Height() < nHeight ? ::ChainActive().Tip() : ::ChainActive().Tip()->GetAncestor(nHeight);
assert(nHeight <= m_chainstate.m_chain.Height() + 1);
const auto *const pindex = m_chainstate.m_chain.Height() < nHeight ? m_chainstate.m_chain.Tip() : m_chainstate.m_chain.Tip()->GetAncestor(nHeight);

bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams, pindex);
bool basic_bls_enabled = utils::IsV19Active(pindex);
Expand Down
Loading

0 comments on commit 96d0ce2

Please sign in to comment.