diff options
Diffstat (limited to 'src/walletdb.cpp')
| -rw-r--r-- | src/walletdb.cpp | 148 |
1 files changed, 121 insertions, 27 deletions
diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 2dc6594e9..b5b523740 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -11,8 +11,6 @@ #include "sync.h" #include "wallet.h" -#include <inttypes.h> - #include <boost/filesystem.hpp> #include <boost/foreach.hpp> @@ -154,12 +152,6 @@ bool CWalletDB::ErasePool(int64_t nPool) return Erase(std::make_pair(std::string("pool"), nPool)); } -bool CWalletDB::EraseSetting(const std::string& strKey) -{ - nWalletDBUpdated++; - return Erase(std::make_pair(std::string("setting"), strKey)); -} - bool CWalletDB::WriteMinVersion(int nVersion) { return Write(std::string("minversion"), nVersion); @@ -357,16 +349,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, { uint256 hash; ssKey >> hash; - CWalletTx& wtx = pwallet->mapWallet[hash]; + CWalletTx wtx; ssValue >> wtx; CValidationState state; if (CheckTransaction(wtx, state) && (wtx.GetHash() == hash) && state.IsValid()) wtx.BindWallet(pwallet); else - { - pwallet->mapWallet.erase(hash); return false; - } // Undo serialize changes in 31600 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703) @@ -377,12 +366,12 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, char fUnused; ssValue >> fTmp >> fUnused >> wtx.strFromAccount; strErr = strprintf("LoadWallet() upgrading tx ver=%d %d '%s' %s", - wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount.c_str(), hash.ToString().c_str()); + wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount, hash.ToString()); wtx.fTimeReceivedIsTxTime = fTmp; } else { - strErr = strprintf("LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString().c_str()); + strErr = strprintf("LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString()); wtx.fTimeReceivedIsTxTime = 0; } wss.vWalletUpgrade.push_back(hash); @@ -391,13 +380,14 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, if (wtx.nOrderPos == -1) wss.fAnyUnordered = true; + pwallet->AddToWallet(wtx, true); //// debug print - //LogPrintf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); + //LogPrintf("LoadWallet %s\n", wtx.GetHash().ToString()); //LogPrintf(" %12"PRId64" %s %s %s\n", // wtx.vout[0].nValue, - // DateTimeStrFormat("%Y-%m-%d %H:%M:%S", wtx.GetBlockTime()).c_str(), - // wtx.hashBlock.ToString().c_str(), - // wtx.mapValue["message"].c_str()); + // DateTimeStrFormat("%Y-%m-%d %H:%M:%S", wtx.GetBlockTime()), + // wtx.hashBlock.ToString(), + // wtx.mapValue["message"]); } else if (strType == "acentry") { @@ -566,6 +556,18 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, { ssValue >> pwallet->nOrderPosNext; } + else if (strType == "destdata") + { + std::string strAddress, strKey, strValue; + ssKey >> strAddress; + ssKey >> strKey; + ssValue >> strValue; + if (!pwallet->LoadDestData(CBitcoinAddress(strAddress).Get(), strKey, strValue)) + { + strErr = "Error reading wallet database: LoadDestData failed"; + return false; + } + } } catch (...) { return false; @@ -636,7 +638,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) } } if (!strErr.empty()) - LogPrintf("%s\n", strErr.c_str()); + LogPrintf("%s\n", strErr); } pcursor->close(); } @@ -680,6 +682,86 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) return result; } +DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash) +{ + pwallet->vchDefaultKey = CPubKey(); + CWalletScanState wss; + bool fNoncriticalErrors = false; + DBErrors result = DB_LOAD_OK; + + try { + LOCK(pwallet->cs_wallet); + int nMinVersion = 0; + if (Read((string)"minversion", nMinVersion)) + { + if (nMinVersion > CLIENT_VERSION) + return DB_TOO_NEW; + pwallet->LoadMinVersion(nMinVersion); + } + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + { + LogPrintf("Error getting wallet database cursor\n"); + return DB_CORRUPT; + } + + while (true) + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + LogPrintf("Error reading next record from wallet database\n"); + return DB_CORRUPT; + } + + string strType; + ssKey >> strType; + if (strType == "tx") { + uint256 hash; + ssKey >> hash; + + vTxHash.push_back(hash); + } + } + pcursor->close(); + } + catch (boost::thread_interrupted) { + throw; + } + catch (...) { + result = DB_CORRUPT; + } + + if (fNoncriticalErrors && result == DB_LOAD_OK) + result = DB_NONCRITICAL_ERROR; + + return result; +} + +DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet) +{ + // build list of wallet TXs + vector<uint256> vTxHash; + DBErrors err = FindWalletTx(pwallet, vTxHash); + if (err != DB_LOAD_OK) + return err; + + // erase each wallet TX + BOOST_FOREACH (uint256& hash, vTxHash) { + if (!EraseTx(hash)) + return DB_CORRUPT; + } + + return DB_LOAD_OK; +} + void ThreadFlushWalletDB(const string& strFile) { // Make this thread recognisable as the wallet flushing thread @@ -769,10 +851,10 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) #else filesystem::copy_file(pathSrc, pathDest); #endif - LogPrintf("copied wallet.dat to %s\n", pathDest.string().c_str()); + LogPrintf("copied wallet.dat to %s\n", pathDest.string()); return true; } catch(const filesystem::filesystem_error &e) { - LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what()); + LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what()); return false; } } @@ -800,10 +882,10 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) int result = dbenv.dbenv.dbrename(NULL, filename.c_str(), NULL, newFilename.c_str(), DB_AUTO_COMMIT); if (result == 0) - LogPrintf("Renamed %s to %s\n", filename.c_str(), newFilename.c_str()); + LogPrintf("Renamed %s to %s\n", filename, newFilename); else { - LogPrintf("Failed to rename %s to %s\n", filename.c_str(), newFilename.c_str()); + LogPrintf("Failed to rename %s to %s\n", filename, newFilename); return false; } @@ -811,7 +893,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) bool allOK = dbenv.Salvage(newFilename, true, salvagedData); if (salvagedData.empty()) { - LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename.c_str()); + LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename); return false; } LogPrintf("Salvage(aggressive) found %"PRIszu" records\n", salvagedData.size()); @@ -826,7 +908,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) 0); if (ret > 0) { - LogPrintf("Cannot create database file %s\n", filename.c_str()); + LogPrintf("Cannot create database file %s\n", filename); return false; } CWallet dummyWallet; @@ -846,7 +928,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) continue; if (!fReadOK) { - LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType.c_str(), strErr.c_str()); + LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType, strErr); continue; } } @@ -867,3 +949,15 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename) { return CWalletDB::Recover(dbenv, filename, false); } + +bool CWalletDB::WriteDestData(const std::string &address, const std::string &key, const std::string &value) +{ + nWalletDBUpdated++; + return Write(boost::make_tuple(std::string("destdata"), address, key), value); +} + +bool CWalletDB::EraseDestData(const std::string &address, const std::string &key) +{ + nWalletDBUpdated++; + return Erase(boost::make_tuple(string("destdata"), address, key)); +} |