diff --git a/src/cheatcatcher.cpp b/src/cheatcatcher.cpp index 8cdfa9718..ab4af2141 100644 --- a/src/cheatcatcher.cpp +++ b/src/cheatcatcher.cpp @@ -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::iterator, multimap::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)) diff --git a/src/cheatcatcher.h b/src/cheatcatcher.h index dfce7a1db..7ae6c4e54 100644 --- a/src/cheatcatcher.h +++ b/src/cheatcatcher.h @@ -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); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f7af5ee50..3d89507b6 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -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;