diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro index 14ee947c..5d359c05 100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -117,9 +117,9 @@ HEADERS += src/qt/bitcoingui.h \ src/net.h \ src/key.h \ src/db.h \ + src/walletdb.h \ src/script.h \ src/init.h \ - src/headers.h \ src/irc.h \ src/mruset.h \ src/json/json_spirit_writer_template.h \ @@ -182,6 +182,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/checkpoints.cpp \ src/addrman.cpp \ src/db.cpp \ + src/walletdb.cpp \ src/json/json_spirit_writer.cpp \ src/json/json_spirit_value.cpp \ src/json/json_spirit_reader.cpp \ diff --git a/src/addrman.cpp b/src/addrman.cpp index 11dd2a7b..345261e2 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -8,12 +8,12 @@ using namespace std; int CAddrInfo::GetTriedBucket(const std::vector &nKey) const { - CDataStream ss1(SER_GETHASH); + CDataStream ss1(SER_GETHASH, 0); std::vector vchKey = GetKey(); ss1 << nKey << vchKey; uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64(); - CDataStream ss2(SER_GETHASH); + CDataStream ss2(SER_GETHASH, 0); std::vector vchGroupKey = GetGroup(); ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64(); @@ -22,13 +22,13 @@ int CAddrInfo::GetTriedBucket(const std::vector &nKey) const int CAddrInfo::GetNewBucket(const std::vector &nKey, const CNetAddr& src) const { - CDataStream ss1(SER_GETHASH); + CDataStream ss1(SER_GETHASH, 0); std::vector vchGroupKey = GetGroup(); std::vector vchSourceGroupKey = src.GetGroup(); ss1 << nKey << vchGroupKey << vchSourceGroupKey; uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64(); - CDataStream ss2(SER_GETHASH); + CDataStream ss2(SER_GETHASH, 0); ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64(); return hash2 % ADDRMAN_NEW_BUCKET_COUNT; diff --git a/src/allocators.h b/src/allocators.h index 85d9cfbb..cdea66dd 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -8,6 +8,9 @@ #include #ifdef WIN32 +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif #define _WIN32_WINNT 0x0501 #define WIN32_LEAN_AND_MEAN 1 #ifndef NOMINMAX diff --git a/src/bignum.h b/src/bignum.h index daf5f688..cea8e1e3 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -9,7 +9,7 @@ #include #include -#include "util.h" +#include "util.h" // for uint64 /** Errors thrown by the bignum class */ class bignum_error : public std::runtime_error diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 9fafee32..b7d00c40 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -3,10 +3,14 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" +#include "main.h" +#include "wallet.h" #include "db.h" +#include "walletdb.h" #include "net.h" #include "init.h" +#include "ui_interface.h" + #undef printf #include #include @@ -138,7 +142,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) { Object result; result.push_back(Pair("hash", block.GetHash().GetHex())); - result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK))); + result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); @@ -598,7 +602,7 @@ Value signmessage(const Array& params, bool fHelp) if (!pwalletMain->GetKey(addr, key)) throw JSONRPCError(-4, "Private key not available"); - CDataStream ss(SER_GETHASH); + CDataStream ss(SER_GETHASH, 0); ss << strMessageMagic; ss << strMessage; @@ -630,7 +634,7 @@ Value verifymessage(const Array& params, bool fHelp) if (fInvalid) throw JSONRPCError(-5, "Malformed base64 encoding"); - CDataStream ss(SER_GETHASH); + CDataStream ss(SER_GETHASH, 0); ss << strMessageMagic; ss << strMessage; @@ -1917,7 +1921,7 @@ Value getmemorypool(const Array& params, bool fHelp) if(tx.IsCoinBase()) continue; - CDataStream ssTx; + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << tx; transactions.push_back(HexStr(ssTx.begin(), ssTx.end())); @@ -1939,7 +1943,7 @@ Value getmemorypool(const Array& params, bool fHelp) else { // Parse parameters - CDataStream ssBlock(ParseHex(params[0].get_str())); + CDataStream ssBlock(ParseHex(params[0].get_str()), SER_NETWORK, PROTOCOL_VERSION); CBlock pblock; ssBlock >> pblock; diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index f5ce0538..cf56fa06 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -5,9 +5,11 @@ #include // for 'map_list_of()' #include -#include "headers.h" #include "checkpoints.h" +#include "main.h" +#include "uint256.h" + namespace Checkpoints { typedef std::map MapCheckpoints; diff --git a/src/checkpoints.h b/src/checkpoints.h index 38902ac0..5d3228f3 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -5,7 +5,6 @@ #define BITCOIN_CHECKPOINT_H #include -#include "util.h" class uint256; class CBlockIndex; diff --git a/src/compat.h b/src/compat.h index 88261003..db340445 100644 --- a/src/compat.h +++ b/src/compat.h @@ -5,6 +5,28 @@ #ifndef _BITCOIN_COMPAT_H #define _BITCOIN_COMPAT_H 1 +#ifdef WIN32 +#define _WIN32_WINNT 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#endif +#ifdef BSD +#include +#endif + typedef u_int SOCKET; #ifdef WIN32 #define MSG_NOSIGNAL 0 @@ -39,4 +61,5 @@ inline int myclosesocket(SOCKET& hSocket) } #define closesocket(s) myclosesocket(s) + #endif diff --git a/src/crypter.cpp b/src/crypter.cpp index 2501305e..4f37575a 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -6,14 +6,11 @@ #include #include #include -#include "headers.h" #ifdef WIN32 #include #endif #include "crypter.h" -#include "main.h" -#include "util.h" bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) { diff --git a/src/crypter.h b/src/crypter.h index 59a005a2..d1bdb92c 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -6,6 +6,7 @@ #include "allocators.h" /* for SecureString */ #include "key.h" +#include "serialize.h" const unsigned int WALLET_CRYPTO_KEY_SIZE = 32; const unsigned int WALLET_CRYPTO_SALT_SIZE = 8; diff --git a/src/db.cpp b/src/db.cpp index 2d136914..c67cf2f8 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -3,19 +3,22 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" #include "db.h" -#include "net.h" +#include "util.h" +#include "main.h" #include #include #include +#ifndef WIN32 +#include "sys/stat.h" +#endif + using namespace std; using namespace boost; unsigned int nWalletDBUpdated; -uint64 nAccountingEntryNumber = 0; @@ -23,10 +26,10 @@ uint64 nAccountingEntryNumber = 0; // CDB // -static CCriticalSection cs_db; +CCriticalSection cs_db; static bool fDbEnvInit = false; DbEnv dbenv(0); -static map mapFileUseCount; +map mapFileUseCount; static map mapDb; static void EnvShutdown() @@ -173,7 +176,7 @@ void CDB::Close() } } -void static CloseDb(const string& strFile) +void CloseDb(const string& strFile) { { LOCK(cs_db); @@ -225,8 +228,8 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) if (pcursor) while (fSuccess) { - CDataStream ssKey; - CDataStream ssValue; + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); if (ret == DB_NOTFOUND) { @@ -382,10 +385,10 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector& loop { // Read next record - CDataStream ssKey; + CDataStream ssKey(SER_DISK, CLIENT_VERSION); if (fFlags == DB_SET_RANGE) ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0); - CDataStream ssValue; + CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); fFlags = DB_NEXT; if (ret == DB_NOTFOUND) @@ -510,10 +513,10 @@ bool CTxDB::LoadBlockIndex() loop { // Read next record - CDataStream ssKey; + CDataStream ssKey(SER_DISK, CLIENT_VERSION); if (fFlags == DB_SET_RANGE) ssKey << make_pair(string("blockindex"), uint256(0)); - CDataStream ssValue; + CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); fFlags = DB_NEXT; if (ret == DB_NOTFOUND) @@ -750,8 +753,8 @@ bool CAddrDB::LoadAddresses() loop { // Read next record - CDataStream ssKey; - CDataStream ssValue; + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = ReadAtCursor(pcursor, ssKey, ssValue); if (ret == DB_NOTFOUND) break; @@ -786,414 +789,3 @@ bool LoadAddresses() } - - -// -// CWalletDB -// - -bool CWalletDB::WriteName(const string& strAddress, const string& strName) -{ - nWalletDBUpdated++; - return Write(make_pair(string("name"), strAddress), strName); -} - -bool CWalletDB::EraseName(const string& strAddress) -{ - // This should only be used for sending addresses, never for receiving addresses, - // receiving addresses must always have an address book entry if they're not change return. - nWalletDBUpdated++; - return Erase(make_pair(string("name"), strAddress)); -} - -bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account) -{ - account.SetNull(); - return Read(make_pair(string("acc"), strAccount), account); -} - -bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account) -{ - return Write(make_pair(string("acc"), strAccount), account); -} - -bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) -{ - return Write(boost::make_tuple(string("acentry"), acentry.strAccount, ++nAccountingEntryNumber), acentry); -} - -int64 CWalletDB::GetAccountCreditDebit(const string& strAccount) -{ - list entries; - ListAccountCreditDebit(strAccount, entries); - - int64 nCreditDebit = 0; - BOOST_FOREACH (const CAccountingEntry& entry, entries) - nCreditDebit += entry.nCreditDebit; - - return nCreditDebit; -} - -void CWalletDB::ListAccountCreditDebit(const string& strAccount, list& entries) -{ - bool fAllAccounts = (strAccount == "*"); - - Dbc* pcursor = GetCursor(); - if (!pcursor) - throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor"); - unsigned int fFlags = DB_SET_RANGE; - loop - { - // Read next record - CDataStream ssKey; - if (fFlags == DB_SET_RANGE) - ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64(0)); - CDataStream ssValue; - int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); - fFlags = DB_NEXT; - if (ret == DB_NOTFOUND) - break; - else if (ret != 0) - { - pcursor->close(); - throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB"); - } - - // Unserialize - string strType; - ssKey >> strType; - if (strType != "acentry") - break; - CAccountingEntry acentry; - ssKey >> acentry.strAccount; - if (!fAllAccounts && acentry.strAccount != strAccount) - break; - - ssValue >> acentry; - entries.push_back(acentry); - } - - pcursor->close(); -} - - -int CWalletDB::LoadWallet(CWallet* pwallet) -{ - pwallet->vchDefaultKey.clear(); - int nFileVersion = 0; - vector vWalletUpgrade; - bool fIsEncrypted = false; - - //// todo: shouldn't we catch exceptions and try to recover and continue? - { - 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) - { - printf("Error getting wallet database cursor\n"); - return DB_CORRUPT; - } - - loop - { - // Read next record - CDataStream ssKey; - CDataStream ssValue; - int ret = ReadAtCursor(pcursor, ssKey, ssValue); - if (ret == DB_NOTFOUND) - break; - else if (ret != 0) - { - printf("Error reading next record from wallet database\n"); - return DB_CORRUPT; - } - - // Unserialize - // Taking advantage of the fact that pair serialization - // is just the two items serialized one after the other - string strType; - ssKey >> strType; - if (strType == "name") - { - string strAddress; - ssKey >> strAddress; - ssValue >> pwallet->mapAddressBook[strAddress]; - } - else if (strType == "tx") - { - uint256 hash; - ssKey >> hash; - CWalletTx& wtx = pwallet->mapWallet[hash]; - ssValue >> wtx; - wtx.BindWallet(pwallet); - - if (wtx.GetHash() != hash) - printf("Error in wallet.dat, hash mismatch\n"); - - // Undo serialize changes in 31600 - if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703) - { - if (!ssValue.empty()) - { - char fTmp; - char fUnused; - ssValue >> fTmp >> fUnused >> wtx.strFromAccount; - printf("LoadWallet() upgrading tx ver=%d %d '%s' %s\n", wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount.c_str(), hash.ToString().c_str()); - wtx.fTimeReceivedIsTxTime = fTmp; - } - else - { - printf("LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString().c_str()); - wtx.fTimeReceivedIsTxTime = 0; - } - vWalletUpgrade.push_back(hash); - } - - //// debug print - //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); - //printf(" %12I64d %s %s %s\n", - // wtx.vout[0].nValue, - // DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()).c_str(), - // wtx.hashBlock.ToString().substr(0,20).c_str(), - // wtx.mapValue["message"].c_str()); - } - else if (strType == "acentry") - { - string strAccount; - ssKey >> strAccount; - uint64 nNumber; - ssKey >> nNumber; - if (nNumber > nAccountingEntryNumber) - nAccountingEntryNumber = nNumber; - } - else if (strType == "key" || strType == "wkey") - { - vector vchPubKey; - ssKey >> vchPubKey; - CKey key; - if (strType == "key") - { - CPrivKey pkey; - ssValue >> pkey; - key.SetPubKey(vchPubKey); - key.SetPrivKey(pkey); - if (key.GetPubKey() != vchPubKey) - { - printf("Error reading wallet database: CPrivKey pubkey inconsistency\n"); - return DB_CORRUPT; - } - if (!key.IsValid()) - { - printf("Error reading wallet database: invalid CPrivKey\n"); - return DB_CORRUPT; - } - } - else - { - CWalletKey wkey; - ssValue >> wkey; - key.SetPubKey(vchPubKey); - key.SetPrivKey(wkey.vchPrivKey); - if (key.GetPubKey() != vchPubKey) - { - printf("Error reading wallet database: CWalletKey pubkey inconsistency\n"); - return DB_CORRUPT; - } - if (!key.IsValid()) - { - printf("Error reading wallet database: invalid CWalletKey\n"); - return DB_CORRUPT; - } - } - if (!pwallet->LoadKey(key)) - { - printf("Error reading wallet database: LoadKey failed\n"); - return DB_CORRUPT; - } - } - else if (strType == "mkey") - { - unsigned int nID; - ssKey >> nID; - CMasterKey kMasterKey; - ssValue >> kMasterKey; - if(pwallet->mapMasterKeys.count(nID) != 0) - { - printf("Error reading wallet database: duplicate CMasterKey id %u\n", nID); - return DB_CORRUPT; - } - pwallet->mapMasterKeys[nID] = kMasterKey; - if (pwallet->nMasterKeyMaxID < nID) - pwallet->nMasterKeyMaxID = nID; - } - else if (strType == "ckey") - { - vector vchPubKey; - ssKey >> vchPubKey; - vector vchPrivKey; - ssValue >> vchPrivKey; - if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey)) - { - printf("Error reading wallet database: LoadCryptedKey failed\n"); - return DB_CORRUPT; - } - fIsEncrypted = true; - } - else if (strType == "defaultkey") - { - ssValue >> pwallet->vchDefaultKey; - } - else if (strType == "pool") - { - int64 nIndex; - ssKey >> nIndex; - pwallet->setKeyPool.insert(nIndex); - } - else if (strType == "version") - { - ssValue >> nFileVersion; - if (nFileVersion == 10300) - nFileVersion = 300; - } - else if (strType == "cscript") - { - uint160 hash; - ssKey >> hash; - CScript script; - ssValue >> script; - if (!pwallet->LoadCScript(script)) - { - printf("Error reading wallet database: LoadCScript failed\n"); - return DB_CORRUPT; - } - } - } - pcursor->close(); - } - - BOOST_FOREACH(uint256 hash, vWalletUpgrade) - WriteTx(hash, pwallet->mapWallet[hash]); - - printf("nFileVersion = %d\n", nFileVersion); - - - // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc: - if (fIsEncrypted && (nFileVersion == 40000 || nFileVersion == 50000)) - return DB_NEED_REWRITE; - - if (nFileVersion < CLIENT_VERSION) // Update - WriteVersion(CLIENT_VERSION); - - return DB_LOAD_OK; -} - -void ThreadFlushWalletDB(void* parg) -{ - const string& strFile = ((const string*)parg)[0]; - static bool fOneThread; - if (fOneThread) - return; - fOneThread = true; - if (!GetBoolArg("-flushwallet", true)) - return; - - unsigned int nLastSeen = nWalletDBUpdated; - unsigned int nLastFlushed = nWalletDBUpdated; - int64 nLastWalletUpdate = GetTime(); - while (!fShutdown) - { - Sleep(500); - - if (nLastSeen != nWalletDBUpdated) - { - nLastSeen = nWalletDBUpdated; - nLastWalletUpdate = GetTime(); - } - - if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) - { - TRY_LOCK(cs_db,lockDb); - if (lockDb) - { - // Don't do this if any databases are in use - int nRefCount = 0; - map::iterator mi = mapFileUseCount.begin(); - while (mi != mapFileUseCount.end()) - { - nRefCount += (*mi).second; - mi++; - } - - if (nRefCount == 0 && !fShutdown) - { - map::iterator mi = mapFileUseCount.find(strFile); - if (mi != mapFileUseCount.end()) - { - printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); - printf("Flushing wallet.dat\n"); - nLastFlushed = nWalletDBUpdated; - int64 nStart = GetTimeMillis(); - - // Flush wallet.dat so it's self contained - CloseDb(strFile); - dbenv.txn_checkpoint(0, 0, 0); - dbenv.lsn_reset(strFile.c_str(), 0); - - mapFileUseCount.erase(mi++); - printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); - } - } - } - } - } -} - -bool BackupWallet(const CWallet& wallet, const string& strDest) -{ - if (!wallet.fFileBacked) - return false; - while (!fShutdown) - { - { - LOCK(cs_db); - if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0) - { - // Flush log data to the dat file - CloseDb(wallet.strWalletFile); - dbenv.txn_checkpoint(0, 0, 0); - dbenv.lsn_reset(wallet.strWalletFile.c_str(), 0); - mapFileUseCount.erase(wallet.strWalletFile); - - // Copy wallet.dat - filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; - filesystem::path pathDest(strDest); - if (filesystem::is_directory(pathDest)) - pathDest /= wallet.strWalletFile; - - try { -#if BOOST_VERSION >= 104000 - filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists); -#else - filesystem::copy_file(pathSrc, pathDest); -#endif - printf("copied wallet.dat to %s\n", pathDest.string().c_str()); - return true; - } catch(const filesystem::filesystem_error &e) { - printf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what()); - return false; - } - } - } - Sleep(100); - } - return false; -} diff --git a/src/db.h b/src/db.h index 47fa4024..48e10a95 100644 --- a/src/db.h +++ b/src/db.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_DB_H #define BITCOIN_DB_H -#include "key.h" +#include "main.h" #include #include @@ -13,8 +13,6 @@ #include -class CAccount; -class CAccountingEntry; class CAddress; class CAddrMan; class CBlockLocator; @@ -59,7 +57,7 @@ protected: return false; // Key - CDataStream ssKey(SER_DISK); + CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; Dbt datKey(&ssKey[0], ssKey.size()); @@ -73,7 +71,7 @@ protected: return false; // Unserialize value - CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK); + CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); ssValue >> value; // Clear and free memory @@ -91,13 +89,13 @@ protected: assert(!"Write called on database in read-only mode"); // Key - CDataStream ssKey(SER_DISK); + CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; Dbt datKey(&ssKey[0], ssKey.size()); // Value - CDataStream ssValue(SER_DISK); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); ssValue.reserve(10000); ssValue << value; Dbt datValue(&ssValue[0], ssValue.size()); @@ -120,7 +118,7 @@ protected: assert(!"Erase called on database in read-only mode"); // Key - CDataStream ssKey(SER_DISK); + CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; Dbt datKey(&ssKey[0], ssKey.size()); @@ -140,7 +138,7 @@ protected: return false; // Key - CDataStream ssKey(SER_DISK); + CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; Dbt datKey(&ssKey[0], ssKey.size()); @@ -313,198 +311,4 @@ public: bool LoadAddresses(); -/** A key pool entry */ -class CKeyPool -{ -public: - int64 nTime; - std::vector vchPubKey; - - CKeyPool() - { - nTime = GetTime(); - } - - CKeyPool(const std::vector& vchPubKeyIn) - { - nTime = GetTime(); - vchPubKey = vchPubKeyIn; - } - - IMPLEMENT_SERIALIZE - ( - if (!(nType & SER_GETHASH)) - READWRITE(nVersion); - READWRITE(nTime); - READWRITE(vchPubKey); - ) -}; - - - -/** Error statuses for the wallet database */ -enum DBErrors -{ - DB_LOAD_OK, - DB_CORRUPT, - DB_TOO_NEW, - DB_LOAD_FAIL, - DB_NEED_REWRITE -}; - -/** Access to the wallet database (wallet.dat) */ -class CWalletDB : public CDB -{ -public: - CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode) - { - } -private: - CWalletDB(const CWalletDB&); - void operator=(const CWalletDB&); -public: - bool ReadName(const std::string& strAddress, std::string& strName) - { - strName = ""; - return Read(std::make_pair(std::string("name"), strAddress), strName); - } - - bool WriteName(const std::string& strAddress, const std::string& strName); - - bool EraseName(const std::string& strAddress); - - bool ReadTx(uint256 hash, CWalletTx& wtx) - { - return Read(std::make_pair(std::string("tx"), hash), wtx); - } - - bool WriteTx(uint256 hash, const CWalletTx& wtx) - { - nWalletDBUpdated++; - return Write(std::make_pair(std::string("tx"), hash), wtx); - } - - bool EraseTx(uint256 hash) - { - nWalletDBUpdated++; - return Erase(std::make_pair(std::string("tx"), hash)); - } - - bool ReadKey(const std::vector& vchPubKey, CPrivKey& vchPrivKey) - { - vchPrivKey.clear(); - return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey); - } - - bool WriteKey(const std::vector& vchPubKey, const CPrivKey& vchPrivKey) - { - nWalletDBUpdated++; - return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false); - } - - bool WriteCryptedKey(const std::vector& vchPubKey, const std::vector& vchCryptedSecret, bool fEraseUnencryptedKey = true) - { - nWalletDBUpdated++; - if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false)) - return false; - if (fEraseUnencryptedKey) - { - Erase(std::make_pair(std::string("key"), vchPubKey)); - Erase(std::make_pair(std::string("wkey"), vchPubKey)); - } - return true; - } - - bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) - { - nWalletDBUpdated++; - return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); - } - - // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013 - bool ReadCScript(const uint160 &hash, CScript& redeemScript) - { - redeemScript.clear(); - return Read(std::make_pair(std::string("cscript"), hash), redeemScript); - } - - bool WriteCScript(const uint160& hash, const CScript& redeemScript) - { - nWalletDBUpdated++; - return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false); - } - - bool WriteBestBlock(const CBlockLocator& locator) - { - nWalletDBUpdated++; - return Write(std::string("bestblock"), locator); - } - - bool ReadBestBlock(CBlockLocator& locator) - { - return Read(std::string("bestblock"), locator); - } - - bool ReadDefaultKey(std::vector& vchPubKey) - { - vchPubKey.clear(); - return Read(std::string("defaultkey"), vchPubKey); - } - - bool WriteDefaultKey(const std::vector& vchPubKey) - { - nWalletDBUpdated++; - return Write(std::string("defaultkey"), vchPubKey); - } - - bool ReadPool(int64 nPool, CKeyPool& keypool) - { - return Read(std::make_pair(std::string("pool"), nPool), keypool); - } - - bool WritePool(int64 nPool, const CKeyPool& keypool) - { - nWalletDBUpdated++; - return Write(std::make_pair(std::string("pool"), nPool), keypool); - } - - bool ErasePool(int64 nPool) - { - nWalletDBUpdated++; - return Erase(std::make_pair(std::string("pool"), nPool)); - } - - // Settings are no longer stored in wallet.dat; these are - // used only for backwards compatibility: - template - bool ReadSetting(const std::string& strKey, T& value) - { - return Read(std::make_pair(std::string("setting"), strKey), value); - } - template - bool WriteSetting(const std::string& strKey, const T& value) - { - nWalletDBUpdated++; - return Write(std::make_pair(std::string("setting"), strKey), value); - } - bool EraseSetting(const std::string& strKey) - { - nWalletDBUpdated++; - return Erase(std::make_pair(std::string("setting"), strKey)); - } - - bool WriteMinVersion(int nVersion) - { - return Write(std::string("minversion"), nVersion); - } - - bool ReadAccount(const std::string& strAccount, CAccount& account); - bool WriteAccount(const std::string& strAccount, const CAccount& account); - bool WriteAccountingEntry(const CAccountingEntry& acentry); - int64 GetAccountCreditDebit(const std::string& strAccount); - void ListAccountCreditDebit(const std::string& strAccount, std::list& acentries); - - int LoadWallet(CWallet* pwallet); -}; - -#endif +#endif // BITCOIN_DB_H diff --git a/src/headers.h b/src/headers.h deleted file mode 100644 index ceee0289..00000000 --- a/src/headers.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. - -#ifdef _MSC_VER -#pragma warning(disable:4786) -#pragma warning(disable:4804) -#pragma warning(disable:4805) -#pragma warning(disable:4717) -#endif -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 -#ifdef _WIN32_IE -#undef _WIN32_IE -#endif -#define _WIN32_IE 0x0400 -#define WIN32_LEAN_AND_MEAN 1 -#ifndef NOMINMAX -#define NOMINMAX -#endif -// Include boost/foreach here as it defines __STDC_LIMIT_MACROS on some systems. -#include - -#if (defined(__unix__) || defined(unix)) && !defined(USG) -#include // to get BSD define -#endif -#ifdef MAC_OSX -#ifndef BSD -#define BSD 1 -#endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -#include -#include -#include -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif -#ifdef BSD -#include -#endif - - -#include "serialize.h" -#include "uint256.h" -#include "util.h" -#include "bignum.h" -#include "base58.h" -#include "main.h" -#include "wallet.h" -#include "ui_interface.h" diff --git a/src/init.cpp b/src/init.cpp index 2be0027a..0eb37fe9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2,19 +2,20 @@ // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" #include "db.h" +#include "walletdb.h" #include "bitcoinrpc.h" #include "net.h" #include "init.h" -#include "strlcpy.h" +#include "util.h" +#include "ui_interface.h" #include #include #include #include -#ifdef WIN32 -#define strncasecmp strnicmp +#ifndef WIN32 +#include #endif using namespace std; @@ -583,145 +584,3 @@ bool AppInit2(int argc, char* argv[]) return true; } -#ifdef WIN32 -boost::filesystem::path StartupShortcutPath() -{ - return MyGetSpecialFolderPath(CSIDL_STARTUP, true) / "Bitcoin.lnk"; -} - -bool GetStartOnSystemStartup() -{ - return filesystem::exists(StartupShortcutPath()); -} - -bool SetStartOnSystemStartup(bool fAutoStart) -{ - // If the shortcut exists already, remove it for updating - boost::filesystem::remove(StartupShortcutPath()); - - if (fAutoStart) - { - CoInitialize(NULL); - - // Get a pointer to the IShellLink interface. - IShellLink* psl = NULL; - HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, - CLSCTX_INPROC_SERVER, IID_IShellLink, - reinterpret_cast(&psl)); - - if (SUCCEEDED(hres)) - { - // Get the current executable path - TCHAR pszExePath[MAX_PATH]; - GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); - - TCHAR pszArgs[5] = TEXT("-min"); - - // Set the path to the shortcut target - psl->SetPath(pszExePath); - PathRemoveFileSpec(pszExePath); - psl->SetWorkingDirectory(pszExePath); - psl->SetShowCmd(SW_SHOWMINNOACTIVE); - psl->SetArguments(pszArgs); - - // Query IShellLink for the IPersistFile interface for - // saving the shortcut in persistent storage. - IPersistFile* ppf = NULL; - hres = psl->QueryInterface(IID_IPersistFile, - reinterpret_cast(&ppf)); - if (SUCCEEDED(hres)) - { - WCHAR pwsz[MAX_PATH]; - // Ensure that the string is ANSI. - MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH); - // Save the link by calling IPersistFile::Save. - hres = ppf->Save(pwsz, TRUE); - ppf->Release(); - psl->Release(); - CoUninitialize(); - return true; - } - psl->Release(); - } - CoUninitialize(); - return false; - } - return true; -} - -#elif defined(LINUX) - -// Follow the Desktop Application Autostart Spec: -// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html - -boost::filesystem::path GetAutostartDir() -{ - namespace fs = boost::filesystem; - - char* pszConfigHome = getenv("XDG_CONFIG_HOME"); - if (pszConfigHome) return fs::path(pszConfigHome) / "autostart"; - char* pszHome = getenv("HOME"); - if (pszHome) return fs::path(pszHome) / ".config" / "autostart"; - return fs::path(); -} - -boost::filesystem::path GetAutostartFilePath() -{ - return GetAutostartDir() / "bitcoin.desktop"; -} - -bool GetStartOnSystemStartup() -{ - boost::filesystem::ifstream optionFile(GetAutostartFilePath()); - if (!optionFile.good()) - return false; - // Scan through file for "Hidden=true": - string line; - while (!optionFile.eof()) - { - getline(optionFile, line); - if (line.find("Hidden") != string::npos && - line.find("true") != string::npos) - return false; - } - optionFile.close(); - - return true; -} - -bool SetStartOnSystemStartup(bool fAutoStart) -{ - if (!fAutoStart) - boost::filesystem::remove(GetAutostartFilePath()); - else - { - char pszExePath[MAX_PATH+1]; - memset(pszExePath, 0, sizeof(pszExePath)); - if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1) - return false; - - boost::filesystem::create_directories(GetAutostartDir()); - - boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc); - if (!optionFile.good()) - return false; - // Write a bitcoin.desktop file to the autostart directory: - optionFile << "[Desktop Entry]\n"; - optionFile << "Type=Application\n"; - optionFile << "Name=Bitcoin\n"; - optionFile << "Exec=" << pszExePath << " -min\n"; - optionFile << "Terminal=false\n"; - optionFile << "Hidden=false\n"; - optionFile.close(); - } - return true; -} -#else - -// TODO: OSX startup stuff; see: -// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html - -bool GetStartOnSystemStartup() { return false; } -bool SetStartOnSystemStartup(bool fAutoStart) { return false; } - -#endif diff --git a/src/init.h b/src/init.h index 0d60e754..e3971c85 100644 --- a/src/init.h +++ b/src/init.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_INIT_H #define BITCOIN_INIT_H +#include "wallet.h" + extern CWallet* pwalletMain; void Shutdown(void* parg); diff --git a/src/irc.cpp b/src/irc.cpp index d535f59c..23749705 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -3,10 +3,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" #include "irc.h" #include "net.h" #include "strlcpy.h" +#include "base58.h" using namespace std; using namespace boost; diff --git a/src/key.h b/src/key.h index 8f220f1c..fc113182 100644 --- a/src/key.h +++ b/src/key.h @@ -12,7 +12,7 @@ #include #include -#include "serialize.h" +// #include "serialize.h" #include "uint256.h" // secp160k1 diff --git a/src/keystore.cpp b/src/keystore.cpp index 7b46f6b0..31351871 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -3,9 +3,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" -#include "crypter.h" -#include "db.h" +#include "keystore.h" #include "script.h" bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector &vchPubKeyOut) const diff --git a/src/keystore.h b/src/keystore.h index 5d29ac1c..76820e20 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -6,7 +6,10 @@ #define BITCOIN_KEYSTORE_H #include "crypter.h" -#include "script.h" +#include "util.h" +#include "base58.h" + +class CScript; /** A virtual base class for key stores */ class CKeyStore diff --git a/src/main.cpp b/src/main.cpp index 60b398c1..16a1f345 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,11 +2,11 @@ // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" #include "checkpoints.h" #include "db.h" #include "net.h" #include "init.h" +#include "ui_interface.h" #include #include #include @@ -411,7 +411,7 @@ bool CTransaction::CheckTransaction() const if (vout.empty()) return DoS(10, error("CTransaction::CheckTransaction() : vout empty")); // Size limits - if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE) + if (::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) return DoS(100, error("CTransaction::CheckTransaction() : size limits failed")); // Check for negative or overflow output values @@ -533,7 +533,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi // reasonable number of ECDSA signature verifications. int64 nFees = GetValueIn(mapInputs)-GetValueOut(); - unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK); + unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); // Don't accept it if it can't get into a block if (nFees < GetMinFee(1000, true, GMF_RELAY)) @@ -1279,7 +1279,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime); //// issue here: it doesn't know the version - unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size()); + unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - 1 + GetSizeOfCompactSize(vtx.size()); map mapQueuedChanges; int64 nFees = 0; @@ -1291,7 +1291,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) return DoS(100, error("ConnectBlock() : too many sigops")); CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); - nTxPos += ::GetSerializeSize(tx, SER_DISK); + nTxPos += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); MapPrevTx mapInputs; if (!tx.IsCoinBase()) @@ -1621,7 +1621,7 @@ bool CBlock::CheckBlock() const // that can be verified before saving an orphan block. // Size limits - if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE) + if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) return DoS(100, error("CheckBlock() : size limits failed")); // Check proof of work matches claimed amount @@ -1691,7 +1691,7 @@ bool CBlock::AcceptBlock() return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight)); // Write block to history file - if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK))) + if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION))) return error("AcceptBlock() : out of disk space"); unsigned int nFile = -1; unsigned int nBlockPos = 0; @@ -2481,7 +2481,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); CBlock block; block.ReadFromDisk(pindex, true); - nBytes += block.GetSerializeSize(SER_NETWORK); + nBytes += block.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION); if (--nLimit <= 0 || nBytes >= SendBufferSize()/2) { // When this block is requested, we'll send an inv that'll make them @@ -3174,7 +3174,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) } // Priority is sum(valuein * age) / txsize - dPriority /= ::GetSerializeSize(tx, SER_NETWORK); + dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); if (porphan) porphan->dPriority = dPriority; @@ -3203,7 +3203,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) mapPriority.erase(mapPriority.begin()); // Size limits - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK); + unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN) continue; diff --git a/src/main.h b/src/main.h index c48252fb..bcd62080 100644 --- a/src/main.h +++ b/src/main.h @@ -7,10 +7,7 @@ #include "bignum.h" #include "net.h" -#include "key.h" #include "script.h" -#include "db.h" -#include "version.h" #ifdef WIN32 #include /* for _commit */ @@ -18,13 +15,11 @@ #include +class CWallet; class CBlock; class CBlockIndex; -class CWalletTx; -class CWallet; class CKeyItem; class CReserveKey; -class CWalletDB; class CAddress; class CInv; @@ -35,8 +30,6 @@ static const unsigned int MAX_BLOCK_SIZE = 1000000; static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2; static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; static const int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100; -static const int64 COIN = 100000000; -static const int64 CENT = 1000000; static const int64 MIN_TX_FEE = 50000; static const int64 MIN_RELAY_TX_FEE = 10000; static const int64 MAX_MONEY = 21000000 * COIN; @@ -550,7 +543,7 @@ public: // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; - unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK); + unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); unsigned int nNewBlockSize = nBlockSize + nBytes; int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; @@ -595,7 +588,7 @@ public: bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) { - CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"); + CAutoFile filein = CAutoFile(OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"), SER_DISK, CLIENT_VERSION); if (!filein) return error("CTransaction::ReadFromDisk() : OpenBlockFile failed"); @@ -946,7 +939,7 @@ public: bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet) { // Open history file to append - CAutoFile fileout = AppendBlockFile(nFileRet); + CAutoFile fileout = CAutoFile(AppendBlockFile(nFileRet), SER_DISK, CLIENT_VERSION); if (!fileout) return error("CBlock::WriteToDisk() : AppendBlockFile failed"); @@ -979,7 +972,7 @@ public: SetNull(); // Open history file to read - CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb"); + CAutoFile filein = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb"), SER_DISK, CLIENT_VERSION); if (!filein) return error("CBlock::ReadFromDisk() : OpenBlockFile failed"); if (!fReadTransactions) @@ -1140,7 +1133,7 @@ public: bool EraseBlockFromDisk() { // Open history file - CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+"); + CAutoFile fileout = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb+"), SER_DISK, CLIENT_VERSION); if (!fileout) return false; @@ -1600,7 +1593,7 @@ public: return error("CAlert::CheckSignature() : verify signature failed"); // Now unserialize the data - CDataStream sMsg(vchMsg); + CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); sMsg >> *(CUnsignedAlert*)this; return true; } diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 9f005424..1ea65cd2 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -62,6 +62,7 @@ OBJS= \ obj/script.o \ obj/util.o \ obj/wallet.o \ + obj/walletdb.o \ obj/noui.o all: bitcoind.exe diff --git a/src/makefile.mingw b/src/makefile.mingw index 397fdf4f..5584df56 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -59,6 +59,7 @@ OBJS= \ obj/script.o \ obj/util.o \ obj/wallet.o \ + obj/walletdb.o \ obj/noui.o diff --git a/src/makefile.osx b/src/makefile.osx index e2e35de5..aaac6700 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -84,6 +84,7 @@ OBJS= \ obj/script.o \ obj/util.o \ obj/wallet.o \ + obj/walletdb.o \ obj/noui.o ifdef USE_UPNP diff --git a/src/makefile.unix b/src/makefile.unix index 9bc780d5..fc901ca0 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -103,6 +103,7 @@ OBJS= \ obj/script.o \ obj/util.o \ obj/wallet.o \ + obj/walletdb.o \ obj/noui.o diff --git a/src/net.cpp b/src/net.cpp index 7d621ac5..38c0d3d5 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3,13 +3,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" #include "irc.h" #include "db.h" #include "net.h" #include "init.h" #include "strlcpy.h" #include "addrman.h" +#include "ui_interface.h" #ifdef WIN32 #include diff --git a/src/net.h b/src/net.h index 95bda9ca..bad49a9f 100644 --- a/src/net.h +++ b/src/net.h @@ -157,14 +157,10 @@ public: CCriticalSection cs_inventory; std::multimap mapAskFor; - CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) + CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION) { nServices = 0; hSocket = hSocketIn; - vSend.SetType(SER_NETWORK); - vRecv.SetType(SER_NETWORK); - vSend.SetVersion(MIN_PROTO_VERSION); - vRecv.SetVersion(MIN_PROTO_VERSION); nLastSend = 0; nLastRecv = 0; nLastSendEmpty = GetTime(); @@ -612,7 +608,7 @@ inline void RelayInventory(const CInv& inv) template void RelayMessage(const CInv& inv, const T& a) { - CDataStream ss(SER_NETWORK); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(10000); ss << a; RelayMessage(inv, ss); @@ -631,7 +627,7 @@ inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) } // Save original serialized message so newer versions are preserved - mapRelay[inv] = ss; + mapRelay.insert(std::make_pair(inv, ss)); vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv)); } diff --git a/src/netbase.h b/src/netbase.h index 6a257cf9..00b6850b 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -7,27 +7,6 @@ #include #include -#ifdef WIN32 -#define _WIN32_WINNT 0x0501 -#define WIN32_LEAN_AND_MEAN 1 -#ifndef NOMINMAX -#define NOMINMAX -#endif -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#endif -#ifdef BSD -#include -#endif - #include "serialize.h" #include "compat.h" diff --git a/src/noui.cpp b/src/noui.cpp index 077e460a..08a08b43 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -5,7 +5,6 @@ #include "ui_interface.h" #include -#include "headers.h" #include "init.h" int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) diff --git a/src/protocol.h b/src/protocol.h index a820563d..f7331c19 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -12,7 +12,6 @@ #include "serialize.h" #include "netbase.h" -#include "util.h" #include #include "uint256.h" diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 0239a167..7b95f51c 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -2,7 +2,7 @@ #include "guiutil.h" #include "walletmodel.h" -#include "headers.h" +#include "wallet.h" #include #include diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 463b2cfa..c7830871 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -7,8 +7,8 @@ #include "optionsmodel.h" #include "guiutil.h" -#include "headers.h" #include "init.h" +#include "ui_interface.h" #include "qtipcserver.h" #include diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 284bee0e..cb602ce3 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -4,7 +4,7 @@ #include "addresstablemodel.h" #include "transactiontablemodel.h" -#include "headers.h" +#include "main.h" #include diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index cb247324..f1e8a5f1 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -3,8 +3,6 @@ #include "walletmodel.h" #include "bitcoinunits.h" -#include "headers.h" - #include #include #include diff --git a/src/qt/messagepage.cpp b/src/qt/messagepage.cpp index 46a0cbae..18bb64fe 100644 --- a/src/qt/messagepage.cpp +++ b/src/qt/messagepage.cpp @@ -91,7 +91,7 @@ void MessagePage::on_signMessage_clicked() return; } - CDataStream ss(SER_GETHASH); + CDataStream ss(SER_GETHASH, 0); ss << strMessageMagic; ss << ui->message->document()->toPlainText().toStdString(); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index ed2225cb..f7d9b0da 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -2,8 +2,8 @@ #include "bitcoinunits.h" #include -#include "headers.h" #include "init.h" +#include "walletdb.h" OptionsModel::OptionsModel(QObject *parent) : QAbstractListModel(parent) diff --git a/src/qt/qtipcserver.cpp b/src/qt/qtipcserver.cpp index 3c7889ca..102ac0ff 100644 --- a/src/qt/qtipcserver.cpp +++ b/src/qt/qtipcserver.cpp @@ -7,7 +7,8 @@ #include #include -#include "headers.h" +#include "ui_interface.h" +#include "util.h" #include "qtipcserver.h" using namespace boost::interprocess; diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index dd7dd613..286cddf2 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -3,7 +3,9 @@ #include "guiutil.h" #include "bitcoinunits.h" -#include "headers.h" +#include "main.h" +#include "wallet.h" +#include "db.h" #include "ui_interface.h" #include diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 2f3b29cc..32350eaa 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -1,6 +1,6 @@ #include "transactionrecord.h" -#include "headers.h" +#include "wallet.h" /* Return positive answer if transaction should be shown in list. */ diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 41c9db11..5f505f44 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -8,7 +8,7 @@ #include "addresstablemodel.h" #include "bitcoinunits.h" -#include "headers.h" +#include "wallet.h" #include #include diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 9c28a8ab..7a83f6ce 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -4,8 +4,9 @@ #include "addresstablemodel.h" #include "transactiontablemodel.h" -#include "headers.h" -#include "db.h" // for BackupWallet +#include "ui_interface.h" +#include "wallet.h" +#include "walletdb.h" // for BackupWallet #include diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 5bb4789c..1bc87e92 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -2,9 +2,9 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" #include "init.h" // for pwalletMain #include "bitcoinrpc.h" +#include "ui_interface.h" #include diff --git a/src/script.cpp b/src/script.cpp index 21f101e1..fc0a5b3e 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -2,11 +2,17 @@ // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" +#include using namespace std; using namespace boost; +#include "script.h" +#include "keystore.h" +#include "bignum.h" +#include "key.h" +#include "main.h" + bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); @@ -1086,7 +1092,7 @@ uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int } // Serialize and hash - CDataStream ss(SER_GETHASH); + CDataStream ss(SER_GETHASH, 0); ss.reserve(10000); ss << txTmp << nHashType; return Hash(ss.begin(), ss.end()); diff --git a/src/serialize.h b/src/serialize.h index 89f498e7..12ea1ec6 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -57,7 +57,7 @@ enum }; #define IMPLEMENT_SERIALIZE(statements) \ - unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const \ + unsigned int GetSerializeSize(int nType, int nVersion) const \ { \ CSerActionGetSerializeSize ser_action; \ const bool fGetSize = true; \ @@ -72,7 +72,7 @@ enum return nSerSize; \ } \ template \ - void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const \ + void Serialize(Stream& s, int nType, int nVersion) const \ { \ CSerActionSerialize ser_action; \ const bool fGetSize = false; \ @@ -83,7 +83,7 @@ enum {statements} \ } \ template \ - void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) \ + void Unserialize(Stream& s, int nType, int nVersion) \ { \ CSerActionUnserialize ser_action; \ const bool fGetSize = false; \ @@ -287,43 +287,43 @@ template void Unserialize(Stream& is, std::basic_st // vector template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&); template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&); -template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion=PROTOCOL_VERSION); +template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion); template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&); template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&); -template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion=PROTOCOL_VERSION); +template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion); template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&); template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&); -template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion=PROTOCOL_VERSION); +template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion); // others derived from vector -extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const CScript& v, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, CScript& v, int nType, int nVersion=PROTOCOL_VERSION); +extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion); +template void Serialize(Stream& os, const CScript& v, int nType, int nVersion); +template void Unserialize(Stream& is, CScript& v, int nType, int nVersion); // pair -template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion); +template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion); +template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion); // 3 tuple -template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); // 4 tuple -template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); // map -template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const std::map& m, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, std::map& m, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::map& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::map& m, int nType, int nVersion); // set -template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const std::set& m, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, std::set& m, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::set& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::set& m, int nType, int nVersion); @@ -336,19 +336,19 @@ template void Unserializ // Thanks to Boost serialization for this idea. // template -inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=PROTOCOL_VERSION) +inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion) { return a.GetSerializeSize((int)nType, nVersion); } template -inline void Serialize(Stream& os, const T& a, long nType, int nVersion=PROTOCOL_VERSION) +inline void Serialize(Stream& os, const T& a, long nType, int nVersion) { a.Serialize(os, (int)nType, nVersion); } template -inline void Unserialize(Stream& is, T& a, long nType, int nVersion=PROTOCOL_VERSION) +inline void Unserialize(Stream& is, T& a, long nType, int nVersion) { a.Unserialize(is, (int)nType, nVersion); } @@ -730,39 +730,39 @@ public: typedef vector_type::const_iterator const_iterator; typedef vector_type::reverse_iterator reverse_iterator; - explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) + explicit CDataStream(int nTypeIn, int nVersionIn) { Init(nTypeIn, nVersionIn); } - CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend) + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) { Init(nTypeIn, nVersionIn); } #if !defined(_MSC_VER) || _MSC_VER >= 1300 - CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend) + CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) { Init(nTypeIn, nVersionIn); } #endif - CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end()) + CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) { Init(nTypeIn, nVersionIn); } - CDataStream(const std::vector& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end()) + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) { Init(nTypeIn, nVersionIn); } - CDataStream(const std::vector& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) { Init(nTypeIn, nVersionIn); } - void Init(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) + void Init(int nTypeIn, int nVersionIn) { nReadPos = 0; nType = nTypeIn; @@ -976,7 +976,7 @@ public: } template - void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const + void Serialize(Stream& s, int nType, int nVersion) const { // Special case: stream << stream concatenates like stream += stream if (!vch.empty()) @@ -1085,7 +1085,7 @@ public: typedef FILE element_type; - CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=PROTOCOL_VERSION) + CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) { file = filenew; nType = nTypeIn; diff --git a/src/strlcpy.h b/src/strlcpy.h index d4d1908e..2cc786e9 100644 --- a/src/strlcpy.h +++ b/src/strlcpy.h @@ -15,6 +15,10 @@ */ #ifndef BITCOIN_STRLCPY_H #define BITCOIN_STRLCPY_H + +#include +#include + /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). diff --git a/src/uint256.h b/src/uint256.h index 309c1f79..bf3c55bc 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -5,9 +5,8 @@ #ifndef BITCOIN_UINT256_H #define BITCOIN_UINT256_H -#include "serialize.h" - #include +#include #include #include @@ -354,19 +353,22 @@ public: return pn[2*n] | (uint64)pn[2*n+1] << 32; } - unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const +// unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const + unsigned int GetSerializeSize(int nType, int nVersion) const { return sizeof(pn); } template - void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const +// void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const + void Serialize(Stream& s, int nType, int nVersion) const { s.write((char*)pn, sizeof(pn)); } template - void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) +// void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) + void Unserialize(Stream& s, int nType, int nVersion) { s.read((char*)pn, sizeof(pn)); } diff --git a/src/util.cpp b/src/util.cpp index c1e3c5a8..ac65d417 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -3,8 +3,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" +#include "util.h" #include "strlcpy.h" +#include "version.h" +#include "ui_interface.h" #include // Work around clang compilation problem in Boost 1.46: @@ -24,6 +26,31 @@ namespace boost { #include #include #include +#include +#include + +#ifdef WIN32 +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4804) +#pragma warning(disable:4805) +#pragma warning(disable:4717) +#endif +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0400 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include "shlobj.h" +#include "shlwapi.h" +#endif using namespace std; using namespace boost; @@ -1064,6 +1091,149 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const return ss.str(); } +#ifdef WIN32 +boost::filesystem::path static StartupShortcutPath() +{ + return MyGetSpecialFolderPath(CSIDL_STARTUP, true) / "Bitcoin.lnk"; +} + +bool GetStartOnSystemStartup() +{ + return filesystem::exists(StartupShortcutPath()); +} + +bool SetStartOnSystemStartup(bool fAutoStart) +{ + // If the shortcut exists already, remove it for updating + boost::filesystem::remove(StartupShortcutPath()); + + if (fAutoStart) + { + CoInitialize(NULL); + + // Get a pointer to the IShellLink interface. + IShellLink* psl = NULL; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); + + if (SUCCEEDED(hres)) + { + // Get the current executable path + TCHAR pszExePath[MAX_PATH]; + GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); + + TCHAR pszArgs[5] = TEXT("-min"); + + // Set the path to the shortcut target + psl->SetPath(pszExePath); + PathRemoveFileSpec(pszExePath); + psl->SetWorkingDirectory(pszExePath); + psl->SetShowCmd(SW_SHOWMINNOACTIVE); + psl->SetArguments(pszArgs); + + // Query IShellLink for the IPersistFile interface for + // saving the shortcut in persistent storage. + IPersistFile* ppf = NULL; + hres = psl->QueryInterface(IID_IPersistFile, + reinterpret_cast(&ppf)); + if (SUCCEEDED(hres)) + { + WCHAR pwsz[MAX_PATH]; + // Ensure that the string is ANSI. + MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH); + // Save the link by calling IPersistFile::Save. + hres = ppf->Save(pwsz, TRUE); + ppf->Release(); + psl->Release(); + CoUninitialize(); + return true; + } + psl->Release(); + } + CoUninitialize(); + return false; + } + return true; +} + +#elif defined(LINUX) + +// Follow the Desktop Application Autostart Spec: +// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html + +boost::filesystem::path static GetAutostartDir() +{ + namespace fs = boost::filesystem; + + char* pszConfigHome = getenv("XDG_CONFIG_HOME"); + if (pszConfigHome) return fs::path(pszConfigHome) / "autostart"; + char* pszHome = getenv("HOME"); + if (pszHome) return fs::path(pszHome) / ".config" / "autostart"; + return fs::path(); +} + +boost::filesystem::path static GetAutostartFilePath() +{ + return GetAutostartDir() / "bitcoin.desktop"; +} + +bool GetStartOnSystemStartup() +{ + boost::filesystem::ifstream optionFile(GetAutostartFilePath()); + if (!optionFile.good()) + return false; + // Scan through file for "Hidden=true": + string line; + while (!optionFile.eof()) + { + getline(optionFile, line); + if (line.find("Hidden") != string::npos && + line.find("true") != string::npos) + return false; + } + optionFile.close(); + + return true; +} + +bool SetStartOnSystemStartup(bool fAutoStart) +{ + if (!fAutoStart) + boost::filesystem::remove(GetAutostartFilePath()); + else + { + char pszExePath[MAX_PATH+1]; + memset(pszExePath, 0, sizeof(pszExePath)); + if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1) + return false; + + boost::filesystem::create_directories(GetAutostartDir()); + + boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc); + if (!optionFile.good()) + return false; + // Write a bitcoin.desktop file to the autostart directory: + optionFile << "[Desktop Entry]\n"; + optionFile << "Type=Application\n"; + optionFile << "Name=Bitcoin\n"; + optionFile << "Exec=" << pszExePath << " -min\n"; + optionFile << "Terminal=false\n"; + optionFile << "Hidden=false\n"; + optionFile.close(); + } + return true; +} +#else + +// TODO: OSX startup stuff; see: +// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html + +bool GetStartOnSystemStartup() { return false; } +bool SetStartOnSystemStartup(bool fAutoStart) { return false; } + +#endif + #ifdef DEBUG_LOCKORDER diff --git a/src/util.h b/src/util.h index f6cb3caa..d9ec68c6 100644 --- a/src/util.h +++ b/src/util.h @@ -31,11 +31,14 @@ typedef int pid_t; /* define for windows compatiblity */ #include #include -#include "netbase.h" +#include "netbase.h" // for AddTimeData typedef long long int64; typedef unsigned long long uint64; +static const int64 COIN = 100000000; +static const int64 CENT = 1000000; + #define loop for (;;) #define BEGIN(a) ((char*)&(a)) #define END(a) ((char*)&((&(a))[1])) @@ -160,9 +163,8 @@ boost::filesystem::path GetConfigFile(); boost::filesystem::path GetPidFile(); void CreatePidFile(const boost::filesystem::path &path, pid_t pid); bool ReadConfigFile(std::map& mapSettingsRet, std::map >& mapMultiSettingsRet); -#ifdef WIN32 -boost::filesystem::path MyGetSpecialFolderPath(int nFolder, bool fCreate); -#endif +bool GetStartOnSystemStartup(); +bool SetStartOnSystemStartup(bool fAutoStart); void ShrinkDebugFile(); int GetRandInt(int nMax); uint64 GetRand(uint64 nMax); diff --git a/src/wallet.cpp b/src/wallet.cpp index 9f531082..53836be0 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -3,9 +3,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" -#include "db.h" +#include "wallet.h" +#include "walletdb.h" #include "crypter.h" +#include "ui_interface.h" using namespace std; @@ -137,6 +138,11 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, return false; } +void CWallet::SetBestChain(const CBlockLocator& loc) +{ + CWalletDB walletdb(strWalletFile); + walletdb.WriteBestBlock(loc); +} // This class implements an addrIncoming entry that causes pre-0.4 // clients to crash on startup if reading a private-key-encrypted wallet. @@ -1116,7 +1122,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW return false; // Limit size - unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK); + unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION); if (nBytes >= MAX_BLOCK_SIZE_GEN/5) return false; dPriority /= nBytes; diff --git a/src/wallet.h b/src/wallet.h index b1ee40ab..c1461b1f 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_WALLET_H #define BITCOIN_WALLET_H -#include "bignum.h" +#include "main.h" #include "key.h" #include "keystore.h" #include "script.h" @@ -25,6 +25,34 @@ enum WalletFeature FEATURE_LATEST = 60000 }; + +/** A key pool entry */ +class CKeyPool +{ +public: + int64 nTime; + std::vector vchPubKey; + + CKeyPool() + { + nTime = GetTime(); + } + + CKeyPool(const std::vector& vchPubKeyIn) + { + nTime = GetTime(); + vchPubKey = vchPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(nTime); + READWRITE(vchPubKey); + ) +}; + /** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, * and provides the ability to create new transactions. */ @@ -196,11 +224,7 @@ public: } return nChange; } - void SetBestChain(const CBlockLocator& loc) - { - CWalletDB walletdb(strWalletFile); - walletdb.WriteBestBlock(loc); - } + void SetBestChain(const CBlockLocator& loc); int LoadWallet(bool& fFirstRunRet); // bool BackupWallet(const std::string& strDest); diff --git a/src/walletdb.cpp b/src/walletdb.cpp new file mode 100644 index 00000000..709ecac1 --- /dev/null +++ b/src/walletdb.cpp @@ -0,0 +1,428 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "walletdb.h" +#include "wallet.h" +#include + +using namespace std; +using namespace boost; + + +static uint64 nAccountingEntryNumber = 0; + +extern CCriticalSection cs_db; +extern map mapFileUseCount; +extern void CloseDb(const string& strFile); + +// +// CWalletDB +// + +bool CWalletDB::WriteName(const string& strAddress, const string& strName) +{ + nWalletDBUpdated++; + return Write(make_pair(string("name"), strAddress), strName); +} + +bool CWalletDB::EraseName(const string& strAddress) +{ + // This should only be used for sending addresses, never for receiving addresses, + // receiving addresses must always have an address book entry if they're not change return. + nWalletDBUpdated++; + return Erase(make_pair(string("name"), strAddress)); +} + +bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account) +{ + account.SetNull(); + return Read(make_pair(string("acc"), strAccount), account); +} + +bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account) +{ + return Write(make_pair(string("acc"), strAccount), account); +} + +bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) +{ + return Write(boost::make_tuple(string("acentry"), acentry.strAccount, ++nAccountingEntryNumber), acentry); +} + +int64 CWalletDB::GetAccountCreditDebit(const string& strAccount) +{ + list entries; + ListAccountCreditDebit(strAccount, entries); + + int64 nCreditDebit = 0; + BOOST_FOREACH (const CAccountingEntry& entry, entries) + nCreditDebit += entry.nCreditDebit; + + return nCreditDebit; +} + +void CWalletDB::ListAccountCreditDebit(const string& strAccount, list& entries) +{ + bool fAllAccounts = (strAccount == "*"); + + Dbc* pcursor = GetCursor(); + if (!pcursor) + throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor"); + unsigned int fFlags = DB_SET_RANGE; + loop + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + if (fFlags == DB_SET_RANGE) + ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64(0)); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + pcursor->close(); + throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB"); + } + + // Unserialize + string strType; + ssKey >> strType; + if (strType != "acentry") + break; + CAccountingEntry acentry; + ssKey >> acentry.strAccount; + if (!fAllAccounts && acentry.strAccount != strAccount) + break; + + ssValue >> acentry; + entries.push_back(acentry); + } + + pcursor->close(); +} + + +int CWalletDB::LoadWallet(CWallet* pwallet) +{ + pwallet->vchDefaultKey.clear(); + int nFileVersion = 0; + vector vWalletUpgrade; + bool fIsEncrypted = false; + + //// todo: shouldn't we catch exceptions and try to recover and continue? + { + 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) + { + printf("Error getting wallet database cursor\n"); + return DB_CORRUPT; + } + + loop + { + // 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) + { + printf("Error reading next record from wallet database\n"); + return DB_CORRUPT; + } + + // Unserialize + // Taking advantage of the fact that pair serialization + // is just the two items serialized one after the other + string strType; + ssKey >> strType; + if (strType == "name") + { + string strAddress; + ssKey >> strAddress; + ssValue >> pwallet->mapAddressBook[strAddress]; + } + else if (strType == "tx") + { + uint256 hash; + ssKey >> hash; + CWalletTx& wtx = pwallet->mapWallet[hash]; + ssValue >> wtx; + wtx.BindWallet(pwallet); + + if (wtx.GetHash() != hash) + printf("Error in wallet.dat, hash mismatch\n"); + + // Undo serialize changes in 31600 + if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703) + { + if (!ssValue.empty()) + { + char fTmp; + char fUnused; + ssValue >> fTmp >> fUnused >> wtx.strFromAccount; + printf("LoadWallet() upgrading tx ver=%d %d '%s' %s\n", wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount.c_str(), hash.ToString().c_str()); + wtx.fTimeReceivedIsTxTime = fTmp; + } + else + { + printf("LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString().c_str()); + wtx.fTimeReceivedIsTxTime = 0; + } + vWalletUpgrade.push_back(hash); + } + + //// debug print + //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); + //printf(" %12I64d %s %s %s\n", + // wtx.vout[0].nValue, + // DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()).c_str(), + // wtx.hashBlock.ToString().substr(0,20).c_str(), + // wtx.mapValue["message"].c_str()); + } + else if (strType == "acentry") + { + string strAccount; + ssKey >> strAccount; + uint64 nNumber; + ssKey >> nNumber; + if (nNumber > nAccountingEntryNumber) + nAccountingEntryNumber = nNumber; + } + else if (strType == "key" || strType == "wkey") + { + vector vchPubKey; + ssKey >> vchPubKey; + CKey key; + if (strType == "key") + { + CPrivKey pkey; + ssValue >> pkey; + key.SetPubKey(vchPubKey); + key.SetPrivKey(pkey); + if (key.GetPubKey() != vchPubKey) + { + printf("Error reading wallet database: CPrivKey pubkey inconsistency\n"); + return DB_CORRUPT; + } + if (!key.IsValid()) + { + printf("Error reading wallet database: invalid CPrivKey\n"); + return DB_CORRUPT; + } + } + else + { + CWalletKey wkey; + ssValue >> wkey; + key.SetPubKey(vchPubKey); + key.SetPrivKey(wkey.vchPrivKey); + if (key.GetPubKey() != vchPubKey) + { + printf("Error reading wallet database: CWalletKey pubkey inconsistency\n"); + return DB_CORRUPT; + } + if (!key.IsValid()) + { + printf("Error reading wallet database: invalid CWalletKey\n"); + return DB_CORRUPT; + } + } + if (!pwallet->LoadKey(key)) + { + printf("Error reading wallet database: LoadKey failed\n"); + return DB_CORRUPT; + } + } + else if (strType == "mkey") + { + unsigned int nID; + ssKey >> nID; + CMasterKey kMasterKey; + ssValue >> kMasterKey; + if(pwallet->mapMasterKeys.count(nID) != 0) + { + printf("Error reading wallet database: duplicate CMasterKey id %u\n", nID); + return DB_CORRUPT; + } + pwallet->mapMasterKeys[nID] = kMasterKey; + if (pwallet->nMasterKeyMaxID < nID) + pwallet->nMasterKeyMaxID = nID; + } + else if (strType == "ckey") + { + vector vchPubKey; + ssKey >> vchPubKey; + vector vchPrivKey; + ssValue >> vchPrivKey; + if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey)) + { + printf("Error reading wallet database: LoadCryptedKey failed\n"); + return DB_CORRUPT; + } + fIsEncrypted = true; + } + else if (strType == "defaultkey") + { + ssValue >> pwallet->vchDefaultKey; + } + else if (strType == "pool") + { + int64 nIndex; + ssKey >> nIndex; + pwallet->setKeyPool.insert(nIndex); + } + else if (strType == "version") + { + ssValue >> nFileVersion; + if (nFileVersion == 10300) + nFileVersion = 300; + } + else if (strType == "cscript") + { + uint160 hash; + ssKey >> hash; + CScript script; + ssValue >> script; + if (!pwallet->LoadCScript(script)) + { + printf("Error reading wallet database: LoadCScript failed\n"); + return DB_CORRUPT; + } + } + } + pcursor->close(); + } + + BOOST_FOREACH(uint256 hash, vWalletUpgrade) + WriteTx(hash, pwallet->mapWallet[hash]); + + printf("nFileVersion = %d\n", nFileVersion); + + + // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc: + if (fIsEncrypted && (nFileVersion == 40000 || nFileVersion == 50000)) + return DB_NEED_REWRITE; + + if (nFileVersion < CLIENT_VERSION) // Update + WriteVersion(CLIENT_VERSION); + + return DB_LOAD_OK; +} + +void ThreadFlushWalletDB(void* parg) +{ + const string& strFile = ((const string*)parg)[0]; + static bool fOneThread; + if (fOneThread) + return; + fOneThread = true; + if (!GetBoolArg("-flushwallet", true)) + return; + + unsigned int nLastSeen = nWalletDBUpdated; + unsigned int nLastFlushed = nWalletDBUpdated; + int64 nLastWalletUpdate = GetTime(); + while (!fShutdown) + { + Sleep(500); + + if (nLastSeen != nWalletDBUpdated) + { + nLastSeen = nWalletDBUpdated; + nLastWalletUpdate = GetTime(); + } + + if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) + { + TRY_LOCK(cs_db,lockDb); + if (lockDb) + { + // Don't do this if any databases are in use + int nRefCount = 0; + map::iterator mi = mapFileUseCount.begin(); + while (mi != mapFileUseCount.end()) + { + nRefCount += (*mi).second; + mi++; + } + + if (nRefCount == 0 && !fShutdown) + { + map::iterator mi = mapFileUseCount.find(strFile); + if (mi != mapFileUseCount.end()) + { + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("Flushing wallet.dat\n"); + nLastFlushed = nWalletDBUpdated; + int64 nStart = GetTimeMillis(); + + // Flush wallet.dat so it's self contained + CloseDb(strFile); + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(strFile.c_str(), 0); + + mapFileUseCount.erase(mi++); + printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); + } + } + } + } + } +} + +bool BackupWallet(const CWallet& wallet, const string& strDest) +{ + if (!wallet.fFileBacked) + return false; + while (!fShutdown) + { + { + LOCK(cs_db); + if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0) + { + // Flush log data to the dat file + CloseDb(wallet.strWalletFile); + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(wallet.strWalletFile.c_str(), 0); + mapFileUseCount.erase(wallet.strWalletFile); + + // Copy wallet.dat + filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; + filesystem::path pathDest(strDest); + if (filesystem::is_directory(pathDest)) + pathDest /= wallet.strWalletFile; + + try { +#if BOOST_VERSION >= 104000 + filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists); +#else + filesystem::copy_file(pathSrc, pathDest); +#endif + printf("copied wallet.dat to %s\n", pathDest.string().c_str()); + return true; + } catch(const filesystem::filesystem_error &e) { + printf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what()); + return false; + } + } + } + Sleep(100); + } + return false; +} diff --git a/src/walletdb.h b/src/walletdb.h new file mode 100644 index 00000000..46ba7967 --- /dev/null +++ b/src/walletdb.h @@ -0,0 +1,179 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_WALLETDB_H +#define BITCOIN_WALLETDB_H + +#include "db.h" + +class CKeyPool; +class CAccount; +class CAccountingEntry; + +/** Error statuses for the wallet database */ +enum DBErrors +{ + DB_LOAD_OK, + DB_CORRUPT, + DB_TOO_NEW, + DB_LOAD_FAIL, + DB_NEED_REWRITE +}; + +/** Access to the wallet database (wallet.dat) */ +class CWalletDB : public CDB +{ +public: + CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode) + { + } +private: + CWalletDB(const CWalletDB&); + void operator=(const CWalletDB&); +public: + bool ReadName(const std::string& strAddress, std::string& strName) + { + strName = ""; + return Read(std::make_pair(std::string("name"), strAddress), strName); + } + + bool WriteName(const std::string& strAddress, const std::string& strName); + + bool EraseName(const std::string& strAddress); + + bool ReadTx(uint256 hash, CWalletTx& wtx) + { + return Read(std::make_pair(std::string("tx"), hash), wtx); + } + + bool WriteTx(uint256 hash, const CWalletTx& wtx) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("tx"), hash), wtx); + } + + bool EraseTx(uint256 hash) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("tx"), hash)); + } + + bool ReadKey(const std::vector& vchPubKey, CPrivKey& vchPrivKey) + { + vchPrivKey.clear(); + return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey); + } + + bool WriteKey(const std::vector& vchPubKey, const CPrivKey& vchPrivKey) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false); + } + + bool WriteCryptedKey(const std::vector& vchPubKey, const std::vector& vchCryptedSecret, bool fEraseUnencryptedKey = true) + { + nWalletDBUpdated++; + if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false)) + return false; + if (fEraseUnencryptedKey) + { + Erase(std::make_pair(std::string("key"), vchPubKey)); + Erase(std::make_pair(std::string("wkey"), vchPubKey)); + } + return true; + } + + bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); + } + + // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013 + bool ReadCScript(const uint160 &hash, CScript& redeemScript) + { + redeemScript.clear(); + return Read(std::make_pair(std::string("cscript"), hash), redeemScript); + } + + bool WriteCScript(const uint160& hash, const CScript& redeemScript) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false); + } + + bool WriteBestBlock(const CBlockLocator& locator) + { + nWalletDBUpdated++; + return Write(std::string("bestblock"), locator); + } + + bool ReadBestBlock(CBlockLocator& locator) + { + return Read(std::string("bestblock"), locator); + } + + bool ReadDefaultKey(std::vector& vchPubKey) + { + vchPubKey.clear(); + return Read(std::string("defaultkey"), vchPubKey); + } + + bool WriteDefaultKey(const std::vector& vchPubKey) + { + nWalletDBUpdated++; + return Write(std::string("defaultkey"), vchPubKey); + } + + bool ReadPool(int64 nPool, CKeyPool& keypool) + { + return Read(std::make_pair(std::string("pool"), nPool), keypool); + } + + bool WritePool(int64 nPool, const CKeyPool& keypool) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("pool"), nPool), keypool); + } + + bool ErasePool(int64 nPool) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("pool"), nPool)); + } + + // Settings are no longer stored in wallet.dat; these are + // used only for backwards compatibility: + template + bool ReadSetting(const std::string& strKey, T& value) + { + return Read(std::make_pair(std::string("setting"), strKey), value); + } + template + bool WriteSetting(const std::string& strKey, const T& value) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("setting"), strKey), value); + } + bool EraseSetting(const std::string& strKey) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("setting"), strKey)); + } + + bool WriteMinVersion(int nVersion) + { + return Write(std::string("minversion"), nVersion); + } + + bool ReadAccount(const std::string& strAccount, CAccount& account); + bool WriteAccount(const std::string& strAccount, const CAccount& account); + bool WriteAccountingEntry(const CAccountingEntry& acentry); + int64 GetAccountCreditDebit(const std::string& strAccount); + void ListAccountCreditDebit(const std::string& strAccount, std::list& acentries); + + int LoadWallet(CWallet* pwallet); +}; + +#endif // BITCOIN_WALLETDB_H