PPCoin: Add RPC command 'checkwallet'
authorSunny King <sunnyking9999@gmail.com>
Thu, 22 Mar 2012 02:38:41 +0000 (02:38 +0000)
committerSunny King <sunnyking9999@gmail.com>
Thu, 22 Mar 2012 02:38:41 +0000 (02:38 +0000)
src/bitcoinrpc.cpp
src/wallet.cpp
src/wallet.h

index 2f76057..e9b9dfb 100644 (file)
@@ -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<string, rpcfn_type> pCallTable[] =
     make_pair("resetcheckpoint",        &resetcheckpoint),
     make_pair("getbranchpoint",         &getbranchpoint),
     make_pair("reservebalance",         &reservebalance),
+    make_pair("checkwallet",            &checkwallet),
 };
 map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
 
index 564362b..e469803 100644 (file)
@@ -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<const CWalletTx*> vCoins;
+       vCoins.reserve(mapWallet.size());
+       for (map<uint256, CWalletTx>::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<unsigned char> CReserveKey::GetReservedKey()
 {
     if (nIndex == -1)
index 8769588..970f2e4 100644 (file)
@@ -213,6 +213,8 @@ public:
     bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
 
     bool SetDefaultKey(const std::vector<unsigned char> &vchPubKey);
+
+    bool CheckSpentCoins(int& nMismatchSpent, int64& nBalanceInQuestion);
 };