Merge pull request #2849 from codablock/pr_dip3_notifymnlistchanged

Refactor and fix missing calls to NotifyMasternodeListChanged
This commit is contained in:
Alexander Block 2019-04-10 18:16:19 +02:00 committed by GitHub
commit 6fd9e51059
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 46 additions and 26 deletions

View File

@ -81,9 +81,9 @@ void CDSNotificationInterface::SyncTransaction(const CTransaction &tx, const CBl
CPrivateSend::SyncTransaction(tx, pindex, posInBlock);
}
void CDSNotificationInterface::NotifyMasternodeListChanged(const CDeterministicMNList& newList)
void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff)
{
CMNAuth::NotifyMasternodeListChanged(newList);
CMNAuth::NotifyMasternodeListChanged(undo, oldMNList, diff);
governance.CheckMasternodeOrphanObjects(connman);
governance.CheckMasternodeOrphanVotes(connman);
governance.UpdateCachesAndClean();

View File

@ -22,7 +22,7 @@ protected:
void NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload) override;
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
void SyncTransaction(const CTransaction &tx, const CBlockIndex *pindex, int posInBlock) override;
void NotifyMasternodeListChanged(const CDeterministicMNList& newList) override;
void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) override;
void NotifyChainLock(const CBlockIndex* pindex) override;
private:

View File

@ -502,8 +502,8 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockInde
}
// Don't hold cs while calling signals
if (!diff.addedMNs.empty() || !diff.removedMns.empty()) {
GetMainSignals().NotifyMasternodeListChanged(newList);
if (diff.HasChanges()) {
GetMainSignals().NotifyMasternodeListChanged(false, oldList, diff);
}
const auto& consensusParams = Params().GetConsensus();
@ -527,20 +527,28 @@ bool CDeterministicMNManager::UndoBlock(const CBlock& block, const CBlockIndex*
int nHeight = pindex->nHeight;
uint256 blockHash = block.GetHash();
CDeterministicMNList curList;
CDeterministicMNList prevList;
CDeterministicMNListDiff diff;
{
LOCK(cs);
evoDb.Read(std::make_pair(DB_LIST_DIFF, blockHash), diff);
if (diff.HasChanges()) {
// need to call this before erasing
curList = GetListForBlock(blockHash);
prevList = GetListForBlock(pindex->pprev->GetBlockHash());
}
evoDb.Erase(std::make_pair(DB_LIST_DIFF, blockHash));
evoDb.Erase(std::make_pair(DB_LIST_SNAPSHOT, blockHash));
mnListsCache.erase(blockHash);
}
if (!diff.addedMNs.empty() || !diff.removedMns.empty()) {
auto prevList = GetListForBlock(pindex->pprev->GetBlockHash());
GetMainSignals().NotifyMasternodeListChanged(prevList);
if (diff.HasChanges()) {
auto inversedDiff = curList.BuildDiff(prevList);
GetMainSignals().NotifyMasternodeListChanged(true, curList, inversedDiff);
}
const auto& consensusParams = Params().GetConsensus();

View File

@ -114,21 +114,31 @@ void CMNAuth::ProcessMessage(CNode* pnode, const std::string& strCommand, CDataS
}
}
void CMNAuth::NotifyMasternodeListChanged(const CDeterministicMNList& newList)
void CMNAuth::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff)
{
std::unordered_set<uint256> pubKeys;
g_connman->ForEachNode([&](const CNode* pnode) {
LOCK(pnode->cs_mnauth);
if (!pnode->verifiedProRegTxHash.IsNull()) {
pubKeys.emplace(pnode->verifiedPubKeyHash);
// we're only interested in updated/removed MNs. Added MNs are of no interest for us
if (diff.updatedMNs.empty() && diff.removedMns.empty()) {
return;
}
});
newList.ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) {
pubKeys.erase(dmn->pdmnState->pubKeyOperator.GetHash());
});
g_connman->ForEachNode([&](CNode* pnode) {
LOCK(pnode->cs_mnauth);
if (!pnode->verifiedProRegTxHash.IsNull() && pubKeys.count(pnode->verifiedPubKeyHash)) {
if (pnode->verifiedProRegTxHash.IsNull()) {
return;
}
bool doRemove = false;
if (diff.removedMns.count(pnode->verifiedProRegTxHash)) {
doRemove = true;
} else {
auto it = diff.updatedMNs.find(pnode->verifiedProRegTxHash);
if (it != diff.updatedMNs.end()) {
if (it->second->pubKeyOperator.GetHash() != pnode->verifiedPubKeyHash) {
doRemove = true;
}
}
}
if (doRemove) {
LogPrint("net", "CMNAuth::NotifyMasternodeListChanged -- Disconnecting MN %s due to key changed/removed, peer=%d\n",
pnode->verifiedProRegTxHash.ToString(), pnode->id);
pnode->fDisconnect = true;

View File

@ -12,6 +12,7 @@ class CConnman;
class CDataStream;
class CDeterministicMN;
class CDeterministicMNList;
class CDeterministicMNListDiff;
class CNode;
class UniValue;
@ -50,7 +51,7 @@ public:
static void PushMNAUTH(CNode* pnode, CConnman& connman);
static void ProcessMessage(CNode* pnode, const std::string& strCommand, CDataStream& vRecv, CConnman& connman);
static void NotifyMasternodeListChanged(const CDeterministicMNList& newList);
static void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff);
};

View File

@ -30,7 +30,7 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.NotifyGovernanceObject.connect(boost::bind(&CValidationInterface::NotifyGovernanceObject, pwalletIn, _1));
g_signals.NotifyGovernanceVote.connect(boost::bind(&CValidationInterface::NotifyGovernanceVote, pwalletIn, _1));
g_signals.NotifyInstantSendDoubleSpendAttempt.connect(boost::bind(&CValidationInterface::NotifyInstantSendDoubleSpendAttempt, pwalletIn, _1, _2));
g_signals.NotifyMasternodeListChanged.connect(boost::bind(&CValidationInterface::NotifyMasternodeListChanged, pwalletIn, _1));
g_signals.NotifyMasternodeListChanged.connect(boost::bind(&CValidationInterface::NotifyMasternodeListChanged, pwalletIn, _1, _2, _3));
}
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
@ -51,7 +51,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.NotifyGovernanceObject.disconnect(boost::bind(&CValidationInterface::NotifyGovernanceObject, pwalletIn, _1));
g_signals.NotifyGovernanceVote.disconnect(boost::bind(&CValidationInterface::NotifyGovernanceVote, pwalletIn, _1));
g_signals.NotifyInstantSendDoubleSpendAttempt.disconnect(boost::bind(&CValidationInterface::NotifyInstantSendDoubleSpendAttempt, pwalletIn, _1, _2));
g_signals.NotifyMasternodeListChanged.disconnect(boost::bind(&CValidationInterface::NotifyMasternodeListChanged, pwalletIn, _1));
g_signals.NotifyMasternodeListChanged.disconnect(boost::bind(&CValidationInterface::NotifyMasternodeListChanged, pwalletIn, _1, _2, _3));
}
void UnregisterAllValidationInterfaces() {

View File

@ -21,6 +21,7 @@ class CValidationState;
class CGovernanceVote;
class CGovernanceObject;
class CDeterministicMNList;
class CDeterministicMNListDiff;
class uint256;
// These functions dispatch to one or all registered wallets
@ -43,7 +44,7 @@ protected:
virtual void NotifyGovernanceVote(const CGovernanceVote &vote) {}
virtual void NotifyGovernanceObject(const CGovernanceObject &object) {}
virtual void NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx) {}
virtual void NotifyMasternodeListChanged(const CDeterministicMNList& newList) {}
virtual void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) {}
virtual void SetBestChain(const CBlockLocator &locator) {}
virtual bool UpdatedTransaction(const uint256 &hash) { return false;}
virtual void Inventory(const uint256 &hash) {}
@ -86,7 +87,7 @@ struct CMainSignals {
/** Notifies listeners of a attempted InstantSend double spend*/
boost::signals2::signal<void(const CTransaction &currentTx, const CTransaction &previousTx)> NotifyInstantSendDoubleSpendAttempt;
/** Notifies listeners that the MN list changed */
boost::signals2::signal<void(const CDeterministicMNList& newList)> NotifyMasternodeListChanged;
boost::signals2::signal<void(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff)> NotifyMasternodeListChanged;
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
boost::signals2::signal<bool (const uint256 &)> UpdatedTransaction;
/** Notifies listeners of a new active block chain. */