Commit e8595792 authored by Tom Bradshaw's avatar Tom Bradshaw

Clean up stale proofs.

parent fedf4031
Pipeline #1020 failed with stage
in 9 minutes and 32 seconds
......@@ -3535,12 +3535,15 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
return error("%s: Proof of stake check failed", __func__);
// Check if this proof hash has been used to package other blocks
if (g_proofTracker->IsSuspicious(hashProofOfStake, pindex->GetBlockHash())) {
if (g_proofTracker->IsSuspicious(hashProofOfStake, pindex->GetBlockHash(), pindex->nHeight)) {
//Stake has been packaged into many different blocks. At this point we wait until enough masternodes have approved
//this block as on the main chain
return state.Suspicious(strprintf("%s: hashProofOfStake has appeared in too many blocks, waiting for masternode approval for "
"block %s", __func__, pindex->GetBlockHash().GetHex()));
}
// Remove any stale witnesses
g_proofTracker->EraseBeforeHeight(pindex->nHeight - Params().MaxReorganizationDepth());
}
int nHeight = pindex->nHeight;
......
......@@ -4,11 +4,11 @@
#define REQUIRED_WITNESS_SIGS 6
#define STAKE_REPACKAGE_THRESHOLD 3
void ProofTracker::AddNewStake(const STAKEHASH& hashStake, const BLOCKHASH& hashBlock)
void ProofTracker::AddNewStake(const STAKEHASH& hashStake, const BLOCKHASH& hashBlock, int nHeight)
{
if (!m_mapStakes.count(hashStake))
m_mapStakes.emplace(std::make_pair(hashStake, std::set<BLOCKHASH>()));
m_mapStakes.at(hashStake).emplace(hashBlock);
m_mapStakes.emplace(std::make_pair(hashStake, std::make_pair(nHeight, std::set<BLOCKHASH>())));
m_mapStakes.at(hashStake).second.emplace(hashBlock);
}
void ProofTracker::AddWitness(const BlockWitness& witness)
......@@ -37,14 +37,14 @@ bool ProofTracker::HasSufficientProof(const BLOCKHASH& hashBlock) const
return m_mapBlockWitness.count(hashBlock) && m_mapBlockWitness.at(hashBlock).size() >= REQUIRED_WITNESS_SIGS;
}
bool ProofTracker::IsSuspicious(const STAKEHASH& hashStake, const BLOCKHASH& hashBlock)
bool ProofTracker::IsSuspicious(const STAKEHASH& hashStake, const BLOCKHASH& hashBlock, int nHeight)
{
if (!m_mapStakes.count(hashStake)) {
AddNewStake(hashStake, hashBlock);
AddNewStake(hashStake, hashBlock, nHeight);
return false;
}
if (m_mapStakes.at(hashStake).size() >= STAKE_REPACKAGE_THRESHOLD) {
if (m_mapStakes.at(hashStake).second.size() >= STAKE_REPACKAGE_THRESHOLD) {
//If there are enough masternode that has signed off on this hash then it is not suspicious
if (!m_mapBlockWitness.count(hashBlock))
return true; //suspicious because no records of mn signing this block
......@@ -58,6 +58,27 @@ bool ProofTracker::IsSuspicious(const STAKEHASH& hashStake, const BLOCKHASH& has
//Not suspicious, but still record knowledge of this stake so potential suspicious repackaging of this stake
//can be tracked
AddNewStake(hashStake, hashBlock);
AddNewStake(hashStake, hashBlock, nHeight);
return false;
}
void ProofTracker::EraseBeforeHeight(int nHeight)
{
std::set<uint256> setErase;
for (const auto& p : m_mapStakes) {
int nBlockHeight = p.second.first;
if (nBlockHeight < nHeight) {
setErase.emplace(p.first);
//Erase all witnesses associated with this stake hash
const std::set<BLOCKHASH>& setWitness = p.second.second;
for (const uint256& hashBlock : setWitness) {
m_mapBlockWitness.erase(hashBlock);
}
}
}
for (const uint256& hashStake : setErase) {
m_mapStakes.erase(hashStake);
}
}
\ No newline at end of file
......@@ -10,14 +10,15 @@ typedef uint256 STAKEHASH;
class ProofTracker
{
private:
std::map<STAKEHASH, std::set<BLOCKHASH>> m_mapStakes;
std::map<STAKEHASH, std::pair<int, std::set<BLOCKHASH> > > m_mapStakes; // {stakehash => [height, blockhash]}
std::map<BLOCKHASH, std::set<BlockWitness>> m_mapBlockWitness;
void AddNewStake(const STAKEHASH& hashStake, const BLOCKHASH& hashBlock);
void AddNewStake(const STAKEHASH& hashStake, const BLOCKHASH& hashBlock, int nHeight);
public:
std::set<BlockWitness> GetWitnesses(const uint256& hashBlock) const;
bool HasSufficientProof(const BLOCKHASH& hashBlock) const;
bool IsSuspicious(const STAKEHASH& hash, const BLOCKHASH& hashBlock);
bool IsSuspicious(const STAKEHASH& hash, const BLOCKHASH& hashBlock, int nHeight);
void AddWitness(const BlockWitness& witness);
int GetWitnessCount(const BLOCKHASH& hashBlock) const;
void EraseBeforeHeight(int nHeight);
};
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment