Avoid any potential double staking penalty that make occur during repeated reorgs

This commit is contained in:
miketout
2018-11-02 03:05:51 -07:00
parent 3613db08b4
commit b276e36826
3 changed files with 39 additions and 1 deletions

View File

@@ -92,6 +92,40 @@ bool CCheatList::IsCheatInList(const CTransaction &tx, CTransaction *cheatTx)
return false;
}
bool CCheatList::IsUTXOInList(COutPoint _utxo, uint32_t height)
{
// for a tx to be cheat, it needs to spend the same UTXO and be for a different prior block
// the list should be pruned before this call
// we return the first valid cheat we find
CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION);
hw << _utxo.hash;
hw << _utxo.n;
uint256 utxo = hw.GetHash();
pair<multimap<const uint256, CTxHolder *>::iterator, multimap<const uint256, CTxHolder *>::iterator> range;
CStakeParams p, s;
LOCK(cs_cheat);
range = indexedCheatCandidates.equal_range(utxo);
for (auto it = range.first; it != range.second; it++)
{
CTransaction &cTx = it->second->tx;
//printf("cTx::opret : %s\n", cTx.vout[1].scriptPubKey.ToString().c_str());
// need both parameters to check
if (GetStakeParams(cTx, s))
{
if (s.blkHeight >= height)
{
return true;
}
}
}
return false;
}
bool CCheatList::Add(const CTxHolder &txh)
{
if (NetworkUpgradeActive(txh.height, Params().GetConsensus(), Consensus::UPGRADE_SAPLING))

View File

@@ -61,6 +61,9 @@ class CCheatList
// check to see if a transaction that could be a cheat for the passed transaction is in our list
bool IsCheatInList(const CTransaction &tx, CTransaction *pcheatTx);
// checks if the out point is in the list
bool IsUTXOInList(COutPoint _utxo, uint32_t height);
// check to see if there are cheat candidates of the same or greater block height in list
bool IsHeightOrGreaterInList(uint32_t height);

View File

@@ -1346,7 +1346,8 @@ bool CWallet::VerusSelectStakeOutput(CBlock *pBlock, arith_uint256 &hashResult,
if (txout.fSpendable && (UintToArith256(txout.tx->GetVerusPOSHash(&(pBlock->nNonce), txout.i, nHeight, pastHash)) <= target) && (txout.nDepth >= VERUS_MIN_STAKEAGE))
{
if ((!pwinner || UintToArith256(curNonce) > UintToArith256(pBlock->nNonce)) &&
(Solver(txout.tx->vout[txout.i].scriptPubKey, whichType, vSolutions) && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH)))
(Solver(txout.tx->vout[txout.i].scriptPubKey, whichType, vSolutions) && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH)) &&
!cheatList.IsUTXOInList(COutPoint(txout.tx->GetHash(), txout.i), nHeight <= 100 ? 1 : nHeight-100))
{
//printf("Found PoS block\nnNonce: %s\n", pBlock->nNonce.GetHex().c_str());
pwinner = &txout;