Merge pull request #1112 from sipa/saneserial
Further reduce header dependencies
This commit is contained in:
commit
1ffeb89a52
52 changed files with 1005 additions and 1015 deletions
|
@ -117,9 +117,9 @@ HEADERS += src/qt/bitcoingui.h \
|
||||||
src/net.h \
|
src/net.h \
|
||||||
src/key.h \
|
src/key.h \
|
||||||
src/db.h \
|
src/db.h \
|
||||||
|
src/walletdb.h \
|
||||||
src/script.h \
|
src/script.h \
|
||||||
src/init.h \
|
src/init.h \
|
||||||
src/headers.h \
|
|
||||||
src/irc.h \
|
src/irc.h \
|
||||||
src/mruset.h \
|
src/mruset.h \
|
||||||
src/json/json_spirit_writer_template.h \
|
src/json/json_spirit_writer_template.h \
|
||||||
|
@ -182,6 +182,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
||||||
src/checkpoints.cpp \
|
src/checkpoints.cpp \
|
||||||
src/addrman.cpp \
|
src/addrman.cpp \
|
||||||
src/db.cpp \
|
src/db.cpp \
|
||||||
|
src/walletdb.cpp \
|
||||||
src/json/json_spirit_writer.cpp \
|
src/json/json_spirit_writer.cpp \
|
||||||
src/json/json_spirit_value.cpp \
|
src/json/json_spirit_value.cpp \
|
||||||
src/json/json_spirit_reader.cpp \
|
src/json/json_spirit_reader.cpp \
|
||||||
|
|
|
@ -8,12 +8,12 @@ using namespace std;
|
||||||
|
|
||||||
int CAddrInfo::GetTriedBucket(const std::vector<unsigned char> &nKey) const
|
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();
|
std::vector<unsigned char> vchKey = GetKey();
|
||||||
ss1 << nKey << vchKey;
|
ss1 << nKey << vchKey;
|
||||||
uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64();
|
uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64();
|
||||||
|
|
||||||
CDataStream ss2(SER_GETHASH);
|
CDataStream ss2(SER_GETHASH, 0);
|
||||||
std::vector<unsigned char> vchGroupKey = GetGroup();
|
std::vector<unsigned char> vchGroupKey = GetGroup();
|
||||||
ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP);
|
ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP);
|
||||||
uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64();
|
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
|
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> vchGroupKey = GetGroup();
|
||||||
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
|
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
|
||||||
ss1 << nKey << vchGroupKey << vchSourceGroupKey;
|
ss1 << nKey << vchGroupKey << vchSourceGroupKey;
|
||||||
uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64();
|
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);
|
ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP);
|
||||||
uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64();
|
uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64();
|
||||||
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
|
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
#ifdef _WIN32_WINNT
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#endif
|
||||||
#define _WIN32_WINNT 0x0501
|
#define _WIN32_WINNT 0x0501
|
||||||
#define WIN32_LEAN_AND_MEAN 1
|
#define WIN32_LEAN_AND_MEAN 1
|
||||||
#ifndef NOMINMAX
|
#ifndef NOMINMAX
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h" // for uint64
|
||||||
|
|
||||||
/** Errors thrown by the bignum class */
|
/** Errors thrown by the bignum class */
|
||||||
class bignum_error : public std::runtime_error
|
class bignum_error : public std::runtime_error
|
||||||
|
|
|
@ -3,10 +3,14 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// 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 "db.h"
|
||||||
|
#include "walletdb.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
|
|
||||||
#undef printf
|
#undef printf
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
@ -138,7 +142,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
|
||||||
{
|
{
|
||||||
Object result;
|
Object result;
|
||||||
result.push_back(Pair("hash", block.GetHash().GetHex()));
|
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("height", blockindex->nHeight));
|
||||||
result.push_back(Pair("version", block.nVersion));
|
result.push_back(Pair("version", block.nVersion));
|
||||||
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
||||||
|
@ -598,7 +602,7 @@ Value signmessage(const Array& params, bool fHelp)
|
||||||
if (!pwalletMain->GetKey(addr, key))
|
if (!pwalletMain->GetKey(addr, key))
|
||||||
throw JSONRPCError(-4, "Private key not available");
|
throw JSONRPCError(-4, "Private key not available");
|
||||||
|
|
||||||
CDataStream ss(SER_GETHASH);
|
CDataStream ss(SER_GETHASH, 0);
|
||||||
ss << strMessageMagic;
|
ss << strMessageMagic;
|
||||||
ss << strMessage;
|
ss << strMessage;
|
||||||
|
|
||||||
|
@ -630,7 +634,7 @@ Value verifymessage(const Array& params, bool fHelp)
|
||||||
if (fInvalid)
|
if (fInvalid)
|
||||||
throw JSONRPCError(-5, "Malformed base64 encoding");
|
throw JSONRPCError(-5, "Malformed base64 encoding");
|
||||||
|
|
||||||
CDataStream ss(SER_GETHASH);
|
CDataStream ss(SER_GETHASH, 0);
|
||||||
ss << strMessageMagic;
|
ss << strMessageMagic;
|
||||||
ss << strMessage;
|
ss << strMessage;
|
||||||
|
|
||||||
|
@ -1917,7 +1921,7 @@ Value getmemorypool(const Array& params, bool fHelp)
|
||||||
if(tx.IsCoinBase())
|
if(tx.IsCoinBase())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CDataStream ssTx;
|
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ssTx << tx;
|
ssTx << tx;
|
||||||
|
|
||||||
transactions.push_back(HexStr(ssTx.begin(), ssTx.end()));
|
transactions.push_back(HexStr(ssTx.begin(), ssTx.end()));
|
||||||
|
@ -1939,7 +1943,7 @@ Value getmemorypool(const Array& params, bool fHelp)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Parse parameters
|
// Parse parameters
|
||||||
CDataStream ssBlock(ParseHex(params[0].get_str()));
|
CDataStream ssBlock(ParseHex(params[0].get_str()), SER_NETWORK, PROTOCOL_VERSION);
|
||||||
CBlock pblock;
|
CBlock pblock;
|
||||||
ssBlock >> pblock;
|
ssBlock >> pblock;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#include "headers.h"
|
|
||||||
#include "checkpoints.h"
|
#include "checkpoints.h"
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "uint256.h"
|
||||||
|
|
||||||
namespace Checkpoints
|
namespace Checkpoints
|
||||||
{
|
{
|
||||||
typedef std::map<int, uint256> MapCheckpoints;
|
typedef std::map<int, uint256> MapCheckpoints;
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#define BITCOIN_CHECKPOINT_H
|
#define BITCOIN_CHECKPOINT_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
class uint256;
|
class uint256;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
|
|
23
src/compat.h
23
src/compat.h
|
@ -5,6 +5,28 @@
|
||||||
#ifndef _BITCOIN_COMPAT_H
|
#ifndef _BITCOIN_COMPAT_H
|
||||||
#define _BITCOIN_COMPAT_H 1
|
#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;
|
typedef u_int SOCKET;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define MSG_NOSIGNAL 0
|
#define MSG_NOSIGNAL 0
|
||||||
|
@ -39,4 +61,5 @@ inline int myclosesocket(SOCKET& hSocket)
|
||||||
}
|
}
|
||||||
#define closesocket(s) myclosesocket(s)
|
#define closesocket(s) myclosesocket(s)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,14 +6,11 @@
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "headers.h"
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "crypter.h"
|
#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)
|
bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "allocators.h" /* for SecureString */
|
#include "allocators.h" /* for SecureString */
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
|
#include "serialize.h"
|
||||||
|
|
||||||
const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
|
const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
|
||||||
const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
|
const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
|
||||||
|
|
442
src/db.cpp
442
src/db.cpp
|
@ -3,19 +3,22 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "headers.h"
|
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "net.h"
|
#include "util.h"
|
||||||
|
#include "main.h"
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#include "sys/stat.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
|
|
||||||
unsigned int nWalletDBUpdated;
|
unsigned int nWalletDBUpdated;
|
||||||
uint64 nAccountingEntryNumber = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,10 +26,10 @@ uint64 nAccountingEntryNumber = 0;
|
||||||
// CDB
|
// CDB
|
||||||
//
|
//
|
||||||
|
|
||||||
static CCriticalSection cs_db;
|
CCriticalSection cs_db;
|
||||||
static bool fDbEnvInit = false;
|
static bool fDbEnvInit = false;
|
||||||
DbEnv dbenv(0);
|
DbEnv dbenv(0);
|
||||||
static map<string, int> mapFileUseCount;
|
map<string, int> mapFileUseCount;
|
||||||
static map<string, Db*> mapDb;
|
static map<string, Db*> mapDb;
|
||||||
|
|
||||||
static void EnvShutdown()
|
static void EnvShutdown()
|
||||||
|
@ -173,7 +176,7 @@ void CDB::Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void static CloseDb(const string& strFile)
|
void CloseDb(const string& strFile)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_db);
|
LOCK(cs_db);
|
||||||
|
@ -225,8 +228,8 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
|
||||||
if (pcursor)
|
if (pcursor)
|
||||||
while (fSuccess)
|
while (fSuccess)
|
||||||
{
|
{
|
||||||
CDataStream ssKey;
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
CDataStream ssValue;
|
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
||||||
int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
|
int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
|
||||||
if (ret == DB_NOTFOUND)
|
if (ret == DB_NOTFOUND)
|
||||||
{
|
{
|
||||||
|
@ -382,10 +385,10 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>&
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
// Read next record
|
// Read next record
|
||||||
CDataStream ssKey;
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
if (fFlags == DB_SET_RANGE)
|
if (fFlags == DB_SET_RANGE)
|
||||||
ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0);
|
ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0);
|
||||||
CDataStream ssValue;
|
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
||||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
|
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
|
||||||
fFlags = DB_NEXT;
|
fFlags = DB_NEXT;
|
||||||
if (ret == DB_NOTFOUND)
|
if (ret == DB_NOTFOUND)
|
||||||
|
@ -510,10 +513,10 @@ bool CTxDB::LoadBlockIndex()
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
// Read next record
|
// Read next record
|
||||||
CDataStream ssKey;
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
if (fFlags == DB_SET_RANGE)
|
if (fFlags == DB_SET_RANGE)
|
||||||
ssKey << make_pair(string("blockindex"), uint256(0));
|
ssKey << make_pair(string("blockindex"), uint256(0));
|
||||||
CDataStream ssValue;
|
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
||||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
|
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
|
||||||
fFlags = DB_NEXT;
|
fFlags = DB_NEXT;
|
||||||
if (ret == DB_NOTFOUND)
|
if (ret == DB_NOTFOUND)
|
||||||
|
@ -750,8 +753,8 @@ bool CAddrDB::LoadAddresses()
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
// Read next record
|
// Read next record
|
||||||
CDataStream ssKey;
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
CDataStream ssValue;
|
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
||||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
|
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
|
||||||
if (ret == DB_NOTFOUND)
|
if (ret == DB_NOTFOUND)
|
||||||
break;
|
break;
|
||||||
|
@ -786,414 +789,3 @@ bool LoadAddresses()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// CWalletDB
|
|
||||||
//
|
|
||||||
|
|
||||||
bool CWalletDB::WriteName(const string& strAddress, const string& strName)
|
|
||||||
{
|
|
||||||
nWalletDBUpdated++;
|
|
||||||
return Write(make_pair(string("name"), strAddress), strName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CWalletDB::EraseName(const string& strAddress)
|
|
||||||
{
|
|
||||||
// This should only be used for sending addresses, never for receiving addresses,
|
|
||||||
// receiving addresses must always have an address book entry if they're not change return.
|
|
||||||
nWalletDBUpdated++;
|
|
||||||
return Erase(make_pair(string("name"), strAddress));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account)
|
|
||||||
{
|
|
||||||
account.SetNull();
|
|
||||||
return Read(make_pair(string("acc"), strAccount), account);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account)
|
|
||||||
{
|
|
||||||
return Write(make_pair(string("acc"), strAccount), account);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry)
|
|
||||||
{
|
|
||||||
return Write(boost::make_tuple(string("acentry"), acentry.strAccount, ++nAccountingEntryNumber), acentry);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 CWalletDB::GetAccountCreditDebit(const string& strAccount)
|
|
||||||
{
|
|
||||||
list<CAccountingEntry> entries;
|
|
||||||
ListAccountCreditDebit(strAccount, entries);
|
|
||||||
|
|
||||||
int64 nCreditDebit = 0;
|
|
||||||
BOOST_FOREACH (const CAccountingEntry& entry, entries)
|
|
||||||
nCreditDebit += entry.nCreditDebit;
|
|
||||||
|
|
||||||
return nCreditDebit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& entries)
|
|
||||||
{
|
|
||||||
bool fAllAccounts = (strAccount == "*");
|
|
||||||
|
|
||||||
Dbc* pcursor = GetCursor();
|
|
||||||
if (!pcursor)
|
|
||||||
throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor");
|
|
||||||
unsigned int fFlags = DB_SET_RANGE;
|
|
||||||
loop
|
|
||||||
{
|
|
||||||
// Read next record
|
|
||||||
CDataStream ssKey;
|
|
||||||
if (fFlags == DB_SET_RANGE)
|
|
||||||
ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64(0));
|
|
||||||
CDataStream ssValue;
|
|
||||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
|
|
||||||
fFlags = DB_NEXT;
|
|
||||||
if (ret == DB_NOTFOUND)
|
|
||||||
break;
|
|
||||||
else if (ret != 0)
|
|
||||||
{
|
|
||||||
pcursor->close();
|
|
||||||
throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unserialize
|
|
||||||
string strType;
|
|
||||||
ssKey >> strType;
|
|
||||||
if (strType != "acentry")
|
|
||||||
break;
|
|
||||||
CAccountingEntry acentry;
|
|
||||||
ssKey >> acentry.strAccount;
|
|
||||||
if (!fAllAccounts && acentry.strAccount != strAccount)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ssValue >> acentry;
|
|
||||||
entries.push_back(acentry);
|
|
||||||
}
|
|
||||||
|
|
||||||
pcursor->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int CWalletDB::LoadWallet(CWallet* pwallet)
|
|
||||||
{
|
|
||||||
pwallet->vchDefaultKey.clear();
|
|
||||||
int nFileVersion = 0;
|
|
||||||
vector<uint256> vWalletUpgrade;
|
|
||||||
bool fIsEncrypted = false;
|
|
||||||
|
|
||||||
//// todo: shouldn't we catch exceptions and try to recover and continue?
|
|
||||||
{
|
|
||||||
LOCK(pwallet->cs_wallet);
|
|
||||||
int nMinVersion = 0;
|
|
||||||
if (Read((string)"minversion", nMinVersion))
|
|
||||||
{
|
|
||||||
if (nMinVersion > CLIENT_VERSION)
|
|
||||||
return DB_TOO_NEW;
|
|
||||||
pwallet->LoadMinVersion(nMinVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get cursor
|
|
||||||
Dbc* pcursor = GetCursor();
|
|
||||||
if (!pcursor)
|
|
||||||
{
|
|
||||||
printf("Error getting wallet database cursor\n");
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
loop
|
|
||||||
{
|
|
||||||
// Read next record
|
|
||||||
CDataStream ssKey;
|
|
||||||
CDataStream ssValue;
|
|
||||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
|
|
||||||
if (ret == DB_NOTFOUND)
|
|
||||||
break;
|
|
||||||
else if (ret != 0)
|
|
||||||
{
|
|
||||||
printf("Error reading next record from wallet database\n");
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unserialize
|
|
||||||
// Taking advantage of the fact that pair serialization
|
|
||||||
// is just the two items serialized one after the other
|
|
||||||
string strType;
|
|
||||||
ssKey >> strType;
|
|
||||||
if (strType == "name")
|
|
||||||
{
|
|
||||||
string strAddress;
|
|
||||||
ssKey >> strAddress;
|
|
||||||
ssValue >> pwallet->mapAddressBook[strAddress];
|
|
||||||
}
|
|
||||||
else if (strType == "tx")
|
|
||||||
{
|
|
||||||
uint256 hash;
|
|
||||||
ssKey >> hash;
|
|
||||||
CWalletTx& wtx = pwallet->mapWallet[hash];
|
|
||||||
ssValue >> wtx;
|
|
||||||
wtx.BindWallet(pwallet);
|
|
||||||
|
|
||||||
if (wtx.GetHash() != hash)
|
|
||||||
printf("Error in wallet.dat, hash mismatch\n");
|
|
||||||
|
|
||||||
// Undo serialize changes in 31600
|
|
||||||
if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
|
|
||||||
{
|
|
||||||
if (!ssValue.empty())
|
|
||||||
{
|
|
||||||
char fTmp;
|
|
||||||
char fUnused;
|
|
||||||
ssValue >> fTmp >> fUnused >> wtx.strFromAccount;
|
|
||||||
printf("LoadWallet() upgrading tx ver=%d %d '%s' %s\n", wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount.c_str(), hash.ToString().c_str());
|
|
||||||
wtx.fTimeReceivedIsTxTime = fTmp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString().c_str());
|
|
||||||
wtx.fTimeReceivedIsTxTime = 0;
|
|
||||||
}
|
|
||||||
vWalletUpgrade.push_back(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
//// debug print
|
|
||||||
//printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
|
|
||||||
//printf(" %12I64d %s %s %s\n",
|
|
||||||
// wtx.vout[0].nValue,
|
|
||||||
// DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()).c_str(),
|
|
||||||
// wtx.hashBlock.ToString().substr(0,20).c_str(),
|
|
||||||
// wtx.mapValue["message"].c_str());
|
|
||||||
}
|
|
||||||
else if (strType == "acentry")
|
|
||||||
{
|
|
||||||
string strAccount;
|
|
||||||
ssKey >> strAccount;
|
|
||||||
uint64 nNumber;
|
|
||||||
ssKey >> nNumber;
|
|
||||||
if (nNumber > nAccountingEntryNumber)
|
|
||||||
nAccountingEntryNumber = nNumber;
|
|
||||||
}
|
|
||||||
else if (strType == "key" || strType == "wkey")
|
|
||||||
{
|
|
||||||
vector<unsigned char> vchPubKey;
|
|
||||||
ssKey >> vchPubKey;
|
|
||||||
CKey key;
|
|
||||||
if (strType == "key")
|
|
||||||
{
|
|
||||||
CPrivKey pkey;
|
|
||||||
ssValue >> pkey;
|
|
||||||
key.SetPubKey(vchPubKey);
|
|
||||||
key.SetPrivKey(pkey);
|
|
||||||
if (key.GetPubKey() != vchPubKey)
|
|
||||||
{
|
|
||||||
printf("Error reading wallet database: CPrivKey pubkey inconsistency\n");
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
if (!key.IsValid())
|
|
||||||
{
|
|
||||||
printf("Error reading wallet database: invalid CPrivKey\n");
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CWalletKey wkey;
|
|
||||||
ssValue >> wkey;
|
|
||||||
key.SetPubKey(vchPubKey);
|
|
||||||
key.SetPrivKey(wkey.vchPrivKey);
|
|
||||||
if (key.GetPubKey() != vchPubKey)
|
|
||||||
{
|
|
||||||
printf("Error reading wallet database: CWalletKey pubkey inconsistency\n");
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
if (!key.IsValid())
|
|
||||||
{
|
|
||||||
printf("Error reading wallet database: invalid CWalletKey\n");
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!pwallet->LoadKey(key))
|
|
||||||
{
|
|
||||||
printf("Error reading wallet database: LoadKey failed\n");
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strType == "mkey")
|
|
||||||
{
|
|
||||||
unsigned int nID;
|
|
||||||
ssKey >> nID;
|
|
||||||
CMasterKey kMasterKey;
|
|
||||||
ssValue >> kMasterKey;
|
|
||||||
if(pwallet->mapMasterKeys.count(nID) != 0)
|
|
||||||
{
|
|
||||||
printf("Error reading wallet database: duplicate CMasterKey id %u\n", nID);
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
pwallet->mapMasterKeys[nID] = kMasterKey;
|
|
||||||
if (pwallet->nMasterKeyMaxID < nID)
|
|
||||||
pwallet->nMasterKeyMaxID = nID;
|
|
||||||
}
|
|
||||||
else if (strType == "ckey")
|
|
||||||
{
|
|
||||||
vector<unsigned char> vchPubKey;
|
|
||||||
ssKey >> vchPubKey;
|
|
||||||
vector<unsigned char> vchPrivKey;
|
|
||||||
ssValue >> vchPrivKey;
|
|
||||||
if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey))
|
|
||||||
{
|
|
||||||
printf("Error reading wallet database: LoadCryptedKey failed\n");
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
fIsEncrypted = true;
|
|
||||||
}
|
|
||||||
else if (strType == "defaultkey")
|
|
||||||
{
|
|
||||||
ssValue >> pwallet->vchDefaultKey;
|
|
||||||
}
|
|
||||||
else if (strType == "pool")
|
|
||||||
{
|
|
||||||
int64 nIndex;
|
|
||||||
ssKey >> nIndex;
|
|
||||||
pwallet->setKeyPool.insert(nIndex);
|
|
||||||
}
|
|
||||||
else if (strType == "version")
|
|
||||||
{
|
|
||||||
ssValue >> nFileVersion;
|
|
||||||
if (nFileVersion == 10300)
|
|
||||||
nFileVersion = 300;
|
|
||||||
}
|
|
||||||
else if (strType == "cscript")
|
|
||||||
{
|
|
||||||
uint160 hash;
|
|
||||||
ssKey >> hash;
|
|
||||||
CScript script;
|
|
||||||
ssValue >> script;
|
|
||||||
if (!pwallet->LoadCScript(script))
|
|
||||||
{
|
|
||||||
printf("Error reading wallet database: LoadCScript failed\n");
|
|
||||||
return DB_CORRUPT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pcursor->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(uint256 hash, vWalletUpgrade)
|
|
||||||
WriteTx(hash, pwallet->mapWallet[hash]);
|
|
||||||
|
|
||||||
printf("nFileVersion = %d\n", nFileVersion);
|
|
||||||
|
|
||||||
|
|
||||||
// Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
|
|
||||||
if (fIsEncrypted && (nFileVersion == 40000 || nFileVersion == 50000))
|
|
||||||
return DB_NEED_REWRITE;
|
|
||||||
|
|
||||||
if (nFileVersion < CLIENT_VERSION) // Update
|
|
||||||
WriteVersion(CLIENT_VERSION);
|
|
||||||
|
|
||||||
return DB_LOAD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadFlushWalletDB(void* parg)
|
|
||||||
{
|
|
||||||
const string& strFile = ((const string*)parg)[0];
|
|
||||||
static bool fOneThread;
|
|
||||||
if (fOneThread)
|
|
||||||
return;
|
|
||||||
fOneThread = true;
|
|
||||||
if (!GetBoolArg("-flushwallet", true))
|
|
||||||
return;
|
|
||||||
|
|
||||||
unsigned int nLastSeen = nWalletDBUpdated;
|
|
||||||
unsigned int nLastFlushed = nWalletDBUpdated;
|
|
||||||
int64 nLastWalletUpdate = GetTime();
|
|
||||||
while (!fShutdown)
|
|
||||||
{
|
|
||||||
Sleep(500);
|
|
||||||
|
|
||||||
if (nLastSeen != nWalletDBUpdated)
|
|
||||||
{
|
|
||||||
nLastSeen = nWalletDBUpdated;
|
|
||||||
nLastWalletUpdate = GetTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2)
|
|
||||||
{
|
|
||||||
TRY_LOCK(cs_db,lockDb);
|
|
||||||
if (lockDb)
|
|
||||||
{
|
|
||||||
// Don't do this if any databases are in use
|
|
||||||
int nRefCount = 0;
|
|
||||||
map<string, int>::iterator mi = mapFileUseCount.begin();
|
|
||||||
while (mi != mapFileUseCount.end())
|
|
||||||
{
|
|
||||||
nRefCount += (*mi).second;
|
|
||||||
mi++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nRefCount == 0 && !fShutdown)
|
|
||||||
{
|
|
||||||
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
|
|
||||||
if (mi != mapFileUseCount.end())
|
|
||||||
{
|
|
||||||
printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
|
|
||||||
printf("Flushing wallet.dat\n");
|
|
||||||
nLastFlushed = nWalletDBUpdated;
|
|
||||||
int64 nStart = GetTimeMillis();
|
|
||||||
|
|
||||||
// Flush wallet.dat so it's self contained
|
|
||||||
CloseDb(strFile);
|
|
||||||
dbenv.txn_checkpoint(0, 0, 0);
|
|
||||||
dbenv.lsn_reset(strFile.c_str(), 0);
|
|
||||||
|
|
||||||
mapFileUseCount.erase(mi++);
|
|
||||||
printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BackupWallet(const CWallet& wallet, const string& strDest)
|
|
||||||
{
|
|
||||||
if (!wallet.fFileBacked)
|
|
||||||
return false;
|
|
||||||
while (!fShutdown)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
LOCK(cs_db);
|
|
||||||
if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0)
|
|
||||||
{
|
|
||||||
// Flush log data to the dat file
|
|
||||||
CloseDb(wallet.strWalletFile);
|
|
||||||
dbenv.txn_checkpoint(0, 0, 0);
|
|
||||||
dbenv.lsn_reset(wallet.strWalletFile.c_str(), 0);
|
|
||||||
mapFileUseCount.erase(wallet.strWalletFile);
|
|
||||||
|
|
||||||
// Copy wallet.dat
|
|
||||||
filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile;
|
|
||||||
filesystem::path pathDest(strDest);
|
|
||||||
if (filesystem::is_directory(pathDest))
|
|
||||||
pathDest /= wallet.strWalletFile;
|
|
||||||
|
|
||||||
try {
|
|
||||||
#if BOOST_VERSION >= 104000
|
|
||||||
filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
|
|
||||||
#else
|
|
||||||
filesystem::copy_file(pathSrc, pathDest);
|
|
||||||
#endif
|
|
||||||
printf("copied wallet.dat to %s\n", pathDest.string().c_str());
|
|
||||||
return true;
|
|
||||||
} catch(const filesystem::filesystem_error &e) {
|
|
||||||
printf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Sleep(100);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
212
src/db.h
212
src/db.h
|
@ -5,7 +5,7 @@
|
||||||
#ifndef BITCOIN_DB_H
|
#ifndef BITCOIN_DB_H
|
||||||
#define BITCOIN_DB_H
|
#define BITCOIN_DB_H
|
||||||
|
|
||||||
#include "key.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -13,8 +13,6 @@
|
||||||
|
|
||||||
#include <db_cxx.h>
|
#include <db_cxx.h>
|
||||||
|
|
||||||
class CAccount;
|
|
||||||
class CAccountingEntry;
|
|
||||||
class CAddress;
|
class CAddress;
|
||||||
class CAddrMan;
|
class CAddrMan;
|
||||||
class CBlockLocator;
|
class CBlockLocator;
|
||||||
|
@ -59,7 +57,7 @@ protected:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Key
|
// Key
|
||||||
CDataStream ssKey(SER_DISK);
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
ssKey.reserve(1000);
|
ssKey.reserve(1000);
|
||||||
ssKey << key;
|
ssKey << key;
|
||||||
Dbt datKey(&ssKey[0], ssKey.size());
|
Dbt datKey(&ssKey[0], ssKey.size());
|
||||||
|
@ -73,7 +71,7 @@ protected:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Unserialize value
|
// 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;
|
ssValue >> value;
|
||||||
|
|
||||||
// Clear and free memory
|
// Clear and free memory
|
||||||
|
@ -91,13 +89,13 @@ protected:
|
||||||
assert(!"Write called on database in read-only mode");
|
assert(!"Write called on database in read-only mode");
|
||||||
|
|
||||||
// Key
|
// Key
|
||||||
CDataStream ssKey(SER_DISK);
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
ssKey.reserve(1000);
|
ssKey.reserve(1000);
|
||||||
ssKey << key;
|
ssKey << key;
|
||||||
Dbt datKey(&ssKey[0], ssKey.size());
|
Dbt datKey(&ssKey[0], ssKey.size());
|
||||||
|
|
||||||
// Value
|
// Value
|
||||||
CDataStream ssValue(SER_DISK);
|
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
||||||
ssValue.reserve(10000);
|
ssValue.reserve(10000);
|
||||||
ssValue << value;
|
ssValue << value;
|
||||||
Dbt datValue(&ssValue[0], ssValue.size());
|
Dbt datValue(&ssValue[0], ssValue.size());
|
||||||
|
@ -120,7 +118,7 @@ protected:
|
||||||
assert(!"Erase called on database in read-only mode");
|
assert(!"Erase called on database in read-only mode");
|
||||||
|
|
||||||
// Key
|
// Key
|
||||||
CDataStream ssKey(SER_DISK);
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
ssKey.reserve(1000);
|
ssKey.reserve(1000);
|
||||||
ssKey << key;
|
ssKey << key;
|
||||||
Dbt datKey(&ssKey[0], ssKey.size());
|
Dbt datKey(&ssKey[0], ssKey.size());
|
||||||
|
@ -140,7 +138,7 @@ protected:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Key
|
// Key
|
||||||
CDataStream ssKey(SER_DISK);
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
ssKey.reserve(1000);
|
ssKey.reserve(1000);
|
||||||
ssKey << key;
|
ssKey << key;
|
||||||
Dbt datKey(&ssKey[0], ssKey.size());
|
Dbt datKey(&ssKey[0], ssKey.size());
|
||||||
|
@ -313,198 +311,4 @@ public:
|
||||||
bool LoadAddresses();
|
bool LoadAddresses();
|
||||||
|
|
||||||
|
|
||||||
/** A key pool entry */
|
#endif // BITCOIN_DB_H
|
||||||
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
|
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
||||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4786)
|
|
||||||
#pragma warning(disable:4804)
|
|
||||||
#pragma warning(disable:4805)
|
|
||||||
#pragma warning(disable:4717)
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32_WINNT
|
|
||||||
#undef _WIN32_WINNT
|
|
||||||
#endif
|
|
||||||
#define _WIN32_WINNT 0x0501
|
|
||||||
#ifdef _WIN32_IE
|
|
||||||
#undef _WIN32_IE
|
|
||||||
#endif
|
|
||||||
#define _WIN32_IE 0x0400
|
|
||||||
#define WIN32_LEAN_AND_MEAN 1
|
|
||||||
#ifndef NOMINMAX
|
|
||||||
#define NOMINMAX
|
|
||||||
#endif
|
|
||||||
// Include boost/foreach here as it defines __STDC_LIMIT_MACROS on some systems.
|
|
||||||
#include <boost/foreach.hpp>
|
|
||||||
|
|
||||||
#if (defined(__unix__) || defined(unix)) && !defined(USG)
|
|
||||||
#include <sys/param.h> // to get BSD define
|
|
||||||
#endif
|
|
||||||
#ifdef MAC_OSX
|
|
||||||
#ifndef BSD
|
|
||||||
#define BSD 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#include <openssl/buffer.h>
|
|
||||||
#include <openssl/ecdsa.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/rand.h>
|
|
||||||
#include <openssl/sha.h>
|
|
||||||
#include <openssl/ripemd.h>
|
|
||||||
#include <db_cxx.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <float.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
#include <deque>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <mswsock.h>
|
|
||||||
#include <shlobj.h>
|
|
||||||
#include <shlwapi.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <process.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#else
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <ifaddrs.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#endif
|
|
||||||
#ifdef BSD
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "serialize.h"
|
|
||||||
#include "uint256.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "bignum.h"
|
|
||||||
#include "base58.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include "wallet.h"
|
|
||||||
#include "ui_interface.h"
|
|
151
src/init.cpp
151
src/init.cpp
|
@ -2,19 +2,20 @@
|
||||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
#include "headers.h"
|
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
#include "walletdb.h"
|
||||||
#include "bitcoinrpc.h"
|
#include "bitcoinrpc.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "strlcpy.h"
|
#include "util.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#include <boost/filesystem/convenience.hpp>
|
#include <boost/filesystem/convenience.hpp>
|
||||||
#include <boost/interprocess/sync/file_lock.hpp>
|
#include <boost/interprocess/sync/file_lock.hpp>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifndef WIN32
|
||||||
#define strncasecmp strnicmp
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -583,145 +584,3 @@ bool AppInit2(int argc, char* argv[])
|
||||||
return true;
|
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
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#ifndef BITCOIN_INIT_H
|
#ifndef BITCOIN_INIT_H
|
||||||
#define BITCOIN_INIT_H
|
#define BITCOIN_INIT_H
|
||||||
|
|
||||||
|
#include "wallet.h"
|
||||||
|
|
||||||
extern CWallet* pwalletMain;
|
extern CWallet* pwalletMain;
|
||||||
|
|
||||||
void Shutdown(void* parg);
|
void Shutdown(void* parg);
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "headers.h"
|
|
||||||
#include "irc.h"
|
#include "irc.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "strlcpy.h"
|
#include "strlcpy.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <openssl/ecdsa.h>
|
#include <openssl/ecdsa.h>
|
||||||
#include <openssl/obj_mac.h>
|
#include <openssl/obj_mac.h>
|
||||||
|
|
||||||
#include "serialize.h"
|
// #include "serialize.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
|
|
||||||
// secp160k1
|
// secp160k1
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "headers.h"
|
#include "keystore.h"
|
||||||
#include "crypter.h"
|
|
||||||
#include "db.h"
|
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
|
||||||
bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
|
bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
|
||||||
|
|
|
@ -6,7 +6,10 @@
|
||||||
#define BITCOIN_KEYSTORE_H
|
#define BITCOIN_KEYSTORE_H
|
||||||
|
|
||||||
#include "crypter.h"
|
#include "crypter.h"
|
||||||
#include "script.h"
|
#include "util.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
|
class CScript;
|
||||||
|
|
||||||
/** A virtual base class for key stores */
|
/** A virtual base class for key stores */
|
||||||
class CKeyStore
|
class CKeyStore
|
||||||
|
|
20
src/main.cpp
20
src/main.cpp
|
@ -2,11 +2,11 @@
|
||||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
#include "headers.h"
|
|
||||||
#include "checkpoints.h"
|
#include "checkpoints.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
@ -411,7 +411,7 @@ bool CTransaction::CheckTransaction() const
|
||||||
if (vout.empty())
|
if (vout.empty())
|
||||||
return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
|
return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
|
||||||
// Size limits
|
// 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"));
|
return DoS(100, error("CTransaction::CheckTransaction() : size limits failed"));
|
||||||
|
|
||||||
// Check for negative or overflow output values
|
// Check for negative or overflow output values
|
||||||
|
@ -533,7 +533,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
||||||
// reasonable number of ECDSA signature verifications.
|
// reasonable number of ECDSA signature verifications.
|
||||||
|
|
||||||
int64 nFees = GetValueIn(mapInputs)-GetValueOut();
|
int64 nFees = GetValueIn(mapInputs)-GetValueOut();
|
||||||
unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK);
|
unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
|
||||||
// Don't accept it if it can't get into a block
|
// Don't accept it if it can't get into a block
|
||||||
if (nFees < GetMinFee(1000, true, GMF_RELAY))
|
if (nFees < GetMinFee(1000, true, GMF_RELAY))
|
||||||
|
@ -1279,7 +1279,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
|
||||||
bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime);
|
bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime);
|
||||||
|
|
||||||
//// issue here: it doesn't know the version
|
//// 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;
|
map<uint256, CTxIndex> mapQueuedChanges;
|
||||||
int64 nFees = 0;
|
int64 nFees = 0;
|
||||||
|
@ -1291,7 +1291,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
|
||||||
return DoS(100, error("ConnectBlock() : too many sigops"));
|
return DoS(100, error("ConnectBlock() : too many sigops"));
|
||||||
|
|
||||||
CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
|
CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
|
||||||
nTxPos += ::GetSerializeSize(tx, SER_DISK);
|
nTxPos += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
||||||
|
|
||||||
MapPrevTx mapInputs;
|
MapPrevTx mapInputs;
|
||||||
if (!tx.IsCoinBase())
|
if (!tx.IsCoinBase())
|
||||||
|
@ -1621,7 +1621,7 @@ bool CBlock::CheckBlock() const
|
||||||
// that can be verified before saving an orphan block.
|
// that can be verified before saving an orphan block.
|
||||||
|
|
||||||
// Size limits
|
// 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"));
|
return DoS(100, error("CheckBlock() : size limits failed"));
|
||||||
|
|
||||||
// Check proof of work matches claimed amount
|
// Check proof of work matches claimed amount
|
||||||
|
@ -1691,7 +1691,7 @@ bool CBlock::AcceptBlock()
|
||||||
return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight));
|
return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight));
|
||||||
|
|
||||||
// Write block to history file
|
// 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");
|
return error("AcceptBlock() : out of disk space");
|
||||||
unsigned int nFile = -1;
|
unsigned int nFile = -1;
|
||||||
unsigned int nBlockPos = 0;
|
unsigned int nBlockPos = 0;
|
||||||
|
@ -2481,7 +2481,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
|
pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
|
||||||
CBlock block;
|
CBlock block;
|
||||||
block.ReadFromDisk(pindex, true);
|
block.ReadFromDisk(pindex, true);
|
||||||
nBytes += block.GetSerializeSize(SER_NETWORK);
|
nBytes += block.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
if (--nLimit <= 0 || nBytes >= SendBufferSize()/2)
|
if (--nLimit <= 0 || nBytes >= SendBufferSize()/2)
|
||||||
{
|
{
|
||||||
// When this block is requested, we'll send an inv that'll make them
|
// When this block is requested, we'll send an inv that'll make them
|
||||||
|
@ -3174,7 +3174,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority is sum(valuein * age) / txsize
|
// Priority is sum(valuein * age) / txsize
|
||||||
dPriority /= ::GetSerializeSize(tx, SER_NETWORK);
|
dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
|
||||||
if (porphan)
|
if (porphan)
|
||||||
porphan->dPriority = dPriority;
|
porphan->dPriority = dPriority;
|
||||||
|
@ -3203,7 +3203,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
|
||||||
mapPriority.erase(mapPriority.begin());
|
mapPriority.erase(mapPriority.begin());
|
||||||
|
|
||||||
// Size limits
|
// 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)
|
if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
21
src/main.h
21
src/main.h
|
@ -7,10 +7,7 @@
|
||||||
|
|
||||||
#include "bignum.h"
|
#include "bignum.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "key.h"
|
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
#include "db.h"
|
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <io.h> /* for _commit */
|
#include <io.h> /* for _commit */
|
||||||
|
@ -18,13 +15,11 @@
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
class CWallet;
|
||||||
class CBlock;
|
class CBlock;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
class CWalletTx;
|
|
||||||
class CWallet;
|
|
||||||
class CKeyItem;
|
class CKeyItem;
|
||||||
class CReserveKey;
|
class CReserveKey;
|
||||||
class CWalletDB;
|
|
||||||
|
|
||||||
class CAddress;
|
class CAddress;
|
||||||
class CInv;
|
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 unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
|
||||||
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
||||||
static const int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
|
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_TX_FEE = 50000;
|
||||||
static const int64 MIN_RELAY_TX_FEE = 10000;
|
static const int64 MIN_RELAY_TX_FEE = 10000;
|
||||||
static const int64 MAX_MONEY = 21000000 * COIN;
|
static const int64 MAX_MONEY = 21000000 * COIN;
|
||||||
|
@ -550,7 +543,7 @@ public:
|
||||||
// Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
|
// Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
|
||||||
int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_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;
|
unsigned int nNewBlockSize = nBlockSize + nBytes;
|
||||||
int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
|
int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
|
||||||
|
|
||||||
|
@ -595,7 +588,7 @@ public:
|
||||||
|
|
||||||
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
|
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)
|
if (!filein)
|
||||||
return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
|
return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
|
||||||
|
|
||||||
|
@ -946,7 +939,7 @@ public:
|
||||||
bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
|
bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
|
||||||
{
|
{
|
||||||
// Open history file to append
|
// Open history file to append
|
||||||
CAutoFile fileout = AppendBlockFile(nFileRet);
|
CAutoFile fileout = CAutoFile(AppendBlockFile(nFileRet), SER_DISK, CLIENT_VERSION);
|
||||||
if (!fileout)
|
if (!fileout)
|
||||||
return error("CBlock::WriteToDisk() : AppendBlockFile failed");
|
return error("CBlock::WriteToDisk() : AppendBlockFile failed");
|
||||||
|
|
||||||
|
@ -979,7 +972,7 @@ public:
|
||||||
SetNull();
|
SetNull();
|
||||||
|
|
||||||
// Open history file to read
|
// Open history file to read
|
||||||
CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
|
CAutoFile filein = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb"), SER_DISK, CLIENT_VERSION);
|
||||||
if (!filein)
|
if (!filein)
|
||||||
return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
|
return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
|
||||||
if (!fReadTransactions)
|
if (!fReadTransactions)
|
||||||
|
@ -1140,7 +1133,7 @@ public:
|
||||||
bool EraseBlockFromDisk()
|
bool EraseBlockFromDisk()
|
||||||
{
|
{
|
||||||
// Open history file
|
// Open history file
|
||||||
CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
|
CAutoFile fileout = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb+"), SER_DISK, CLIENT_VERSION);
|
||||||
if (!fileout)
|
if (!fileout)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1600,7 +1593,7 @@ public:
|
||||||
return error("CAlert::CheckSignature() : verify signature failed");
|
return error("CAlert::CheckSignature() : verify signature failed");
|
||||||
|
|
||||||
// Now unserialize the data
|
// Now unserialize the data
|
||||||
CDataStream sMsg(vchMsg);
|
CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
sMsg >> *(CUnsignedAlert*)this;
|
sMsg >> *(CUnsignedAlert*)this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ OBJS= \
|
||||||
obj/script.o \
|
obj/script.o \
|
||||||
obj/util.o \
|
obj/util.o \
|
||||||
obj/wallet.o \
|
obj/wallet.o \
|
||||||
|
obj/walletdb.o \
|
||||||
obj/noui.o
|
obj/noui.o
|
||||||
|
|
||||||
all: bitcoind.exe
|
all: bitcoind.exe
|
||||||
|
|
|
@ -59,6 +59,7 @@ OBJS= \
|
||||||
obj/script.o \
|
obj/script.o \
|
||||||
obj/util.o \
|
obj/util.o \
|
||||||
obj/wallet.o \
|
obj/wallet.o \
|
||||||
|
obj/walletdb.o \
|
||||||
obj/noui.o
|
obj/noui.o
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ OBJS= \
|
||||||
obj/script.o \
|
obj/script.o \
|
||||||
obj/util.o \
|
obj/util.o \
|
||||||
obj/wallet.o \
|
obj/wallet.o \
|
||||||
|
obj/walletdb.o \
|
||||||
obj/noui.o
|
obj/noui.o
|
||||||
|
|
||||||
ifdef USE_UPNP
|
ifdef USE_UPNP
|
||||||
|
|
|
@ -103,6 +103,7 @@ OBJS= \
|
||||||
obj/script.o \
|
obj/script.o \
|
||||||
obj/util.o \
|
obj/util.o \
|
||||||
obj/wallet.o \
|
obj/wallet.o \
|
||||||
|
obj/walletdb.o \
|
||||||
obj/noui.o
|
obj/noui.o
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "headers.h"
|
|
||||||
#include "irc.h"
|
#include "irc.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "strlcpy.h"
|
#include "strlcpy.h"
|
||||||
#include "addrman.h"
|
#include "addrman.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
10
src/net.h
10
src/net.h
|
@ -157,14 +157,10 @@ public:
|
||||||
CCriticalSection cs_inventory;
|
CCriticalSection cs_inventory;
|
||||||
std::multimap<int64, CInv> mapAskFor;
|
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;
|
nServices = 0;
|
||||||
hSocket = hSocketIn;
|
hSocket = hSocketIn;
|
||||||
vSend.SetType(SER_NETWORK);
|
|
||||||
vRecv.SetType(SER_NETWORK);
|
|
||||||
vSend.SetVersion(MIN_PROTO_VERSION);
|
|
||||||
vRecv.SetVersion(MIN_PROTO_VERSION);
|
|
||||||
nLastSend = 0;
|
nLastSend = 0;
|
||||||
nLastRecv = 0;
|
nLastRecv = 0;
|
||||||
nLastSendEmpty = GetTime();
|
nLastSendEmpty = GetTime();
|
||||||
|
@ -612,7 +608,7 @@ inline void RelayInventory(const CInv& inv)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void RelayMessage(const CInv& inv, const T& a)
|
void RelayMessage(const CInv& inv, const T& a)
|
||||||
{
|
{
|
||||||
CDataStream ss(SER_NETWORK);
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ss.reserve(10000);
|
ss.reserve(10000);
|
||||||
ss << a;
|
ss << a;
|
||||||
RelayMessage(inv, ss);
|
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
|
// 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));
|
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,27 +7,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#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 "serialize.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "headers.h"
|
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
|
||||||
int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
|
int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
#include "netbase.h"
|
#include "netbase.h"
|
||||||
#include "util.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
#include "walletmodel.h"
|
#include "walletmodel.h"
|
||||||
|
|
||||||
#include "headers.h"
|
#include "wallet.h"
|
||||||
|
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include "optionsmodel.h"
|
#include "optionsmodel.h"
|
||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
|
|
||||||
#include "headers.h"
|
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
#include "qtipcserver.h"
|
#include "qtipcserver.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
#include "transactiontablemodel.h"
|
#include "transactiontablemodel.h"
|
||||||
|
|
||||||
#include "headers.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
#include "walletmodel.h"
|
#include "walletmodel.h"
|
||||||
#include "bitcoinunits.h"
|
#include "bitcoinunits.h"
|
||||||
|
|
||||||
#include "headers.h"
|
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDoubleValidator>
|
#include <QDoubleValidator>
|
||||||
|
|
|
@ -91,7 +91,7 @@ void MessagePage::on_signMessage_clicked()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDataStream ss(SER_GETHASH);
|
CDataStream ss(SER_GETHASH, 0);
|
||||||
ss << strMessageMagic;
|
ss << strMessageMagic;
|
||||||
ss << ui->message->document()->toPlainText().toStdString();
|
ss << ui->message->document()->toPlainText().toStdString();
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#include "bitcoinunits.h"
|
#include "bitcoinunits.h"
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
#include "headers.h"
|
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include "walletdb.h"
|
||||||
|
|
||||||
OptionsModel::OptionsModel(QObject *parent) :
|
OptionsModel::OptionsModel(QObject *parent) :
|
||||||
QAbstractListModel(parent)
|
QAbstractListModel(parent)
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
#include <boost/tokenizer.hpp>
|
#include <boost/tokenizer.hpp>
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
#include "headers.h"
|
#include "ui_interface.h"
|
||||||
|
#include "util.h"
|
||||||
#include "qtipcserver.h"
|
#include "qtipcserver.h"
|
||||||
|
|
||||||
using namespace boost::interprocess;
|
using namespace boost::interprocess;
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
#include "bitcoinunits.h"
|
#include "bitcoinunits.h"
|
||||||
|
|
||||||
#include "headers.h"
|
#include "main.h"
|
||||||
|
#include "wallet.h"
|
||||||
|
#include "db.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "transactionrecord.h"
|
#include "transactionrecord.h"
|
||||||
|
|
||||||
#include "headers.h"
|
#include "wallet.h"
|
||||||
|
|
||||||
/* Return positive answer if transaction should be shown in list.
|
/* Return positive answer if transaction should be shown in list.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
#include "bitcoinunits.h"
|
#include "bitcoinunits.h"
|
||||||
|
|
||||||
#include "headers.h"
|
#include "wallet.h"
|
||||||
|
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
#include "transactiontablemodel.h"
|
#include "transactiontablemodel.h"
|
||||||
|
|
||||||
#include "headers.h"
|
#include "ui_interface.h"
|
||||||
#include "db.h" // for BackupWallet
|
#include "wallet.h"
|
||||||
|
#include "walletdb.h" // for BackupWallet
|
||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "headers.h"
|
|
||||||
#include "init.h" // for pwalletMain
|
#include "init.h" // for pwalletMain
|
||||||
#include "bitcoinrpc.h"
|
#include "bitcoinrpc.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,17 @@
|
||||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
#include "headers.h"
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
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);
|
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
|
// Serialize and hash
|
||||||
CDataStream ss(SER_GETHASH);
|
CDataStream ss(SER_GETHASH, 0);
|
||||||
ss.reserve(10000);
|
ss.reserve(10000);
|
||||||
ss << txTmp << nHashType;
|
ss << txTmp << nHashType;
|
||||||
return Hash(ss.begin(), ss.end());
|
return Hash(ss.begin(), ss.end());
|
||||||
|
|
|
@ -57,7 +57,7 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IMPLEMENT_SERIALIZE(statements) \
|
#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; \
|
CSerActionGetSerializeSize ser_action; \
|
||||||
const bool fGetSize = true; \
|
const bool fGetSize = true; \
|
||||||
|
@ -72,7 +72,7 @@ enum
|
||||||
return nSerSize; \
|
return nSerSize; \
|
||||||
} \
|
} \
|
||||||
template<typename Stream> \
|
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; \
|
CSerActionSerialize ser_action; \
|
||||||
const bool fGetSize = false; \
|
const bool fGetSize = false; \
|
||||||
|
@ -83,7 +83,7 @@ enum
|
||||||
{statements} \
|
{statements} \
|
||||||
} \
|
} \
|
||||||
template<typename Stream> \
|
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; \
|
CSerActionUnserialize ser_action; \
|
||||||
const bool fGetSize = false; \
|
const bool fGetSize = false; \
|
||||||
|
@ -287,43 +287,43 @@ template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_st
|
||||||
// vector
|
// 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::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> 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::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> 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::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> 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
|
// others derived from vector
|
||||||
extern inline unsigned int GetSerializeSize(const 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=PROTOCOL_VERSION);
|
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=PROTOCOL_VERSION);
|
template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
|
||||||
|
|
||||||
// pair
|
// pair
|
||||||
template<typename K, typename T> unsigned int GetSerializeSize(const 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=PROTOCOL_VERSION);
|
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=PROTOCOL_VERSION);
|
template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion);
|
||||||
|
|
||||||
// 3 tuple
|
// 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 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=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);
|
||||||
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 Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
|
||||||
|
|
||||||
// 4 tuple
|
// 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 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=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);
|
||||||
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 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
|
// 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 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=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);
|
||||||
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 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
|
// 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 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=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);
|
||||||
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 Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -336,19 +336,19 @@ template<typename Stream, typename K, typename Pred, typename A> void Unserializ
|
||||||
// Thanks to Boost serialization for this idea.
|
// Thanks to Boost serialization for this idea.
|
||||||
//
|
//
|
||||||
template<typename T>
|
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);
|
return a.GetSerializeSize((int)nType, nVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
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);
|
a.Serialize(os, (int)nType, nVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
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);
|
a.Unserialize(is, (int)nType, nVersion);
|
||||||
}
|
}
|
||||||
|
@ -730,39 +730,39 @@ public:
|
||||||
typedef vector_type::const_iterator const_iterator;
|
typedef vector_type::const_iterator const_iterator;
|
||||||
typedef vector_type::reverse_iterator reverse_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);
|
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);
|
Init(nTypeIn, nVersionIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || _MSC_VER >= 1300
|
#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);
|
Init(nTypeIn, nVersionIn);
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
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);
|
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);
|
Init(nTypeIn, nVersionIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION)
|
void Init(int nTypeIn, int nVersionIn)
|
||||||
{
|
{
|
||||||
nReadPos = 0;
|
nReadPos = 0;
|
||||||
nType = nTypeIn;
|
nType = nTypeIn;
|
||||||
|
@ -976,7 +976,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream>
|
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
|
// Special case: stream << stream concatenates like stream += stream
|
||||||
if (!vch.empty())
|
if (!vch.empty())
|
||||||
|
@ -1085,7 +1085,7 @@ public:
|
||||||
|
|
||||||
typedef FILE element_type;
|
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;
|
file = filenew;
|
||||||
nType = nTypeIn;
|
nType = nTypeIn;
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
*/
|
*/
|
||||||
#ifndef BITCOIN_STRLCPY_H
|
#ifndef BITCOIN_STRLCPY_H
|
||||||
#define 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
|
* Copy src to string dst of size siz. At most siz-1 characters
|
||||||
* will be copied. Always NUL terminates (unless siz == 0).
|
* will be copied. Always NUL terminates (unless siz == 0).
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
#ifndef BITCOIN_UINT256_H
|
#ifndef BITCOIN_UINT256_H
|
||||||
#define BITCOIN_UINT256_H
|
#define BITCOIN_UINT256_H
|
||||||
|
|
||||||
#include "serialize.h"
|
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -354,19 +353,22 @@ public:
|
||||||
return pn[2*n] | (uint64)pn[2*n+1] << 32;
|
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);
|
return sizeof(pn);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream>
|
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));
|
s.write((char*)pn, sizeof(pn));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream>
|
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));
|
s.read((char*)pn, sizeof(pn));
|
||||||
}
|
}
|
||||||
|
|
172
src/util.cpp
172
src/util.cpp
|
@ -3,8 +3,10 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "headers.h"
|
#include "util.h"
|
||||||
#include "strlcpy.h"
|
#include "strlcpy.h"
|
||||||
|
#include "version.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
#include <boost/algorithm/string/join.hpp>
|
#include <boost/algorithm/string/join.hpp>
|
||||||
|
|
||||||
// Work around clang compilation problem in Boost 1.46:
|
// 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_mutex.hpp>
|
||||||
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
|
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
|
||||||
#include <boost/foreach.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 std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
@ -1064,6 +1091,149 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const
|
||||||
return ss.str();
|
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
|
#ifdef DEBUG_LOCKORDER
|
||||||
|
|
10
src/util.h
10
src/util.h
|
@ -31,11 +31,14 @@ typedef int pid_t; /* define for windows compatiblity */
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <openssl/ripemd.h>
|
#include <openssl/ripemd.h>
|
||||||
|
|
||||||
#include "netbase.h"
|
#include "netbase.h" // for AddTimeData
|
||||||
|
|
||||||
typedef long long int64;
|
typedef long long int64;
|
||||||
typedef unsigned long long uint64;
|
typedef unsigned long long uint64;
|
||||||
|
|
||||||
|
static const int64 COIN = 100000000;
|
||||||
|
static const int64 CENT = 1000000;
|
||||||
|
|
||||||
#define loop for (;;)
|
#define loop for (;;)
|
||||||
#define BEGIN(a) ((char*)&(a))
|
#define BEGIN(a) ((char*)&(a))
|
||||||
#define END(a) ((char*)&((&(a))[1]))
|
#define END(a) ((char*)&((&(a))[1]))
|
||||||
|
@ -160,9 +163,8 @@ boost::filesystem::path GetConfigFile();
|
||||||
boost::filesystem::path GetPidFile();
|
boost::filesystem::path GetPidFile();
|
||||||
void CreatePidFile(const boost::filesystem::path &path, pid_t pid);
|
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);
|
bool ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
|
||||||
#ifdef WIN32
|
bool GetStartOnSystemStartup();
|
||||||
boost::filesystem::path MyGetSpecialFolderPath(int nFolder, bool fCreate);
|
bool SetStartOnSystemStartup(bool fAutoStart);
|
||||||
#endif
|
|
||||||
void ShrinkDebugFile();
|
void ShrinkDebugFile();
|
||||||
int GetRandInt(int nMax);
|
int GetRandInt(int nMax);
|
||||||
uint64 GetRand(uint64 nMax);
|
uint64 GetRand(uint64 nMax);
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "headers.h"
|
#include "wallet.h"
|
||||||
#include "db.h"
|
#include "walletdb.h"
|
||||||
#include "crypter.h"
|
#include "crypter.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -137,6 +138,11 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
|
||||||
return false;
|
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
|
// This class implements an addrIncoming entry that causes pre-0.4
|
||||||
// clients to crash on startup if reading a private-key-encrypted wallet.
|
// clients to crash on startup if reading a private-key-encrypted wallet.
|
||||||
|
@ -1116,7 +1122,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Limit size
|
// 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)
|
if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
|
||||||
return false;
|
return false;
|
||||||
dPriority /= nBytes;
|
dPriority /= nBytes;
|
||||||
|
|
36
src/wallet.h
36
src/wallet.h
|
@ -5,7 +5,7 @@
|
||||||
#ifndef BITCOIN_WALLET_H
|
#ifndef BITCOIN_WALLET_H
|
||||||
#define BITCOIN_WALLET_H
|
#define BITCOIN_WALLET_H
|
||||||
|
|
||||||
#include "bignum.h"
|
#include "main.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "keystore.h"
|
#include "keystore.h"
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
@ -25,6 +25,34 @@ enum WalletFeature
|
||||||
FEATURE_LATEST = 60000
|
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,
|
/** 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.
|
* and provides the ability to create new transactions.
|
||||||
*/
|
*/
|
||||||
|
@ -196,11 +224,7 @@ public:
|
||||||
}
|
}
|
||||||
return nChange;
|
return nChange;
|
||||||
}
|
}
|
||||||
void SetBestChain(const CBlockLocator& loc)
|
void SetBestChain(const CBlockLocator& loc);
|
||||||
{
|
|
||||||
CWalletDB walletdb(strWalletFile);
|
|
||||||
walletdb.WriteBestBlock(loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
int LoadWallet(bool& fFirstRunRet);
|
int LoadWallet(bool& fFirstRunRet);
|
||||||
// bool BackupWallet(const std::string& strDest);
|
// bool BackupWallet(const std::string& strDest);
|
||||||
|
|
428
src/walletdb.cpp
Normal file
428
src/walletdb.cpp
Normal file
|
@ -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;
|
||||||
|
}
|
179
src/walletdb.h
Normal file
179
src/walletdb.h
Normal file
|
@ -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
|
Loading…
Reference in a new issue