Add compatibility code to CMasternodeMan so that old code is still compatible
...when deterministic MNs are activated.
This commit is contained in:
parent
27e8b48a60
commit
7d14566bcd
@ -52,6 +52,17 @@ CMasternode::CMasternode(const CMasternodeBroadcast& mnb) :
|
|||||||
fAllowMixingTx(true)
|
fAllowMixingTx(true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
CMasternode::CMasternode(const uint256 &proTxHash, const CDeterministicMNCPtr& dmn) :
|
||||||
|
masternode_info_t{ MASTERNODE_ENABLED, dmn->pdmnState->nProtocolVersion, GetAdjustedTime(),
|
||||||
|
COutPoint(proTxHash, dmn->nCollateralIndex), dmn->pdmnState->addr, CKeyID(), dmn->pdmnState->keyIDOwner, dmn->pdmnState->keyIDOperator, dmn->pdmnState->keyIDVoting},
|
||||||
|
fAllowMixingTx(true)
|
||||||
|
{
|
||||||
|
CTxDestination dest;
|
||||||
|
if (!ExtractDestination(dmn->pdmnState->scriptPayout, dest) || !boost::get<CKeyID>(&dest))
|
||||||
|
assert(false); // should not happen (previous verification forbids non p2pkh/p2pk
|
||||||
|
keyIDCollateralAddress = *boost::get<CKeyID>(&dest);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// When a new masternode broadcast is sent, update our information
|
// When a new masternode broadcast is sent, update our information
|
||||||
//
|
//
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "validation.h"
|
#include "validation.h"
|
||||||
#include "spork.h"
|
#include "spork.h"
|
||||||
|
|
||||||
|
#include "evo/deterministicmns.h"
|
||||||
|
|
||||||
class CMasternode;
|
class CMasternode;
|
||||||
class CMasternodeBroadcast;
|
class CMasternodeBroadcast;
|
||||||
class CConnman;
|
class CConnman;
|
||||||
@ -214,6 +216,7 @@ public:
|
|||||||
CMasternode(const CMasternode& other);
|
CMasternode(const CMasternode& other);
|
||||||
CMasternode(const CMasternodeBroadcast& mnb);
|
CMasternode(const CMasternodeBroadcast& mnb);
|
||||||
CMasternode(CService addrNew, COutPoint outpointNew, CPubKey pubKeyCollateralAddressNew, CPubKey pubKeyMasternodeNew, int nProtocolVersionIn);
|
CMasternode(CService addrNew, COutPoint outpointNew, CPubKey pubKeyCollateralAddressNew, CPubKey pubKeyMasternodeNew, int nProtocolVersionIn);
|
||||||
|
CMasternode(const uint256 &proTxHash, const CDeterministicMNCPtr& dmn);
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "warnings.h"
|
#include "warnings.h"
|
||||||
|
|
||||||
#include "evo/deterministicmns.h"
|
#include "evo/deterministicmns.h"
|
||||||
|
#include "evo/providertx.h"
|
||||||
|
|
||||||
/** Masternode manager */
|
/** Masternode manager */
|
||||||
CMasternodeMan mnodeman;
|
CMasternodeMan mnodeman;
|
||||||
@ -389,20 +390,32 @@ void CMasternodeMan::Clear()
|
|||||||
int CMasternodeMan::CountMasternodes(int nProtocolVersion)
|
int CMasternodeMan::CountMasternodes(int nProtocolVersion)
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
|
|
||||||
int nCount = 0;
|
int nCount = 0;
|
||||||
nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion;
|
nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion;
|
||||||
|
|
||||||
for (const auto& mnpair : mapMasternodes) {
|
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||||
if(mnpair.second.nProtocolVersion < nProtocolVersion) continue;
|
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||||
nCount++;
|
for (const auto& dmn : mnList.valid_range()) {
|
||||||
|
if (dmn->pdmnState->nProtocolVersion < nProtocolVersion) continue;
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const auto& mnpair : mapMasternodes) {
|
||||||
|
if(mnpair.second.nProtocolVersion < nProtocolVersion) continue;
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nCount;
|
return nCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMasternodeMan::CountEnabled(int nProtocolVersion)
|
int CMasternodeMan::CountEnabled(int nProtocolVersion)
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
|
|
||||||
|
if (deterministicMNManager->IsDeterministicMNsSporkActive())
|
||||||
|
return CountMasternodes(nProtocolVersion);
|
||||||
|
|
||||||
int nCount = 0;
|
int nCount = 0;
|
||||||
nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion;
|
nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion;
|
||||||
|
|
||||||
@ -464,43 +477,77 @@ void CMasternodeMan::DsegUpdate(CNode* pnode, CConnman& connman)
|
|||||||
CMasternode* CMasternodeMan::Find(const COutPoint &outpoint)
|
CMasternode* CMasternodeMan::Find(const COutPoint &outpoint)
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
auto it = mapMasternodes.find(outpoint);
|
|
||||||
return it == mapMasternodes.end() ? nullptr : &(it->second);
|
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||||
|
// This code keeps compatibility to old code depending on the non-deterministic MN lists
|
||||||
|
// When deterministic MN lists get activated, we stop relying on the MNs we encountered due to MNBs and start
|
||||||
|
// using the MNs found in the deterministic MN manager. To keep compatibility, we create CMasternode entries
|
||||||
|
// for these and return them here. This is needed because we also need to track some data per MN that is not
|
||||||
|
// on-chain, like vote counts
|
||||||
|
|
||||||
|
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||||
|
if (!mnList.IsMNValid(outpoint.hash)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto dmn = mnList.GetMN(outpoint.hash);
|
||||||
|
if (!dmn) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = mapMasternodes.find(outpoint);
|
||||||
|
if (it != mapMasternodes.end()) {
|
||||||
|
return &(it->second);
|
||||||
|
} else {
|
||||||
|
// MN is not in mapMasternodes but in the deterministic list. Create an entry in mapMasternodes for compatibility with legacy code
|
||||||
|
CMasternode mn(outpoint.hash, dmn);
|
||||||
|
it = mapMasternodes.emplace(outpoint, mn).first;
|
||||||
|
return &(it->second);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto it = mapMasternodes.find(outpoint);
|
||||||
|
return it == mapMasternodes.end() ? nullptr : &(it->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMasternodeMan::Get(const COutPoint& outpoint, CMasternode& masternodeRet)
|
bool CMasternodeMan::Get(const COutPoint& outpoint, CMasternode& masternodeRet)
|
||||||
{
|
{
|
||||||
// Theses mutexes are recursive so double locking by the same thread is safe.
|
// Theses mutexes are recursive so double locking by the same thread is safe.
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
auto it = mapMasternodes.find(outpoint);
|
CMasternode* mn = Find(outpoint);
|
||||||
if (it == mapMasternodes.end()) {
|
if (!mn)
|
||||||
return false;
|
return false;
|
||||||
}
|
masternodeRet = *mn;
|
||||||
|
|
||||||
masternodeRet = it->second;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMasternodeMan::GetMasternodeInfo(const COutPoint& outpoint, masternode_info_t& mnInfoRet)
|
bool CMasternodeMan::GetMasternodeInfo(const COutPoint& outpoint, masternode_info_t& mnInfoRet)
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
auto it = mapMasternodes.find(outpoint);
|
CMasternode* mn = Find(outpoint);
|
||||||
if (it == mapMasternodes.end()) {
|
if (!mn)
|
||||||
return false;
|
return false;
|
||||||
}
|
mnInfoRet = mn->GetInfo();
|
||||||
mnInfoRet = it->second.GetInfo();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMasternodeMan::GetMasternodeInfo(const CKeyID& keyIDOperator, masternode_info_t& mnInfoRet) {
|
bool CMasternodeMan::GetMasternodeInfo(const CKeyID& keyIDOperator, masternode_info_t& mnInfoRet) {
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
for (const auto& mnpair : mapMasternodes) {
|
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||||
if (mnpair.second.keyIDOperator == keyIDOperator) {
|
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||||
mnInfoRet = mnpair.second.GetInfo();
|
auto dmn = mnList.GetMNByOperatorKey(keyIDOperator);
|
||||||
return true;
|
if (dmn) {
|
||||||
|
return GetMasternodeInfo(COutPoint(dmn->proTxHash, dmn->nCollateralIndex), mnInfoRet);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
for (const auto& mnpair : mapMasternodes) {
|
||||||
|
if (mnpair.second.keyIDOperator == keyIDOperator) {
|
||||||
|
mnInfoRet = mnpair.second.GetInfo();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMasternodeMan::GetMasternodeInfo(const CPubKey& pubKeyOperator, masternode_info_t& mnInfoRet)
|
bool CMasternodeMan::GetMasternodeInfo(const CPubKey& pubKeyOperator, masternode_info_t& mnInfoRet)
|
||||||
@ -527,7 +574,11 @@ bool CMasternodeMan::GetMasternodeInfo(const CScript& payee, masternode_info_t&
|
|||||||
bool CMasternodeMan::Has(const COutPoint& outpoint)
|
bool CMasternodeMan::Has(const COutPoint& outpoint)
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
return mapMasternodes.find(outpoint) != mapMasternodes.end();
|
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||||
|
return deterministicMNManager->HasValidMNAtChainTip(outpoint.hash);
|
||||||
|
} else {
|
||||||
|
return mapMasternodes.find(outpoint) != mapMasternodes.end();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1546,12 +1597,17 @@ std::string CMasternodeMan::ToString() const
|
|||||||
{
|
{
|
||||||
std::ostringstream info;
|
std::ostringstream info;
|
||||||
|
|
||||||
info << "Masternodes: " << (int)mapMasternodes.size() <<
|
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||||
", peers who asked us for Masternode list: " << (int)mAskedUsForMasternodeList.size() <<
|
info << "Masternodes: masternode object count: " << (int)mapMasternodes.size() <<
|
||||||
", peers we asked for Masternode list: " << (int)mWeAskedForMasternodeList.size() <<
|
", deterministic masternode count: " << deterministicMNManager->GetListAtChainTip().size() <<
|
||||||
", entries in Masternode list we asked for: " << (int)mWeAskedForMasternodeListEntry.size() <<
|
", nDsqCount: " << (int)nDsqCount;
|
||||||
", nDsqCount: " << (int)nDsqCount;
|
} else {
|
||||||
|
info << "Masternodes: " << (int)mapMasternodes.size() <<
|
||||||
|
", peers who asked us for Masternode list: " << (int)mAskedUsForMasternodeList.size() <<
|
||||||
|
", peers we asked for Masternode list: " << (int)mWeAskedForMasternodeList.size() <<
|
||||||
|
", entries in Masternode list we asked for: " << (int)mWeAskedForMasternodeListEntry.size() <<
|
||||||
|
", nDsqCount: " << (int)nDsqCount;
|
||||||
|
}
|
||||||
return info.str();
|
return info.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1802,7 +1858,7 @@ void CMasternodeMan::WarnMasternodeDaemonUpdates()
|
|||||||
fWarned = true;
|
fWarned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMasternodeMan::NotifyMasternodeUpdates(CConnman& connman)
|
void CMasternodeMan::NotifyMasternodeUpdates(CConnman& connman, bool forceAddedChecks, bool forceRemovedChecks)
|
||||||
{
|
{
|
||||||
// Avoid double locking
|
// Avoid double locking
|
||||||
bool fMasternodesAddedLocal = false;
|
bool fMasternodesAddedLocal = false;
|
||||||
@ -1813,11 +1869,11 @@ void CMasternodeMan::NotifyMasternodeUpdates(CConnman& connman)
|
|||||||
fMasternodesRemovedLocal = fMasternodesRemoved;
|
fMasternodesRemovedLocal = fMasternodesRemoved;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fMasternodesAddedLocal) {
|
if(fMasternodesAddedLocal || forceAddedChecks) {
|
||||||
governance.CheckMasternodeOrphanObjects(connman);
|
governance.CheckMasternodeOrphanObjects(connman);
|
||||||
governance.CheckMasternodeOrphanVotes(connman);
|
governance.CheckMasternodeOrphanVotes(connman);
|
||||||
}
|
}
|
||||||
if(fMasternodesRemovedLocal) {
|
if(fMasternodesRemovedLocal || forceRemovedChecks) {
|
||||||
governance.UpdateCachesAndClean();
|
governance.UpdateCachesAndClean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ public:
|
|||||||
* Called to notify CGovernanceManager that the masternode index has been updated.
|
* Called to notify CGovernanceManager that the masternode index has been updated.
|
||||||
* Must be called while not holding the CMasternodeMan::cs mutex
|
* Must be called while not holding the CMasternodeMan::cs mutex
|
||||||
*/
|
*/
|
||||||
void NotifyMasternodeUpdates(CConnman& connman);
|
void NotifyMasternodeUpdates(CConnman& connman, bool forceAddedChecks = false, bool forceRemovedChecks = false);
|
||||||
|
|
||||||
void DoMaintenance(CConnman &connman);
|
void DoMaintenance(CConnman &connman);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user