mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Fix issues introduced with asynchronous signal handling (#3369)
* Introduce SynchronousUpdatedBlockTip signal This version of UpdatedBlockTip mirrors the asynchronous behavior that we had before the introduction of asynchronous signal handling. * Fix tab spacing in validationinterface.cpp * Invoke CDeterministicMNManager::UpdatedBlockTip from validation thread It must be invoked synchronously as otherwise things become inconsistent. * Call CActiveMasternodeManager::Init with block index pindexNew in UpdatedBlockTip is not necessarily the current tip, so we shouldn't rely on it in Init(). This is due to the async nature of the UpdatedBlockTip invocation.
This commit is contained in:
parent
b188c5c25e
commit
0fa2e14065
@ -24,6 +24,7 @@
|
||||
void CDSNotificationInterface::InitializeCurrentBlockTip()
|
||||
{
|
||||
LOCK(cs_main);
|
||||
SynchronousUpdatedBlockTip(chainActive.Tip(), nullptr, IsInitialBlockDownload());
|
||||
UpdatedBlockTip(chainActive.Tip(), nullptr, IsInitialBlockDownload());
|
||||
}
|
||||
|
||||
@ -38,12 +39,18 @@ void CDSNotificationInterface::NotifyHeaderTip(const CBlockIndex *pindexNew, boo
|
||||
masternodeSync.NotifyHeaderTip(pindexNew, fInitialDownload, connman);
|
||||
}
|
||||
|
||||
void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
|
||||
void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
|
||||
{
|
||||
if (pindexNew == pindexFork) // blocks were disconnected without any new ones
|
||||
return;
|
||||
|
||||
deterministicMNManager->UpdatedBlockTip(pindexNew);
|
||||
}
|
||||
|
||||
void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
|
||||
{
|
||||
if (pindexNew == pindexFork) // blocks were disconnected without any new ones
|
||||
return;
|
||||
|
||||
masternodeSync.UpdatedBlockTip(pindexNew, fInitialDownload, connman);
|
||||
|
||||
|
@ -20,6 +20,7 @@ protected:
|
||||
// CValidationInterface
|
||||
void AcceptedBlockHeader(const CBlockIndex *pindexNew) override;
|
||||
void NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload) override;
|
||||
void SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
|
||||
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
|
||||
void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) override;
|
||||
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted) override;
|
||||
|
@ -829,7 +829,12 @@ void ThreadImport(std::vector<fs::path> vImportFiles)
|
||||
|
||||
if (fMasternodeMode) {
|
||||
assert(activeMasternodeManager);
|
||||
activeMasternodeManager->Init();
|
||||
const CBlockIndex* pindexTip;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindexTip = chainActive.Tip();
|
||||
}
|
||||
activeMasternodeManager->Init(pindexTip);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
|
@ -59,13 +59,13 @@ std::string CActiveMasternodeManager::GetStatus() const
|
||||
}
|
||||
}
|
||||
|
||||
void CActiveMasternodeManager::Init()
|
||||
void CActiveMasternodeManager::Init(const CBlockIndex* pindex)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
if (!fMasternodeMode) return;
|
||||
|
||||
if (!deterministicMNManager->IsDIP3Enforced()) return;
|
||||
if (!deterministicMNManager->IsDIP3Enforced(pindex->nHeight)) return;
|
||||
|
||||
// Check that our local network configuration is correct
|
||||
if (!fListen) {
|
||||
@ -81,7 +81,7 @@ void CActiveMasternodeManager::Init()
|
||||
return;
|
||||
}
|
||||
|
||||
CDeterministicMNList mnList = deterministicMNManager->GetListAtChainTip();
|
||||
CDeterministicMNList mnList = deterministicMNManager->GetListForBlock(pindex);
|
||||
|
||||
CDeterministicMNCPtr dmn = mnList.GetMNByOperatorKey(*activeMasternodeInfo.blsPubKeyOperator);
|
||||
if (!dmn) {
|
||||
@ -148,7 +148,7 @@ void CActiveMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, con
|
||||
activeMasternodeInfo.proTxHash = uint256();
|
||||
activeMasternodeInfo.outpoint.SetNull();
|
||||
// MN might have reappeared in same block with a new ProTx
|
||||
Init();
|
||||
Init(pindexNew);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ void CActiveMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, con
|
||||
activeMasternodeInfo.proTxHash = uint256();
|
||||
activeMasternodeInfo.outpoint.SetNull();
|
||||
// MN might have reappeared in same block with a new ProTx
|
||||
Init();
|
||||
Init(pindexNew);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -169,13 +169,13 @@ void CActiveMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, con
|
||||
state = MASTERNODE_PROTX_IP_CHANGED;
|
||||
activeMasternodeInfo.proTxHash = uint256();
|
||||
activeMasternodeInfo.outpoint.SetNull();
|
||||
Init();
|
||||
Init(pindexNew);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// MN might have (re)appeared with a new ProTx or we've found some peers
|
||||
// and figured out our local address
|
||||
Init();
|
||||
Init(pindexNew);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ private:
|
||||
public:
|
||||
virtual void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload);
|
||||
|
||||
void Init();
|
||||
void Init(const CBlockIndex* pindex);
|
||||
|
||||
std::string GetStateString() const;
|
||||
std::string GetStatus() const;
|
||||
|
@ -2887,6 +2887,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
|
||||
// Notifications/callbacks that can run without cs_main
|
||||
|
||||
// Notify external listeners about the new tip.
|
||||
GetMainSignals().SynchronousUpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
|
||||
GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
|
||||
|
||||
// Always notify the UI if a new block tip was connected
|
||||
@ -3009,6 +3010,7 @@ bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, C
|
||||
}
|
||||
|
||||
InvalidChainFound(pindex);
|
||||
GetMainSignals().SynchronousUpdatedBlockTip(chainActive.Tip(), nullptr, IsInitialBlockDownload());
|
||||
GetMainSignals().UpdatedBlockTip(chainActive.Tip(), nullptr, IsInitialBlockDownload());
|
||||
uiInterface.NotifyBlockTip(IsInitialBlockDownload(), pindex->pprev);
|
||||
return true;
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
struct MainSignalsInstance {
|
||||
boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip;
|
||||
boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> SynchronousUpdatedBlockTip;
|
||||
boost::signals2::signal<void (const CTransactionRef &, int64_t)> TransactionAddedToMempool;
|
||||
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef>&)> BlockConnected;
|
||||
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex* pindexDisconnected)> BlockDisconnected;
|
||||
@ -78,6 +79,7 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
|
||||
g_signals.m_internals->AcceptedBlockHeader.connect(boost::bind(&CValidationInterface::AcceptedBlockHeader, pwalletIn, _1));
|
||||
g_signals.m_internals->NotifyHeaderTip.connect(boost::bind(&CValidationInterface::NotifyHeaderTip, pwalletIn, _1, _2));
|
||||
g_signals.m_internals->UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
|
||||
g_signals.m_internals->SynchronousUpdatedBlockTip.connect(boost::bind(&CValidationInterface::SynchronousUpdatedBlockTip, pwalletIn, _1, _2, _3));
|
||||
g_signals.m_internals->TransactionAddedToMempool.connect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1, _2));
|
||||
g_signals.m_internals->BlockConnected.connect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
|
||||
g_signals.m_internals->BlockDisconnected.connect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1, _2));
|
||||
@ -107,6 +109,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
|
||||
g_signals.m_internals->BlockDisconnected.disconnect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1, _2));
|
||||
g_signals.m_internals->TransactionRemovedFromMempool.disconnect(boost::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
|
||||
g_signals.m_internals->UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
|
||||
g_signals.m_internals->SynchronousUpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::SynchronousUpdatedBlockTip, pwalletIn, _1, _2, _3));
|
||||
g_signals.m_internals->NewPoWValidBlock.disconnect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
|
||||
g_signals.m_internals->NotifyHeaderTip.disconnect(boost::bind(&CValidationInterface::NotifyHeaderTip, pwalletIn, _1, _2));
|
||||
g_signals.m_internals->AcceptedBlockHeader.disconnect(boost::bind(&CValidationInterface::AcceptedBlockHeader, pwalletIn, _1));
|
||||
@ -131,6 +134,7 @@ void UnregisterAllValidationInterfaces() {
|
||||
g_signals.m_internals->BlockDisconnected.disconnect_all_slots();
|
||||
g_signals.m_internals->TransactionRemovedFromMempool.disconnect_all_slots();
|
||||
g_signals.m_internals->UpdatedBlockTip.disconnect_all_slots();
|
||||
g_signals.m_internals->SynchronousUpdatedBlockTip.disconnect_all_slots();
|
||||
g_signals.m_internals->NewPoWValidBlock.disconnect_all_slots();
|
||||
g_signals.m_internals->NotifyHeaderTip.disconnect_all_slots();
|
||||
g_signals.m_internals->AcceptedBlockHeader.disconnect_all_slots();
|
||||
@ -158,6 +162,10 @@ void CMainSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockInd
|
||||
});
|
||||
}
|
||||
|
||||
void CMainSignals::SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
|
||||
m_internals->SynchronousUpdatedBlockTip(pindexNew, pindexFork, fInitialDownload);
|
||||
}
|
||||
|
||||
void CMainSignals::TransactionAddedToMempool(const CTransactionRef &ptx, int64_t nAcceptTime) {
|
||||
m_internals->m_schedulerClient.AddToProcessQueue([ptx, nAcceptTime, this] {
|
||||
m_internals->TransactionAddedToMempool(ptx, nAcceptTime);
|
||||
@ -205,29 +213,29 @@ void CMainSignals::AcceptedBlockHeader(const CBlockIndex *pindexNew) {
|
||||
}
|
||||
|
||||
void CMainSignals::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload) {
|
||||
m_internals->NotifyHeaderTip(pindexNew, fInitialDownload);
|
||||
m_internals->NotifyHeaderTip(pindexNew, fInitialDownload);
|
||||
}
|
||||
|
||||
void CMainSignals::NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock& islock) {
|
||||
m_internals->NotifyTransactionLock(tx, islock);
|
||||
m_internals->NotifyTransactionLock(tx, islock);
|
||||
}
|
||||
|
||||
void CMainSignals::NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLockSig& clsig) {
|
||||
m_internals->NotifyChainLock(pindex, clsig);
|
||||
m_internals->NotifyChainLock(pindex, clsig);
|
||||
}
|
||||
|
||||
void CMainSignals::NotifyGovernanceVote(const CGovernanceVote &vote) {
|
||||
m_internals->NotifyGovernanceVote(vote);
|
||||
m_internals->NotifyGovernanceVote(vote);
|
||||
}
|
||||
|
||||
void CMainSignals::NotifyGovernanceObject(const CGovernanceObject &object) {
|
||||
m_internals->NotifyGovernanceObject(object);
|
||||
m_internals->NotifyGovernanceObject(object);
|
||||
}
|
||||
|
||||
void CMainSignals::NotifyInstantSendDoubleSpendAttempt(const CTransaction ¤tTx, const CTransaction &previousTx) {
|
||||
m_internals->NotifyInstantSendDoubleSpendAttempt(currentTx, previousTx);
|
||||
m_internals->NotifyInstantSendDoubleSpendAttempt(currentTx, previousTx);
|
||||
}
|
||||
|
||||
void CMainSignals::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) {
|
||||
m_internals->NotifyMasternodeListChanged(undo, oldMNList, diff);
|
||||
m_internals->NotifyMasternodeListChanged(undo, oldMNList, diff);
|
||||
}
|
@ -61,6 +61,10 @@ protected:
|
||||
* Called on a background thread.
|
||||
*/
|
||||
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {}
|
||||
/**
|
||||
* Same as UpdatedBlockTip, but called from the caller's thread
|
||||
*/
|
||||
virtual void SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {}
|
||||
/**
|
||||
* Notifies listeners of a transaction having been added to mempool.
|
||||
*
|
||||
@ -155,6 +159,7 @@ public:
|
||||
void AcceptedBlockHeader(const CBlockIndex *pindexNew);
|
||||
void NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload);
|
||||
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
|
||||
void SynchronousUpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
|
||||
void TransactionAddedToMempool(const CTransactionRef &, int64_t);
|
||||
void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>> &);
|
||||
void BlockDisconnected(const std::shared_ptr<const CBlock> &, const CBlockIndex* pindexDisconnected);
|
||||
|
Loading…
Reference in New Issue
Block a user