Incorrect number of Masternode confirmations is used in CalculateScore
Problem
There is a crash that was caused by a bug in ' Masternode::CalculateScore' method for a masternode that just received the necessary number of confirmations (15) to be considered a valid node. The bug was caused by access to a non-existing block in the chain (next block to be created) because the CalculateScore consideres a Masternode valid only after 16 confirmations
//
// Deterministically calculate a given "score" for a Masternode depending on how close it's hash is to
// the proof of work for that block. The further away they are the better, the furthest will win the election
// and get paid this block
//
arith_uint256 CMasternode::CalculateScore(int64_t nBlockHeight) const
{
if(chainActive.Tip() == NULL)
return arith_uint256();
assert(chainActive.Height() >= GetInputHeight(vin) + MASTERNODE_MIN_CONFIRMATIONS); // <-- assertion failes
// Find the block hash where tx got MASTERNODE_MIN_CONFIRMATIONS
CBlockIndex *pblockIndex = chainActive[GetInputHeight(vin) + MASTERNODE_MIN_CONFIRMATIONS - 1]; // <-- crash was here
uint256 collateralMinConfBlockHash = pblockIndex->GetBlockHash();
uint256 hash = uint256();
if(!GetBlockHash(hash, nBlockHeight)) {
LogPrintf("CalculateScore ERROR - nHeight %d - Returned 0\n", nBlockHeight);
return arith_uint256();
}
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << vin.prevout << collateralMinConfBlockHash << hash;
return UintToArith256(ss.GetHash());
}
Solution
It's neccessary to change the logic so CalculateScore considers a masternode valid after 15 confirmations. The checks in CalculateScore
and
CheckInputsAndAdd(int& nDoS)
{
...
if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
...
}
should produce the same result so when a masternode is added to the list and the score is calculated
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information