From: alex Date: Wed, 22 Jan 2014 16:21:42 +0000 (+0400) Subject: Sanity checking for coinstake inputs and checkwallet/repairwallet refactoring X-Git-Tag: v0.4.4.7-nvc-next-testing~9 X-Git-Url: https://git.novaco.in/?a=commitdiff_plain;h=8bcd64f62569c687b6f521872355a3100589a5df;hp=ec444599c0ee829118dbc89185a95ef16497b39d;p=novacoin.git Sanity checking for coinstake inputs and checkwallet/repairwallet refactoring --- diff --git a/src/kernel.cpp b/src/kernel.cpp index 85c0e36..1c1ca44 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -381,6 +381,13 @@ bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hash const CTxOut& txout = txPrev.vout[txin.prevout.n]; + // Check transaction consistency + if (txin.prevout.n >= txPrev.vout.size()) + { + fFatal = true; + return error("CheckProofOfStake() : invalid prevout found in coinstake %s", tx.GetHash().ToString().c_str()); + } + // Verify script if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, tx, 0, true, false, 0)) { diff --git a/src/wallet.cpp b/src/wallet.cpp index 025b6c9..4eef99e 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -2213,8 +2213,9 @@ set< set > CWallet::GetAddressGroupings() return ret; } -// ppcoin: check 'spent' consistency between wallet and txindex -// ppcoin: fix wallet spent state according to txindex +// 1. check 'spent' consistency between wallet and coins database +// 2. fix wallet spent state according to coins database +// 3. remove orphaned coinstakes and coinbases from wallet void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion, bool fCheckOnly) { nMismatchFound = 0; @@ -2229,46 +2230,50 @@ void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion, bool CCoinsViewCache &view = *pcoinsTip; BOOST_FOREACH(CWalletTx* pcoin, vCoins) { - // Find the corresponding transaction index - CCoins coins; + uint256 hash = pcoin->GetHash(); + if(!view.HaveCoins(hash)) + continue; - bool fNotFound = view.GetCoins(pcoin->GetHash(), coins); + // Find the corresponding transaction index + CCoins &coins = view.GetCoins(hash); for (unsigned int n=0; n < pcoin->vout.size(); n++) { - if (!fNotFound && IsMine(pcoin->vout[n]) && pcoin->IsSpent(n) && coins.IsAvailable(n)) + if (IsMine(pcoin->vout[n])) { - printf("FixSpentCoins found lost coin %sppc %s[%d], %s\n", - FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); - nMismatchFound++; - nBalanceInQuestion += pcoin->vout[n].nValue; - if (!fCheckOnly) + if (pcoin->IsSpent(n) && coins.IsAvailable(n)) { - pcoin->MarkUnspent(n); - pcoin->WriteToDisk(); + printf("FixSpentCoins found lost coin %snvc %s[%d], %s\n", + FormatMoney(pcoin->vout[n].nValue).c_str(), hash.ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); + nMismatchFound++; + nBalanceInQuestion += pcoin->vout[n].nValue; + if (!fCheckOnly) + { + pcoin->MarkUnspent(n); + pcoin->WriteToDisk(); + } } - } - else if (!fNotFound && IsMine(pcoin->vout[n]) && !pcoin->IsSpent(n) && coins.IsAvailable(n)) - { - printf("FixSpentCoins found spent coin %sppc %s[%d], %s\n", - FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); - nMismatchFound++; - nBalanceInQuestion += pcoin->vout[n].nValue; - if (!fCheckOnly) + else if (!pcoin->IsSpent(n) && !coins.IsAvailable(n)) { - pcoin->MarkSpent(n); - pcoin->WriteToDisk(); + printf("FixSpentCoins found spent coin %snvc %s[%d], %s\n", + FormatMoney(pcoin->vout[n].nValue).c_str(), hash.ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); + nMismatchFound++; + nBalanceInQuestion += pcoin->vout[n].nValue; + if (!fCheckOnly) + { + pcoin->MarkSpent(n); + pcoin->WriteToDisk(); + } } } - } - if(IsMine((CTransaction)*pcoin) && (pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetDepthInMainChain() == 0) + if((pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetDepthInMainChain() == 0) { - printf("FixSpentCoins %s tx %s\n", fCheckOnly ? "found" : "removed", pcoin->GetHash().ToString().c_str()); + printf("FixSpentCoins %s orphaned generation tx %s\n", fCheckOnly ? "found" : "removed", hash.ToString().c_str()); if (!fCheckOnly) { - EraseFromWallet(pcoin->GetHash()); + EraseFromWallet(hash); } } }