aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/addrman.cpp12
-rw-r--r--src/allocators.h3
-rw-r--r--src/base58.h2
-rw-r--r--src/bignum.h2
-rw-r--r--src/bitcoinrpc.cpp22
-rw-r--r--src/checkpoints.cpp4
-rw-r--r--src/checkpoints.h1
-rw-r--r--src/compat.h23
-rw-r--r--src/crypter.cpp5
-rw-r--r--src/crypter.h1
-rw-r--r--src/db.cpp442
-rw-r--r--src/db.h212
-rw-r--r--src/headers.h91
-rw-r--r--src/init.cpp151
-rw-r--r--src/init.h2
-rw-r--r--src/irc.cpp10
-rw-r--r--src/key.h6
-rw-r--r--src/keystore.cpp4
-rw-r--r--src/keystore.h5
-rw-r--r--src/main.cpp249
-rw-r--r--src/main.h68
-rw-r--r--src/makefile.linux-mingw1
-rw-r--r--src/makefile.mingw1
-rw-r--r--src/makefile.osx1
-rw-r--r--src/makefile.unix1
-rw-r--r--src/net.cpp12
-rw-r--r--src/net.h18
-rw-r--r--src/netbase.cpp10
-rw-r--r--src/netbase.h27
-rw-r--r--src/noui.cpp1
-rw-r--r--src/protocol.cpp2
-rw-r--r--src/protocol.h8
-rw-r--r--src/qt/addresstablemodel.cpp2
-rw-r--r--src/qt/bitcoin.cpp2
-rw-r--r--src/qt/clientmodel.cpp2
-rw-r--r--src/qt/csvmodelwriter.cpp2
-rw-r--r--src/qt/guiutil.cpp2
-rw-r--r--src/qt/messagepage.cpp2
-rw-r--r--src/qt/optionsmodel.cpp2
-rw-r--r--src/qt/qtipcserver.cpp3
-rw-r--r--src/qt/transactiondesc.cpp4
-rw-r--r--src/qt/transactionrecord.cpp8
-rw-r--r--src/qt/transactiontablemodel.cpp2
-rw-r--r--src/qt/walletmodel.cpp5
-rw-r--r--src/rpcdump.cpp2
-rw-r--r--src/script.cpp10
-rw-r--r--src/serialize.h130
-rw-r--r--src/strlcpy.h4
-rw-r--r--src/test/DoS_tests.cpp4
-rw-r--r--src/test/miner_tests.cpp3
-rw-r--r--src/test/transaction_tests.cpp2
-rw-r--r--src/uint256.h14
-rw-r--r--src/util.cpp173
-rw-r--r--src/util.h10
-rw-r--r--src/version.cpp10
-rw-r--r--src/version.h36
-rw-r--r--src/wallet.cpp26
-rw-r--r--src/wallet.h42
-rw-r--r--src/walletdb.cpp428
-rw-r--r--src/walletdb.h179
60 files changed, 1263 insertions, 1243 deletions
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 8fb40b46df..345261e229 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -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
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;
@@ -124,7 +124,7 @@ int CAddrMan::SelectTried(int nKBucket)
// random shuffle the first few elements (using the entire list)
// find the least recently tried among them
int64 nOldest = -1;
- for (int i=0; i<ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i<vTried.size(); i++)
+ for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++)
{
int nPos = GetRandInt(vTried.size() - i) + i;
int nTemp = vTried[nPos];
@@ -270,7 +270,7 @@ void CAddrMan::Good_(const CService &addr, int64 nTime)
// find a bucket it is in now
int nRnd = GetRandInt(vvNew.size());
int nUBucket = -1;
- for (int n = 0; n < vvNew.size(); n++)
+ for (unsigned int n = 0; n < vvNew.size(); n++)
{
int nB = (n+nRnd) % vvNew.size();
std::set<int> &vNew = vvNew[nB];
diff --git a/src/allocators.h b/src/allocators.h
index 85d9cfbbb8..cdea66dd38 100644
--- a/src/allocators.h
+++ b/src/allocators.h
@@ -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
diff --git a/src/base58.h b/src/base58.h
index 7fefbc5d74..90ce34b05b 100644
--- a/src/base58.h
+++ b/src/base58.h
@@ -288,7 +288,7 @@ public:
bool IsValid() const
{
- int nExpectedSize = 20;
+ unsigned int nExpectedSize = 20;
bool fExpectTestNet = false;
switch(nVersion)
{
diff --git a/src/bignum.h b/src/bignum.h
index daf5f6883a..cea8e1e357 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -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
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index 63c51ada8d..3c2d69e506 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 <boost/asio.hpp>
#include <boost/filesystem.hpp>
@@ -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()));
@@ -201,7 +205,7 @@ Value help(const Array& params, bool fHelp)
// Help text is returned in an exception
string strHelp = string(e.what());
if (strCommand == "")
- if (strHelp.find('\n') != -1)
+ if (strHelp.find('\n') != string::npos)
strHelp = strHelp.substr(0, strHelp.find('\n'));
strRet += strHelp + "\n";
}
@@ -363,7 +367,7 @@ Value getmininginfo(const Array& params, bool fHelp)
obj.push_back(Pair("generate", GetBoolArg("-gen")));
obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
- obj.push_back(Pair("pooledtx", (uint64_t)nPooledTx));
+ obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
obj.push_back(Pair("testnet", fTestNet));
return obj;
}
@@ -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;
@@ -1000,7 +1004,7 @@ Value addmultisigaddress(const Array& params, bool fHelp)
"(got %d, need at least %d)", keys.size(), nRequired));
std::vector<CKey> pubkeys;
pubkeys.resize(keys.size());
- for (int i = 0; i < keys.size(); i++)
+ for (unsigned int i = 0; i < keys.size(); i++)
{
const std::string& ks = keys[i].get_str();
@@ -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 f5ce053870..cf56fa0695 100644
--- a/src/checkpoints.cpp
+++ b/src/checkpoints.cpp
@@ -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;
diff --git a/src/checkpoints.h b/src/checkpoints.h
index 38902ac0a1..5d3228f3fc 100644
--- a/src/checkpoints.h
+++ b/src/checkpoints.h
@@ -5,7 +5,6 @@
#define BITCOIN_CHECKPOINT_H
#include <map>
-#include "util.h"
class uint256;
class CBlockIndex;
diff --git a/src/compat.h b/src/compat.h
index 882610031a..db340445b2 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 <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)
}
#define closesocket(s) myclosesocket(s)
+
#endif
diff --git a/src/crypter.cpp b/src/crypter.cpp
index 83041addb4..4f37575a6a 100644
--- a/src/crypter.cpp
+++ b/src/crypter.cpp
@@ -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)
{
@@ -31,7 +28,7 @@ bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::v
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
(unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
- if (i != WALLET_CRYPTO_KEY_SIZE)
+ if (i != (int)WALLET_CRYPTO_KEY_SIZE)
{
memset(&chKey, 0, sizeof chKey);
memset(&chIV, 0, sizeof chIV);
diff --git a/src/crypter.h b/src/crypter.h
index 59a005a220..d1bdb92c91 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 0652e4a8f6..c38070f347 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 <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;
// 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()
@@ -175,7 +178,7 @@ void CDB::Close()
}
}
-void static CloseDb(const string& strFile)
+void CloseDb(const string& strFile)
{
{
LOCK(cs_db);
@@ -227,8 +230,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)
{
@@ -384,10 +387,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)
@@ -512,10 +515,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)
@@ -752,8 +755,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;
@@ -788,414 +791,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;
-}
diff --git a/src/db.h b/src/db.h
index 47fa40245e..48e10a95a7 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 <map>
#include <string>
@@ -13,8 +13,6 @@
#include <db_cxx.h>
-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<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
diff --git a/src/headers.h b/src/headers.h
deleted file mode 100644
index ceee028977..0000000000
--- 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 <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"
diff --git a/src/init.cpp b/src/init.cpp
index 2be0027a5b..0eb37fe99c 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 <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[])
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
diff --git a/src/init.h b/src/init.h
index 0d60e7549f..e3971c85e3 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 09bacc1658..237497055d 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;
@@ -108,13 +108,13 @@ int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const cha
if (!RecvLineIRC(hSocket, strLine))
return 0;
printf("IRC %s\n", strLine.c_str());
- if (psz1 && strLine.find(psz1) != -1)
+ if (psz1 && strLine.find(psz1) != string::npos)
return 1;
- if (psz2 && strLine.find(psz2) != -1)
+ if (psz2 && strLine.find(psz2) != string::npos)
return 2;
- if (psz3 && strLine.find(psz3) != -1)
+ if (psz3 && strLine.find(psz3) != string::npos)
return 3;
- if (psz4 && strLine.find(psz4) != -1)
+ if (psz4 && strLine.find(psz4) != string::npos)
return 4;
}
}
diff --git a/src/key.h b/src/key.h
index b8fc0cd772..1579cdc40a 100644
--- a/src/key.h
+++ b/src/key.h
@@ -12,7 +12,7 @@
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
-#include "serialize.h"
+#include "allocators.h"
#include "uint256.h"
// secp160k1
@@ -173,7 +173,7 @@ public:
CPrivKey GetPrivKey() const
{
- unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
+ int nSize = i2d_ECPrivateKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
CPrivKey vchPrivKey(nSize, 0);
@@ -196,7 +196,7 @@ public:
std::vector<unsigned char> GetPubKey() const
{
- unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
+ int nSize = i2o_ECPublicKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
std::vector<unsigned char> vchPubKey(nSize, 0);
diff --git a/src/keystore.cpp b/src/keystore.cpp
index 7b46f6b07a..313518711b 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<unsigned char> &vchPubKeyOut) const
diff --git a/src/keystore.h b/src/keystore.h
index 5d29ac1cb9..76820e204b 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 f2932804e3..78d84d9064 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 <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@@ -23,10 +23,8 @@ set<CWallet*> setpwalletRegistered;
CCriticalSection cs_main;
-static map<uint256, CTransaction> mapTransactions;
-CCriticalSection cs_mapTransactions;
+CTxMemPool mempool;
unsigned int nTransactionsUpdated = 0;
-map<COutPoint, CInPoint> mapNextTx;
map<uint256, CBlockIndex*> mapBlockIndex;
uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
@@ -288,7 +286,7 @@ bool CTransaction::AreInputsStandard(const MapPrevTx& mapInputs) const
if (IsCoinBase())
return true; // Coinbases don't use vin normally
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
{
const CTxOut& prev = GetOutputFor(vin[i], mapInputs);
@@ -411,7 +409,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
@@ -451,31 +449,32 @@ bool CTransaction::CheckTransaction() const
return true;
}
-bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
+bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs,
+ bool* pfMissingInputs)
{
if (pfMissingInputs)
*pfMissingInputs = false;
- if (!CheckTransaction())
- return error("AcceptToMemoryPool() : CheckTransaction failed");
+ if (!tx.CheckTransaction())
+ return error("CTxMemPool::accept() : CheckTransaction failed");
// Coinbase is only valid in a block, not as a loose transaction
- if (IsCoinBase())
- return DoS(100, error("AcceptToMemoryPool() : coinbase as individual tx"));
+ if (tx.IsCoinBase())
+ return tx.DoS(100, error("CTxMemPool::accept() : coinbase as individual tx"));
// To help v0.1.5 clients who would see it as a negative number
- if ((int64)nLockTime > std::numeric_limits<int>::max())
- return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet");
+ if ((int64)tx.nLockTime > std::numeric_limits<int>::max())
+ return error("CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet");
// Rather not work on nonstandard transactions (unless -testnet)
- if (!fTestNet && !IsStandard())
- return error("AcceptToMemoryPool() : nonstandard transaction type");
+ if (!fTestNet && !tx.IsStandard())
+ return error("CTxMemPool::accept() : nonstandard transaction type");
// Do we already have it?
- uint256 hash = GetHash();
+ uint256 hash = tx.GetHash();
{
- LOCK(cs_mapTransactions);
- if (mapTransactions.count(hash))
+ LOCK(cs);
+ if (mapTx.count(hash))
return false;
}
if (fCheckInputs)
@@ -484,9 +483,9 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
// Check for conflicts with in-memory transactions
CTransaction* ptxOld = NULL;
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
{
- COutPoint outpoint = vin[i].prevout;
+ COutPoint outpoint = tx.vin[i].prevout;
if (mapNextTx.count(outpoint))
{
// Disable replacement feature for now
@@ -498,11 +497,11 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
ptxOld = mapNextTx[outpoint].ptx;
if (ptxOld->IsFinal())
return false;
- if (!IsNewerThan(*ptxOld))
+ if (!tx.IsNewerThan(*ptxOld))
return false;
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
{
- COutPoint outpoint = vin[i].prevout;
+ COutPoint outpoint = tx.vin[i].prevout;
if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)
return false;
}
@@ -515,29 +514,29 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
MapPrevTx mapInputs;
map<uint256, CTxIndex> mapUnused;
bool fInvalid = false;
- if (!FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid))
+ if (!tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid))
{
if (fInvalid)
- return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
+ return error("CTxMemPool::accept() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
if (pfMissingInputs)
*pfMissingInputs = true;
- return error("AcceptToMemoryPool() : FetchInputs failed %s", hash.ToString().substr(0,10).c_str());
+ return error("CTxMemPool::accept() : FetchInputs failed %s", hash.ToString().substr(0,10).c_str());
}
// Check for non-standard pay-to-script-hash in inputs
- if (!AreInputsStandard(mapInputs) && !fTestNet)
- return error("AcceptToMemoryPool() : nonstandard transaction input");
+ if (!tx.AreInputsStandard(mapInputs) && !fTestNet)
+ return error("CTxMemPool::accept() : nonstandard transaction input");
// Note: if you modify this code to accept non-standard transactions, then
// you should add code here to check that the transaction does a
// reasonable number of ECDSA signature verifications.
- int64 nFees = GetValueIn(mapInputs)-GetValueOut();
- unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK);
+ int64 nFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
+ unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
// Don't accept it if it can't get into a block
- if (nFees < GetMinFee(1000, true, GMF_RELAY))
- return error("AcceptToMemoryPool() : not enough fees");
+ if (nFees < tx.GetMinFee(1000, true, GMF_RELAY))
+ return error("CTxMemPool::accept() : not enough fees");
// Continuously rate-limit free transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
@@ -556,8 +555,8 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
nLastTime = nNow;
// -limitfreerelay unit is thousand-bytes-per-minute
// At default rate it would take over a month to fill 1GB
- if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(*this))
- return error("AcceptToMemoryPool() : free transaction rejected by rate limiter");
+ if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(tx))
+ return error("CTxMemPool::accept() : free transaction rejected by rate limiter");
if (fDebug)
printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
dFreeCount += nSize;
@@ -566,21 +565,21 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
- if (!ConnectInputs(mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false))
+ if (!tx.ConnectInputs(mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false))
{
- return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
+ return error("CTxMemPool::accept() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
}
}
// Store transaction in memory
{
- LOCK(cs_mapTransactions);
+ LOCK(cs);
if (ptxOld)
{
- printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
- ptxOld->RemoveFromMemoryPool();
+ printf("CTxMemPool::accept() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
+ remove(*ptxOld);
}
- AddToMemoryPoolUnchecked();
+ addUnchecked(tx);
}
///// are we sure this is ok when loading transactions or restoring block txes
@@ -588,43 +587,44 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
if (ptxOld)
EraseFromWallets(ptxOld->GetHash());
- printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,10).c_str());
+ printf("CTxMemPool::accept() : accepted %s\n", hash.ToString().substr(0,10).c_str());
return true;
}
-uint64 nPooledTx = 0;
+bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
+{
+ return mempool.accept(txdb, *this, fCheckInputs, pfMissingInputs);
+}
-bool CTransaction::AddToMemoryPoolUnchecked()
+bool CTxMemPool::addUnchecked(CTransaction &tx)
{
- printf("AcceptToMemoryPoolUnchecked(): size %lu\n", mapTransactions.size());
+ printf("addUnchecked(): size %lu\n", mapTx.size());
// Add to memory pool without checking anything. Don't call this directly,
- // call AcceptToMemoryPool to properly check the transaction first.
+ // call CTxMemPool::accept to properly check the transaction first.
{
- LOCK(cs_mapTransactions);
- uint256 hash = GetHash();
- mapTransactions[hash] = *this;
- for (int i = 0; i < vin.size(); i++)
- mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i);
+ LOCK(cs);
+ uint256 hash = tx.GetHash();
+ mapTx[hash] = tx;
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
+ mapNextTx[tx.vin[i].prevout] = CInPoint(&mapTx[hash], i);
nTransactionsUpdated++;
- ++nPooledTx;
}
return true;
}
-bool CTransaction::RemoveFromMemoryPool()
+bool CTxMemPool::remove(CTransaction &tx)
{
// Remove transaction from memory pool
{
- LOCK(cs_mapTransactions);
- uint256 hash = GetHash();
- if (mapTransactions.count(hash))
+ LOCK(cs);
+ uint256 hash = tx.GetHash();
+ if (mapTx.count(hash))
{
- BOOST_FOREACH(const CTxIn& txin, vin)
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
mapNextTx.erase(txin.prevout);
- mapTransactions.erase(hash);
+ mapTx.erase(hash);
nTransactionsUpdated++;
- --nPooledTx;
}
}
return true;
@@ -695,14 +695,14 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
{
{
- LOCK(cs_mapTransactions);
+ LOCK(mempool.cs);
// Add previous supporting transactions first
BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
{
if (!tx.IsCoinBase())
{
uint256 hash = tx.GetHash();
- if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
+ if (!mempool.exists(hash) && !txdb.ContainsTx(hash))
tx.AcceptToMemoryPool(txdb, fCheckInputs);
}
}
@@ -989,7 +989,7 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes
if (IsCoinBase())
return true; // Coinbase transactions have no inputs to fetch.
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
{
COutPoint prevout = vin[i].prevout;
if (inputsRet.count(prevout.hash))
@@ -1017,10 +1017,10 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes
{
// Get prev tx from single transactions in memory
{
- LOCK(cs_mapTransactions);
- if (!mapTransactions.count(prevout.hash))
- return error("FetchInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
- txPrev = mapTransactions[prevout.hash];
+ LOCK(mempool.cs);
+ if (!mempool.exists(prevout.hash))
+ return error("FetchInputs() : %s mempool Tx prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
+ txPrev = mempool.lookup(prevout.hash);
}
if (!fFound)
txindex.vSpent.resize(txPrev.vout.size());
@@ -1034,7 +1034,7 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes
}
// Make sure all prevout.n's are valid:
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
{
const COutPoint prevout = vin[i].prevout;
assert(inputsRet.count(prevout.hash) != 0);
@@ -1071,7 +1071,7 @@ int64 CTransaction::GetValueIn(const MapPrevTx& inputs) const
return 0;
int64 nResult = 0;
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
{
nResult += GetOutputFor(vin[i], inputs).nValue;
}
@@ -1085,7 +1085,7 @@ int CTransaction::GetP2SHSigOpCount(const MapPrevTx& inputs) const
return 0;
int nSigOps = 0;
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
{
const CTxOut& prevout = GetOutputFor(vin[i], inputs);
if (prevout.scriptPubKey.IsPayToScriptHash())
@@ -1106,7 +1106,7 @@ bool CTransaction::ConnectInputs(MapPrevTx inputs,
{
int64 nValueIn = 0;
int64 nFees = 0;
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
{
COutPoint prevout = vin[i].prevout;
assert(inputs.count(prevout.hash) > 0);
@@ -1183,15 +1183,15 @@ bool CTransaction::ClientConnectInputs()
// Take over previous transactions' spent pointers
{
- LOCK(cs_mapTransactions);
+ LOCK(mempool.cs);
int64 nValueIn = 0;
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
{
// Get prev tx from single transactions in memory
COutPoint prevout = vin[i].prevout;
- if (!mapTransactions.count(prevout.hash))
+ if (!mempool.exists(prevout.hash))
return false;
- CTransaction& txPrev = mapTransactions[prevout.hash];
+ CTransaction& txPrev = mempool.lookup(prevout.hash);
if (prevout.n >= txPrev.vout.size())
return false;
@@ -1200,7 +1200,8 @@ bool CTransaction::ClientConnectInputs()
if (!VerifySignature(txPrev, *this, i, true, 0))
return error("ConnectInputs() : VerifySignature failed");
- ///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of
+ ///// this is redundant with the mempool.mapNextTx stuff,
+ ///// not sure which I want to get rid of
///// this has to go away now that posNext is gone
// // Check for conflicts
// if (!txPrev.vout[prevout.n].posNext.IsNull())
@@ -1279,7 +1280,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<uint256, CTxIndex> mapQueuedChanges;
int64 nFees = 0;
@@ -1291,7 +1292,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())
@@ -1396,7 +1397,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
// Connect longer branch
vector<CTransaction> vDelete;
- for (int i = 0; i < vConnect.size(); i++)
+ for (unsigned int i = 0; i < vConnect.size(); i++)
{
CBlockIndex* pindex = vConnect[i];
CBlock block;
@@ -1436,7 +1437,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
// Delete redundant memory transactions that are in the connected branch
BOOST_FOREACH(CTransaction& tx, vDelete)
- tx.RemoveFromMemoryPool();
+ mempool.remove(tx);
printf("REORGANIZE: done\n");
@@ -1472,7 +1473,7 @@ bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew)
// Delete redundant memory transactions
BOOST_FOREACH(CTransaction& tx, vtx)
- tx.RemoveFromMemoryPool();
+ mempool.remove(tx);
return true;
}
@@ -1621,7 +1622,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
@@ -1635,7 +1636,7 @@ bool CBlock::CheckBlock() const
// First transaction must be coinbase, the rest must not be
if (vtx.empty() || !vtx[0].IsCoinBase())
return DoS(100, error("CheckBlock() : first tx is not coinbase"));
- for (int i = 1; i < vtx.size(); i++)
+ for (unsigned int i = 1; i < vtx.size(); i++)
if (vtx[i].IsCoinBase())
return DoS(100, error("CheckBlock() : more than one coinbase"));
@@ -1691,7 +1692,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;
@@ -1771,7 +1772,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
// Recursively process any orphan blocks that depended on this one
vector<uint256> vWorkQueue;
vWorkQueue.push_back(hash);
- for (int i = 0; i < vWorkQueue.size(); i++)
+ for (unsigned int i = 0; i < vWorkQueue.size(); i++)
{
uint256 hashPrev = vWorkQueue[i];
for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
@@ -1995,7 +1996,7 @@ void PrintBlockTree()
// put the main timechain first
vector<CBlockIndex*>& vNext = mapNext[pindex];
- for (int i = 0; i < vNext.size(); i++)
+ for (unsigned int i = 0; i < vNext.size(); i++)
{
if (vNext[i]->pnext)
{
@@ -2005,7 +2006,7 @@ void PrintBlockTree()
}
// iterate children
- for (int i = 0; i < vNext.size(); i++)
+ for (unsigned int i = 0; i < vNext.size(); i++)
vStack.push_back(make_pair(nCol+i, vNext[i]));
}
}
@@ -2135,8 +2136,21 @@ bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
{
switch (inv.type)
{
- case MSG_TX: return mapTransactions.count(inv.hash) || mapOrphanTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
- case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
+ case MSG_TX:
+ {
+ bool txInMap = false;
+ {
+ LOCK(mempool.cs);
+ txInMap = (mempool.exists(inv.hash));
+ }
+ return txInMap ||
+ mapOrphanTransactions.count(inv.hash) ||
+ txdb.ContainsTx(inv.hash);
+ }
+
+ case MSG_BLOCK:
+ return mapBlockIndex.count(inv.hash) ||
+ mapOrphanBlocks.count(inv.hash);
}
// Don't know what it is, just say we already got one
return true;
@@ -2183,7 +2197,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
CAddress addrFrom;
uint64 nNonce = 1;
vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
- if (pfrom->nVersion < 209)
+ if (pfrom->nVersion < MIN_PROTO_VERSION)
{
// Since February 20, 2012, the protocol is initiated at version 209,
// and earlier versions are no longer supported
@@ -2233,7 +2247,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
// Get recent addresses
- if (pfrom->nVersion >= 31402 || addrman.size() < 1000)
+ if (pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
{
pfrom->PushMessage("getaddr");
pfrom->fGetAddr = true;
@@ -2250,7 +2264,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Ask the first connected node for block updates
static int nAskedForBlocks = 0;
if (!pfrom->fClient &&
- (pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) &&
+ (pfrom->nVersion < NOBLKS_VERSION_START ||
+ pfrom->nVersion >= NOBLKS_VERSION_END) &&
(nAskedForBlocks < 1 || vNodes.size() <= 1))
{
nAskedForBlocks++;
@@ -2292,7 +2307,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vRecv >> vAddr;
// Don't want addr from older versions unless seeding
- if (pfrom->nVersion < 31402 && addrman.size() > 1000)
+ if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
return true;
if (vAddr.size() > 1000)
{
@@ -2329,7 +2344,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
multimap<uint256, CNode*> mapMix;
BOOST_FOREACH(CNode* pnode, vNodes)
{
- if (pnode->nVersion < 31402)
+ if (pnode->nVersion < CADDR_TIME_VERSION)
continue;
unsigned int nPointer;
memcpy(&nPointer, &pnode, sizeof(nPointer));
@@ -2360,7 +2375,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
CTxDB txdb("r");
- for (int nInv = 0; nInv < vInv.size(); nInv++)
+ for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
{
const CInv &inv = vInv[nInv];
@@ -2467,7 +2482,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
@@ -2536,7 +2551,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vWorkQueue.push_back(inv.hash);
// Recursively process any orphan transactions that depended on this one
- for (int i = 0; i < vWorkQueue.size(); i++)
+ for (unsigned int i = 0; i < vWorkQueue.size(); i++)
{
uint256 hashPrev = vWorkQueue[i];
for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
@@ -2651,6 +2666,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
else if (strCommand == "ping")
{
+ if (pfrom->nVersion > BIP0031_VERSION)
+ {
+ uint64 nonce = 0;
+ vRecv >> nonce;
+ // Echo the message back with the nonce. This allows for two useful features:
+ //
+ // 1) A remote node can quickly check if the connection is operational
+ // 2) Remote nodes can measure the latency of the network thread. If this node
+ // is overloaded it won't respond to pings quickly and the remote node can
+ // avoid sending us more work, like chain download requests.
+ //
+ // The nonce stops the remote getting confused between different pings: without
+ // it, if the remote node sends a ping once per second and this node takes 5
+ // seconds to respond to each, the 5th ping the remote sends would appear to
+ // return very quickly.
+ pfrom->PushMessage("pong", nonce);
+ }
}
@@ -2807,15 +2839,20 @@ bool ProcessMessages(CNode* pfrom)
bool SendMessages(CNode* pto, bool fSendTrickle)
{
- {
- LOCK(cs_main);
+ TRY_LOCK(cs_main, lockMain);
+ if (lockMain) {
// Don't send anything until we get their version message
if (pto->nVersion == 0)
return true;
- // Keep-alive ping
- if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty())
- pto->PushMessage("ping");
+ // Keep-alive ping. We send a nonce of zero because we don't use it anywhere
+ // right now.
+ if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) {
+ if (pto->nVersion > BIP0031_VERSION)
+ pto->PushMessage("ping", 0);
+ else
+ pto->PushMessage("ping");
+ }
// Resend wallet transactions that haven't gotten in a block yet
ResendWalletTransactions();
@@ -3093,14 +3130,14 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
// Collect memory pool transactions into the block
int64 nFees = 0;
{
- LOCK2(cs_main, cs_mapTransactions);
+ LOCK2(cs_main, mempool.cs);
CTxDB txdb("r");
// Priority order to process transactions
list<COrphan> vOrphan; // list memory doesn't move
map<uint256, vector<COrphan*> > mapDependers;
multimap<double, CTransaction*> mapPriority;
- for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi)
+ for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
{
CTransaction& tx = (*mi).second;
if (tx.IsCoinBase() || !tx.IsFinal())
@@ -3138,7 +3175,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;
@@ -3167,7 +3204,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;
@@ -3294,7 +3331,7 @@ void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash
FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
// Byte swap all the input buffer
- for (int i = 0; i < sizeof(tmp)/4; i++)
+ for (unsigned int i = 0; i < sizeof(tmp)/4; i++)
((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
// Precalc the first half of the first hash, which stays constant
@@ -3419,7 +3456,7 @@ void static BitcoinMiner(CWallet *pwallet)
// Check if something found
if (nNonceFound != -1)
{
- for (int i = 0; i < sizeof(hash)/4; i++)
+ for (unsigned int i = 0; i < sizeof(hash)/4; i++)
((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
if (hash <= hashTarget)
diff --git a/src/main.h b/src/main.h
index a89c0935fe..d12a3cc258 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 <io.h> /* for _commit */
@@ -18,13 +15,11 @@
#include <list>
+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;
@@ -67,7 +60,6 @@ extern CBigNum bnBestChainWork;
extern CBigNum bnBestInvalidWork;
extern uint256 hashBestChain;
extern CBlockIndex* pindexBest;
-extern uint64 nPooledTx;
extern unsigned int nTransactionsUpdated;
extern uint64 nLastBlockTx;
extern uint64 nLastBlockSize;
@@ -457,13 +449,13 @@ public:
{
if (vin.size() != old.vin.size())
return false;
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
if (vin[i].prevout != old.vin[i].prevout)
return false;
bool fNewer = false;
unsigned int nLowest = std::numeric_limits<unsigned int>::max();
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
{
if (vin[i].nSequence != old.vin[i].nSequence)
{
@@ -550,7 +542,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 +587,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");
@@ -637,9 +629,9 @@ public:
vin.size(),
vout.size(),
nLockTime);
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
str += " " + vin[i].ToString() + "\n";
- for (int i = 0; i < vout.size(); i++)
+ for (unsigned int i = 0; i < vout.size(); i++)
str += " " + vout[i].ToString() + "\n";
return str;
}
@@ -689,9 +681,6 @@ public:
protected:
const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const;
- bool AddToMemoryPoolUnchecked();
-public:
- bool RemoveFromMemoryPool();
};
@@ -946,7 +935,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 +968,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)
@@ -1006,13 +995,13 @@ public:
hashMerkleRoot.ToString().substr(0,10).c_str(),
nTime, nBits, nNonce,
vtx.size());
- for (int i = 0; i < vtx.size(); i++)
+ for (unsigned int i = 0; i < vtx.size(); i++)
{
printf(" ");
vtx[i].print();
}
printf(" vMerkleTree: ");
- for (int i = 0; i < vMerkleTree.size(); i++)
+ for (unsigned int i = 0; i < vMerkleTree.size(); i++)
printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
printf("\n");
}
@@ -1140,7 +1129,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 +1589,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;
}
@@ -1608,4 +1597,35 @@ public:
bool ProcessAlert();
};
+class CTxMemPool
+{
+public:
+ mutable CCriticalSection cs;
+ std::map<uint256, CTransaction> mapTx;
+ std::map<COutPoint, CInPoint> mapNextTx;
+
+ bool accept(CTxDB& txdb, CTransaction &tx,
+ bool fCheckInputs, bool* pfMissingInputs);
+ bool addUnchecked(CTransaction &tx);
+ bool remove(CTransaction &tx);
+
+ unsigned long size()
+ {
+ LOCK(cs);
+ return mapTx.size();
+ }
+
+ bool exists(uint256 hash)
+ {
+ return (mapTx.count(hash) != 0);
+ }
+
+ CTransaction& lookup(uint256 hash)
+ {
+ return mapTx[hash];
+ }
+};
+
+extern CTxMemPool mempool;
+
#endif
diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw
index 9f005424f6..1ea65cd2e5 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 397fdf4f32..5584df5603 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 e2e35de5cc..aaac6700bd 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 9bc780d53c..fc901ca02c 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 b0f365061c..38c0d3d582 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 <string.h>
@@ -162,14 +162,14 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha
}
if (pszKeyword == NULL)
break;
- if (strLine.find(pszKeyword) != -1)
+ if (strLine.find(pszKeyword) != string::npos)
{
strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
break;
}
}
closesocket(hSocket);
- if (strLine.find("<") != -1)
+ if (strLine.find("<") != string::npos)
strLine = strLine.substr(0, strLine.find("<"));
strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
@@ -624,7 +624,7 @@ void ThreadSocketHandler2(void* parg)
if (hSocketMax > -1)
{
printf("socket select error %d\n", nErr);
- for (int i = 0; i <= hSocketMax; i++)
+ for (unsigned int i = 0; i <= hSocketMax; i++)
FD_SET(i, &fdsetRecv);
}
FD_ZERO(&fdsetSend);
@@ -1024,7 +1024,7 @@ void ThreadDNSAddressSeed2(void* parg)
{
printf("Loading addresses from DNS seeds (could take a while)\n");
- for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
+ for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
vector<CNetAddr> vaddr;
vector<CAddress> vAdd;
if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
@@ -1238,7 +1238,7 @@ void ThreadOpenConnections2(void* parg)
if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
{
std::vector<CAddress> vAdd;
- for (int i = 0; i < ARRAYLEN(pnSeed); i++)
+ for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
{
// It'll only connect to one or two seed nodes because once it connects,
// it'll get a pile of addresses with newer timestamps.
diff --git a/src/net.h b/src/net.h
index 3c84650c27..bad49a9f8f 100644
--- a/src/net.h
+++ b/src/net.h
@@ -117,7 +117,7 @@ public:
int64 nLastRecv;
int64 nLastSendEmpty;
int64 nTimeConnected;
- unsigned int nHeaderStart;
+ int nHeaderStart;
unsigned int nMessageStart;
CAddress addr;
int nVersion;
@@ -157,14 +157,10 @@ public:
CCriticalSection cs_inventory;
std::multimap<int64, CInv> 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(209);
- vRecv.SetVersion(209);
nLastSend = 0;
nLastRecv = 0;
nLastSendEmpty = GetTime();
@@ -299,7 +295,7 @@ public:
void AbortMessage()
{
- if (nHeaderStart == -1)
+ if (nHeaderStart < 0)
return;
vSend.resize(nHeaderStart);
nHeaderStart = -1;
@@ -319,7 +315,7 @@ public:
return;
}
- if (nHeaderStart == -1)
+ if (nHeaderStart < 0)
return;
// Set the size
@@ -344,7 +340,7 @@ public:
void EndMessageAbortIfEmpty()
{
- if (nHeaderStart == -1)
+ if (nHeaderStart < 0)
return;
int nSize = vSend.size() - nMessageStart;
if (nSize > 0)
@@ -612,7 +608,7 @@ inline void RelayInventory(const CInv& inv)
template<typename T>
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.cpp b/src/netbase.cpp
index baf7c412a0..8b30ffc140 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -22,7 +22,7 @@ int nConnectTimeout = 5000;
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
-bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions, bool fAllowLookup)
+bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
vIP.clear();
struct addrinfo aiHint;
@@ -77,7 +77,7 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, int nM
return (vIP.size() > 0);
}
-bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions, bool fAllowLookup)
+bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
if (pszName[0] == 0)
return false;
@@ -93,12 +93,12 @@ bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutio
return LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup);
}
-bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions)
+bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions)
{
return LookupHost(pszName, vIP, nMaxSolutions, false);
}
-bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, int nMaxSolutions)
+bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
{
if (pszName[0] == 0)
return false;
@@ -136,7 +136,7 @@ bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault,
if (!fRet)
return false;
vAddr.resize(vIP.size());
- for (int i = 0; i < vIP.size(); i++)
+ for (unsigned int i = 0; i < vIP.size(); i++)
vAddr[i] = CService(vIP[i], port);
return true;
}
diff --git a/src/netbase.h b/src/netbase.h
index 9e79de4253..00b6850b2a 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -7,27 +7,6 @@
#include <string>
#include <vector>
-#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 <arpa/inet.h>
-#include <netdb.h>
-#include <net/if.h>
-#include <ifaddrs.h>
-#endif
-#ifdef BSD
-#include <netinet/in.h>
-#endif
-
#include "serialize.h"
#include "compat.h"
@@ -134,10 +113,10 @@ class CService : public CNetAddr
)
};
-bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions = 0, bool fAllowLookup = true);
-bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, int nMaxSolutions = 0);
+bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);
+bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0);
bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
-bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, int nMaxSolutions = 0);
+bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0);
bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
diff --git a/src/noui.cpp b/src/noui.cpp
index 077e460a70..08a08b439a 100644
--- a/src/noui.cpp
+++ b/src/noui.cpp
@@ -5,7 +5,6 @@
#include "ui_interface.h"
#include <string>
-#include "headers.h"
#include "init.h"
int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 15fbf9fc0d..06306cf8e1 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -107,7 +107,7 @@ CInv::CInv(int typeIn, const uint256& hashIn)
CInv::CInv(const std::string& strType, const uint256& hashIn)
{
- int i;
+ unsigned int i;
for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
{
if (strType == ppszTypeName[i])
diff --git a/src/protocol.h b/src/protocol.h
index e639127355..f7331c1923 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -12,7 +12,6 @@
#include "serialize.h"
#include "netbase.h"
-#include "util.h"
#include <string>
#include "uint256.h"
@@ -79,9 +78,10 @@ class CAddress : public CService
if (fRead)
pthis->Init();
if (nType & SER_DISK)
- READWRITE(nVersion);
- if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH)))
- READWRITE(nTime);
+ READWRITE(nVersion);
+ if ((nType & SER_DISK) ||
+ (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH)))
+ READWRITE(nTime);
READWRITE(nServices);
READWRITE(*pip);
)
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index 0239a167d7..7b95f51c04 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 <QFont>
#include <QColor>
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 463b2cfa79..c7830871b5 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 <QApplication>
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 284bee0e8e..cb602ce327 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 <QDateTime>
diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp
index 4b21b8c4be..84578b3322 100644
--- a/src/qt/csvmodelwriter.cpp
+++ b/src/qt/csvmodelwriter.cpp
@@ -6,7 +6,7 @@
CSVModelWriter::CSVModelWriter(const QString &filename, QObject *parent) :
QObject(parent),
- filename(filename)
+ filename(filename), model(0)
{
}
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index cb2473240e..f1e8a5f1bc 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 <QString>
#include <QDateTime>
#include <QDoubleValidator>
diff --git a/src/qt/messagepage.cpp b/src/qt/messagepage.cpp
index 46a0cbae24..18bb64fe6c 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 ed2225cbf5..f7d9b0da2e 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -2,8 +2,8 @@
#include "bitcoinunits.h"
#include <QSettings>
-#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 3c7889ca71..102ac0ff4e 100644
--- a/src/qt/qtipcserver.cpp
+++ b/src/qt/qtipcserver.cpp
@@ -7,7 +7,8 @@
#include <boost/tokenizer.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
-#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 dd7dd61390..286cddf2a9 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 <QString>
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index 57210dcc02..32350eaa5a 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.
*/
@@ -146,12 +146,6 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
//
// Mixed debit transaction, can't break down payees
//
- bool fAllMine = true;
- BOOST_FOREACH(const CTxOut& txout, wtx.vout)
- fAllMine = fAllMine && wallet->IsMine(txout);
- BOOST_FOREACH(const CTxIn& txin, wtx.vin)
- fAllMine = fAllMine && wallet->IsMine(txin);
-
parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
}
}
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index 41c9db1123..5f505f444e 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 <QLocale>
#include <QList>
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 9c28a8abc8..7a83f6cefb 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 <QSet>
diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp
index 5bb4789cd3..1bc87e9217 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 <boost/lexical_cast.hpp>
diff --git a/src/script.cpp b/src/script.cpp
index 21f101e1c5..fc0a5b3eaa 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 <boost/foreach.hpp>
using namespace std;
using namespace boost;
+#include "script.h"
+#include "keystore.h"
+#include "bignum.h"
+#include "key.h"
+#include "main.h"
+
bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> 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 2d4aaba6a9..12ea1ec695 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -20,6 +20,7 @@
#include <boost/tuple/tuple_io.hpp>
#include "allocators.h"
+#include "version.h"
typedef long long int64;
typedef unsigned long long uint64;
@@ -29,8 +30,6 @@ class CDataStream;
class CAutoFile;
static const unsigned int MAX_SIZE = 0x02000000;
-static const int PROTOCOL_VERSION = 60000;
-
// Used to bypass the rule against non-const reference to temporary
// where it makes sense with wrappers such as CFlatData or CTxDB
template<typename T>
@@ -58,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; \
@@ -73,7 +72,7 @@ enum
return nSerSize; \
} \
template<typename Stream> \
- 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; \
@@ -84,7 +83,7 @@ enum
{statements} \
} \
template<typename Stream> \
- 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; \
@@ -276,48 +275,6 @@ public:
}
};
-
-
-/** string stored as a fixed length field */
-template<std::size_t LEN>
-class CFixedFieldString
-{
-protected:
- const std::string* pcstr;
- std::string* pstr;
-public:
- explicit CFixedFieldString(const std::string& str) : pcstr(&str), pstr(NULL) { }
- explicit CFixedFieldString(std::string& str) : pcstr(&str), pstr(&str) { }
-
- unsigned int GetSerializeSize(int, int=0) const
- {
- return LEN;
- }
-
- template<typename Stream>
- void Serialize(Stream& s, int, int=0) const
- {
- char pszBuf[LEN];
- strncpy(pszBuf, pcstr->c_str(), LEN);
- s.write(pszBuf, LEN);
- }
-
- template<typename Stream>
- void Unserialize(Stream& s, int, int=0)
- {
- if (pstr == NULL)
- throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string");
- char pszBuf[LEN+1];
- s.read(pszBuf, LEN);
- pszBuf[LEN] = '\0';
- *pstr = pszBuf;
- }
-};
-
-
-
-
-
//
// Forward declarations
//
@@ -330,43 +287,43 @@ template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_st
// vector
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
-template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
-template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
-template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
// others derived from vector
-extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream> 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<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
+template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
// pair
-template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion);
+template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion);
+template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion);
// 3 tuple
-template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
+template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
+template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
// 4 tuple
-template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
+template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
+template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
// map
-template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion);
+template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion);
+template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion);
// set
-template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
-template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
+template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion);
+template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion);
+template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion);
@@ -379,19 +336,19 @@ template<typename Stream, typename K, typename Pred, typename A> void Unserializ
// Thanks to Boost serialization for this idea.
//
template<typename T>
-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<typename Stream, typename T>
-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<typename Stream, typename T>
-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);
}
@@ -479,10 +436,6 @@ inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVe
template<typename Stream, typename T, typename A>
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
{
- //unsigned int nSize = ReadCompactSize(is);
- //v.resize(nSize);
- //is.read((char*)&v[0], nSize * sizeof(T));
-
// Limit size per read so bogus size value won't cause out of memory
v.clear();
unsigned int nSize = ReadCompactSize(is);
@@ -499,11 +452,6 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion,
template<typename Stream, typename T, typename A>
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
{
- //unsigned int nSize = ReadCompactSize(is);
- //v.resize(nSize);
- //for (std::vector<T, A>::iterator vi = v.begin(); vi != v.end(); ++vi)
- // Unserialize(is, (*vi), nType, nVersion);
-
v.clear();
unsigned int nSize = ReadCompactSize(is);
unsigned int i = 0;
@@ -782,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<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end())
+ CDataStream(const std::vector<char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
{
Init(nTypeIn, nVersionIn);
}
- CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
+ CDataStream(const std::vector<unsigned char>& 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;
@@ -1028,7 +976,7 @@ public:
}
template<typename Stream>
- 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())
@@ -1137,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;
@@ -1190,7 +1138,7 @@ public:
void ReadVersion() { *this >> nVersion; }
void WriteVersion() { *this << nVersion; }
- CAutoFile& read(char* pch, int nSize)
+ CAutoFile& read(char* pch, size_t nSize)
{
if (!file)
throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
@@ -1199,7 +1147,7 @@ public:
return (*this);
}
- CAutoFile& write(const char* pch, int nSize)
+ CAutoFile& write(const char* pch, size_t nSize)
{
if (!file)
throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
diff --git a/src/strlcpy.h b/src/strlcpy.h
index d4d1908e7a..2cc786e953 100644
--- a/src/strlcpy.h
+++ b/src/strlcpy.h
@@ -15,6 +15,10 @@
*/
#ifndef BITCOIN_STRLCPY_H
#define BITCOIN_STRLCPY_H
+
+#include <stdlib.h>
+#include <string.h>
+
/*
* 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/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 0b89414048..c0b00102a0 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
- CDataStream ds;
+ CDataStream ds(SER_DISK, CLIENT_VERSION);
ds << tx;
AddOrphanTx(ds);
}
@@ -187,7 +187,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
SignSignature(keystore, txPrev, tx, 0);
- CDataStream ds;
+ CDataStream ds(SER_DISK, CLIENT_VERSION);
ds << tx;
AddOrphanTx(ds);
}
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index d4abd6d2a7..5712b4a1b1 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -1,6 +1,7 @@
#include <boost/test/unit_test.hpp>
#include "uint256.h"
+#include "util.h"
extern void SHA256Transform(void* pstate, void* pinput, const void* pinit);
@@ -11,7 +12,7 @@ BOOST_AUTO_TEST_CASE(sha256transform_equality)
unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
- unsigned char pstate[32];
+ // unsigned char pstate[32];
unsigned char pinput[64];
int i;
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 99163e55f2..b680ede9a5 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -12,7 +12,7 @@ BOOST_AUTO_TEST_CASE(basic_transaction_tests)
// Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436)
unsigned char ch[] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00};
vector<unsigned char> vch(ch, ch + sizeof(ch) -1);
- CDataStream stream(vch);
+ CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
CTransaction tx;
stream >> tx;
BOOST_CHECK_MESSAGE(tx.CheckTransaction(), "Simple deserialized transaction should be valid.");
diff --git a/src/uint256.h b/src/uint256.h
index 0947816785..bf3c55bccb 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 <limits.h>
+#include <string.h>
#include <string>
#include <vector>
@@ -287,7 +286,7 @@ public:
std::string GetHex() const
{
char psz[sizeof(pn)*2 + 1];
- for (int i = 0; i < sizeof(pn); i++)
+ for (unsigned int i = 0; i < sizeof(pn); i++)
sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
return std::string(psz, psz + sizeof(pn)*2);
}
@@ -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<typename Stream>
- 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<typename Stream>
- 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 a5427c061b..ac65d417b3 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 <boost/algorithm/string/join.hpp>
// Work around clang compilation problem in Boost 1.46:
@@ -24,6 +26,31 @@ namespace boost {
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
#include <boost/foreach.hpp>
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+
+#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;
@@ -301,7 +328,6 @@ bool error(const char *format, ...)
va_end(arg_ptr);
if (ret < 0 || ret >= limit)
{
- ret = limit - 1;
buffer[limit-1] = 0;
}
printf("ERROR: %s\n", buffer);
@@ -1065,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<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 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 f6cb3caa1d..d9ec68c620 100644
--- a/src/util.h
+++ b/src/util.h
@@ -31,11 +31,14 @@ typedef int pid_t; /* define for windows compatiblity */
#include <openssl/sha.h>
#include <openssl/ripemd.h>
-#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<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& 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/version.cpp b/src/version.cpp
index e1be5f491b..0c1e8bfa80 100644
--- a/src/version.cpp
+++ b/src/version.cpp
@@ -11,18 +11,8 @@
const std::string CLIENT_NAME("Satoshi");
// Client version number
-#define CLIENT_VERSION_MAJOR 0
-#define CLIENT_VERSION_MINOR 6
-#define CLIENT_VERSION_REVISION 0
-#define CLIENT_VERSION_BUILD 99
#define CLIENT_VERSION_SUFFIX "-beta"
-const int CLIENT_VERSION = 1000000 * CLIENT_VERSION_MAJOR
- + 10000 * CLIENT_VERSION_MINOR
- + 100 * CLIENT_VERSION_REVISION
- + 1 * CLIENT_VERSION_BUILD;
-
-
// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
diff --git a/src/version.h b/src/version.h
index c93b28fb7d..f63b1bdadd 100644
--- a/src/version.h
+++ b/src/version.h
@@ -6,9 +6,43 @@
#include <string>
+//
+// client versioning
+//
+
+static const int CLIENT_VERSION_MAJOR = 0;
+static const int CLIENT_VERSION_MINOR = 6;
+static const int CLIENT_VERSION_REVISION = 0;
+static const int CLIENT_VERSION_BUILD = 99;
+
+static const int CLIENT_VERSION =
+ 1000000 * CLIENT_VERSION_MAJOR
+ + 10000 * CLIENT_VERSION_MINOR
+ + 100 * CLIENT_VERSION_REVISION
+ + 1 * CLIENT_VERSION_BUILD;
+
extern const std::string CLIENT_NAME;
extern const std::string CLIENT_BUILD;
extern const std::string CLIENT_DATE;
-extern const int CLIENT_VERSION;
+
+//
+// network protocol versioning
+//
+
+static const int PROTOCOL_VERSION = 60001;
+
+// earlier versions not supported as of Feb 2012, and are disconnected
+static const int MIN_PROTO_VERSION = 209;
+
+// nTime field added to CAddress, starting with this version;
+// if possible, avoid requesting addresses nodes older than this
+static const int CADDR_TIME_VERSION = 31402;
+
+// only request blocks from nodes outside this range of versions
+static const int NOBLKS_VERSION_START = 32000;
+static const int NOBLKS_VERSION_END = 32400;
+
+// BIP 0031, pong message, is enabled for all versions AFTER this one
+static const int BIP0031_VERSION = 60000;
#endif
diff --git a/src/wallet.cpp b/src/wallet.cpp
index ff10e0cef8..53836be0cd 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.
@@ -615,7 +621,7 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
LOCK(pwallet->cs_wallet);
map<uint256, const CMerkleTx*> mapWalletPrev;
set<uint256> setAlreadyDone;
- for (int i = 0; i < vWorkQueue.size(); i++)
+ for (unsigned int i = 0; i < vWorkQueue.size(); i++)
{
uint256 hash = vWorkQueue[i];
if (setAlreadyDone.count(hash))
@@ -723,7 +729,7 @@ void CWallet::ReacceptWalletTransactions()
printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
continue;
}
- for (int i = 0; i < txindex.vSpent.size(); i++)
+ for (unsigned int i = 0; i < txindex.vSpent.size(); i++)
{
if (wtx.IsSpent(i))
continue;
@@ -902,7 +908,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
if (nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
continue;
- for (int i = 0; i < pcoin->vout.size(); i++)
+ for (unsigned int i = 0; i < pcoin->vout.size(); i++)
{
if (pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]))
continue;
@@ -935,7 +941,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
if (nTotalLower == nTargetValue || nTotalLower == nTargetValue + CENT)
{
- for (int i = 0; i < vValue.size(); ++i)
+ for (unsigned int i = 0; i < vValue.size(); ++i)
{
setCoinsRet.insert(vValue[i].second);
nValueRet += vValue[i].first;
@@ -968,7 +974,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
bool fReachedTarget = false;
for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
{
- for (int i = 0; i < vValue.size(); i++)
+ for (unsigned int i = 0; i < vValue.size(); i++)
{
if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
{
@@ -997,7 +1003,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
nValueRet += coinLowestLarger.first;
}
else {
- for (int i = 0; i < vValue.size(); i++)
+ for (unsigned int i = 0; i < vValue.size(); i++)
if (vfBest[i])
{
setCoinsRet.insert(vValue[i].second);
@@ -1006,7 +1012,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
//// debug print
printf("SelectCoins() best subset: ");
- for (int i = 0; i < vValue.size(); i++)
+ for (unsigned int i = 0; i < vValue.size(); i++)
if (vfBest[i])
printf("%s ", FormatMoney(vValue[i].first).c_str());
printf("total %s\n", FormatMoney(nBest).c_str());
@@ -1116,7 +1122,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& 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 869e888fcd..c1461b1feb 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<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);
+ )
+};
+
/** 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);
@@ -402,7 +426,7 @@ public:
bool UpdateSpent(const std::vector<char>& vfNewSpent)
{
bool fReturn = false;
- for (int i=0; i < vfNewSpent.size(); i++)
+ for (unsigned int i = 0; i < vfNewSpent.size(); i++)
{
if (i == vfSpent.size())
break;
@@ -488,7 +512,7 @@ public:
return nAvailableCreditCached;
int64 nCredit = 0;
- for (int i = 0; i < vout.size(); i++)
+ for (unsigned int i = 0; i < vout.size(); i++)
{
if (!IsSpent(i))
{
@@ -541,7 +565,7 @@ public:
std::vector<const CMerkleTx*> vWorkQueue;
vWorkQueue.reserve(vtxPrev.size()+1);
vWorkQueue.push_back(this);
- for (int i = 0; i < vWorkQueue.size(); i++)
+ for (unsigned int i = 0; i < vWorkQueue.size(); i++)
{
const CMerkleTx* ptx = vWorkQueue[i];
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
new file mode 100644
index 0000000000..709ecac184
--- /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 <boost/filesystem.hpp>
+
+using namespace std;
+using namespace boost;
+
+
+static uint64 nAccountingEntryNumber = 0;
+
+extern CCriticalSection cs_db;
+extern map<string, int> 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<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(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<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(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<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;
+}
diff --git a/src/walletdb.h b/src/walletdb.h
new file mode 100644
index 0000000000..46ba7967ca
--- /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<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 // BITCOIN_WALLETDB_H