Skip to content

Commit

Permalink
fix: should not notify about mnlist changes while ConnectBlock isn't …
Browse files Browse the repository at this point in the history
…done yet
  • Loading branch information
UdjinM6 committed Nov 16, 2023
1 parent 25e5ce6 commit 94749be
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/dsnotificationinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ void CDSNotificationInterface::BlockDisconnected(const std::shared_ptr<const CBl
CCoinJoin::BlockDisconnected(pblock, pindexDisconnected);
}

void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& connman)
void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff)
{
CMNAuth::NotifyMasternodeListChanged(undo, oldMNList, diff, connman);
govman.UpdateCachesAndClean();
Expand Down
2 changes: 1 addition & 1 deletion src/dsnotificationinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class CDSNotificationInterface : public CValidationInterface
void TransactionRemovedFromMempool(const CTransactionRef& ptx, MemPoolRemovalReason reason) override;
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex) override;
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected) override;
void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& connman) override;
void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) override;
void NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig) override;

private:
Expand Down
11 changes: 4 additions & 7 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash)
mnInternalIdMap = mnInternalIdMap.erase(dmn->GetInternalId());
}

bool CDeterministicMNManager::ProcessBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindex, BlockValidationState& state, const CCoinsViewCache& view, bool fJustCheck)
bool CDeterministicMNManager::ProcessBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindex, BlockValidationState& state, const CCoinsViewCache& view, bool fJustCheck, std::optional<MNListUpdates>& updatesRet)
{
AssertLockHeld(cs_main);

Expand Down Expand Up @@ -641,10 +641,8 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, gsl::not_null<co
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "failed-dmn-block");
}

// Don't hold cs while calling signals
if (diff.HasChanges()) {
GetMainSignals().NotifyMasternodeListChanged(false, oldList, diff, connman);
uiInterface.NotifyMasternodeListChanged(newList, pindex);
updatesRet = {newList, oldList, diff};
}

if (nHeight == consensusParams.DIP0003EnforcementHeight) {
Expand All @@ -660,7 +658,7 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, gsl::not_null<co
return true;
}

bool CDeterministicMNManager::UndoBlock(gsl::not_null<const CBlockIndex*> pindex)
bool CDeterministicMNManager::UndoBlock(gsl::not_null<const CBlockIndex*> pindex, std::optional<MNListUpdates>& updatesRet)
{
int nHeight = pindex->nHeight;
uint256 blockHash = pindex->GetBlockHash();
Expand All @@ -684,8 +682,7 @@ bool CDeterministicMNManager::UndoBlock(gsl::not_null<const CBlockIndex*> pindex

if (diff.HasChanges()) {
auto inversedDiff = curList.BuildDiff(prevList);
GetMainSignals().NotifyMasternodeListChanged(true, curList, inversedDiff, connman);
uiInterface.NotifyMasternodeListChanged(prevList, pindex->pprev);
updatesRet = {curList, prevList, inversedDiff};
}

const auto& consensusParams = Params().GetConsensus();
Expand Down
11 changes: 9 additions & 2 deletions src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,13 @@ constexpr int llmq_max_blocks() {
return max_blocks;
}

struct MNListUpdates
{
CDeterministicMNList old_list;
CDeterministicMNList new_list;
CDeterministicMNListDiff diff;
};

class CDeterministicMNManager
{
static constexpr int DISK_SNAPSHOT_PERIOD = 576; // once per day
Expand Down Expand Up @@ -596,8 +603,8 @@ class CDeterministicMNManager
~CDeterministicMNManager() = default;

bool ProcessBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindex, BlockValidationState& state,
const CCoinsViewCache& view, bool fJustCheck) EXCLUSIVE_LOCKS_REQUIRED(cs_main) LOCKS_EXCLUDED(cs);
bool UndoBlock(gsl::not_null<const CBlockIndex*> pindex) LOCKS_EXCLUDED(cs);
const CCoinsViewCache& view, bool fJustCheck, std::optional<MNListUpdates>& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(cs_main) LOCKS_EXCLUDED(cs);
bool UndoBlock(gsl::not_null<const CBlockIndex*> pindex, std::optional<MNListUpdates>& updatesRet) LOCKS_EXCLUDED(cs);

void UpdatedBlockTip(gsl::not_null<const CBlockIndex*> pindex) LOCKS_EXCLUDED(cs);

Expand Down
8 changes: 4 additions & 4 deletions src/evo/specialtxman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex)
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager,
llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler,
const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots,
BlockValidationState& state)
BlockValidationState& state, std::optional<MNListUpdates>& updatesRet)
{
AssertLockHeld(cs_main);

Expand Down Expand Up @@ -181,7 +181,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CM
nTimeQuorum += nTime3 - nTime2;
LogPrint(BCLog::BENCHMARK, " - quorumBlockProcessor: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeQuorum * 0.000001);

if (!deterministicMNManager->ProcessBlock(block, pindex, state, view, fJustCheck)) {
if (!deterministicMNManager->ProcessBlock(block, pindex, state, view, fJustCheck, updatesRet)) {
// pass the state returned by the function above
return false;
}
Expand Down Expand Up @@ -231,7 +231,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CM
return true;
}

bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager, llmq::CQuorumBlockProcessor& quorum_block_processor)
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager, llmq::CQuorumBlockProcessor& quorum_block_processor, std::optional<MNListUpdates>& updatesRet)
{
AssertLockHeld(cs_main);

Expand All @@ -256,7 +256,7 @@ bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHF
return false;
}

if (!deterministicMNManager->UndoBlock(pindex)) {
if (!deterministicMNManager->UndoBlock(pindex, updatesRet)) {
return false;
}

Expand Down
5 changes: 3 additions & 2 deletions src/evo/specialtxman.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class CBlockIndex;
class CCoinsViewCache;
class CMNHFManager;
class TxValidationState;
struct MNListUpdates;
namespace llmq {
class CQuorumBlockProcessor;
class CChainLocksHandler;
Expand All @@ -30,9 +31,9 @@ bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager,
llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CChainLocksHandler& chainlock_handler,
const Consensus::Params& consensusParams, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots,
BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
BlockValidationState& state, std::optional<MNListUpdates>& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CMNHFManager& mnhfManager,
llmq::CQuorumBlockProcessor& quorum_block_processor) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
llmq::CQuorumBlockProcessor& quorum_block_processor, std::optional<MNListUpdates>& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool CheckCreditPoolDiffForBlock(const CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams,
const CAmount blockSubsidy, BlockValidationState& state);

Expand Down
22 changes: 19 additions & 3 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include <masternode/payments.h>
#include <masternode/sync.h>

#include <evo/deterministicmns.h>
#include <evo/evodb.h>
#include <evo/mnhftx.h>
#include <evo/specialtx.h>
Expand Down Expand Up @@ -1731,7 +1732,8 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;

if (!UndoSpecialTxsInBlock(block, pindex, m_mnhfManager, *m_quorum_block_processor)) {
std::optional<MNListUpdates> mnlist_updates_opt{std::nullopt};
if (!UndoSpecialTxsInBlock(block, pindex, m_mnhfManager, *m_quorum_block_processor, mnlist_updates_opt)) {
error("DisconnectBlock(): UndoSpecialTxsInBlock failed");
return DISCONNECT_FAILED;
}
Expand Down Expand Up @@ -1847,6 +1849,12 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
view.SetBestBlock(pindex->pprev->GetBlockHash());
m_evoDb.WriteBestBlock(pindex->pprev->GetBlockHash());

if (mnlist_updates_opt.has_value()) {
auto mnlu = mnlist_updates_opt.value();
GetMainSignals().NotifyMasternodeListChanged(true, mnlu.old_list, mnlu.diff);
uiInterface.NotifyMasternodeListChanged(mnlu.new_list, pindex->pprev);
}

auto finish = Now<SteadyMilliseconds>();
auto diff = finish - start;
statsClient.timing("DisconnectBlock_ms", count_milliseconds(diff), 1.0f);
Expand Down Expand Up @@ -2210,7 +2218,8 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
bool fDIP0001Active_context = pindex->nHeight >= Params().GetConsensus().DIP0001Height;

// MUST process special txes before updating UTXO to ensure consistency between mempool and block processing
if (!ProcessSpecialTxsInBlock(block, pindex, m_mnhfManager, *m_quorum_block_processor, *m_clhandler, m_params.GetConsensus(), view, fJustCheck, fScriptChecks, state)) {
std::optional<MNListUpdates> mnlist_updates_opt{std::nullopt};
if (!ProcessSpecialTxsInBlock(block, pindex, m_mnhfManager, *m_quorum_block_processor, *m_clhandler, m_params.GetConsensus(), view, fJustCheck, fScriptChecks, state, mnlist_updates_opt)) {
return error("ConnectBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s",
pindex->GetBlockHash().ToString(), state.ToString());
}
Expand Down Expand Up @@ -2470,6 +2479,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
view.SetBestBlock(pindex->GetBlockHash());
m_evoDb.WriteBestBlock(pindex->GetBlockHash());

if (mnlist_updates_opt.has_value()) {
auto mnlu = mnlist_updates_opt.value();
GetMainSignals().NotifyMasternodeListChanged(false, mnlu.old_list, mnlu.diff);
uiInterface.NotifyMasternodeListChanged(mnlu.new_list, pindex);
}

int64_t nTime8 = GetTimeMicros(); nTimeCallbacks += nTime8 - nTime5;
LogPrint(BCLog::BENCHMARK, " - Callbacks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime8 - nTime5), nTimeCallbacks * MICRO, nTimeCallbacks * MILLI / nBlocksTotal);

Expand Down Expand Up @@ -4838,7 +4853,8 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i

// MUST process special txes before updating UTXO to ensure consistency between mempool and block processing
BlockValidationState state;
if (!ProcessSpecialTxsInBlock(block, pindex, m_mnhfManager, *m_quorum_block_processor, *m_clhandler, m_params.GetConsensus(), inputs, false /*fJustCheck*/, false /*fScriptChecks*/, state)) {
std::optional<MNListUpdates> mnlist_updates_opt{std::nullopt};
if (!ProcessSpecialTxsInBlock(block, pindex, m_mnhfManager, *m_quorum_block_processor, *m_clhandler, m_params.GetConsensus(), inputs, false /*fJustCheck*/, false /*fScriptChecks*/, state, mnlist_updates_opt)) {
return error("RollforwardBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s",
pindex->GetBlockHash().ToString(), state.ToString());
}
Expand Down
4 changes: 2 additions & 2 deletions src/validationinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ void CMainSignals::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecover
sig->GetHash().ToString());
}

void CMainSignals::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& connman) {
void CMainSignals::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) {
LOG_EVENT("%s: notify mn list changed undo=%d", __func__, undo);
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NotifyMasternodeListChanged(undo, oldMNList, diff, connman); });
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NotifyMasternodeListChanged(undo, oldMNList, diff); });
}
4 changes: 2 additions & 2 deletions src/validationinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class CValidationInterface {
virtual void NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object) {}
virtual void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) {}
virtual void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig) {}
virtual void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& connman) {}
virtual void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) {}
/**
* Notifies listeners of the new active block chain on-disk.
*
Expand Down Expand Up @@ -232,7 +232,7 @@ class CMainSignals {
void NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object);
void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef &currentTx, const CTransactionRef &previousTx);
void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig> &sig);
void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& connman);
void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff);
void ChainStateFlushed(const CBlockLocator &);
void BlockChecked(const CBlock&, const BlockValidationState&);
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&);
Expand Down
1 change: 1 addition & 0 deletions test/lint/lint-circular-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
"llmq/debug -> llmq/dkgsessionhandler -> llmq/dkgsession -> llmq/debug"
"llmq/utils -> validation -> llmq/utils"
"evo/mnhftx -> validation -> evo/mnhftx"
"evo/deterministicmns -> validation -> evo/deterministicmns"
)

EXIT_CODE=0
Expand Down

0 comments on commit 94749be

Please sign in to comment.