From 7237fa069ba1e3c33769e03c883974350bb404d0 Mon Sep 17 00:00:00 2001 From: Sunny King Date: Thu, 22 Mar 2012 02:38:41 +0000 Subject: [PATCH] PPCoin: Add RPC command 'checkwallet' --- src/bitcoinrpc.cpp | 22 ++++++++++++++++++++++ src/wallet.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/wallet.h | 2 ++ 3 files changed, 63 insertions(+), 0 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 2f76057..e9b9dfb 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -1885,6 +1885,27 @@ Value reservebalance(const Array& params, bool fHelp) } +// ppcoin: check wallet integrity +Value checkwallet(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 0) + throw runtime_error( + "checkwallet\n" + "Check wallet for integrity.\n"); + + int nMismatchSpent; + int64 nBalanceInQuestion; + if (!pwalletMain->CheckSpentCoins(nMismatchSpent, nBalanceInQuestion)) + { + Object result; + result.push_back(Pair("mismatched spent coins", nMismatchSpent)); + result.push_back(Pair("amount in question", ValueFromAmount(nBalanceInQuestion))); + return result; + } + return Value::null; +} + + @@ -1938,6 +1959,7 @@ pair pCallTable[] = make_pair("resetcheckpoint", &resetcheckpoint), make_pair("getbranchpoint", &getbranchpoint), make_pair("reservebalance", &reservebalance), + make_pair("checkwallet", &checkwallet), }; map mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); diff --git a/src/wallet.cpp b/src/wallet.cpp index 564362b..e469803 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1471,6 +1471,45 @@ int64 CWallet::GetOldestKeyPoolTime() return keypool.nTime; } +// ppcoin: check 'spent' consistency between wallet and txindex +bool CWallet::CheckSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion) +{ + nMismatchFound = 0; + nBalanceInQuestion = 0; + CRITICAL_BLOCK(cs_wallet) + { + vector vCoins; + vCoins.reserve(mapWallet.size()); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + vCoins.push_back(&(*it).second); + + CTxDB txdb("r"); + BOOST_FOREACH(const CWalletTx* pcoin, vCoins) + { + // Find the corresponding transaction index + CTxIndex txindex; + if (!txdb.ReadTxIndex(pcoin->GetHash(), txindex)) + continue; + for (int n=0; n < pcoin->vout.size(); n++) + { + if (pcoin->IsSpent(n) && (txindex.vSpent.size() <= n || txindex.vSpent[n].IsNull())) + { + printf("CheckSpentCoins found lost coin %sppc %s[%d]\n", FormatMoney(pcoin->GetCredit()).c_str(), pcoin->GetHash().ToString().c_str(), n); + nMismatchFound++; + nBalanceInQuestion += pcoin->vout[n].nValue; + } + else if (!pcoin->IsSpent(n) && (txindex.vSpent.size() > n && !txindex.vSpent[n].IsNull())) + { + printf("CheckSpentCoins found spent coin %sppc %s[%d]\n", FormatMoney(pcoin->GetCredit()).c_str(), pcoin->GetHash().ToString().c_str(), n); + nMismatchFound++; + nBalanceInQuestion += pcoin->vout[n].nValue; + } + } + } + } + return (nMismatchFound == 0); +} + vector CReserveKey::GetReservedKey() { if (nIndex == -1) diff --git a/src/wallet.h b/src/wallet.h index 8769588..970f2e4 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -213,6 +213,8 @@ public: bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); bool SetDefaultKey(const std::vector &vchPubKey); + + bool CheckSpentCoins(int& nMismatchSpent, int64& nBalanceInQuestion); }; -- 1.7.1