Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
96e0385
Let "masternode winner/current" directly use deterministicMNManager
codablock Dec 17, 2018
ae229e2
Directly use deterministicMNManager in CGovernanceManager::GetCurrent…
codablock Dec 17, 2018
b49ef5d
Directly use deterministicMNManager when processing DSTX
codablock Dec 17, 2018
bc29fe1
Remove compatibility code from governance RPCs and directly use deter…
codablock Dec 17, 2018
45f34e1
Implement HasValidMN, HasValidMNByCollateral and GetValidMNByCollateral
codablock Dec 17, 2018
1ff2418
Directly use deterministicMNManager in some places
codablock Dec 17, 2018
14d8ce0
Don't use GetMasternodeInfo in CTxLockVote::IsValid
codablock Dec 17, 2018
2b2e4f4
Remove a few uses of mnodeman from governance code
codablock Dec 17, 2018
da92451
Remove support for legacy signatures in CTxLockVote
codablock Dec 17, 2018
5f5fcc4
Remove legacy signatures support in CPrivateSendQueue
codablock Dec 17, 2018
fb13b00
Remove support for legacy operator keys in CPrivateSendBroadcastTx
codablock Dec 17, 2018
eedb158
Remove use of mnodeman.GetMasternodeInfo from IX code
codablock Dec 17, 2018
2f66d6a
Replace uses of mnodeman in PS code when deterministicMNManager can b…
codablock Dec 17, 2018
71a6951
Move logic from FindRandomNotInVec into GetRandomNotUsedMasternode
codablock Dec 17, 2018
17c792c
Remove MN upgrade check in ComputeBlockVersion
codablock Dec 17, 2018
37541ee
Change GetMasternodeScores and GetMasternodeRank/s to use CDeterminis…
codablock Dec 17, 2018
0594cd7
Remove code that is incompatible now due to GetMasternodeRanks return…
codablock Dec 28, 2018
4c3bb73
Remove call to mnodeman.PoSeBan
codablock Dec 17, 2018
4b150e7
Directly use deterministicMNManager instead of mnodeman.CountXXX
codablock Dec 17, 2018
adc2ec2
Remove unsupported types/fields from "masternode list"
codablock Dec 17, 2018
0fe97a0
Remove support for "masternode list rank"
codablock Dec 17, 2018
4c749b7
Directly use deterministicMNManager in "masternode list"
codablock Dec 17, 2018
1efd773
Remove non-DIP3 code path in CMasternodePayments::IsScheduled
codablock Dec 28, 2018
536229d
Apply suggestions from code review
UdjinM6 Dec 31, 2018
e54f6b2
Use ban score of 10 for invalid DSQ sigs
codablock Dec 31, 2018
78c22ad
Multiple fixes for "masternode list"
codablock Dec 31, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,15 @@ CDeterministicMNCPtr CDeterministicMNList::GetMNByCollateral(const COutPoint& co
return GetUniquePropertyMN(collateralOutpoint);
}

CDeterministicMNCPtr CDeterministicMNList::GetValidMNByCollateral(const COutPoint& collateralOutpoint) const
{
auto dmn = GetMNByCollateral(collateralOutpoint);
if (dmn && !IsMNValid(dmn)) {
return nullptr;
}
return dmn;
}

static int CompareByLastPaid_GetHeight(const CDeterministicMN& dmn)
{
int height = dmn.pdmnState->nLastPaidHeight;
Expand Down Expand Up @@ -826,20 +835,6 @@ CDeterministicMNList CDeterministicMNManager::GetListAtChainTip()
return GetListForBlock(tipBlockHash);
}

bool CDeterministicMNManager::HasValidMNCollateralAtChainTip(const COutPoint& outpoint)
{
auto mnList = GetListAtChainTip();
auto dmn = mnList.GetMNByCollateral(outpoint);
return dmn && mnList.IsMNValid(dmn);
}

bool CDeterministicMNManager::HasMNCollateralAtChainTip(const COutPoint& outpoint)
{
auto mnList = GetListAtChainTip();
auto dmn = mnList.GetMNByCollateral(outpoint);
return dmn != nullptr;
}

bool CDeterministicMNManager::IsProTxWithCollateral(const CTransactionRef& tx, uint32_t n)
{
if (tx->nVersion != 3 || tx->nType != TRANSACTION_PROVIDER_REGISTER) {
Expand Down
17 changes: 13 additions & 4 deletions src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,23 @@ class CDeterministicMNList
{
return GetMN(proTxHash) != nullptr;
}
bool HasValidMN(const uint256& proTxHash) const
{
return GetValidMN(proTxHash) != nullptr;
}
bool HasMNByCollateral(const COutPoint& collateralOutpoint) const
{
return GetMNByCollateral(collateralOutpoint) != nullptr;
}
bool HasValidMNByCollateral(const COutPoint& collateralOutpoint) const
{
return GetValidMNByCollateral(collateralOutpoint) != nullptr;
}
CDeterministicMNCPtr GetMN(const uint256& proTxHash) const;
CDeterministicMNCPtr GetValidMN(const uint256& proTxHash) const;
CDeterministicMNCPtr GetMNByOperatorKey(const CBLSPublicKey& pubKey);
CDeterministicMNCPtr GetMNByCollateral(const COutPoint& collateralOutpoint) const;
CDeterministicMNCPtr GetValidMNByCollateral(const COutPoint& collateralOutpoint) const;
CDeterministicMNCPtr GetMNPayee() const;

/**
Expand Down Expand Up @@ -479,10 +492,6 @@ class CDeterministicMNManager
CDeterministicMNList GetListForBlock(const uint256& blockHash);
CDeterministicMNList GetListAtChainTip();

// TODO remove after removal of old non-deterministic lists
bool HasValidMNCollateralAtChainTip(const COutPoint& outpoint);
bool HasMNCollateralAtChainTip(const COutPoint& outpoint);

// Test if given TX is a ProRegTx which also contains the collateral at index n
bool IsProTxWithCollateral(const CTransactionRef& tx, uint32_t n);

Expand Down
35 changes: 16 additions & 19 deletions src/governance-object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,13 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom,
return false;
}

if (!mnodeman.Has(vote.GetMasternodeOutpoint())) {
auto mnList = deterministicMNManager->GetListAtChainTip();

if (!mnList.HasValidMNByCollateral(vote.GetMasternodeOutpoint())) {
std::ostringstream ostr;
ostr << "CGovernanceObject::ProcessVote -- Masternode " << vote.GetMasternodeOutpoint().ToStringShort() << " not found";
exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_WARNING);
if (cmmapOrphanVotes.Insert(vote.GetMasternodeOutpoint(), vote_time_pair_t(vote, GetAdjustedTime() + GOVERNANCE_ORPHAN_EXPIRATION_TIME))) {
if (pfrom) {
mnodeman.AskForMN(pfrom, vote.GetMasternodeOutpoint(), connman);
}
LogPrintf("%s\n", ostr.str());
} else {
LogPrint("gobject", "%s\n", ostr.str());
Expand Down Expand Up @@ -212,9 +211,11 @@ void CGovernanceObject::ClearMasternodeVotes()
{
LOCK(cs);

auto mnList = deterministicMNManager->GetListAtChainTip();

vote_m_it it = mapCurrentMNVotes.begin();
while (it != mapCurrentMNVotes.end()) {
if (!mnodeman.Has(it->first)) {
if (!mnList.HasValidMNByCollateral(it->first)) {
fileVotes.RemoveVotesFromMasternode(it->first);
mapCurrentMNVotes.erase(it++);
} else {
Expand Down Expand Up @@ -552,9 +553,11 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast
return true;
}

auto mnList = deterministicMNManager->GetListAtChainTip();

std::string strOutpoint = masternodeOutpoint.ToStringShort();
masternode_info_t infoMn;
if (!mnodeman.GetMasternodeInfo(masternodeOutpoint, infoMn)) {
auto dmn = mnList.GetValidMNByCollateral(masternodeOutpoint);
if (!dmn) {
CMasternode::CollateralStatus err = CMasternode::CheckCollateral(masternodeOutpoint, CKeyID());
if (err == CMasternode::COLLATERAL_UTXO_NOT_FOUND) {
strError = "Failed to find Masternode UTXO, missing masternode=" + strOutpoint + "\n";
Expand All @@ -572,16 +575,9 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast
}

// Check that we have a valid MN signature
if (deterministicMNManager->IsDIP3Active()) {
if (!CheckSignature(infoMn.blsPubKeyOperator)) {
strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey id = " + infoMn.blsPubKeyOperator.ToString();
return false;
}
} else {
if (!CheckSignature(infoMn.legacyKeyIDOperator)) {
strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey id = " + infoMn.legacyKeyIDOperator.ToString();
return false;
}
if (!CheckSignature(dmn->pdmnState->pubKeyOperator)) {
strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey = " + dmn->pdmnState->pubKeyOperator.ToString();
return false;
}

return true;
Expand Down Expand Up @@ -779,7 +775,7 @@ void CGovernanceObject::UpdateSentinelVariables()
{
// CALCULATE MINIMUM SUPPORT LEVELS REQUIRED

int nMnCount = mnodeman.CountEnabled();
int nMnCount = (int)deterministicMNManager->GetListAtChainTip().GetValidMNsCount();
if (nMnCount == 0) return;

// CALCULATE THE MINUMUM VOTE COUNT REQUIRED FOR FULL SIGNAL
Expand Down Expand Up @@ -812,6 +808,7 @@ void CGovernanceObject::UpdateSentinelVariables()
void CGovernanceObject::CheckOrphanVotes(CConnman& connman)
{
int64_t nNow = GetAdjustedTime();
auto mnList = deterministicMNManager->GetListAtChainTip();
const vote_cmm_t::list_t& listVotes = cmmapOrphanVotes.GetItemList();
vote_cmm_t::list_cit it = listVotes.begin();
while (it != listVotes.end()) {
Expand All @@ -821,7 +818,7 @@ void CGovernanceObject::CheckOrphanVotes(CConnman& connman)
const CGovernanceVote& vote = pairVote.first;
if (pairVote.second < nNow) {
fRemove = true;
} else if (!mnodeman.Has(vote.GetMasternodeOutpoint())) {
} else if (!mnList.HasValidMNByCollateral(vote.GetMasternodeOutpoint())) {
++it;
continue;
}
Expand Down
12 changes: 4 additions & 8 deletions src/governance-vote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,20 +256,16 @@ bool CGovernanceVote::IsValid(bool useVotingKey) const
return false;
}

masternode_info_t infoMn;
if (!mnodeman.GetMasternodeInfo(masternodeOutpoint, infoMn)) {
auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMNByCollateral(masternodeOutpoint);
if (!dmn) {
LogPrint("gobject", "CGovernanceVote::IsValid -- Unknown Masternode - %s\n", masternodeOutpoint.ToStringShort());
return false;
}

if (useVotingKey) {
return CheckSignature(infoMn.keyIDVoting);
return CheckSignature(dmn->pdmnState->keyIDVoting);
} else {
if (deterministicMNManager->IsDIP3Active()) {
return CheckSignature(infoMn.blsPubKeyOperator);
} else {
return CheckSignature(infoMn.legacyKeyIDOperator);
}
return CheckSignature(dmn->pdmnState->pubKeyOperator);
}
}

Expand Down
17 changes: 11 additions & 6 deletions src/governance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,17 @@ std::vector<CGovernanceVote> CGovernanceManager::GetCurrentVotes(const uint256&
if (it == mapObjects.end()) return vecResult;
const CGovernanceObject& govobj = it->second;

CMasternode mn;
std::map<COutPoint, CMasternode> mapMasternodes;
auto mnList = deterministicMNManager->GetListAtChainTip();
std::map<COutPoint, CDeterministicMNCPtr> mapMasternodes;
if (mnCollateralOutpointFilter.IsNull()) {
mapMasternodes = mnodeman.GetFullMasternodeMap();
} else if (mnodeman.Get(mnCollateralOutpointFilter, mn)) {
mapMasternodes[mnCollateralOutpointFilter] = mn;
mnList.ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) {
mapMasternodes.emplace(dmn->collateralOutpoint, dmn);
});
} else {
auto dmn = mnList.GetValidMNByCollateral(mnCollateralOutpointFilter);
if (dmn) {
mapMasternodes.emplace(dmn->collateralOutpoint, dmn);
}
}

// Loop thru each MN collateral outpoint and get the votes for the `nParentHash` governance object
Expand Down Expand Up @@ -1074,7 +1079,7 @@ int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector<CNode*>&
int nMaxObjRequestsPerNode = 1;
size_t nProjectedVotes = 2000;
if (Params().NetworkIDString() != CBaseChainParams::MAIN) {
nMaxObjRequestsPerNode = std::max(1, int(nProjectedVotes / std::max(1, mnodeman.size())));
nMaxObjRequestsPerNode = std::max(1, int(nProjectedVotes / std::max(1, (int)deterministicMNManager->GetListAtChainTip().GetValidMNsCount())));
}

{
Expand Down
102 changes: 27 additions & 75 deletions src/instantx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,7 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman)

int nRank;
uint256 quorumModifierHash;
int nMinRequiredProtocol = std::max(MIN_INSTANTSEND_PROTO_VERSION, mnpayments.GetMinMasternodePaymentsProto());
if (!mnodeman.GetMasternodeRank(activeMasternodeInfo.outpoint, nRank, quorumModifierHash, nLockInputHeight, nMinRequiredProtocol)) {
if (!mnodeman.GetMasternodeRank(activeMasternodeInfo.outpoint, nRank, quorumModifierHash, nLockInputHeight)) {
LogPrint("instantsend", "CInstantSend::Vote -- Can't calculate rank for masternode %s\n", activeMasternodeInfo.outpoint.ToStringShort());
continue;
}
Expand Down Expand Up @@ -469,7 +468,8 @@ void CInstantSend::UpdateVotedOutpoints(const CTxLockVote& vote, CTxLockCandidat
txLockCandidate.MarkOutpointAsAttacked(vote.GetOutpoint());
it2->second.MarkOutpointAsAttacked(vote.GetOutpoint());
// apply maximum PoSe ban score to this masternode i.e. PoSe-ban it instantly
mnodeman.PoSeBan(vote.GetMasternodeOutpoint());
// TODO Call new PoSe system when it's ready
//mnodeman.PoSeBan(vote.GetMasternodeOutpoint());
// NOTE: This vote must be relayed further to let all other nodes know about such
// misbehaviour of this masternode. This way they should also be able to construct
// conflicting lock and PoSe-ban this masternode.
Expand Down Expand Up @@ -1029,22 +1029,25 @@ bool CTxLockRequest::IsSimple() const

bool CTxLockVote::IsValid(CNode* pnode, CConnman& connman) const
{
if (!mnodeman.Has(outpointMasternode)) {
auto mnList = deterministicMNManager->GetListAtChainTip();

if (!mnList.HasValidMNByCollateral(outpointMasternode)) {
LogPrint("instantsend", "CTxLockVote::IsValid -- Unknown masternode %s\n", outpointMasternode.ToStringShort());
mnodeman.AskForMN(pnode, outpointMasternode, connman);
return false;
}

// Verify that masternodeProTxHash belongs to the same MN referred by the collateral
// Only v13 nodes will send us locks with this field set, and only after spork15 activation
// This is a leftover from the legacy non-deterministic MN list where we used the collateral to identify MNs
// TODO eventually remove the collateral from CTxLockVote
if (!masternodeProTxHash.IsNull()) {
masternode_info_t mnInfo;
if (!mnodeman.GetMasternodeInfo(masternodeProTxHash, mnInfo) || mnInfo.outpoint != outpointMasternode) {
auto dmn = mnList.GetValidMN(masternodeProTxHash);
if (!dmn || dmn->collateralOutpoint != outpointMasternode) {
LogPrint("instantsend", "CTxLockVote::IsValid -- invalid masternodeProTxHash %s\n", masternodeProTxHash.ToString());
return false;
}
} else if (deterministicMNManager->IsDIP3Active()) {
LogPrint("instantsend", "CTxLockVote::IsValid -- missing masternodeProTxHash while DIP3 is active\n");
} else {
LogPrint("instantsend", "CTxLockVote::IsValid -- missing masternodeProTxHash\n");
return false;
}

Expand All @@ -1058,8 +1061,7 @@ bool CTxLockVote::IsValid(CNode* pnode, CConnman& connman) const

int nRank;
uint256 expectedQuorumModifierHash;
int nMinRequiredProtocol = std::max(MIN_INSTANTSEND_PROTO_VERSION, mnpayments.GetMinMasternodePaymentsProto());
if (!mnodeman.GetMasternodeRank(outpointMasternode, nRank, expectedQuorumModifierHash, nLockInputHeight, nMinRequiredProtocol)) {
if (!mnodeman.GetMasternodeRank(outpointMasternode, nRank, expectedQuorumModifierHash, nLockInputHeight)) {
//can be caused by past versions trying to vote with an invalid protocol
LogPrint("instantsend", "CTxLockVote::IsValid -- Can't calculate rank for masternode %s\n", outpointMasternode.ToStringShort());
return false;
Expand Down Expand Up @@ -1105,83 +1107,33 @@ bool CTxLockVote::CheckSignature() const
{
std::string strError;

masternode_info_t infoMn;

if (!mnodeman.GetMasternodeInfo(outpointMasternode, infoMn)) {
LogPrintf("CTxLockVote::CheckSignature -- Unknown Masternode: masternode=%s\n", outpointMasternode.ToString());
auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMN(masternodeProTxHash);
if (!dmn) {
LogPrintf("CTxLockVote::CheckSignature -- Unknown Masternode: masternode=%s\n", masternodeProTxHash.ToString());
return false;
}

if (deterministicMNManager->IsDIP3Active()) {
uint256 hash = GetSignatureHash();
uint256 hash = GetSignatureHash();

CBLSSignature sig;
sig.SetBuf(vchMasternodeSignature);
if (!sig.IsValid() || !sig.VerifyInsecure(infoMn.blsPubKeyOperator, hash)) {
LogPrintf("CTxLockVote::CheckSignature -- VerifyInsecure() failed\n");
return false;
}
} else if (sporkManager.IsSporkActive(SPORK_6_NEW_SIGS)) {
uint256 hash = GetSignatureHash();

if (!CHashSigner::VerifyHash(hash, infoMn.legacyKeyIDOperator, vchMasternodeSignature, strError)) {
// could be a signature in old format
std::string strMessage = txHash.ToString() + outpoint.ToStringShort();
if (!CMessageSigner::VerifyMessage(infoMn.legacyKeyIDOperator, vchMasternodeSignature, strMessage, strError)) {
// nope, not in old format either
LogPrintf("CTxLockVote::CheckSignature -- VerifyMessage() failed, error: %s\n", strError);
return false;
}
}
} else {
std::string strMessage = txHash.ToString() + outpoint.ToStringShort();
if (!CMessageSigner::VerifyMessage(infoMn.legacyKeyIDOperator, vchMasternodeSignature, strMessage, strError)) {
LogPrintf("CTxLockVote::CheckSignature -- VerifyMessage() failed, error: %s\n", strError);
return false;
}
CBLSSignature sig;
sig.SetBuf(vchMasternodeSignature);
if (!sig.IsValid() || !sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator, hash)) {
LogPrintf("CTxLockVote::CheckSignature -- VerifyInsecure() failed\n");
return false;
}

return true;
}

bool CTxLockVote::Sign()
{
std::string strError;

if (deterministicMNManager->IsDIP3Active()) {
uint256 hash = GetSignatureHash();

CBLSSignature sig = activeMasternodeInfo.blsKeyOperator->Sign(hash);
if (!sig.IsValid()) {
return false;
}
sig.GetBuf(vchMasternodeSignature);
} else if (sporkManager.IsSporkActive(SPORK_6_NEW_SIGS)) {
uint256 hash = GetSignatureHash();

if (!CHashSigner::SignHash(hash, activeMasternodeInfo.legacyKeyOperator, vchMasternodeSignature)) {
LogPrintf("CTxLockVote::Sign -- SignHash() failed\n");
return false;
}

if (!CHashSigner::VerifyHash(hash, activeMasternodeInfo.legacyKeyIDOperator, vchMasternodeSignature, strError)) {
LogPrintf("CTxLockVote::Sign -- VerifyHash() failed, error: %s\n", strError);
return false;
}
} else {
std::string strMessage = txHash.ToString() + outpoint.ToStringShort();

if (!CMessageSigner::SignMessage(strMessage, vchMasternodeSignature, activeMasternodeInfo.legacyKeyOperator)) {
LogPrintf("CTxLockVote::Sign -- SignMessage() failed\n");
return false;
}
uint256 hash = GetSignatureHash();

if (!CMessageSigner::VerifyMessage(activeMasternodeInfo.legacyKeyIDOperator, vchMasternodeSignature, strMessage, strError)) {
LogPrintf("CTxLockVote::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false;
}
CBLSSignature sig = activeMasternodeInfo.blsKeyOperator->Sign(hash);
if (!sig.IsValid()) {
return false;
}

sig.GetBuf(vchMasternodeSignature);
return true;
}

Expand Down
Loading