Add quorumModifierHash to instant send lock vote (#2505)

* Let GetMasternodeRank also return the block hash at the given height

* Add outpointConfirmedBlock to CTxLockVote and verify it

* Match order of parameters with member order

* Rename outpointConfirmedBlock to quorumModifierHash

* Add overload of GetMasternodeRank that does not return the block hash
This commit is contained in:
Alexander Block 2018-11-28 11:43:28 +01:00 committed by GitHub
parent 812834dc5f
commit 35550a3f93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 8 deletions

View File

@ -244,11 +244,16 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman)
int nLockInputHeight = nPrevoutHeight + Params().GetConsensus().nInstantSendConfirmationsRequired - 2; int nLockInputHeight = nPrevoutHeight + Params().GetConsensus().nInstantSendConfirmationsRequired - 2;
int nRank; int nRank;
uint256 quorumModifierHash;
int nMinRequiredProtocol = std::max(MIN_INSTANTSEND_PROTO_VERSION, mnpayments.GetMinMasternodePaymentsProto()); int nMinRequiredProtocol = std::max(MIN_INSTANTSEND_PROTO_VERSION, mnpayments.GetMinMasternodePaymentsProto());
if (!mnodeman.GetMasternodeRank(activeMasternodeInfo.outpoint, nRank, nLockInputHeight, nMinRequiredProtocol)) { if (!mnodeman.GetMasternodeRank(activeMasternodeInfo.outpoint, nRank, quorumModifierHash, nLockInputHeight, nMinRequiredProtocol)) {
LogPrint("instantsend", "CInstantSend::Vote -- Can't calculate rank for masternode %s\n", activeMasternodeInfo.outpoint.ToStringShort()); LogPrint("instantsend", "CInstantSend::Vote -- Can't calculate rank for masternode %s\n", activeMasternodeInfo.outpoint.ToStringShort());
continue; continue;
} }
if (!deterministicMNManager->IsDeterministicMNsSporkActive()) {
// not used until spork15 activation
quorumModifierHash = uint256();
}
int nSignaturesTotal = COutPointLock::SIGNATURES_TOTAL; int nSignaturesTotal = COutPointLock::SIGNATURES_TOTAL;
if (nRank > nSignaturesTotal) { if (nRank > nSignaturesTotal) {
@ -282,7 +287,7 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman)
// we haven't voted for this outpoint yet, let's try to do this now // we haven't voted for this outpoint yet, let's try to do this now
// Please note that activeMasternodeInfo.proTxHash is only valid after spork15 activation // Please note that activeMasternodeInfo.proTxHash is only valid after spork15 activation
CTxLockVote vote(txHash, outpointLockPair.first, activeMasternodeInfo.outpoint, activeMasternodeInfo.proTxHash); CTxLockVote vote(txHash, outpointLockPair.first, activeMasternodeInfo.outpoint, quorumModifierHash, activeMasternodeInfo.proTxHash);
if (!vote.Sign()) { if (!vote.Sign()) {
LogPrintf("CInstantSend::Vote -- Failed to sign consensus vote\n"); LogPrintf("CInstantSend::Vote -- Failed to sign consensus vote\n");
@ -1052,12 +1057,23 @@ bool CTxLockVote::IsValid(CNode* pnode, CConnman& connman) const
int nLockInputHeight = coin.nHeight + Params().GetConsensus().nInstantSendConfirmationsRequired - 2; int nLockInputHeight = coin.nHeight + Params().GetConsensus().nInstantSendConfirmationsRequired - 2;
int nRank; int nRank;
uint256 expectedQuorumModifierHash;
int nMinRequiredProtocol = std::max(MIN_INSTANTSEND_PROTO_VERSION, mnpayments.GetMinMasternodePaymentsProto()); int nMinRequiredProtocol = std::max(MIN_INSTANTSEND_PROTO_VERSION, mnpayments.GetMinMasternodePaymentsProto());
if (!mnodeman.GetMasternodeRank(outpointMasternode, nRank, nLockInputHeight, nMinRequiredProtocol)) { if (!mnodeman.GetMasternodeRank(outpointMasternode, nRank, expectedQuorumModifierHash, nLockInputHeight, nMinRequiredProtocol)) {
//can be caused by past versions trying to vote with an invalid protocol //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()); LogPrint("instantsend", "CTxLockVote::IsValid -- Can't calculate rank for masternode %s\n", outpointMasternode.ToStringShort());
return false; return false;
} }
if (!quorumModifierHash.IsNull()) {
if (quorumModifierHash != expectedQuorumModifierHash) {
LogPrint("instantsend", "CTxLockVote::IsValid -- invalid quorumModifierHash %s, expected %s\n", quorumModifierHash.ToString(), expectedQuorumModifierHash.ToString());
return false;
}
} else if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
LogPrint("instantsend", "CTxLockVote::IsValid -- missing quorumModifierHash while DIP3 is active\n");
return false;
}
LogPrint("instantsend", "CTxLockVote::IsValid -- Masternode %s, rank=%d\n", outpointMasternode.ToStringShort(), nRank); LogPrint("instantsend", "CTxLockVote::IsValid -- Masternode %s, rank=%d\n", outpointMasternode.ToStringShort(), nRank);
int nSignaturesTotal = COutPointLock::SIGNATURES_TOTAL; int nSignaturesTotal = COutPointLock::SIGNATURES_TOTAL;

View File

@ -235,6 +235,7 @@ private:
COutPoint outpoint; COutPoint outpoint;
// TODO remove this member when the legacy masternode code is removed after DIP3 deployment // TODO remove this member when the legacy masternode code is removed after DIP3 deployment
COutPoint outpointMasternode; COutPoint outpointMasternode;
uint256 quorumModifierHash;
uint256 masternodeProTxHash; uint256 masternodeProTxHash;
std::vector<unsigned char> vchMasternodeSignature; std::vector<unsigned char> vchMasternodeSignature;
// local memory only // local memory only
@ -246,16 +247,18 @@ public:
txHash(), txHash(),
outpoint(), outpoint(),
outpointMasternode(), outpointMasternode(),
quorumModifierHash(),
masternodeProTxHash(), masternodeProTxHash(),
vchMasternodeSignature(), vchMasternodeSignature(),
nConfirmedHeight(-1), nConfirmedHeight(-1),
nTimeCreated(GetTime()) nTimeCreated(GetTime())
{} {}
CTxLockVote(const uint256& txHashIn, const COutPoint& outpointIn, const COutPoint& outpointMasternodeIn, const uint256& masternodeProTxHashIn) : CTxLockVote(const uint256& txHashIn, const COutPoint& outpointIn, const COutPoint& outpointMasternodeIn, const uint256& quorumModifierHashIn, const uint256& masternodeProTxHashIn) :
txHash(txHashIn), txHash(txHashIn),
outpoint(outpointIn), outpoint(outpointIn),
outpointMasternode(outpointMasternodeIn), outpointMasternode(outpointMasternodeIn),
quorumModifierHash(quorumModifierHashIn),
masternodeProTxHash(masternodeProTxHashIn), masternodeProTxHash(masternodeProTxHashIn),
vchMasternodeSignature(), vchMasternodeSignature(),
nConfirmedHeight(-1), nConfirmedHeight(-1),
@ -270,8 +273,9 @@ public:
READWRITE(outpoint); READWRITE(outpoint);
READWRITE(outpointMasternode); READWRITE(outpointMasternode);
if (deterministicMNManager->IsDeterministicMNsSporkActive()) { if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
// Starting with spork15 activation, the proTxHash is included. When we bump to >= 70213, we can remove // Starting with spork15 activation, the proTxHash and quorumModifierHash is included. When we bump to >= 70213, we can remove
// the surrounding if. We might also remove outpointMasternode as well later // the surrounding if. We might also remove outpointMasternode as well later
READWRITE(quorumModifierHash);
READWRITE(masternodeProTxHash); READWRITE(masternodeProTxHash);
} }
if (!(s.GetType() & SER_GETHASH)) { if (!(s.GetType() & SER_GETHASH)) {

View File

@ -821,6 +821,12 @@ bool CMasternodeMan::GetMasternodeScores(const uint256& nBlockHash, CMasternodeM
} }
bool CMasternodeMan::GetMasternodeRank(const COutPoint& outpoint, int& nRankRet, int nBlockHeight, int nMinProtocol) bool CMasternodeMan::GetMasternodeRank(const COutPoint& outpoint, int& nRankRet, int nBlockHeight, int nMinProtocol)
{
uint256 tmp;
return GetMasternodeRank(outpoint, nRankRet, tmp, nBlockHeight, nMinProtocol);
}
bool CMasternodeMan::GetMasternodeRank(const COutPoint& outpoint, int& nRankRet, uint256& blockHashRet, int nBlockHeight, int nMinProtocol)
{ {
nRankRet = -1; nRankRet = -1;
@ -828,8 +834,8 @@ bool CMasternodeMan::GetMasternodeRank(const COutPoint& outpoint, int& nRankRet,
return false; return false;
// make sure we know about this block // make sure we know about this block
uint256 nBlockHash = uint256(); blockHashRet = uint256();
if (!GetBlockHash(nBlockHash, nBlockHeight)) { if (!GetBlockHash(blockHashRet, nBlockHeight)) {
LogPrintf("CMasternodeMan::%s -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", __func__, nBlockHeight); LogPrintf("CMasternodeMan::%s -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", __func__, nBlockHeight);
return false; return false;
} }
@ -837,7 +843,7 @@ bool CMasternodeMan::GetMasternodeRank(const COutPoint& outpoint, int& nRankRet,
LOCK(cs); LOCK(cs);
score_pair_vec_t vecMasternodeScores; score_pair_vec_t vecMasternodeScores;
if (!GetMasternodeScores(nBlockHash, vecMasternodeScores, nMinProtocol)) if (!GetMasternodeScores(blockHashRet, vecMasternodeScores, nMinProtocol))
return false; return false;
int nRank = 0; int nRank = 0;

View File

@ -187,6 +187,7 @@ public:
bool GetMasternodeRanks(rank_pair_vec_t& vecMasternodeRanksRet, int nBlockHeight = -1, int nMinProtocol = 0); bool GetMasternodeRanks(rank_pair_vec_t& vecMasternodeRanksRet, int nBlockHeight = -1, int nMinProtocol = 0);
bool GetMasternodeRank(const COutPoint &outpoint, int& nRankRet, int nBlockHeight = -1, int nMinProtocol = 0); bool GetMasternodeRank(const COutPoint &outpoint, int& nRankRet, int nBlockHeight = -1, int nMinProtocol = 0);
bool GetMasternodeRank(const COutPoint &outpoint, int& nRankRet, uint256& blockHashRet, int nBlockHeight = -1, int nMinProtocol = 0);
void ProcessMasternodeConnections(CConnman& connman); void ProcessMasternodeConnections(CConnman& connman);
std::pair<CService, std::set<uint256> > PopScheduledMnbRequestConnection(); std::pair<CService, std::set<uint256> > PopScheduledMnbRequestConnection();