Browse Source

Merge pull request #1112 from sipa/saneserial

Further reduce header dependencies
pull/1/head
Pieter Wuille 10 years ago
parent
commit
1ffeb89a52
  1. 3
      bitcoin-qt.pro
  2. 8
      src/addrman.cpp
  3. 3
      src/allocators.h
  4. 2
      src/bignum.h
  5. 16
      src/bitcoinrpc.cpp
  6. 4
      src/checkpoints.cpp
  7. 1
      src/checkpoints.h
  8. 23
      src/compat.h
  9. 3
      src/crypter.cpp
  10. 1
      src/crypter.h
  11. 442
      src/db.cpp
  12. 212
      src/db.h
  13. 91
      src/headers.h
  14. 151
      src/init.cpp
  15. 2
      src/init.h
  16. 2
      src/irc.cpp
  17. 2
      src/key.h
  18. 4
      src/keystore.cpp
  19. 5
      src/keystore.h
  20. 20
      src/main.cpp
  21. 21
      src/main.h
  22. 1
      src/makefile.linux-mingw
  23. 1
      src/makefile.mingw
  24. 1
      src/makefile.osx
  25. 1
      src/makefile.unix
  26. 2
      src/net.cpp
  27. 10
      src/net.h
  28. 21
      src/netbase.h
  29. 1
      src/noui.cpp
  30. 1
      src/protocol.h
  31. 2
      src/qt/addresstablemodel.cpp
  32. 2
      src/qt/bitcoin.cpp
  33. 2
      src/qt/clientmodel.cpp
  34. 2
      src/qt/guiutil.cpp
  35. 2
      src/qt/messagepage.cpp
  36. 2
      src/qt/optionsmodel.cpp
  37. 3
      src/qt/qtipcserver.cpp
  38. 4
      src/qt/transactiondesc.cpp
  39. 2
      src/qt/transactionrecord.cpp
  40. 2
      src/qt/transactiontablemodel.cpp
  41. 5
      src/qt/walletmodel.cpp
  42. 2
      src/rpcdump.cpp
  43. 10
      src/script.cpp
  44. 72
      src/serialize.h
  45. 4
      src/strlcpy.h
  46. 12
      src/uint256.h
  47. 172
      src/util.cpp
  48. 10
      src/util.h
  49. 12
      src/wallet.cpp
  50. 36
      src/wallet.h
  51. 428
      src/walletdb.cpp
  52. 179
      src/walletdb.h

3
bitcoin-qt.pro

@ -117,9 +117,9 @@ HEADERS += src/qt/bitcoingui.h \ @@ -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 \ @@ -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 \

8
src/addrman.cpp

@ -8,12 +8,12 @@ using namespace std; @@ -8,12 +8,12 @@ using namespace std;
int CAddrInfo::GetTriedBucket(const std::vector<unsigned char> &nKey) const
{
CDataStream ss1(SER_GETHASH);
CDataStream ss1(SER_GETHASH, 0);
std::vector<unsigned char> vchKey = GetKey();
ss1 << nKey << vchKey;
uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64();
CDataStream ss2(SER_GETHASH);
CDataStream ss2(SER_GETHASH, 0);
std::vector<unsigned char> 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<unsigned char> &nKey) const @@ -22,13 +22,13 @@ int CAddrInfo::GetTriedBucket(const std::vector<unsigned char> &nKey) const
int CAddrInfo::GetNewBucket(const std::vector<unsigned char> &nKey, const CNetAddr& src) const
{
CDataStream ss1(SER_GETHASH);
CDataStream ss1(SER_GETHASH, 0);
std::vector<unsigned char> vchGroupKey = GetGroup();
std::vector<unsigned char> 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;

3
src/allocators.h

@ -8,6 +8,9 @@ @@ -8,6 +8,9 @@
#include <string>
#ifdef WIN32
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX

2
src/bignum.h

@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
#include <vector>
#include <openssl/bn.h>
#include "util.h"
#include "util.h" // for uint64
/** Errors thrown by the bignum class */
class bignum_error : public std::runtime_error

16
src/bitcoinrpc.cpp

@ -3,10 +3,14 @@ @@ -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 <boost/asio.hpp>
#include <boost/filesystem.hpp>
@ -138,7 +142,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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;

4
src/checkpoints.cpp

@ -5,9 +5,11 @@ @@ -5,9 +5,11 @@
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>
#include "headers.h"
#include "checkpoints.h"
#include "main.h"
#include "uint256.h"
namespace Checkpoints
{
typedef std::map<int, uint256> MapCheckpoints;

1
src/checkpoints.h

@ -5,7 +5,6 @@ @@ -5,7 +5,6 @@
#define BITCOIN_CHECKPOINT_H
#include <map>
#include "util.h"
class uint256;
class CBlockIndex;

23
src/compat.h

@ -5,6 +5,28 @@ @@ -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 <winsock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <ifaddrs.h>
#endif
#ifdef BSD
#include <netinet/in.h>
#endif
typedef u_int SOCKET;
#ifdef WIN32
#define MSG_NOSIGNAL 0
@ -39,4 +61,5 @@ inline int myclosesocket(SOCKET& hSocket) @@ -39,4 +61,5 @@ inline int myclosesocket(SOCKET& hSocket)
}
#define closesocket(s) myclosesocket(s)
#endif

3
src/crypter.cpp

@ -6,14 +6,11 @@ @@ -6,14 +6,11 @@
#include <openssl/evp.h>
#include <vector>
#include <string>
#include "headers.h"
#ifdef WIN32
#include <windows.h>
#endif
#include "crypter.h"
#include "main.h"
#include "util.h"
bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
{

1
src/crypter.h

@ -6,6 +6,7 @@ @@ -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;

442
src/db.cpp

@ -3,19 +3,22 @@ @@ -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 <boost/version.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#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; @@ -23,10 +26,10 @@ uint64 nAccountingEntryNumber = 0;
// CDB
//
static CCriticalSection cs_db;
CCriticalSection cs_db;
static bool fDbEnvInit = false;
DbEnv dbenv(0);
static map<string, int> mapFileUseCount;
map<string, int> mapFileUseCount;
static map<string, Db*> mapDb;
static void EnvShutdown()
@ -173,7 +176,7 @@ void CDB::Close() @@ -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) @@ -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<CTransaction>& @@ -382,10 +385,10 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>&
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() @@ -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() @@ -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() @@ -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<CAccountingEntry> 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<CAccountingEntry>& 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<uint256> 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<unsigned char> 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<unsigned char> vchPubKey;
ssKey >> vchPubKey;
vector<unsigned char> 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<string, int>::iterator mi = mapFileUseCount.begin();
while (mi != mapFileUseCount.end())
{
nRefCount += (*mi).second;
mi++;
}
if (nRefCount == 0 && !fShutdown)
{
map<string, int>::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;
}

212
src/db.h

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
#ifndef BITCOIN_DB_H
#define BITCOIN_DB_H
#include "key.h"
#include "main.h"
#include <map>
#include <string>
@ -13,8 +13,6 @@ @@ -13,8 +13,6 @@
#include <db_cxx.h>
class CAccount;
class CAccountingEntry;
class CAddress;
class CAddrMan;
class CBlockLocator;
@ -59,7 +57,7 @@ protected: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -313,198 +311,4 @@ public:
bool LoadAddresses();
/** A key pool entry */
class CKeyPool
{
public:
int64 nTime;
std::vector<unsigned char> vchPubKey;
CKeyPool()
{
nTime = GetTime();
}
CKeyPool(const std::vector<unsigned char>& 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<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
{
vchPrivKey.clear();
return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
}
bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
}
bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& 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<unsigned char>& vchPubKey)
{
vchPubKey.clear();
return Read(std::string("defaultkey"), vchPubKey);
}
bool WriteDefaultKey(const std::vector<unsigned char>& 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<typename T>
bool ReadSetting(const std::string& strKey, T& value)
{
return Read(std::make_pair(std::string("setting"), strKey), value);
}
template<typename T>
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<CAccountingEntry>& acentries);
int LoadWallet(CWallet* pwallet);
};
#endif
#endif // BITCOIN_DB_H

91
src/headers.h

@ -1,91 +0,0 @@ @@ -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 <boost/foreach.hpp>
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h> // to get BSD define
#endif
#ifdef MAC_OSX
#ifndef BSD
#define BSD 1
#endif
#endif
#include <openssl/buffer.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <db_cxx.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <float.h>
#include <assert.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <map>
#ifdef WIN32
#include <windows.h>
#include <winsock2.h>
#include <mswsock.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <io.h>
#include <process.h>
#include <malloc.h>
#else
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <fcntl.h>
#include <signal.h>
#endif
#ifdef BSD
#include <netinet/in.h>
#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"

151
src/init.cpp

@ -2,19 +2,20 @@ @@ -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 <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#ifdef WIN32
#define strncasecmp strnicmp
#ifndef WIN32
#include <signal.h>
#endif
using namespace std;
@ -583,145 +584,3 @@ bool AppInit2(int argc, char* argv[]) @@ -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<void**>(&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<void**>(&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

2
src/init.h

@ -5,6 +5,8 @@ @@ -5,6 +5,8 @@
#ifndef BITCOIN_INIT_H
#define BITCOIN_INIT_H
#include "wallet.h"
extern CWallet* pwalletMain;
void Shutdown(void* parg);

2
src/irc.cpp

@ -3,10 +3,10 @@ @@ -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;

2
src/key.h

@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#include "serialize.h"
// #include "serialize.h"
#include "uint256.h"
// secp160k1

4
src/keystore.cpp

@ -3,9 +3,7 @@ @@ -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<unsigned char> &vchPubKeyOut) const

5
src/keystore.h

@ -6,7 +6,10 @@ @@ -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

20
src/main.cpp

@ -2,11 +2,11 @@ @@ -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 <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>