mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-02-06 12:14:14 +00:00
update core to d0d80170a2ca73004e08fb85007fe055cbf4e411 (CWallet class)
This commit is contained in:
parent
d99f5a470c
commit
e8ef3da713
@ -70,7 +70,9 @@ HEADERS += src/qt/bitcoingui.h \
|
|||||||
src/qtui.h \
|
src/qtui.h \
|
||||||
src/qt/transactiondesc.h \
|
src/qt/transactiondesc.h \
|
||||||
src/qt/transactiondescdialog.h \
|
src/qt/transactiondescdialog.h \
|
||||||
src/qt/bitcoinamountfield.h
|
src/qt/bitcoinamountfield.h \
|
||||||
|
src/wallet.h \
|
||||||
|
src/keystore.h
|
||||||
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
||||||
src/qt/transactiontablemodel.cpp \
|
src/qt/transactiontablemodel.cpp \
|
||||||
src/qt/addresstablemodel.cpp \
|
src/qt/addresstablemodel.cpp \
|
||||||
@ -101,7 +103,9 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
|||||||
src/qt/transactiondesc.cpp \
|
src/qt/transactiondesc.cpp \
|
||||||
src/qt/transactiondescdialog.cpp \
|
src/qt/transactiondescdialog.cpp \
|
||||||
src/qt/bitcoinstrings.cpp \
|
src/qt/bitcoinstrings.cpp \
|
||||||
src/qt/bitcoinamountfield.cpp
|
src/qt/bitcoinamountfield.cpp \
|
||||||
|
src/wallet.cpp \
|
||||||
|
src/keystore.cpp
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
src/qt/bitcoin.qrc
|
src/qt/bitcoin.qrc
|
||||||
|
168
src/db.cpp
168
src/db.cpp
@ -5,14 +5,12 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include <boost/filesystem/operations.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
void ThreadFlushWalletDB(void* parg);
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int nWalletDBUpdated;
|
unsigned int nWalletDBUpdated;
|
||||||
uint64 nAccountingEntryNumber = 0;
|
uint64 nAccountingEntryNumber = 0;
|
||||||
@ -151,7 +149,7 @@ void CDB::Close()
|
|||||||
--mapFileUseCount[strFile];
|
--mapFileUseCount[strFile];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseDb(const string& strFile)
|
void static CloseDb(const string& strFile)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_db)
|
CRITICAL_BLOCK(cs_db)
|
||||||
{
|
{
|
||||||
@ -360,7 +358,7 @@ bool CTxDB::WriteBestInvalidWork(CBigNum bnBestInvalidWork)
|
|||||||
return Write(string("bnBestInvalidWork"), bnBestInvalidWork);
|
return Write(string("bnBestInvalidWork"), bnBestInvalidWork);
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockIndex* InsertBlockIndex(uint256 hash)
|
CBlockIndex static * InsertBlockIndex(uint256 hash)
|
||||||
{
|
{
|
||||||
if (hash == 0)
|
if (hash == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -585,8 +583,19 @@ bool LoadAddresses()
|
|||||||
// CWalletDB
|
// CWalletDB
|
||||||
//
|
//
|
||||||
|
|
||||||
static set<int64> setKeyPool;
|
bool CWalletDB::WriteName(const string& strAddress, const string& strName)
|
||||||
static CCriticalSection cs_setKeyPool;
|
{
|
||||||
|
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)
|
bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account)
|
||||||
{
|
{
|
||||||
@ -661,9 +670,9 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CWalletDB::LoadWallet()
|
bool CWalletDB::LoadWallet(CWallet* pwallet)
|
||||||
{
|
{
|
||||||
vchDefaultKey.clear();
|
pwallet->vchDefaultKey.clear();
|
||||||
int nFileVersion = 0;
|
int nFileVersion = 0;
|
||||||
vector<uint256> vWalletUpgrade;
|
vector<uint256> vWalletUpgrade;
|
||||||
|
|
||||||
@ -675,8 +684,8 @@ bool CWalletDB::LoadWallet()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//// todo: shouldn't we catch exceptions and try to recover and continue?
|
//// todo: shouldn't we catch exceptions and try to recover and continue?
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwallet->cs_mapWallet)
|
||||||
CRITICAL_BLOCK(cs_mapKeys)
|
CRITICAL_BLOCK(pwallet->cs_mapKeys)
|
||||||
{
|
{
|
||||||
// Get cursor
|
// Get cursor
|
||||||
Dbc* pcursor = GetCursor();
|
Dbc* pcursor = GetCursor();
|
||||||
@ -703,14 +712,15 @@ bool CWalletDB::LoadWallet()
|
|||||||
{
|
{
|
||||||
string strAddress;
|
string strAddress;
|
||||||
ssKey >> strAddress;
|
ssKey >> strAddress;
|
||||||
ssValue >> mapAddressBook[strAddress];
|
ssValue >> pwallet->mapAddressBook[strAddress];
|
||||||
}
|
}
|
||||||
else if (strType == "tx")
|
else if (strType == "tx")
|
||||||
{
|
{
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
ssKey >> hash;
|
ssKey >> hash;
|
||||||
CWalletTx& wtx = mapWallet[hash];
|
CWalletTx& wtx = pwallet->mapWallet[hash];
|
||||||
ssValue >> wtx;
|
ssValue >> wtx;
|
||||||
|
wtx.pwallet = pwallet;
|
||||||
|
|
||||||
if (wtx.GetHash() != hash)
|
if (wtx.GetHash() != hash)
|
||||||
printf("Error in wallet.dat, hash mismatch\n");
|
printf("Error in wallet.dat, hash mismatch\n");
|
||||||
@ -761,18 +771,18 @@ bool CWalletDB::LoadWallet()
|
|||||||
else
|
else
|
||||||
ssValue >> wkey;
|
ssValue >> wkey;
|
||||||
|
|
||||||
mapKeys[vchPubKey] = wkey.vchPrivKey;
|
pwallet->mapKeys[vchPubKey] = wkey.vchPrivKey;
|
||||||
mapPubKeys[Hash160(vchPubKey)] = vchPubKey;
|
mapPubKeys[Hash160(vchPubKey)] = vchPubKey;
|
||||||
}
|
}
|
||||||
else if (strType == "defaultkey")
|
else if (strType == "defaultkey")
|
||||||
{
|
{
|
||||||
ssValue >> vchDefaultKey;
|
ssValue >> pwallet->vchDefaultKey;
|
||||||
}
|
}
|
||||||
else if (strType == "pool")
|
else if (strType == "pool")
|
||||||
{
|
{
|
||||||
int64 nIndex;
|
int64 nIndex;
|
||||||
ssKey >> nIndex;
|
ssKey >> nIndex;
|
||||||
setKeyPool.insert(nIndex);
|
pwallet->setKeyPool.insert(nIndex);
|
||||||
}
|
}
|
||||||
else if (strType == "version")
|
else if (strType == "version")
|
||||||
{
|
{
|
||||||
@ -804,7 +814,7 @@ bool CWalletDB::LoadWallet()
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(uint256 hash, vWalletUpgrade)
|
BOOST_FOREACH(uint256 hash, vWalletUpgrade)
|
||||||
WriteTx(hash, mapWallet[hash]);
|
WriteTx(hash, pwallet->mapWallet[hash]);
|
||||||
|
|
||||||
printf("nFileVersion = %d\n", nFileVersion);
|
printf("nFileVersion = %d\n", nFileVersion);
|
||||||
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
|
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
|
||||||
@ -832,36 +842,9 @@ bool CWalletDB::LoadWallet()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadWallet(bool& fFirstRunRet)
|
|
||||||
{
|
|
||||||
fFirstRunRet = false;
|
|
||||||
if (!CWalletDB("cr+").LoadWallet())
|
|
||||||
return false;
|
|
||||||
fFirstRunRet = vchDefaultKey.empty();
|
|
||||||
|
|
||||||
if (mapKeys.count(vchDefaultKey))
|
|
||||||
{
|
|
||||||
// Set keyUser
|
|
||||||
keyUser.SetPubKey(vchDefaultKey);
|
|
||||||
keyUser.SetPrivKey(mapKeys[vchDefaultKey]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Create new keyUser and set as default key
|
|
||||||
RandAddSeedPerfmon();
|
|
||||||
|
|
||||||
CWalletDB walletdb;
|
|
||||||
vchDefaultKey = GetKeyFromKeyPool();
|
|
||||||
walletdb.WriteDefaultKey(vchDefaultKey);
|
|
||||||
walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateThread(ThreadFlushWalletDB, NULL);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadFlushWalletDB(void* parg)
|
void ThreadFlushWalletDB(void* parg)
|
||||||
{
|
{
|
||||||
|
const string& strFile = ((const string*)parg)[0];
|
||||||
static bool fOneThread;
|
static bool fOneThread;
|
||||||
if (fOneThread)
|
if (fOneThread)
|
||||||
return;
|
return;
|
||||||
@ -897,7 +880,6 @@ void ThreadFlushWalletDB(void* parg)
|
|||||||
|
|
||||||
if (nRefCount == 0 && !fShutdown)
|
if (nRefCount == 0 && !fShutdown)
|
||||||
{
|
{
|
||||||
string strFile = "wallet.dat";
|
|
||||||
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
|
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
|
||||||
if (mi != mapFileUseCount.end())
|
if (mi != mapFileUseCount.end())
|
||||||
{
|
{
|
||||||
@ -920,26 +902,27 @@ void ThreadFlushWalletDB(void* parg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackupWallet(const string& strDest)
|
bool BackupWallet(const CWallet& wallet, const string& strDest)
|
||||||
{
|
{
|
||||||
|
if (!wallet.fFileBacked)
|
||||||
|
return false;
|
||||||
while (!fShutdown)
|
while (!fShutdown)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_db)
|
CRITICAL_BLOCK(cs_db)
|
||||||
{
|
{
|
||||||
const string strFile = "wallet.dat";
|
if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0)
|
||||||
if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0)
|
|
||||||
{
|
{
|
||||||
// Flush log data to the dat file
|
// Flush log data to the dat file
|
||||||
CloseDb(strFile);
|
CloseDb(wallet.strWalletFile);
|
||||||
dbenv.txn_checkpoint(0, 0, 0);
|
dbenv.txn_checkpoint(0, 0, 0);
|
||||||
dbenv.lsn_reset(strFile.c_str(), 0);
|
dbenv.lsn_reset(wallet.strWalletFile.c_str(), 0);
|
||||||
mapFileUseCount.erase(strFile);
|
mapFileUseCount.erase(wallet.strWalletFile);
|
||||||
|
|
||||||
// Copy wallet.dat
|
// Copy wallet.dat
|
||||||
filesystem::path pathSrc(GetDataDir() + "/" + strFile);
|
filesystem::path pathSrc(GetDataDir() + "/" + wallet.strWalletFile);
|
||||||
filesystem::path pathDest(strDest);
|
filesystem::path pathDest(strDest);
|
||||||
if (filesystem::is_directory(pathDest))
|
if (filesystem::is_directory(pathDest))
|
||||||
pathDest = pathDest / strFile;
|
pathDest = pathDest / wallet.strWalletFile;
|
||||||
#if BOOST_VERSION >= 104000
|
#if BOOST_VERSION >= 104000
|
||||||
filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
|
filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
|
||||||
#else
|
#else
|
||||||
@ -947,83 +930,10 @@ void BackupWallet(const string& strDest)
|
|||||||
#endif
|
#endif
|
||||||
printf("copied wallet.dat to %s\n", pathDest.string().c_str());
|
printf("copied wallet.dat to %s\n", pathDest.string().c_str());
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
|
|
||||||
|
|
||||||
void CWalletDB::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
|
|
||||||
{
|
|
||||||
nIndex = -1;
|
|
||||||
keypool.vchPubKey.clear();
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
|
||||||
CRITICAL_BLOCK(cs_setKeyPool)
|
|
||||||
{
|
|
||||||
// Top up key pool
|
|
||||||
int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
|
|
||||||
while (setKeyPool.size() < nTargetSize+1)
|
|
||||||
{
|
|
||||||
int64 nEnd = 1;
|
|
||||||
if (!setKeyPool.empty())
|
|
||||||
nEnd = *(--setKeyPool.end()) + 1;
|
|
||||||
if (!Write(make_pair(string("pool"), nEnd), CKeyPool(GenerateNewKey())))
|
|
||||||
throw runtime_error("ReserveKeyFromKeyPool() : writing generated key failed");
|
|
||||||
setKeyPool.insert(nEnd);
|
|
||||||
printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the oldest key
|
|
||||||
assert(!setKeyPool.empty());
|
|
||||||
nIndex = *(setKeyPool.begin());
|
|
||||||
setKeyPool.erase(setKeyPool.begin());
|
|
||||||
if (!Read(make_pair(string("pool"), nIndex), keypool))
|
|
||||||
throw runtime_error("ReserveKeyFromKeyPool() : read failed");
|
|
||||||
if (!mapKeys.count(keypool.vchPubKey))
|
|
||||||
throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
|
|
||||||
assert(!keypool.vchPubKey.empty());
|
|
||||||
printf("keypool reserve %"PRI64d"\n", nIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWalletDB::KeepKey(int64 nIndex)
|
|
||||||
{
|
|
||||||
// Remove from key pool
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
|
||||||
{
|
|
||||||
Erase(make_pair(string("pool"), nIndex));
|
|
||||||
}
|
|
||||||
printf("keypool keep %"PRI64d"\n", nIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWalletDB::ReturnKey(int64 nIndex)
|
|
||||||
{
|
|
||||||
// Return to key pool
|
|
||||||
CRITICAL_BLOCK(cs_setKeyPool)
|
|
||||||
setKeyPool.insert(nIndex);
|
|
||||||
printf("keypool return %"PRI64d"\n", nIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<unsigned char> GetKeyFromKeyPool()
|
|
||||||
{
|
|
||||||
CWalletDB walletdb;
|
|
||||||
int64 nIndex = 0;
|
|
||||||
CKeyPool keypool;
|
|
||||||
walletdb.ReserveKeyFromKeyPool(nIndex, keypool);
|
|
||||||
walletdb.KeepKey(nIndex);
|
|
||||||
return keypool.vchPubKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetOldestKeyPoolTime()
|
|
||||||
{
|
|
||||||
CWalletDB walletdb;
|
|
||||||
int64 nIndex = 0;
|
|
||||||
CKeyPool keypool;
|
|
||||||
walletdb.ReserveKeyFromKeyPool(nIndex, keypool);
|
|
||||||
walletdb.ReturnKey(nIndex);
|
|
||||||
return keypool.nTime;
|
|
||||||
}
|
}
|
||||||
|
118
src/db.h
118
src/db.h
@ -12,33 +12,25 @@
|
|||||||
|
|
||||||
#include <db_cxx.h>
|
#include <db_cxx.h>
|
||||||
|
|
||||||
class CTransaction;
|
|
||||||
class CTxIndex;
|
class CTxIndex;
|
||||||
class CDiskBlockIndex;
|
class CDiskBlockIndex;
|
||||||
class CDiskTxPos;
|
class CDiskTxPos;
|
||||||
class COutPoint;
|
class COutPoint;
|
||||||
class CUser;
|
|
||||||
class CReview;
|
|
||||||
class CAddress;
|
class CAddress;
|
||||||
class CWalletTx;
|
class CWalletTx;
|
||||||
|
class CWallet;
|
||||||
class CAccount;
|
class CAccount;
|
||||||
class CAccountingEntry;
|
class CAccountingEntry;
|
||||||
class CBlockLocator;
|
class CBlockLocator;
|
||||||
|
|
||||||
extern std::map<std::string, std::string> mapAddressBook;
|
|
||||||
extern CCriticalSection cs_mapAddressBook;
|
|
||||||
extern std::vector<unsigned char> vchDefaultKey;
|
|
||||||
extern bool fClient;
|
|
||||||
extern int nBestHeight;
|
|
||||||
|
|
||||||
|
|
||||||
extern unsigned int nWalletDBUpdated;
|
extern unsigned int nWalletDBUpdated;
|
||||||
extern DbEnv dbenv;
|
extern DbEnv dbenv;
|
||||||
|
|
||||||
|
|
||||||
extern void DBFlush(bool fShutdown);
|
extern void DBFlush(bool fShutdown);
|
||||||
extern std::vector<unsigned char> GetKeyFromKeyPool();
|
void ThreadFlushWalletDB(void* parg);
|
||||||
extern int64 GetOldestKeyPoolTime();
|
bool BackupWallet(const CWallet& wallet, const std::string& strDest);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -321,9 +313,6 @@ bool LoadAddresses();
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CKeyPool
|
class CKeyPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -356,7 +345,7 @@ public:
|
|||||||
class CWalletDB : public CDB
|
class CWalletDB : public CDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode)
|
CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
@ -369,23 +358,9 @@ public:
|
|||||||
return Read(std::make_pair(std::string("name"), strAddress), strName);
|
return Read(std::make_pair(std::string("name"), strAddress), strName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteName(const std::string& strAddress, const std::string& strName)
|
bool WriteName(const std::string& strAddress, const std::string& strName);
|
||||||
{
|
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
|
||||||
mapAddressBook[strAddress] = strName;
|
|
||||||
nWalletDBUpdated++;
|
|
||||||
return Write(std::make_pair(std::string("name"), strAddress), strName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EraseName(const std::string& strAddress)
|
bool EraseName(const std::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.
|
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
|
||||||
mapAddressBook.erase(strAddress);
|
|
||||||
nWalletDBUpdated++;
|
|
||||||
return Erase(std::make_pair(std::string("name"), strAddress));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadTx(uint256 hash, CWalletTx& wtx)
|
bool ReadTx(uint256 hash, CWalletTx& wtx)
|
||||||
{
|
{
|
||||||
@ -435,11 +410,27 @@ public:
|
|||||||
|
|
||||||
bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
|
bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
|
||||||
{
|
{
|
||||||
vchDefaultKey = vchPubKey;
|
|
||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
return Write(std::string("defaultkey"), vchPubKey);
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool ReadSetting(const std::string& strKey, T& value)
|
bool ReadSetting(const std::string& strKey, T& value)
|
||||||
{
|
{
|
||||||
@ -459,68 +450,7 @@ public:
|
|||||||
int64 GetAccountCreditDebit(const std::string& strAccount);
|
int64 GetAccountCreditDebit(const std::string& strAccount);
|
||||||
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
|
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
|
||||||
|
|
||||||
bool LoadWallet();
|
bool LoadWallet(CWallet* pwallet);
|
||||||
protected:
|
|
||||||
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
|
|
||||||
void KeepKey(int64 nIndex);
|
|
||||||
static void ReturnKey(int64 nIndex);
|
|
||||||
friend class CReserveKey;
|
|
||||||
friend std::vector<unsigned char> GetKeyFromKeyPool();
|
|
||||||
friend int64 GetOldestKeyPoolTime();
|
|
||||||
};
|
|
||||||
|
|
||||||
bool LoadWallet(bool& fFirstRunRet);
|
|
||||||
void BackupWallet(const std::string& strDest);
|
|
||||||
|
|
||||||
inline bool SetAddressBookName(const std::string& strAddress, const std::string& strName)
|
|
||||||
{
|
|
||||||
return CWalletDB().WriteName(strAddress, strName);
|
|
||||||
}
|
|
||||||
|
|
||||||
class CReserveKey
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
int64 nIndex;
|
|
||||||
std::vector<unsigned char> vchPubKey;
|
|
||||||
public:
|
|
||||||
CReserveKey()
|
|
||||||
{
|
|
||||||
nIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
~CReserveKey()
|
|
||||||
{
|
|
||||||
if (!fShutdown)
|
|
||||||
ReturnKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<unsigned char> GetReservedKey()
|
|
||||||
{
|
|
||||||
if (nIndex == -1)
|
|
||||||
{
|
|
||||||
CKeyPool keypool;
|
|
||||||
CWalletDB().ReserveKeyFromKeyPool(nIndex, keypool);
|
|
||||||
vchPubKey = keypool.vchPubKey;
|
|
||||||
}
|
|
||||||
assert(!vchPubKey.empty());
|
|
||||||
return vchPubKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeepKey()
|
|
||||||
{
|
|
||||||
if (nIndex != -1)
|
|
||||||
CWalletDB().KeepKey(nIndex);
|
|
||||||
nIndex = -1;
|
|
||||||
vchPubKey.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReturnKey()
|
|
||||||
{
|
|
||||||
if (nIndex != -1)
|
|
||||||
CWalletDB::ReturnKey(nIndex);
|
|
||||||
nIndex = -1;
|
|
||||||
vchPubKey.clear();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,10 +91,8 @@
|
|||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "key.h"
|
|
||||||
#include "bignum.h"
|
#include "bignum.h"
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "script.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#ifdef GUI
|
#ifdef GUI
|
||||||
#include "uibase.h"
|
#include "uibase.h"
|
||||||
|
37
src/init.cpp
37
src/init.cpp
@ -7,13 +7,15 @@
|
|||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "strlcpy.h"
|
#include "strlcpy.h"
|
||||||
#include <boost/filesystem/operations.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#include <boost/interprocess/sync/file_lock.hpp>
|
#include <boost/interprocess/sync/file_lock.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
|
CWallet* pwalletMain;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Shutdown
|
// Shutdown
|
||||||
@ -46,6 +48,8 @@ void Shutdown(void* parg)
|
|||||||
StopNode();
|
StopNode();
|
||||||
DBFlush(true);
|
DBFlush(true);
|
||||||
boost::filesystem::remove(GetPidFile());
|
boost::filesystem::remove(GetPidFile());
|
||||||
|
UnregisterWallet(pwalletMain);
|
||||||
|
delete pwalletMain;
|
||||||
CreateThread(ExitTimeout, NULL);
|
CreateThread(ExitTimeout, NULL);
|
||||||
Sleep(50);
|
Sleep(50);
|
||||||
printf("Bitcoin exiting\n\n");
|
printf("Bitcoin exiting\n\n");
|
||||||
@ -137,10 +141,19 @@ bool AppInit2(int argc, char* argv[])
|
|||||||
|
|
||||||
if (mapArgs.count("-datadir"))
|
if (mapArgs.count("-datadir"))
|
||||||
{
|
{
|
||||||
filesystem::path pathDataDir = filesystem::system_complete(mapArgs["-datadir"]);
|
if (filesystem::is_directory(filesystem::system_complete(mapArgs["-datadir"])))
|
||||||
strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir));
|
{
|
||||||
|
filesystem::path pathDataDir = filesystem::system_complete(mapArgs["-datadir"]);
|
||||||
|
strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: Specified directory does not exist\n");
|
||||||
|
Shutdown(NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
|
ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
|
||||||
|
|
||||||
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
||||||
@ -372,16 +385,19 @@ bool AppInit2(int argc, char* argv[])
|
|||||||
printf("Loading wallet...\n");
|
printf("Loading wallet...\n");
|
||||||
nStart = GetTimeMillis();
|
nStart = GetTimeMillis();
|
||||||
bool fFirstRun;
|
bool fFirstRun;
|
||||||
if (!LoadWallet(fFirstRun))
|
pwalletMain = new CWallet("wallet.dat");
|
||||||
|
if (!pwalletMain->LoadWallet(fFirstRun))
|
||||||
strErrors += _("Error loading wallet.dat \n");
|
strErrors += _("Error loading wallet.dat \n");
|
||||||
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
|
|
||||||
|
RegisterWallet(pwalletMain);
|
||||||
|
|
||||||
CBlockIndex *pindexRescan = pindexBest;
|
CBlockIndex *pindexRescan = pindexBest;
|
||||||
if (GetBoolArg("-rescan"))
|
if (GetBoolArg("-rescan"))
|
||||||
pindexRescan = pindexGenesisBlock;
|
pindexRescan = pindexGenesisBlock;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CWalletDB walletdb;
|
CWalletDB walletdb("wallet.dat");
|
||||||
CBlockLocator locator;
|
CBlockLocator locator;
|
||||||
if (walletdb.ReadBestBlock(locator))
|
if (walletdb.ReadBestBlock(locator))
|
||||||
pindexRescan = locator.GetBlockIndex();
|
pindexRescan = locator.GetBlockIndex();
|
||||||
@ -390,7 +406,7 @@ bool AppInit2(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
|
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
|
||||||
nStart = GetTimeMillis();
|
nStart = GetTimeMillis();
|
||||||
ScanForWalletTransactions(pindexRescan, true);
|
pwalletMain->ScanForWalletTransactions(pindexRescan, true);
|
||||||
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,10 +415,11 @@ bool AppInit2(int argc, char* argv[])
|
|||||||
//// debug print
|
//// debug print
|
||||||
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
|
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
|
||||||
printf("nBestHeight = %d\n", nBestHeight);
|
printf("nBestHeight = %d\n", nBestHeight);
|
||||||
printf("mapKeys.size() = %d\n", mapKeys.size());
|
printf("mapKeys.size() = %d\n", pwalletMain->mapKeys.size());
|
||||||
|
printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
|
||||||
printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
|
printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
|
||||||
printf("mapWallet.size() = %d\n", mapWallet.size());
|
printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
|
||||||
printf("mapAddressBook.size() = %d\n", mapAddressBook.size());
|
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
|
||||||
|
|
||||||
if (!strErrors.empty())
|
if (!strErrors.empty())
|
||||||
{
|
{
|
||||||
@ -411,7 +428,7 @@ bool AppInit2(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add wallet transactions that aren't already in a block to mapTransactions
|
// Add wallet transactions that aren't already in a block to mapTransactions
|
||||||
ReacceptWalletTransactions();
|
pwalletMain->ReacceptWalletTransactions();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Parameters
|
// Parameters
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#ifndef BITCOIN_INIT_H
|
#ifndef BITCOIN_INIT_H
|
||||||
#define BITCOIN_INIT_H
|
#define BITCOIN_INIT_H
|
||||||
|
|
||||||
|
extern CWallet* pwalletMain;
|
||||||
|
|
||||||
void Shutdown(void* parg);
|
void Shutdown(void* parg);
|
||||||
bool AppInit(int argc, char* argv[]);
|
bool AppInit(int argc, char* argv[]);
|
||||||
bool AppInit2(int argc, char* argv[]);
|
bool AppInit2(int argc, char* argv[]);
|
||||||
|
33
src/keystore.cpp
Normal file
33
src/keystore.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "headers.h"
|
||||||
|
#include "db.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// mapKeys
|
||||||
|
//
|
||||||
|
|
||||||
|
std::vector<unsigned char> CKeyStore::GenerateNewKey()
|
||||||
|
{
|
||||||
|
RandAddSeedPerfmon();
|
||||||
|
CKey key;
|
||||||
|
key.MakeNewKey();
|
||||||
|
if (!AddKey(key))
|
||||||
|
throw std::runtime_error("GenerateNewKey() : AddKey failed");
|
||||||
|
return key.GetPubKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CKeyStore::AddKey(const CKey& key)
|
||||||
|
{
|
||||||
|
CRITICAL_BLOCK(cs_mapKeys)
|
||||||
|
{
|
||||||
|
mapKeys[key.GetPubKey()] = key.GetPrivKey();
|
||||||
|
mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
30
src/keystore.h
Normal file
30
src/keystore.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) 2009-2011 Satoshi Nakamoto & 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_KEYSTORE_H
|
||||||
|
#define BITCOIN_KEYSTORE_H
|
||||||
|
|
||||||
|
class CKeyStore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::map<std::vector<unsigned char>, CPrivKey> mapKeys;
|
||||||
|
mutable CCriticalSection cs_mapKeys;
|
||||||
|
virtual bool AddKey(const CKey& key);
|
||||||
|
bool HaveKey(const std::vector<unsigned char> &vchPubKey) const
|
||||||
|
{
|
||||||
|
return (mapKeys.count(vchPubKey) > 0);
|
||||||
|
}
|
||||||
|
bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CPrivKey& keyOut) const
|
||||||
|
{
|
||||||
|
std::map<std::vector<unsigned char>, CPrivKey>::const_iterator mi = mapKeys.find(vchPubKey);
|
||||||
|
if (mi != mapKeys.end())
|
||||||
|
{
|
||||||
|
keyOut = (*mi).second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::vector<unsigned char> GenerateNewKey();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
1473
src/main.cpp
1473
src/main.cpp
File diff suppressed because it is too large
Load Diff
567
src/main.h
567
src/main.h
@ -7,22 +7,18 @@
|
|||||||
#include "bignum.h"
|
#include "bignum.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "db.h"
|
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
#include "db.h"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
class COutPoint;
|
|
||||||
class CInPoint;
|
|
||||||
class CDiskTxPos;
|
|
||||||
class CCoinBase;
|
|
||||||
class CTxIn;
|
|
||||||
class CTxOut;
|
|
||||||
class CTransaction;
|
|
||||||
class CBlock;
|
class CBlock;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
class CWalletTx;
|
class CWalletTx;
|
||||||
|
class CWallet;
|
||||||
class CKeyItem;
|
class CKeyItem;
|
||||||
|
class CReserveKey;
|
||||||
|
class CWalletDB;
|
||||||
|
|
||||||
class CMessageHeader;
|
class CMessageHeader;
|
||||||
class CAddress;
|
class CAddress;
|
||||||
@ -63,13 +59,11 @@ extern CBigNum bnBestInvalidWork;
|
|||||||
extern uint256 hashBestChain;
|
extern uint256 hashBestChain;
|
||||||
extern CBlockIndex* pindexBest;
|
extern CBlockIndex* pindexBest;
|
||||||
extern unsigned int nTransactionsUpdated;
|
extern unsigned int nTransactionsUpdated;
|
||||||
extern std::map<uint256, int> mapRequestCount;
|
|
||||||
extern CCriticalSection cs_mapRequestCount;
|
|
||||||
extern std::map<std::string, std::string> mapAddressBook;
|
|
||||||
extern CCriticalSection cs_mapAddressBook;
|
|
||||||
extern std::vector<unsigned char> vchDefaultKey;
|
|
||||||
extern double dHashesPerSec;
|
extern double dHashesPerSec;
|
||||||
extern int64 nHPSTimerStart;
|
extern int64 nHPSTimerStart;
|
||||||
|
extern int64 nTimeBestReceived;
|
||||||
|
extern CCriticalSection cs_setpwalletRegistered;
|
||||||
|
extern std::set<CWallet*> setpwalletRegistered;
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
extern int fGenerateBitcoins;
|
extern int fGenerateBitcoins;
|
||||||
@ -89,34 +83,20 @@ class CReserveKey;
|
|||||||
class CTxDB;
|
class CTxDB;
|
||||||
class CTxIndex;
|
class CTxIndex;
|
||||||
|
|
||||||
|
void RegisterWallet(CWallet* pwalletIn);
|
||||||
|
void UnregisterWallet(CWallet* pwalletIn);
|
||||||
bool CheckDiskSpace(uint64 nAdditionalBytes=0);
|
bool CheckDiskSpace(uint64 nAdditionalBytes=0);
|
||||||
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
|
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
|
||||||
FILE* AppendBlockFile(unsigned int& nFileRet);
|
FILE* AppendBlockFile(unsigned int& nFileRet);
|
||||||
bool AddKey(const CKey& key);
|
|
||||||
std::vector<unsigned char> GenerateNewKey();
|
|
||||||
bool AddToWallet(const CWalletTx& wtxIn);
|
|
||||||
void WalletUpdateSpent(const COutPoint& prevout);
|
|
||||||
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
|
|
||||||
void ReacceptWalletTransactions();
|
|
||||||
bool LoadBlockIndex(bool fAllowNew=true);
|
bool LoadBlockIndex(bool fAllowNew=true);
|
||||||
void PrintBlockTree();
|
void PrintBlockTree();
|
||||||
bool ProcessMessages(CNode* pfrom);
|
bool ProcessMessages(CNode* pfrom);
|
||||||
bool ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vRecv);
|
|
||||||
bool SendMessages(CNode* pto, bool fSendTrickle);
|
bool SendMessages(CNode* pto, bool fSendTrickle);
|
||||||
int64 GetBalance();
|
void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
|
||||||
bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
|
|
||||||
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
|
|
||||||
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
|
|
||||||
bool BroadcastTransaction(CWalletTx& wtxNew);
|
|
||||||
std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
|
||||||
std::string SendMoneyToBitcoinAddress(std::string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
|
||||||
void GenerateBitcoins(bool fGenerate);
|
|
||||||
void ThreadBitcoinMiner(void* parg);
|
|
||||||
CBlock* CreateNewBlock(CReserveKey& reservekey);
|
CBlock* CreateNewBlock(CReserveKey& reservekey);
|
||||||
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime);
|
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime);
|
||||||
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
|
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
|
||||||
bool CheckWork(CBlock* pblock, CReserveKey& reservekey);
|
bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
|
||||||
void BitcoinMiner();
|
|
||||||
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
|
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
|
||||||
int GetTotalBlocksEstimate();
|
int GetTotalBlocksEstimate();
|
||||||
bool IsInitialBlockDownload();
|
bool IsInitialBlockDownload();
|
||||||
@ -133,6 +113,23 @@ std::string GetWarnings(std::string strFor);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool WriteSetting(const std::string& strKey, const T& value)
|
||||||
|
{
|
||||||
|
bool fOk = false;
|
||||||
|
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||||
|
{
|
||||||
|
std::string strWalletFile;
|
||||||
|
if (!GetWalletFile(pwallet, strWalletFile))
|
||||||
|
continue;
|
||||||
|
fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
|
||||||
|
}
|
||||||
|
return fOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class CDiskTxPos
|
class CDiskTxPos
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -315,9 +312,6 @@ public:
|
|||||||
{
|
{
|
||||||
printf("%s\n", ToString().c_str());
|
printf("%s\n", ToString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsMine() const;
|
|
||||||
int64 GetDebit() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -366,36 +360,6 @@ public:
|
|||||||
return SerializeHash(*this);
|
return SerializeHash(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsMine() const
|
|
||||||
{
|
|
||||||
return ::IsMine(scriptPubKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetCredit() const
|
|
||||||
{
|
|
||||||
if (!MoneyRange(nValue))
|
|
||||||
throw std::runtime_error("CTxOut::GetCredit() : value out of range");
|
|
||||||
return (IsMine() ? nValue : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsChange() const
|
|
||||||
{
|
|
||||||
// On a debit transaction, a txout that's mine but isn't in the address book is change
|
|
||||||
std::vector<unsigned char> vchPubKey;
|
|
||||||
if (ExtractPubKey(scriptPubKey, true, vchPubKey))
|
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
|
||||||
if (!mapAddressBook.count(PubKeyToAddress(vchPubKey)))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetChange() const
|
|
||||||
{
|
|
||||||
if (!MoneyRange(nValue))
|
|
||||||
throw std::runtime_error("CTxOut::GetChange() : value out of range");
|
|
||||||
return (IsChange() ? nValue : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator==(const CTxOut& a, const CTxOut& b)
|
friend bool operator==(const CTxOut& a, const CTxOut& b)
|
||||||
{
|
{
|
||||||
return (a.nValue == b.nValue &&
|
return (a.nValue == b.nValue &&
|
||||||
@ -540,57 +504,6 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsMine() const
|
|
||||||
{
|
|
||||||
BOOST_FOREACH(const CTxOut& txout, vout)
|
|
||||||
if (txout.IsMine())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsFromMe() const
|
|
||||||
{
|
|
||||||
return (GetDebit() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetDebit() const
|
|
||||||
{
|
|
||||||
int64 nDebit = 0;
|
|
||||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
|
||||||
{
|
|
||||||
nDebit += txin.GetDebit();
|
|
||||||
if (!MoneyRange(nDebit))
|
|
||||||
throw std::runtime_error("CTransaction::GetDebit() : value out of range");
|
|
||||||
}
|
|
||||||
return nDebit;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetCredit() const
|
|
||||||
{
|
|
||||||
int64 nCredit = 0;
|
|
||||||
BOOST_FOREACH(const CTxOut& txout, vout)
|
|
||||||
{
|
|
||||||
nCredit += txout.GetCredit();
|
|
||||||
if (!MoneyRange(nCredit))
|
|
||||||
throw std::runtime_error("CTransaction::GetCredit() : value out of range");
|
|
||||||
}
|
|
||||||
return nCredit;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetChange() const
|
|
||||||
{
|
|
||||||
if (IsCoinBase())
|
|
||||||
return 0;
|
|
||||||
int64 nChange = 0;
|
|
||||||
BOOST_FOREACH(const CTxOut& txout, vout)
|
|
||||||
{
|
|
||||||
nChange += txout.GetChange();
|
|
||||||
if (!MoneyRange(nChange))
|
|
||||||
throw std::runtime_error("CTransaction::GetChange() : value out of range");
|
|
||||||
}
|
|
||||||
return nChange;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetValueOut() const
|
int64 GetValueOut() const
|
||||||
{
|
{
|
||||||
int64 nValueOut = 0;
|
int64 nValueOut = 0;
|
||||||
@ -722,11 +635,7 @@ public:
|
|||||||
bool ClientConnectInputs();
|
bool ClientConnectInputs();
|
||||||
bool CheckTransaction() const;
|
bool CheckTransaction() const;
|
||||||
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
|
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
|
||||||
bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
|
bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
|
||||||
{
|
|
||||||
CTxDB txdb("r");
|
|
||||||
return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs);
|
|
||||||
}
|
|
||||||
protected:
|
protected:
|
||||||
bool AddToMemoryPoolUnchecked();
|
bool AddToMemoryPoolUnchecked();
|
||||||
public:
|
public:
|
||||||
@ -785,307 +694,7 @@ public:
|
|||||||
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
|
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
|
||||||
int GetBlocksToMaturity() const;
|
int GetBlocksToMaturity() const;
|
||||||
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
|
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
|
||||||
bool AcceptToMemoryPool() { CTxDB txdb("r"); return AcceptToMemoryPool(txdb); }
|
bool AcceptToMemoryPool();
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// A transaction with a bunch of additional info that only the owner cares
|
|
||||||
// about. It includes any unrecorded transactions needed to link it back
|
|
||||||
// to the block chain.
|
|
||||||
//
|
|
||||||
class CWalletTx : public CMerkleTx
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::vector<CMerkleTx> vtxPrev;
|
|
||||||
std::map<std::string, std::string> mapValue;
|
|
||||||
std::vector<std::pair<std::string, std::string> > vOrderForm;
|
|
||||||
unsigned int fTimeReceivedIsTxTime;
|
|
||||||
unsigned int nTimeReceived; // time received by this node
|
|
||||||
char fFromMe;
|
|
||||||
std::string strFromAccount;
|
|
||||||
std::vector<char> vfSpent;
|
|
||||||
|
|
||||||
// memory only
|
|
||||||
mutable char fDebitCached;
|
|
||||||
mutable char fCreditCached;
|
|
||||||
mutable char fAvailableCreditCached;
|
|
||||||
mutable char fChangeCached;
|
|
||||||
mutable int64 nDebitCached;
|
|
||||||
mutable int64 nCreditCached;
|
|
||||||
mutable int64 nAvailableCreditCached;
|
|
||||||
mutable int64 nChangeCached;
|
|
||||||
|
|
||||||
// memory only UI hints
|
|
||||||
mutable unsigned int nTimeDisplayed;
|
|
||||||
mutable int nLinesDisplayed;
|
|
||||||
mutable char fConfirmedDisplayed;
|
|
||||||
|
|
||||||
|
|
||||||
CWalletTx()
|
|
||||||
{
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn)
|
|
||||||
{
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn)
|
|
||||||
{
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
vtxPrev.clear();
|
|
||||||
mapValue.clear();
|
|
||||||
vOrderForm.clear();
|
|
||||||
fTimeReceivedIsTxTime = false;
|
|
||||||
nTimeReceived = 0;
|
|
||||||
fFromMe = false;
|
|
||||||
strFromAccount.clear();
|
|
||||||
vfSpent.clear();
|
|
||||||
fDebitCached = false;
|
|
||||||
fCreditCached = false;
|
|
||||||
fAvailableCreditCached = false;
|
|
||||||
fChangeCached = false;
|
|
||||||
nDebitCached = 0;
|
|
||||||
nCreditCached = 0;
|
|
||||||
nAvailableCreditCached = 0;
|
|
||||||
nChangeCached = 0;
|
|
||||||
nTimeDisplayed = 0;
|
|
||||||
nLinesDisplayed = 0;
|
|
||||||
fConfirmedDisplayed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
|
||||||
(
|
|
||||||
CWalletTx* pthis = const_cast<CWalletTx*>(this);
|
|
||||||
if (fRead)
|
|
||||||
pthis->Init();
|
|
||||||
char fSpent = false;
|
|
||||||
|
|
||||||
if (!fRead)
|
|
||||||
{
|
|
||||||
pthis->mapValue["fromaccount"] = pthis->strFromAccount;
|
|
||||||
|
|
||||||
std::string str;
|
|
||||||
BOOST_FOREACH(char f, vfSpent)
|
|
||||||
{
|
|
||||||
str += (f ? '1' : '0');
|
|
||||||
if (f)
|
|
||||||
fSpent = true;
|
|
||||||
}
|
|
||||||
pthis->mapValue["spent"] = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
|
|
||||||
READWRITE(vtxPrev);
|
|
||||||
READWRITE(mapValue);
|
|
||||||
READWRITE(vOrderForm);
|
|
||||||
READWRITE(fTimeReceivedIsTxTime);
|
|
||||||
READWRITE(nTimeReceived);
|
|
||||||
READWRITE(fFromMe);
|
|
||||||
READWRITE(fSpent);
|
|
||||||
|
|
||||||
if (fRead)
|
|
||||||
{
|
|
||||||
pthis->strFromAccount = pthis->mapValue["fromaccount"];
|
|
||||||
|
|
||||||
if (mapValue.count("spent"))
|
|
||||||
BOOST_FOREACH(char c, pthis->mapValue["spent"])
|
|
||||||
pthis->vfSpent.push_back(c != '0');
|
|
||||||
else
|
|
||||||
pthis->vfSpent.assign(vout.size(), fSpent);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthis->mapValue.erase("fromaccount");
|
|
||||||
pthis->mapValue.erase("version");
|
|
||||||
pthis->mapValue.erase("spent");
|
|
||||||
)
|
|
||||||
|
|
||||||
// marks certain txout's as spent
|
|
||||||
// returns true if any update took place
|
|
||||||
bool UpdateSpent(const std::vector<char>& vfNewSpent)
|
|
||||||
{
|
|
||||||
bool fReturn = false;
|
|
||||||
for (int i=0; i < vfNewSpent.size(); i++)
|
|
||||||
{
|
|
||||||
if (i == vfSpent.size())
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (vfNewSpent[i] && !vfSpent[i])
|
|
||||||
{
|
|
||||||
vfSpent[i] = true;
|
|
||||||
fReturn = true;
|
|
||||||
fAvailableCreditCached = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MarkDirty()
|
|
||||||
{
|
|
||||||
fCreditCached = false;
|
|
||||||
fAvailableCreditCached = false;
|
|
||||||
fDebitCached = false;
|
|
||||||
fChangeCached = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MarkSpent(unsigned int nOut)
|
|
||||||
{
|
|
||||||
if (nOut >= vout.size())
|
|
||||||
throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range");
|
|
||||||
vfSpent.resize(vout.size());
|
|
||||||
if (!vfSpent[nOut])
|
|
||||||
{
|
|
||||||
vfSpent[nOut] = true;
|
|
||||||
fAvailableCreditCached = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsSpent(unsigned int nOut) const
|
|
||||||
{
|
|
||||||
if (nOut >= vout.size())
|
|
||||||
throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range");
|
|
||||||
if (nOut >= vfSpent.size())
|
|
||||||
return false;
|
|
||||||
return (!!vfSpent[nOut]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetDebit() const
|
|
||||||
{
|
|
||||||
if (vin.empty())
|
|
||||||
return 0;
|
|
||||||
if (fDebitCached)
|
|
||||||
return nDebitCached;
|
|
||||||
nDebitCached = CTransaction::GetDebit();
|
|
||||||
fDebitCached = true;
|
|
||||||
return nDebitCached;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetCredit(bool fUseCache=true) const
|
|
||||||
{
|
|
||||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// GetBalance can assume transactions in mapWallet won't change
|
|
||||||
if (fUseCache && fCreditCached)
|
|
||||||
return nCreditCached;
|
|
||||||
nCreditCached = CTransaction::GetCredit();
|
|
||||||
fCreditCached = true;
|
|
||||||
return nCreditCached;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 GetAvailableCredit(bool fUseCache=true) const
|
|
||||||
{
|
|
||||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (fUseCache && fAvailableCreditCached)
|
|
||||||
return nAvailableCreditCached;
|
|
||||||
|
|
||||||
int64 nCredit = 0;
|
|
||||||
for (int i = 0; i < vout.size(); i++)
|
|
||||||
{
|
|
||||||
if (!IsSpent(i))
|
|
||||||
{
|
|
||||||
const CTxOut &txout = vout[i];
|
|
||||||
nCredit += txout.GetCredit();
|
|
||||||
if (!MoneyRange(nCredit))
|
|
||||||
throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nAvailableCreditCached = nCredit;
|
|
||||||
fAvailableCreditCached = true;
|
|
||||||
return nCredit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int64 GetChange() const
|
|
||||||
{
|
|
||||||
if (fChangeCached)
|
|
||||||
return nChangeCached;
|
|
||||||
nChangeCached = CTransaction::GetChange();
|
|
||||||
fChangeCached = true;
|
|
||||||
return nChangeCached;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<std::string /* address */, int64> >& listReceived,
|
|
||||||
std::list<std::pair<std::string /* address */, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
|
|
||||||
|
|
||||||
void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived,
|
|
||||||
int64& nSent, int64& nFee) const;
|
|
||||||
|
|
||||||
bool IsFromMe() const
|
|
||||||
{
|
|
||||||
return (GetDebit() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsConfirmed() const
|
|
||||||
{
|
|
||||||
// Quick answer in most cases
|
|
||||||
if (!IsFinal())
|
|
||||||
return false;
|
|
||||||
if (GetDepthInMainChain() >= 1)
|
|
||||||
return true;
|
|
||||||
if (!IsFromMe()) // using wtx's cached debit
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// If no confirmations but it's from us, we can still
|
|
||||||
// consider it confirmed if all dependencies are confirmed
|
|
||||||
std::map<uint256, const CMerkleTx*> mapPrev;
|
|
||||||
std::vector<const CMerkleTx*> vWorkQueue;
|
|
||||||
vWorkQueue.reserve(vtxPrev.size()+1);
|
|
||||||
vWorkQueue.push_back(this);
|
|
||||||
for (int i = 0; i < vWorkQueue.size(); i++)
|
|
||||||
{
|
|
||||||
const CMerkleTx* ptx = vWorkQueue[i];
|
|
||||||
|
|
||||||
if (!ptx->IsFinal())
|
|
||||||
return false;
|
|
||||||
if (ptx->GetDepthInMainChain() >= 1)
|
|
||||||
continue;
|
|
||||||
if (!ptx->IsFromMe())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (mapPrev.empty())
|
|
||||||
BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
|
|
||||||
mapPrev[tx.GetHash()] = &tx;
|
|
||||||
|
|
||||||
BOOST_FOREACH(const CTxIn& txin, ptx->vin)
|
|
||||||
{
|
|
||||||
if (!mapPrev.count(txin.prevout.hash))
|
|
||||||
return false;
|
|
||||||
vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteToDisk()
|
|
||||||
{
|
|
||||||
return CWalletDB().WriteTx(GetHash(), *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int64 GetTxTime() const;
|
|
||||||
int GetRequestCount() const;
|
|
||||||
|
|
||||||
void AddSupportingTransactions(CTxDB& txdb);
|
|
||||||
|
|
||||||
bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
|
|
||||||
bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); }
|
|
||||||
|
|
||||||
void RelayWalletTransaction(CTxDB& txdb);
|
|
||||||
void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1745,114 +1354,6 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Private key that includes an expiration date in case it never gets used.
|
|
||||||
//
|
|
||||||
class CWalletKey
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CPrivKey vchPrivKey;
|
|
||||||
int64 nTimeCreated;
|
|
||||||
int64 nTimeExpires;
|
|
||||||
std::string strComment;
|
|
||||||
//// todo: add something to note what created it (user, getnewaddress, change)
|
|
||||||
//// maybe should have a map<string, string> property map
|
|
||||||
|
|
||||||
CWalletKey(int64 nExpires=0)
|
|
||||||
{
|
|
||||||
nTimeCreated = (nExpires ? GetTime() : 0);
|
|
||||||
nTimeExpires = nExpires;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
|
||||||
(
|
|
||||||
if (!(nType & SER_GETHASH))
|
|
||||||
READWRITE(nVersion);
|
|
||||||
READWRITE(vchPrivKey);
|
|
||||||
READWRITE(nTimeCreated);
|
|
||||||
READWRITE(nTimeExpires);
|
|
||||||
READWRITE(strComment);
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Account information.
|
|
||||||
// Stored in wallet with key "acc"+string account name
|
|
||||||
//
|
|
||||||
class CAccount
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::vector<unsigned char> vchPubKey;
|
|
||||||
|
|
||||||
CAccount()
|
|
||||||
{
|
|
||||||
SetNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetNull()
|
|
||||||
{
|
|
||||||
vchPubKey.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
|
||||||
(
|
|
||||||
if (!(nType & SER_GETHASH))
|
|
||||||
READWRITE(nVersion);
|
|
||||||
READWRITE(vchPubKey);
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Internal transfers.
|
|
||||||
// Database key is acentry<account><counter>
|
|
||||||
//
|
|
||||||
class CAccountingEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string strAccount;
|
|
||||||
int64 nCreditDebit;
|
|
||||||
int64 nTime;
|
|
||||||
std::string strOtherAccount;
|
|
||||||
std::string strComment;
|
|
||||||
|
|
||||||
CAccountingEntry()
|
|
||||||
{
|
|
||||||
SetNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetNull()
|
|
||||||
{
|
|
||||||
nCreditDebit = 0;
|
|
||||||
nTime = 0;
|
|
||||||
strAccount.clear();
|
|
||||||
strOtherAccount.clear();
|
|
||||||
strComment.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
|
||||||
(
|
|
||||||
if (!(nType & SER_GETHASH))
|
|
||||||
READWRITE(nVersion);
|
|
||||||
// Note: strAccount is serialized as part of the key, not here.
|
|
||||||
READWRITE(nCreditDebit);
|
|
||||||
READWRITE(nTime);
|
|
||||||
READWRITE(strOtherAccount);
|
|
||||||
READWRITE(strComment);
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2064,13 +1565,9 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern std::map<uint256, CTransaction> mapTransactions;
|
extern std::map<uint256, CTransaction> mapTransactions;
|
||||||
extern std::map<uint256, CWalletTx> mapWallet;
|
|
||||||
extern std::vector<uint256> vWalletUpdated;
|
|
||||||
extern CCriticalSection cs_mapWallet;
|
|
||||||
extern std::map<std::vector<unsigned char>, CPrivKey> mapKeys;
|
|
||||||
extern std::map<uint160, std::vector<unsigned char> > mapPubKeys;
|
extern std::map<uint160, std::vector<unsigned char> > mapPubKeys;
|
||||||
extern CCriticalSection cs_mapKeys;
|
extern CCriticalSection cs_mapPubKeys;
|
||||||
extern CKey keyUser;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1117,7 +1117,7 @@ void MapPort(bool fMapPort)
|
|||||||
if (fUseUPnP != fMapPort)
|
if (fUseUPnP != fMapPort)
|
||||||
{
|
{
|
||||||
fUseUPnP = fMapPort;
|
fUseUPnP = fMapPort;
|
||||||
CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
|
WriteSetting("fUseUPnP", fUseUPnP);
|
||||||
}
|
}
|
||||||
if (fUseUPnP && vnThreadsRunning[5] < 1)
|
if (fUseUPnP && vnThreadsRunning[5] < 1)
|
||||||
{
|
{
|
||||||
@ -1698,7 +1698,7 @@ void StartNode(void* parg)
|
|||||||
printf("Error: CreateThread(ThreadMessageHandler) failed\n");
|
printf("Error: CreateThread(ThreadMessageHandler) failed\n");
|
||||||
|
|
||||||
// Generate coins in the background
|
// Generate coins in the background
|
||||||
GenerateBitcoins(fGenerateBitcoins);
|
GenerateBitcoins(fGenerateBitcoins, pwalletMain);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StopNode()
|
bool StopNode()
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#define BITCOIN_NOUI_H
|
#define BITCOIN_NOUI_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include "wallet.h"
|
||||||
|
|
||||||
typedef void wxWindow;
|
typedef void wxWindow;
|
||||||
#define wxYES 0x00000002
|
#define wxYES 0x00000002
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
#include "main.h"
|
|
||||||
|
#include "headers.h"
|
||||||
|
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
@ -22,31 +23,25 @@ struct AddressTableEntry
|
|||||||
AddressTableEntry() {}
|
AddressTableEntry() {}
|
||||||
AddressTableEntry(Type type, const QString &label, const QString &address):
|
AddressTableEntry(Type type, const QString &label, const QString &address):
|
||||||
type(type), label(label), address(address) {}
|
type(type), label(label), address(address) {}
|
||||||
|
|
||||||
bool isDefaultAddress() const
|
|
||||||
{
|
|
||||||
std::vector<unsigned char> vchPubKey;
|
|
||||||
if (CWalletDB("r").ReadDefaultKey(vchPubKey))
|
|
||||||
{
|
|
||||||
return address == QString::fromStdString(PubKeyToAddress(vchPubKey));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Private implementation
|
// Private implementation
|
||||||
struct AddressTablePriv
|
struct AddressTablePriv
|
||||||
{
|
{
|
||||||
|
CWallet *wallet;
|
||||||
QList<AddressTableEntry> cachedAddressTable;
|
QList<AddressTableEntry> cachedAddressTable;
|
||||||
|
|
||||||
|
AddressTablePriv(CWallet *wallet):
|
||||||
|
wallet(wallet) {}
|
||||||
|
|
||||||
void refreshAddressTable()
|
void refreshAddressTable()
|
||||||
{
|
{
|
||||||
cachedAddressTable.clear();
|
cachedAddressTable.clear();
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_mapKeys)
|
CRITICAL_BLOCK(wallet->cs_mapKeys)
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(wallet->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item, mapAddressBook)
|
BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item, wallet->mapAddressBook)
|
||||||
{
|
{
|
||||||
std::string strAddress = item.first;
|
std::string strAddress = item.first;
|
||||||
std::string strName = item.second;
|
std::string strName = item.second;
|
||||||
@ -75,13 +70,18 @@ struct AddressTablePriv
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isDefaultAddress(const AddressTableEntry *rec)
|
||||||
|
{
|
||||||
|
return rec->address == QString::fromStdString(wallet->GetDefaultAddress());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
AddressTableModel::AddressTableModel(QObject *parent) :
|
AddressTableModel::AddressTableModel(CWallet *wallet, QObject *parent) :
|
||||||
QAbstractTableModel(parent),priv(0)
|
QAbstractTableModel(parent),wallet(wallet),priv(0)
|
||||||
{
|
{
|
||||||
columns << tr("Label") << tr("Address");
|
columns << tr("Label") << tr("Address");
|
||||||
priv = new AddressTablePriv();
|
priv = new AddressTablePriv(wallet);
|
||||||
priv->refreshAddressTable();
|
priv->refreshAddressTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const
|
|||||||
case Address:
|
case Address:
|
||||||
return rec->address;
|
return rec->address;
|
||||||
case IsDefaultAddress:
|
case IsDefaultAddress:
|
||||||
return rec->isDefaultAddress();
|
return priv->isDefaultAddress(rec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (role == Qt::FontRole)
|
else if (role == Qt::FontRole)
|
||||||
@ -128,7 +128,7 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const
|
|||||||
{
|
{
|
||||||
font = GUIUtil::bitcoinAddressFont();
|
font = GUIUtil::bitcoinAddressFont();
|
||||||
}
|
}
|
||||||
if(rec->isDefaultAddress())
|
if(priv->isDefaultAddress(rec))
|
||||||
{
|
{
|
||||||
font.setBold(true);
|
font.setBold(true);
|
||||||
}
|
}
|
||||||
@ -137,14 +137,14 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const
|
|||||||
else if (role == Qt::ForegroundRole)
|
else if (role == Qt::ForegroundRole)
|
||||||
{
|
{
|
||||||
// Show default address in alternative color
|
// Show default address in alternative color
|
||||||
if(rec->isDefaultAddress())
|
if(priv->isDefaultAddress(rec))
|
||||||
{
|
{
|
||||||
return QColor(0,0,255);
|
return QColor(0,0,255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (role == Qt::ToolTipRole)
|
else if (role == Qt::ToolTipRole)
|
||||||
{
|
{
|
||||||
if(rec->isDefaultAddress())
|
if(priv->isDefaultAddress(rec))
|
||||||
{
|
{
|
||||||
return tr("Default receiving address");
|
return tr("Default receiving address");
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
|
|||||||
switch(index.column())
|
switch(index.column())
|
||||||
{
|
{
|
||||||
case Label:
|
case Label:
|
||||||
SetAddressBookName(rec->address.toStdString(), value.toString().toStdString());
|
wallet->SetAddressBookName(rec->address.toStdString(), value.toString().toStdString());
|
||||||
rec->label = value.toString();
|
rec->label = value.toString();
|
||||||
break;
|
break;
|
||||||
case Address:
|
case Address:
|
||||||
@ -182,9 +182,9 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
|
|||||||
if(rec->type == AddressTableEntry::Sending)
|
if(rec->type == AddressTableEntry::Sending)
|
||||||
{
|
{
|
||||||
// Remove old entry
|
// Remove old entry
|
||||||
CWalletDB().EraseName(rec->address.toStdString());
|
wallet->EraseAddressBookName(rec->address.toStdString());
|
||||||
// Add new entry with new address
|
// Add new entry with new address
|
||||||
SetAddressBookName(value.toString().toStdString(), rec->label.toStdString());
|
wallet->SetAddressBookName(value.toString().toStdString(), rec->label.toStdString());
|
||||||
|
|
||||||
rec->address = value.toString();
|
rec->address = value.toString();
|
||||||
}
|
}
|
||||||
@ -245,9 +245,9 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||||||
if(type == Send)
|
if(type == Send)
|
||||||
{
|
{
|
||||||
// Check for duplicate
|
// Check for duplicate
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(wallet->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
if(mapAddressBook.count(strAddress))
|
if(wallet->mapAddressBook.count(strAddress))
|
||||||
{
|
{
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
@ -257,7 +257,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||||||
{
|
{
|
||||||
// Generate a new address to associate with given label, optionally
|
// Generate a new address to associate with given label, optionally
|
||||||
// set as default receiving address.
|
// set as default receiving address.
|
||||||
strAddress = PubKeyToAddress(GetKeyFromKeyPool());
|
strAddress = PubKeyToAddress(wallet->GetKeyFromKeyPool());
|
||||||
if(setAsDefault)
|
if(setAsDefault)
|
||||||
{
|
{
|
||||||
setDefaultAddress(QString::fromStdString(strAddress));
|
setDefaultAddress(QString::fromStdString(strAddress));
|
||||||
@ -268,7 +268,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
// Add entry and update list
|
// Add entry and update list
|
||||||
SetAddressBookName(strAddress, strLabel);
|
wallet->SetAddressBookName(strAddress, strLabel);
|
||||||
updateList();
|
updateList();
|
||||||
return QString::fromStdString(strAddress);
|
return QString::fromStdString(strAddress);
|
||||||
}
|
}
|
||||||
@ -283,33 +283,19 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
|
|||||||
// Also refuse to remove receiving addresses.
|
// Also refuse to remove receiving addresses.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CWalletDB().EraseName(rec->address.toStdString());
|
wallet->EraseAddressBookName(rec->address.toStdString());
|
||||||
updateList();
|
updateList();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AddressTableModel::getDefaultAddress() const
|
QString AddressTableModel::getDefaultAddress() const
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> vchPubKey;
|
return QString::fromStdString(wallet->GetDefaultAddress());
|
||||||
if (CWalletDB("r").ReadDefaultKey(vchPubKey))
|
|
||||||
{
|
|
||||||
return QString::fromStdString(PubKeyToAddress(vchPubKey));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressTableModel::setDefaultAddress(const QString &defaultAddress)
|
void AddressTableModel::setDefaultAddress(const QString &defaultAddress)
|
||||||
{
|
{
|
||||||
uint160 hash160;
|
wallet->SetDefaultAddress(defaultAddress.toStdString());
|
||||||
std::string strAddress = defaultAddress.toStdString();
|
|
||||||
if (!AddressToHash160(strAddress, hash160))
|
|
||||||
return;
|
|
||||||
if (!mapPubKeys.count(hash160))
|
|
||||||
return;
|
|
||||||
CWalletDB().WriteDefaultKey(mapPubKeys[hash160]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressTableModel::update()
|
void AddressTableModel::update()
|
||||||
|
@ -5,12 +5,13 @@
|
|||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
class AddressTablePriv;
|
class AddressTablePriv;
|
||||||
|
class CWallet;
|
||||||
|
|
||||||
class AddressTableModel : public QAbstractTableModel
|
class AddressTableModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AddressTableModel(QObject *parent = 0);
|
explicit AddressTableModel(CWallet *wallet, QObject *parent = 0);
|
||||||
~AddressTableModel();
|
~AddressTableModel();
|
||||||
|
|
||||||
enum ColumnIndex {
|
enum ColumnIndex {
|
||||||
@ -49,6 +50,7 @@ public:
|
|||||||
void updateList();
|
void updateList();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
CWallet *wallet;
|
||||||
AddressTablePriv *priv;
|
AddressTablePriv *priv;
|
||||||
QStringList columns;
|
QStringList columns;
|
||||||
|
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
#include "bitcoingui.h"
|
#include "bitcoingui.h"
|
||||||
#include "clientmodel.h"
|
#include "clientmodel.h"
|
||||||
#include "util.h"
|
|
||||||
|
#include "headers.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "main.h"
|
|
||||||
#include "qtui.h"
|
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
@ -114,7 +113,7 @@ int main(int argc, char *argv[])
|
|||||||
if(AppInit2(argc, argv))
|
if(AppInit2(argc, argv))
|
||||||
{
|
{
|
||||||
BitcoinGUI window;
|
BitcoinGUI window;
|
||||||
ClientModel model;
|
ClientModel model(pwalletMain);
|
||||||
guiref = &window;
|
guiref = &window;
|
||||||
window.setModel(&model);
|
window.setModel(&model);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "transactiondescdialog.h"
|
#include "transactiondescdialog.h"
|
||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
|
|
||||||
#include "main.h"
|
#include "headers.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
#include "clientmodel.h"
|
#include "clientmodel.h"
|
||||||
#include "main.h"
|
|
||||||
#include "guiconstants.h"
|
#include "guiconstants.h"
|
||||||
#include "optionsmodel.h"
|
#include "optionsmodel.h"
|
||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
#include "transactiontablemodel.h"
|
#include "transactiontablemodel.h"
|
||||||
|
|
||||||
|
#include "headers.h"
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
ClientModel::ClientModel(QObject *parent) :
|
ClientModel::ClientModel(CWallet *wallet, QObject *parent) :
|
||||||
QObject(parent), optionsModel(0), addressTableModel(0),
|
QObject(parent), wallet(wallet), optionsModel(0), addressTableModel(0),
|
||||||
transactionTableModel(0)
|
transactionTableModel(0)
|
||||||
{
|
{
|
||||||
// Until signal notifications is built into the bitcoin core,
|
// Until signal notifications is built into the bitcoin core,
|
||||||
@ -17,14 +18,14 @@ ClientModel::ClientModel(QObject *parent) :
|
|||||||
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
|
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
|
||||||
timer->start(MODEL_UPDATE_DELAY);
|
timer->start(MODEL_UPDATE_DELAY);
|
||||||
|
|
||||||
optionsModel = new OptionsModel(this);
|
optionsModel = new OptionsModel(wallet, this);
|
||||||
addressTableModel = new AddressTableModel(this);
|
addressTableModel = new AddressTableModel(wallet, this);
|
||||||
transactionTableModel = new TransactionTableModel(this);
|
transactionTableModel = new TransactionTableModel(wallet, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 ClientModel::getBalance() const
|
qint64 ClientModel::getBalance() const
|
||||||
{
|
{
|
||||||
return GetBalance();
|
return wallet->GetBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ClientModel::getNumConnections() const
|
int ClientModel::getNumConnections() const
|
||||||
@ -40,9 +41,9 @@ int ClientModel::getNumBlocks() const
|
|||||||
int ClientModel::getNumTransactions() const
|
int ClientModel::getNumTransactions() const
|
||||||
{
|
{
|
||||||
int numTransactions = 0;
|
int numTransactions = 0;
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(wallet->cs_mapWallet)
|
||||||
{
|
{
|
||||||
numTransactions = mapWallet.size();
|
numTransactions = wallet->mapWallet.size();
|
||||||
}
|
}
|
||||||
return numTransactions;
|
return numTransactions;
|
||||||
}
|
}
|
||||||
@ -92,7 +93,7 @@ ClientModel::StatusCode ClientModel::sendCoins(const QString &payTo, qint64 payA
|
|||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
|
scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||||
|
|
||||||
std::string strError = SendMoney(scriptPubKey, payAmount, wtx, true);
|
std::string strError = wallet->SendMoney(scriptPubKey, payAmount, wtx, true);
|
||||||
if (strError == "")
|
if (strError == "")
|
||||||
{
|
{
|
||||||
// OK
|
// OK
|
||||||
@ -110,9 +111,11 @@ ClientModel::StatusCode ClientModel::sendCoins(const QString &payTo, qint64 payA
|
|||||||
|
|
||||||
// Add addresses that we've sent to to the address book
|
// Add addresses that we've sent to to the address book
|
||||||
std::string strAddress = payTo.toStdString();
|
std::string strAddress = payTo.toStdString();
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(wallet->cs_mapAddressBook)
|
||||||
if (!mapAddressBook.count(strAddress))
|
{
|
||||||
SetAddressBookName(strAddress, addToAddressBookAs.toStdString());
|
if (!wallet->mapAddressBook.count(strAddress))
|
||||||
|
wallet->SetAddressBookName(strAddress, addToAddressBookAs.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,13 @@
|
|||||||
class OptionsModel;
|
class OptionsModel;
|
||||||
class AddressTableModel;
|
class AddressTableModel;
|
||||||
class TransactionTableModel;
|
class TransactionTableModel;
|
||||||
|
class CWallet;
|
||||||
|
|
||||||
class ClientModel : public QObject
|
class ClientModel : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ClientModel(QObject *parent = 0);
|
explicit ClientModel(CWallet *wallet, QObject *parent = 0);
|
||||||
|
|
||||||
enum StatusCode
|
enum StatusCode
|
||||||
{
|
{
|
||||||
@ -41,6 +42,8 @@ public:
|
|||||||
/* Send coins */
|
/* Send coins */
|
||||||
StatusCode sendCoins(const QString &payTo, qint64 payAmount, const QString &addToAddressBookAs=QString());
|
StatusCode sendCoins(const QString &payTo, qint64 payAmount, const QString &addToAddressBookAs=QString());
|
||||||
private:
|
private:
|
||||||
|
CWallet *wallet;
|
||||||
|
|
||||||
OptionsModel *optionsModel;
|
OptionsModel *optionsModel;
|
||||||
AddressTableModel *addressTableModel;
|
AddressTableModel *addressTableModel;
|
||||||
TransactionTableModel *transactionTableModel;
|
TransactionTableModel *transactionTableModel;
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
#include "optionsmodel.h"
|
#include "optionsmodel.h"
|
||||||
#include "main.h"
|
|
||||||
#include "net.h"
|
#include "headers.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
OptionsModel::OptionsModel(QObject *parent) :
|
OptionsModel::OptionsModel(CWallet *wallet, QObject *parent) :
|
||||||
QAbstractListModel(parent)
|
QAbstractListModel(parent),
|
||||||
|
wallet(wallet)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
|||||||
bool successful = true; /* set to false on parse error */
|
bool successful = true; /* set to false on parse error */
|
||||||
if(role == Qt::EditRole)
|
if(role == Qt::EditRole)
|
||||||
{
|
{
|
||||||
CWalletDB walletdb;
|
CWalletDB walletdb(wallet->strWalletFile);
|
||||||
switch(index.row())
|
switch(index.row())
|
||||||
{
|
{
|
||||||
case StartAtStartup:
|
case StartAtStartup:
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
class CWallet;
|
||||||
|
|
||||||
/* Interface from QT to configuration data structure for bitcoin client.
|
/* Interface from QT to configuration data structure for bitcoin client.
|
||||||
To QT, the options are presented as a list with the different options
|
To QT, the options are presented as a list with the different options
|
||||||
laid out vertically.
|
laid out vertically.
|
||||||
@ -13,7 +15,7 @@ class OptionsModel : public QAbstractListModel
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit OptionsModel(QObject *parent = 0);
|
explicit OptionsModel(CWallet *wallet, QObject *parent = 0);
|
||||||
|
|
||||||
enum OptionID {
|
enum OptionID {
|
||||||
StartAtStartup,
|
StartAtStartup,
|
||||||
@ -35,6 +37,9 @@ public:
|
|||||||
qint64 getTransactionFee();
|
qint64 getTransactionFee();
|
||||||
bool getMinimizeToTray();
|
bool getMinimizeToTray();
|
||||||
bool getMinimizeOnClose();
|
bool getMinimizeOnClose();
|
||||||
|
private:
|
||||||
|
// Wallet stores persistent options
|
||||||
|
CWallet *wallet;
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -70,10 +70,10 @@ static string FormatTxStatus(const CWalletTx& wtx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string TransactionDesc::toHTML(CWalletTx &wtx)
|
string TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||||
{
|
{
|
||||||
string strHTML;
|
string strHTML;
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(wallet->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
strHTML.reserve(4000);
|
strHTML.reserve(4000);
|
||||||
strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
|
strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
|
||||||
@ -122,19 +122,19 @@ string TransactionDesc::toHTML(CWalletTx &wtx)
|
|||||||
// Credit
|
// Credit
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
{
|
{
|
||||||
if (txout.IsMine())
|
if (wallet->IsMine(txout))
|
||||||
{
|
{
|
||||||
vector<unsigned char> vchPubKey;
|
vector<unsigned char> vchPubKey;
|
||||||
if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
|
if (ExtractPubKey(txout.scriptPubKey, wallet, vchPubKey))
|
||||||
{
|
{
|
||||||
string strAddress = PubKeyToAddress(vchPubKey);
|
string strAddress = PubKeyToAddress(vchPubKey);
|
||||||
if (mapAddressBook.count(strAddress))
|
if (wallet->mapAddressBook.count(strAddress))
|
||||||
{
|
{
|
||||||
strHTML += string() + _("<b>From:</b> ") + _("unknown") + "<br>";
|
strHTML += string() + _("<b>From:</b> ") + _("unknown") + "<br>";
|
||||||
strHTML += _("<b>To:</b> ");
|
strHTML += _("<b>To:</b> ");
|
||||||
strHTML += HtmlEscape(strAddress);
|
strHTML += HtmlEscape(strAddress);
|
||||||
if (!mapAddressBook[strAddress].empty())
|
if (!wallet->mapAddressBook[strAddress].empty())
|
||||||
strHTML += _(" (yours, label: ") + mapAddressBook[strAddress] + ")";
|
strHTML += _(" (yours, label: ") + wallet->mapAddressBook[strAddress] + ")";
|
||||||
else
|
else
|
||||||
strHTML += _(" (yours)");
|
strHTML += _(" (yours)");
|
||||||
strHTML += "<br>";
|
strHTML += "<br>";
|
||||||
@ -156,8 +156,8 @@ string TransactionDesc::toHTML(CWalletTx &wtx)
|
|||||||
// Online transaction
|
// Online transaction
|
||||||
strAddress = wtx.mapValue["to"];
|
strAddress = wtx.mapValue["to"];
|
||||||
strHTML += _("<b>To:</b> ");
|
strHTML += _("<b>To:</b> ");
|
||||||
if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
|
if (wallet->mapAddressBook.count(strAddress) && !wallet->mapAddressBook[strAddress].empty())
|
||||||
strHTML += mapAddressBook[strAddress] + " ";
|
strHTML += wallet->mapAddressBook[strAddress] + " ";
|
||||||
strHTML += HtmlEscape(strAddress) + "<br>";
|
strHTML += HtmlEscape(strAddress) + "<br>";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ string TransactionDesc::toHTML(CWalletTx &wtx)
|
|||||||
//
|
//
|
||||||
int64 nUnmatured = 0;
|
int64 nUnmatured = 0;
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
nUnmatured += txout.GetCredit();
|
nUnmatured += wallet->GetCredit(txout);
|
||||||
strHTML += _("<b>Credit:</b> ");
|
strHTML += _("<b>Credit:</b> ");
|
||||||
if (wtx.IsInMainChain())
|
if (wtx.IsInMainChain())
|
||||||
strHTML += strprintf(_("(%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());
|
strHTML += strprintf(_("(%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());
|
||||||
@ -191,11 +191,11 @@ string TransactionDesc::toHTML(CWalletTx &wtx)
|
|||||||
{
|
{
|
||||||
bool fAllFromMe = true;
|
bool fAllFromMe = true;
|
||||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||||
fAllFromMe = fAllFromMe && txin.IsMine();
|
fAllFromMe = fAllFromMe && wallet->IsMine(txin);
|
||||||
|
|
||||||
bool fAllToMe = true;
|
bool fAllToMe = true;
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
fAllToMe = fAllToMe && txout.IsMine();
|
fAllToMe = fAllToMe && wallet->IsMine(txout);
|
||||||
|
|
||||||
if (fAllFromMe)
|
if (fAllFromMe)
|
||||||
{
|
{
|
||||||
@ -204,7 +204,7 @@ string TransactionDesc::toHTML(CWalletTx &wtx)
|
|||||||
//
|
//
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
{
|
{
|
||||||
if (txout.IsMine())
|
if (wallet->IsMine(txout))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (wtx.mapValue["to"].empty())
|
if (wtx.mapValue["to"].empty())
|
||||||
@ -215,8 +215,8 @@ string TransactionDesc::toHTML(CWalletTx &wtx)
|
|||||||
{
|
{
|
||||||
string strAddress = Hash160ToAddress(hash160);
|
string strAddress = Hash160ToAddress(hash160);
|
||||||
strHTML += _("<b>To:</b> ");
|
strHTML += _("<b>To:</b> ");
|
||||||
if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
|
if (wallet->mapAddressBook.count(strAddress) && !wallet->mapAddressBook[strAddress].empty())
|
||||||
strHTML += mapAddressBook[strAddress] + " ";
|
strHTML += wallet->mapAddressBook[strAddress] + " ";
|
||||||
strHTML += strAddress;
|
strHTML += strAddress;
|
||||||
strHTML += "<br>";
|
strHTML += "<br>";
|
||||||
}
|
}
|
||||||
@ -244,11 +244,11 @@ string TransactionDesc::toHTML(CWalletTx &wtx)
|
|||||||
// Mixed debit transaction
|
// Mixed debit transaction
|
||||||
//
|
//
|
||||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||||
if (txin.IsMine())
|
if (wallet->IsMine(txin))
|
||||||
strHTML += _("<b>Debit:</b> ") + FormatMoney(-txin.GetDebit()) + "<br>";
|
strHTML += _("<b>Debit:</b> ") + FormatMoney(-wallet->GetDebit(txin)) + "<br>";
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
if (txout.IsMine())
|
if (wallet->IsMine(txout))
|
||||||
strHTML += _("<b>Credit:</b> ") + FormatMoney(txout.GetCredit()) + "<br>";
|
strHTML += _("<b>Credit:</b> ") + FormatMoney(wallet->GetCredit(txout)) + "<br>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,30 +274,30 @@ string TransactionDesc::toHTML(CWalletTx &wtx)
|
|||||||
{
|
{
|
||||||
strHTML += "<hr><br>debug print<br><br>";
|
strHTML += "<hr><br>debug print<br><br>";
|
||||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||||
if (txin.IsMine())
|
if(wallet->IsMine(txin))
|
||||||
strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";
|
strHTML += "<b>Debit:</b> " + FormatMoney(-wallet->IsMine(txin)) + "<br>";
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
if (txout.IsMine())
|
if(wallet->IsMine(txout))
|
||||||
strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";
|
strHTML += "<b>Credit:</b> " + FormatMoney(wallet->IsMine(txout)) + "<br>";
|
||||||
|
|
||||||
strHTML += "<br><b>Transaction:</b><br>";
|
strHTML += "<br><b>Transaction:</b><br>";
|
||||||
strHTML += HtmlEscape(wtx.ToString(), true);
|
strHTML += HtmlEscape(wtx.ToString(), true);
|
||||||
|
|
||||||
strHTML += "<br><b>Inputs:</b><br>";
|
strHTML += "<br><b>Inputs:</b><br>";
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(wallet->cs_mapWallet)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||||
{
|
{
|
||||||
COutPoint prevout = txin.prevout;
|
COutPoint prevout = txin.prevout;
|
||||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
|
map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(prevout.hash);
|
||||||
if (mi != mapWallet.end())
|
if (mi != wallet->mapWallet.end())
|
||||||
{
|
{
|
||||||
const CWalletTx& prev = (*mi).second;
|
const CWalletTx& prev = (*mi).second;
|
||||||
if (prevout.n < prev.vout.size())
|
if (prevout.n < prev.vout.size())
|
||||||
{
|
{
|
||||||
strHTML += HtmlEscape(prev.ToString(), true);
|
strHTML += HtmlEscape(prev.ToString(), true);
|
||||||
strHTML += " " + FormatTxStatus(prev) + ", ";
|
strHTML += " " + FormatTxStatus(prev) + ", ";
|
||||||
strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "<br>";
|
strHTML = strHTML + "IsMine=" + (wallet->IsMine(prev.vout[prevout.n]) ? "true" : "false") + "<br>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
class CWallet;
|
||||||
class CWalletTx;
|
class CWalletTx;
|
||||||
|
|
||||||
class TransactionDesc
|
class TransactionDesc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* Provide human-readable extended HTML description of a transaction */
|
/* Provide human-readable extended HTML description of a transaction */
|
||||||
static std::string toHTML(CWalletTx &wtx);
|
static std::string toHTML(CWallet *wallet, CWalletTx &wtx);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRANSACTIONDESC_H
|
#endif // TRANSACTIONDESC_H
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "transactionrecord.h"
|
#include "transactionrecord.h"
|
||||||
|
|
||||||
|
#include "headers.h"
|
||||||
|
|
||||||
/* Return positive answer if transaction should be shown in list.
|
/* Return positive answer if transaction should be shown in list.
|
||||||
*/
|
*/
|
||||||
@ -29,7 +30,7 @@ bool TransactionRecord::showTransaction(const CWalletTx &wtx)
|
|||||||
/*
|
/*
|
||||||
* Decompose CWallet transaction to model transaction records.
|
* Decompose CWallet transaction to model transaction records.
|
||||||
*/
|
*/
|
||||||
QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWalletTx &wtx)
|
QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
|
||||||
{
|
{
|
||||||
QList<TransactionRecord> parts;
|
QList<TransactionRecord> parts;
|
||||||
int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime();
|
int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime();
|
||||||
@ -59,7 +60,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWalletTx
|
|||||||
{
|
{
|
||||||
int64 nUnmatured = 0;
|
int64 nUnmatured = 0;
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
nUnmatured += txout.GetCredit();
|
nUnmatured += wallet->GetCredit(txout);
|
||||||
sub.credit = nUnmatured;
|
sub.credit = nUnmatured;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,10 +77,10 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWalletTx
|
|||||||
sub.type = TransactionRecord::RecvWithAddress;
|
sub.type = TransactionRecord::RecvWithAddress;
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
{
|
{
|
||||||
if (txout.IsMine())
|
if(wallet->IsMine(txout))
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> vchPubKey;
|
std::vector<unsigned char> vchPubKey;
|
||||||
if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
|
if (ExtractPubKey(txout.scriptPubKey, wallet, vchPubKey))
|
||||||
{
|
{
|
||||||
sub.address = PubKeyToAddress(vchPubKey);
|
sub.address = PubKeyToAddress(vchPubKey);
|
||||||
}
|
}
|
||||||
@ -93,11 +94,11 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWalletTx
|
|||||||
{
|
{
|
||||||
bool fAllFromMe = true;
|
bool fAllFromMe = true;
|
||||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||||
fAllFromMe = fAllFromMe && txin.IsMine();
|
fAllFromMe = fAllFromMe && wallet->IsMine(txin);
|
||||||
|
|
||||||
bool fAllToMe = true;
|
bool fAllToMe = true;
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
fAllToMe = fAllToMe && txout.IsMine();
|
fAllToMe = fAllToMe && wallet->IsMine(txout);
|
||||||
|
|
||||||
if (fAllFromMe && fAllToMe)
|
if (fAllFromMe && fAllToMe)
|
||||||
{
|
{
|
||||||
@ -120,13 +121,13 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWalletTx
|
|||||||
TransactionRecord sub(hash, nTime);
|
TransactionRecord sub(hash, nTime);
|
||||||
sub.idx = parts.size();
|
sub.idx = parts.size();
|
||||||
|
|
||||||
if (txout.IsMine())
|
if(wallet->IsMine(txout))
|
||||||
{
|
{
|
||||||
// Ignore parts sent to self, as this is usually the change
|
// Ignore parts sent to self, as this is usually the change
|
||||||
// from a transaction sent back to our own address.
|
// from a transaction sent back to our own address.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (!mapValue["to"].empty())
|
else if(!mapValue["to"].empty())
|
||||||
{
|
{
|
||||||
// Sent to IP
|
// Sent to IP
|
||||||
sub.type = TransactionRecord::SendToIP;
|
sub.type = TransactionRecord::SendToIP;
|
||||||
@ -160,9 +161,9 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWalletTx
|
|||||||
//
|
//
|
||||||
bool fAllMine = true;
|
bool fAllMine = true;
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
fAllMine = fAllMine && txout.IsMine();
|
fAllMine = fAllMine && wallet->IsMine(txout);
|
||||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||||
fAllMine = fAllMine && txin.IsMine();
|
fAllMine = fAllMine && wallet->IsMine(txin);
|
||||||
|
|
||||||
parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
|
parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
|
class CWallet;
|
||||||
|
|
||||||
class TransactionStatus
|
class TransactionStatus
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -84,7 +86,7 @@ public:
|
|||||||
/* Decompose CWallet transaction to model transaction records.
|
/* Decompose CWallet transaction to model transaction records.
|
||||||
*/
|
*/
|
||||||
static bool showTransaction(const CWalletTx &wtx);
|
static bool showTransaction(const CWalletTx &wtx);
|
||||||
static QList<TransactionRecord> decomposeTransaction(const CWalletTx &wtx);
|
static QList<TransactionRecord> decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx);
|
||||||
|
|
||||||
/* Fixed */
|
/* Fixed */
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
#include "transactionrecord.h"
|
#include "transactionrecord.h"
|
||||||
#include "guiconstants.h"
|
#include "guiconstants.h"
|
||||||
#include "main.h"
|
|
||||||
#include "transactiondesc.h"
|
#include "transactiondesc.h"
|
||||||
|
|
||||||
|
#include "headers.h"
|
||||||
|
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@ -37,11 +38,12 @@ struct TxLessThan
|
|||||||
// Private implementation
|
// Private implementation
|
||||||
struct TransactionTablePriv
|
struct TransactionTablePriv
|
||||||
{
|
{
|
||||||
TransactionTablePriv(TransactionTableModel *parent):
|
TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent):
|
||||||
|
wallet(wallet),
|
||||||
parent(parent)
|
parent(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
CWallet *wallet;
|
||||||
TransactionTableModel *parent;
|
TransactionTableModel *parent;
|
||||||
|
|
||||||
/* Local cache of wallet.
|
/* Local cache of wallet.
|
||||||
@ -58,11 +60,11 @@ struct TransactionTablePriv
|
|||||||
qDebug() << "refreshWallet";
|
qDebug() << "refreshWallet";
|
||||||
#endif
|
#endif
|
||||||
cachedWallet.clear();
|
cachedWallet.clear();
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(wallet->cs_mapWallet)
|
||||||
{
|
{
|
||||||
for(std::map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for(std::map<uint256, CWalletTx>::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
cachedWallet.append(TransactionRecord::decomposeTransaction(it->second));
|
cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,14 +86,14 @@ struct TransactionTablePriv
|
|||||||
QList<uint256> updated_sorted = updated;
|
QList<uint256> updated_sorted = updated;
|
||||||
qSort(updated_sorted);
|
qSort(updated_sorted);
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(wallet->cs_mapWallet)
|
||||||
{
|
{
|
||||||
for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx)
|
for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx)
|
||||||
{
|
{
|
||||||
const uint256 &hash = updated_sorted.at(update_idx);
|
const uint256 &hash = updated_sorted.at(update_idx);
|
||||||
/* Find transaction in wallet */
|
/* Find transaction in wallet */
|
||||||
std::map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
|
||||||
bool inWallet = mi != mapWallet.end();
|
bool inWallet = mi != wallet->mapWallet.end();
|
||||||
/* Find bounds of this transaction in model */
|
/* Find bounds of this transaction in model */
|
||||||
QList<TransactionRecord>::iterator lower = qLowerBound(
|
QList<TransactionRecord>::iterator lower = qLowerBound(
|
||||||
cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
|
cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
|
||||||
@ -100,6 +102,7 @@ struct TransactionTablePriv
|
|||||||
int lowerIndex = (lower - cachedWallet.begin());
|
int lowerIndex = (lower - cachedWallet.begin());
|
||||||
int upperIndex = (upper - cachedWallet.begin());
|
int upperIndex = (upper - cachedWallet.begin());
|
||||||
|
|
||||||
|
// Determine if transaction is in model already
|
||||||
bool inModel = false;
|
bool inModel = false;
|
||||||
if(lower != upper)
|
if(lower != upper)
|
||||||
{
|
{
|
||||||
@ -115,7 +118,7 @@ struct TransactionTablePriv
|
|||||||
{
|
{
|
||||||
// Added -- insert at the right position
|
// Added -- insert at the right position
|
||||||
QList<TransactionRecord> toInsert =
|
QList<TransactionRecord> toInsert =
|
||||||
TransactionRecord::decomposeTransaction(mi->second);
|
TransactionRecord::decomposeTransaction(wallet, mi->second);
|
||||||
if(!toInsert.isEmpty()) /* only if something to insert */
|
if(!toInsert.isEmpty()) /* only if something to insert */
|
||||||
{
|
{
|
||||||
parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
|
parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
|
||||||
@ -159,11 +162,11 @@ struct TransactionTablePriv
|
|||||||
// simply re-use the cached status.
|
// simply re-use the cached status.
|
||||||
if(rec->statusUpdateNeeded())
|
if(rec->statusUpdateNeeded())
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(wallet->cs_mapWallet)
|
||||||
{
|
{
|
||||||
std::map<uint256, CWalletTx>::iterator mi = mapWallet.find(rec->hash);
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
|
||||||
|
|
||||||
if(mi != mapWallet.end())
|
if(mi != wallet->mapWallet.end())
|
||||||
{
|
{
|
||||||
rec->updateStatus(mi->second);
|
rec->updateStatus(mi->second);
|
||||||
}
|
}
|
||||||
@ -179,12 +182,12 @@ struct TransactionTablePriv
|
|||||||
|
|
||||||
QString describe(TransactionRecord *rec)
|
QString describe(TransactionRecord *rec)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(wallet->cs_mapWallet)
|
||||||
{
|
{
|
||||||
std::map<uint256, CWalletTx>::iterator mi = mapWallet.find(rec->hash);
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
|
||||||
if(mi != mapWallet.end())
|
if(mi != wallet->mapWallet.end())
|
||||||
{
|
{
|
||||||
return QString::fromStdString(TransactionDesc::toHTML(mi->second));
|
return QString::fromStdString(TransactionDesc::toHTML(wallet, mi->second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QString("");
|
return QString("");
|
||||||
@ -202,9 +205,10 @@ static int column_alignments[] = {
|
|||||||
Qt::AlignLeft|Qt::AlignVCenter
|
Qt::AlignLeft|Qt::AlignVCenter
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionTableModel::TransactionTableModel(QObject *parent):
|
TransactionTableModel::TransactionTableModel(CWallet* wallet, QObject *parent):
|
||||||
QAbstractTableModel(parent),
|
QAbstractTableModel(parent),
|
||||||
priv(new TransactionTablePriv(this))
|
wallet(wallet),
|
||||||
|
priv(new TransactionTablePriv(wallet, this))
|
||||||
{
|
{
|
||||||
columns << tr("Status") << tr("Date") << tr("Description") << tr("Debit") << tr("Credit");
|
columns << tr("Status") << tr("Date") << tr("Description") << tr("Debit") << tr("Credit");
|
||||||
|
|
||||||
@ -225,15 +229,15 @@ void TransactionTableModel::update()
|
|||||||
QList<uint256> updated;
|
QList<uint256> updated;
|
||||||
|
|
||||||
// Check if there are changes to wallet map
|
// Check if there are changes to wallet map
|
||||||
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
TRY_CRITICAL_BLOCK(wallet->cs_mapWallet)
|
||||||
{
|
{
|
||||||
if(!vWalletUpdated.empty())
|
if(!wallet->vWalletUpdated.empty())
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(uint256 hash, vWalletUpdated)
|
BOOST_FOREACH(uint256 hash, wallet->vWalletUpdated)
|
||||||
{
|
{
|
||||||
updated.append(hash);
|
updated.append(hash);
|
||||||
}
|
}
|
||||||
vWalletUpdated.clear();
|
wallet->vWalletUpdated.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,13 +306,13 @@ QVariant TransactionTableModel::formatTxDate(const TransactionRecord *wtx) const
|
|||||||
address[0:12]... (label)
|
address[0:12]... (label)
|
||||||
otherwise just return address
|
otherwise just return address
|
||||||
*/
|
*/
|
||||||
std::string lookupAddress(const std::string &address)
|
std::string TransactionTableModel::lookupAddress(const std::string &address) const
|
||||||
{
|
{
|
||||||
std::string description;
|
std::string description;
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(wallet->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string>::iterator mi = mapAddressBook.find(address);
|
std::map<std::string, std::string>::iterator mi = wallet->mapAddressBook.find(address);
|
||||||
if (mi != mapAddressBook.end() && !(*mi).second.empty())
|
if (mi != wallet->mapAddressBook.end() && !(*mi).second.empty())
|
||||||
{
|
{
|
||||||
std::string label = (*mi).second;
|
std::string label = (*mi).second;
|
||||||
description += address.substr(0,12) + "... ";
|
description += address.substr(0,12) + "... ";
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
|
class CWallet;
|
||||||
class TransactionTablePriv;
|
class TransactionTablePriv;
|
||||||
class TransactionRecord;
|
class TransactionRecord;
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ class TransactionTableModel : public QAbstractTableModel
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TransactionTableModel(QObject *parent = 0);
|
explicit TransactionTableModel(CWallet* wallet, QObject *parent = 0);
|
||||||
~TransactionTableModel();
|
~TransactionTableModel();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -39,9 +40,11 @@ public:
|
|||||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||||
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
|
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
|
||||||
private:
|
private:
|
||||||
|
CWallet* wallet;
|
||||||
QStringList columns;
|
QStringList columns;
|
||||||
TransactionTablePriv *priv;
|
TransactionTablePriv *priv;
|
||||||
|
|
||||||
|
std::string lookupAddress(const std::string &address) const;
|
||||||
QVariant formatTxStatus(const TransactionRecord *wtx) const;
|
QVariant formatTxStatus(const TransactionRecord *wtx) const;
|
||||||
QVariant formatTxDate(const TransactionRecord *wtx) const;
|
QVariant formatTxDate(const TransactionRecord *wtx) const;
|
||||||
QVariant formatTxDescription(const TransactionRecord *wtx) const;
|
QVariant formatTxDescription(const TransactionRecord *wtx) const;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/function/function0.hpp>
|
#include <boost/function/function0.hpp>
|
||||||
|
#include "wallet.h"
|
||||||
|
|
||||||
typedef void wxWindow;
|
typedef void wxWindow;
|
||||||
#define wxYES 0x00000002
|
#define wxYES 0x00000002
|
||||||
|
149
src/rpc.cpp
149
src/rpc.cpp
@ -14,6 +14,7 @@
|
|||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
#include <boost/asio/ssl.hpp>
|
#include <boost/asio/ssl.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
|
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
|
||||||
#endif
|
#endif
|
||||||
@ -264,14 +265,14 @@ Value setgenerate(const Array& params, bool fHelp)
|
|||||||
{
|
{
|
||||||
int nGenProcLimit = params[1].get_int();
|
int nGenProcLimit = params[1].get_int();
|
||||||
fLimitProcessors = (nGenProcLimit != -1);
|
fLimitProcessors = (nGenProcLimit != -1);
|
||||||
CWalletDB().WriteSetting("fLimitProcessors", fLimitProcessors);
|
WriteSetting("fLimitProcessors", fLimitProcessors);
|
||||||
if (nGenProcLimit != -1)
|
if (nGenProcLimit != -1)
|
||||||
CWalletDB().WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
|
WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
|
||||||
if (nGenProcLimit == 0)
|
if (nGenProcLimit == 0)
|
||||||
fGenerate = false;
|
fGenerate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateBitcoins(fGenerate);
|
GenerateBitcoins(fGenerate, pwalletMain);
|
||||||
return Value::null;
|
return Value::null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +299,7 @@ Value getinfo(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
Object obj;
|
Object obj;
|
||||||
obj.push_back(Pair("version", (int)VERSION));
|
obj.push_back(Pair("version", (int)VERSION));
|
||||||
obj.push_back(Pair("balance", ValueFromAmount(GetBalance())));
|
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
|
||||||
obj.push_back(Pair("blocks", (int)nBestHeight));
|
obj.push_back(Pair("blocks", (int)nBestHeight));
|
||||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||||
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
|
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
|
||||||
@ -307,7 +308,7 @@ Value getinfo(const Array& params, bool fHelp)
|
|||||||
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
||||||
obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
|
obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
|
||||||
obj.push_back(Pair("testnet", fTestNet));
|
obj.push_back(Pair("testnet", fTestNet));
|
||||||
obj.push_back(Pair("keypoololdest", (boost::int64_t)GetOldestKeyPoolTime()));
|
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
||||||
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
|
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
|
||||||
obj.push_back(Pair("errors", GetWarnings("statusbar")));
|
obj.push_back(Pair("errors", GetWarnings("statusbar")));
|
||||||
return obj;
|
return obj;
|
||||||
@ -329,9 +330,9 @@ Value getnewaddress(const Array& params, bool fHelp)
|
|||||||
strAccount = AccountFromValue(params[0]);
|
strAccount = AccountFromValue(params[0]);
|
||||||
|
|
||||||
// Generate a new key that is added to wallet
|
// Generate a new key that is added to wallet
|
||||||
string strAddress = PubKeyToAddress(GetKeyFromKeyPool());
|
string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool());
|
||||||
|
|
||||||
SetAddressBookName(strAddress, strAccount);
|
pwalletMain->SetAddressBookName(strAddress, strAccount);
|
||||||
return strAddress;
|
return strAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +342,7 @@ string GetAccountAddress(string strAccount, bool bForceNew=false)
|
|||||||
{
|
{
|
||||||
string strAddress;
|
string strAddress;
|
||||||
|
|
||||||
CWalletDB walletdb;
|
CWalletDB walletdb(pwalletMain->strWalletFile);
|
||||||
walletdb.TxnBegin();
|
walletdb.TxnBegin();
|
||||||
|
|
||||||
CAccount account;
|
CAccount account;
|
||||||
@ -352,8 +353,8 @@ string GetAccountAddress(string strAccount, bool bForceNew=false)
|
|||||||
{
|
{
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
scriptPubKey.SetBitcoinAddress(account.vchPubKey);
|
scriptPubKey.SetBitcoinAddress(account.vchPubKey);
|
||||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin();
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
|
||||||
it != mapWallet.end() && !account.vchPubKey.empty();
|
it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
const CWalletTx& wtx = (*it).second;
|
const CWalletTx& wtx = (*it).second;
|
||||||
@ -366,9 +367,9 @@ string GetAccountAddress(string strAccount, bool bForceNew=false)
|
|||||||
// Generate a new key
|
// Generate a new key
|
||||||
if (account.vchPubKey.empty() || bForceNew)
|
if (account.vchPubKey.empty() || bForceNew)
|
||||||
{
|
{
|
||||||
account.vchPubKey = GetKeyFromKeyPool();
|
account.vchPubKey = pwalletMain->GetKeyFromKeyPool();
|
||||||
string strAddress = PubKeyToAddress(account.vchPubKey);
|
string strAddress = PubKeyToAddress(account.vchPubKey);
|
||||||
SetAddressBookName(strAddress, strAccount);
|
pwalletMain->SetAddressBookName(strAddress, strAccount);
|
||||||
walletdb.WriteAccount(strAccount, account);
|
walletdb.WriteAccount(strAccount, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +392,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
|
|||||||
Value ret;
|
Value ret;
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
CRITICAL_BLOCK(cs_main)
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
ret = GetAccountAddress(strAccount);
|
ret = GetAccountAddress(strAccount);
|
||||||
}
|
}
|
||||||
@ -421,18 +422,18 @@ Value setaccount(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
// Detect when changing the account of an address that is the 'unused current key' of another account:
|
// Detect when changing the account of an address that is the 'unused current key' of another account:
|
||||||
CRITICAL_BLOCK(cs_main)
|
CRITICAL_BLOCK(cs_main)
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
if (mapAddressBook.count(strAddress))
|
if (pwalletMain->mapAddressBook.count(strAddress))
|
||||||
{
|
{
|
||||||
string strOldAccount = mapAddressBook[strAddress];
|
string strOldAccount = pwalletMain->mapAddressBook[strAddress];
|
||||||
if (strAddress == GetAccountAddress(strOldAccount))
|
if (strAddress == GetAccountAddress(strOldAccount))
|
||||||
GetAccountAddress(strOldAccount, true);
|
GetAccountAddress(strOldAccount, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetAddressBookName(strAddress, strAccount);
|
pwalletMain->SetAddressBookName(strAddress, strAccount);
|
||||||
return Value::null;
|
return Value::null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,10 +448,10 @@ Value getaccount(const Array& params, bool fHelp)
|
|||||||
string strAddress = params[0].get_str();
|
string strAddress = params[0].get_str();
|
||||||
|
|
||||||
string strAccount;
|
string strAccount;
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
map<string, string>::iterator mi = mapAddressBook.find(strAddress);
|
map<string, string>::iterator mi = pwalletMain->mapAddressBook.find(strAddress);
|
||||||
if (mi != mapAddressBook.end() && !(*mi).second.empty())
|
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
|
||||||
strAccount = (*mi).second;
|
strAccount = (*mi).second;
|
||||||
}
|
}
|
||||||
return strAccount;
|
return strAccount;
|
||||||
@ -468,9 +469,9 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
// Find all addresses that have the given account
|
// Find all addresses that have the given account
|
||||||
Array ret;
|
Array ret;
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapAddressBook)
|
BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook)
|
||||||
{
|
{
|
||||||
const string& strAddress = item.first;
|
const string& strAddress = item.first;
|
||||||
const string& strName = item.second;
|
const string& strName = item.second;
|
||||||
@ -523,7 +524,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
CRITICAL_BLOCK(cs_main)
|
||||||
{
|
{
|
||||||
string strError = SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
|
string strError = pwalletMain->SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
|
||||||
if (strError != "")
|
if (strError != "")
|
||||||
throw JSONRPCError(-4, strError);
|
throw JSONRPCError(-4, strError);
|
||||||
}
|
}
|
||||||
@ -544,7 +545,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
|||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
if (!scriptPubKey.SetBitcoinAddress(strAddress))
|
if (!scriptPubKey.SetBitcoinAddress(strAddress))
|
||||||
throw JSONRPCError(-5, "Invalid bitcoin address");
|
throw JSONRPCError(-5, "Invalid bitcoin address");
|
||||||
if (!IsMine(scriptPubKey))
|
if (!IsMine(*pwalletMain,scriptPubKey))
|
||||||
return (double)0.0;
|
return (double)0.0;
|
||||||
|
|
||||||
// Minimum confirmations
|
// Minimum confirmations
|
||||||
@ -554,9 +555,9 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
// Tally
|
// Tally
|
||||||
int64 nAmount = 0;
|
int64 nAmount = 0;
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx& wtx = (*it).second;
|
const CWalletTx& wtx = (*it).second;
|
||||||
if (wtx.IsCoinBase() || !wtx.IsFinal())
|
if (wtx.IsCoinBase() || !wtx.IsFinal())
|
||||||
@ -575,9 +576,9 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey)
|
void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapAddressBook)
|
BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook)
|
||||||
{
|
{
|
||||||
const string& strAddress = item.first;
|
const string& strAddress = item.first;
|
||||||
const string& strName = item.second;
|
const string& strName = item.second;
|
||||||
@ -586,7 +587,7 @@ void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey)
|
|||||||
// We're only counting our own valid bitcoin addresses and not ip addresses
|
// We're only counting our own valid bitcoin addresses and not ip addresses
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
if (scriptPubKey.SetBitcoinAddress(strAddress))
|
if (scriptPubKey.SetBitcoinAddress(strAddress))
|
||||||
if (IsMine(scriptPubKey))
|
if (IsMine(*pwalletMain,scriptPubKey))
|
||||||
setPubKey.insert(scriptPubKey);
|
setPubKey.insert(scriptPubKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -613,9 +614,9 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
// Tally
|
// Tally
|
||||||
int64 nAmount = 0;
|
int64 nAmount = 0;
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx& wtx = (*it).second;
|
const CWalletTx& wtx = (*it).second;
|
||||||
if (wtx.IsCoinBase() || !wtx.IsFinal())
|
if (wtx.IsCoinBase() || !wtx.IsFinal())
|
||||||
@ -635,10 +636,10 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
|
|||||||
int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
|
int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
|
||||||
{
|
{
|
||||||
int64 nBalance = 0;
|
int64 nBalance = 0;
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
// Tally wallet transactions
|
// Tally wallet transactions
|
||||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx& wtx = (*it).second;
|
const CWalletTx& wtx = (*it).second;
|
||||||
if (!wtx.IsFinal())
|
if (!wtx.IsFinal())
|
||||||
@ -661,7 +662,7 @@ int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinD
|
|||||||
|
|
||||||
int64 GetAccountBalance(const string& strAccount, int nMinDepth)
|
int64 GetAccountBalance(const string& strAccount, int nMinDepth)
|
||||||
{
|
{
|
||||||
CWalletDB walletdb;
|
CWalletDB walletdb(pwalletMain->strWalletFile);
|
||||||
return GetAccountBalance(walletdb, strAccount, nMinDepth);
|
return GetAccountBalance(walletdb, strAccount, nMinDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,7 +676,7 @@ Value getbalance(const Array& params, bool fHelp)
|
|||||||
"If [account] is specified, returns the balance in the account.");
|
"If [account] is specified, returns the balance in the account.");
|
||||||
|
|
||||||
if (params.size() == 0)
|
if (params.size() == 0)
|
||||||
return ValueFromAmount(GetBalance());
|
return ValueFromAmount(pwalletMain->GetBalance());
|
||||||
|
|
||||||
int nMinDepth = 1;
|
int nMinDepth = 1;
|
||||||
if (params.size() > 1)
|
if (params.size() > 1)
|
||||||
@ -686,7 +687,7 @@ Value getbalance(const Array& params, bool fHelp)
|
|||||||
// (GetBalance() sums up all unspent TxOuts)
|
// (GetBalance() sums up all unspent TxOuts)
|
||||||
// getbalance and getbalance '*' should always return the same number.
|
// getbalance and getbalance '*' should always return the same number.
|
||||||
int64 nBalance = 0;
|
int64 nBalance = 0;
|
||||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx& wtx = (*it).second;
|
const CWalletTx& wtx = (*it).second;
|
||||||
if (!wtx.IsFinal())
|
if (!wtx.IsFinal())
|
||||||
@ -734,9 +735,9 @@ Value movecmd(const Array& params, bool fHelp)
|
|||||||
if (params.size() > 4)
|
if (params.size() > 4)
|
||||||
strComment = params[4].get_str();
|
strComment = params[4].get_str();
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
CWalletDB walletdb;
|
CWalletDB walletdb(pwalletMain->strWalletFile);
|
||||||
walletdb.TxnBegin();
|
walletdb.TxnBegin();
|
||||||
|
|
||||||
int64 nNow = GetAdjustedTime();
|
int64 nNow = GetAdjustedTime();
|
||||||
@ -787,7 +788,7 @@ Value sendfrom(const Array& params, bool fHelp)
|
|||||||
wtx.mapValue["to"] = params[5].get_str();
|
wtx.mapValue["to"] = params[5].get_str();
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
CRITICAL_BLOCK(cs_main)
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
// Check funds
|
// Check funds
|
||||||
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
|
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
|
||||||
@ -795,7 +796,7 @@ Value sendfrom(const Array& params, bool fHelp)
|
|||||||
throw JSONRPCError(-6, "Account has insufficient funds");
|
throw JSONRPCError(-6, "Account has insufficient funds");
|
||||||
|
|
||||||
// Send
|
// Send
|
||||||
string strError = SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
|
string strError = pwalletMain->SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
|
||||||
if (strError != "")
|
if (strError != "")
|
||||||
throw JSONRPCError(-4, strError);
|
throw JSONRPCError(-4, strError);
|
||||||
}
|
}
|
||||||
@ -844,7 +845,7 @@ Value sendmany(const Array& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
CRITICAL_BLOCK(cs_main)
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
// Check funds
|
// Check funds
|
||||||
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
|
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
|
||||||
@ -852,16 +853,16 @@ Value sendmany(const Array& params, bool fHelp)
|
|||||||
throw JSONRPCError(-6, "Account has insufficient funds");
|
throw JSONRPCError(-6, "Account has insufficient funds");
|
||||||
|
|
||||||
// Send
|
// Send
|
||||||
CReserveKey keyChange;
|
CReserveKey keyChange(pwalletMain);
|
||||||
int64 nFeeRequired = 0;
|
int64 nFeeRequired = 0;
|
||||||
bool fCreated = CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
|
bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
|
||||||
if (!fCreated)
|
if (!fCreated)
|
||||||
{
|
{
|
||||||
if (totalAmount + nFeeRequired > GetBalance())
|
if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
|
||||||
throw JSONRPCError(-6, "Insufficient funds");
|
throw JSONRPCError(-6, "Insufficient funds");
|
||||||
throw JSONRPCError(-4, "Transaction creation failed");
|
throw JSONRPCError(-4, "Transaction creation failed");
|
||||||
}
|
}
|
||||||
if (!CommitTransaction(wtx, keyChange))
|
if (!pwalletMain->CommitTransaction(wtx, keyChange))
|
||||||
throw JSONRPCError(-4, "Transaction commit failed");
|
throw JSONRPCError(-4, "Transaction commit failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,9 +895,9 @@ Value ListReceived(const Array& params, bool fByAccounts)
|
|||||||
|
|
||||||
// Tally
|
// Tally
|
||||||
map<uint160, tallyitem> mapTally;
|
map<uint160, tallyitem> mapTally;
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx& wtx = (*it).second;
|
const CWalletTx& wtx = (*it).second;
|
||||||
if (wtx.IsCoinBase() || !wtx.IsFinal())
|
if (wtx.IsCoinBase() || !wtx.IsFinal())
|
||||||
@ -923,9 +924,9 @@ Value ListReceived(const Array& params, bool fByAccounts)
|
|||||||
// Reply
|
// Reply
|
||||||
Array ret;
|
Array ret;
|
||||||
map<string, tallyitem> mapAccountTally;
|
map<string, tallyitem> mapAccountTally;
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapAddressBook)
|
BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook)
|
||||||
{
|
{
|
||||||
const string& strAddress = item.first;
|
const string& strAddress = item.first;
|
||||||
const string& strAccount = item.second;
|
const string& strAccount = item.second;
|
||||||
@ -1061,13 +1062,13 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
|||||||
|
|
||||||
// Received
|
// Received
|
||||||
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
|
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const PAIRTYPE(string, int64)& r, listReceived)
|
BOOST_FOREACH(const PAIRTYPE(string, int64)& r, listReceived)
|
||||||
{
|
{
|
||||||
string account;
|
string account;
|
||||||
if (mapAddressBook.count(r.first))
|
if (pwalletMain->mapAddressBook.count(r.first))
|
||||||
account = mapAddressBook[r.first];
|
account = pwalletMain->mapAddressBook[r.first];
|
||||||
if (fAllAccounts || (account == strAccount))
|
if (fAllAccounts || (account == strAccount))
|
||||||
{
|
{
|
||||||
Object entry;
|
Object entry;
|
||||||
@ -1119,16 +1120,16 @@ Value listtransactions(const Array& params, bool fHelp)
|
|||||||
nFrom = params[2].get_int();
|
nFrom = params[2].get_int();
|
||||||
|
|
||||||
Array ret;
|
Array ret;
|
||||||
CWalletDB walletdb;
|
CWalletDB walletdb(pwalletMain->strWalletFile);
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
// Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
|
// Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
|
||||||
typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
|
typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
|
||||||
typedef multimap<int64, TxPair > TxItems;
|
typedef multimap<int64, TxPair > TxItems;
|
||||||
TxItems txByTime;
|
TxItems txByTime;
|
||||||
|
|
||||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
CWalletTx* wtx = &((*it).second);
|
CWalletTx* wtx = &((*it).second);
|
||||||
txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
|
txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
|
||||||
@ -1180,16 +1181,16 @@ Value listaccounts(const Array& params, bool fHelp)
|
|||||||
nMinDepth = params[0].get_int();
|
nMinDepth = params[0].get_int();
|
||||||
|
|
||||||
map<string, int64> mapAccountBalances;
|
map<string, int64> mapAccountBalances;
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const PAIRTYPE(string, string)& entry, mapAddressBook) {
|
BOOST_FOREACH(const PAIRTYPE(string, string)& entry, pwalletMain->mapAddressBook) {
|
||||||
uint160 hash160;
|
uint160 hash160;
|
||||||
if(AddressToHash160(entry.first, hash160) && mapPubKeys.count(hash160)) // This address belongs to me
|
if(AddressToHash160(entry.first, hash160) && mapPubKeys.count(hash160)) // This address belongs to me
|
||||||
mapAccountBalances[entry.second] = 0;
|
mapAccountBalances[entry.second] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx& wtx = (*it).second;
|
const CWalletTx& wtx = (*it).second;
|
||||||
int64 nGeneratedImmature, nGeneratedMature, nFee;
|
int64 nGeneratedImmature, nGeneratedMature, nFee;
|
||||||
@ -1204,8 +1205,8 @@ Value listaccounts(const Array& params, bool fHelp)
|
|||||||
{
|
{
|
||||||
mapAccountBalances[""] += nGeneratedMature;
|
mapAccountBalances[""] += nGeneratedMature;
|
||||||
BOOST_FOREACH(const PAIRTYPE(string, int64)& r, listReceived)
|
BOOST_FOREACH(const PAIRTYPE(string, int64)& r, listReceived)
|
||||||
if (mapAddressBook.count(r.first))
|
if (pwalletMain->mapAddressBook.count(r.first))
|
||||||
mapAccountBalances[mapAddressBook[r.first]] += r.second;
|
mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
|
||||||
else
|
else
|
||||||
mapAccountBalances[""] += r.second;
|
mapAccountBalances[""] += r.second;
|
||||||
}
|
}
|
||||||
@ -1213,7 +1214,7 @@ Value listaccounts(const Array& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list<CAccountingEntry> acentries;
|
list<CAccountingEntry> acentries;
|
||||||
CWalletDB().ListAccountCreditDebit("*", acentries);
|
CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries);
|
||||||
BOOST_FOREACH(const CAccountingEntry& entry, acentries)
|
BOOST_FOREACH(const CAccountingEntry& entry, acentries)
|
||||||
mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
|
mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
|
||||||
|
|
||||||
@ -1235,11 +1236,11 @@ Value gettransaction(const Array& params, bool fHelp)
|
|||||||
hash.SetHex(params[0].get_str());
|
hash.SetHex(params[0].get_str());
|
||||||
|
|
||||||
Object entry;
|
Object entry;
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
|
||||||
{
|
{
|
||||||
if (!mapWallet.count(hash))
|
if (!pwalletMain->mapWallet.count(hash))
|
||||||
throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
|
throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
|
||||||
const CWalletTx& wtx = mapWallet[hash];
|
const CWalletTx& wtx = pwalletMain->mapWallet[hash];
|
||||||
|
|
||||||
int64 nCredit = wtx.GetCredit();
|
int64 nCredit = wtx.GetCredit();
|
||||||
int64 nDebit = wtx.GetDebit();
|
int64 nDebit = wtx.GetDebit();
|
||||||
@ -1250,10 +1251,10 @@ Value gettransaction(const Array& params, bool fHelp)
|
|||||||
if (wtx.IsFromMe())
|
if (wtx.IsFromMe())
|
||||||
entry.push_back(Pair("fee", ValueFromAmount(nFee)));
|
entry.push_back(Pair("fee", ValueFromAmount(nFee)));
|
||||||
|
|
||||||
WalletTxToJSON(mapWallet[hash], entry);
|
WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
|
||||||
|
|
||||||
Array details;
|
Array details;
|
||||||
ListTransactions(mapWallet[hash], "*", 0, false, details);
|
ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
|
||||||
entry.push_back(Pair("details", details));
|
entry.push_back(Pair("details", details));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1269,7 +1270,7 @@ Value backupwallet(const Array& params, bool fHelp)
|
|||||||
"Safely copies wallet.dat to destination, which can be a directory or a path with filename.");
|
"Safely copies wallet.dat to destination, which can be a directory or a path with filename.");
|
||||||
|
|
||||||
string strDest = params[0].get_str();
|
string strDest = params[0].get_str();
|
||||||
BackupWallet(strDest);
|
BackupWallet(*pwalletMain, strDest);
|
||||||
|
|
||||||
return Value::null;
|
return Value::null;
|
||||||
}
|
}
|
||||||
@ -1295,10 +1296,10 @@ Value validateaddress(const Array& params, bool fHelp)
|
|||||||
string currentAddress = Hash160ToAddress(hash160);
|
string currentAddress = Hash160ToAddress(hash160);
|
||||||
ret.push_back(Pair("address", currentAddress));
|
ret.push_back(Pair("address", currentAddress));
|
||||||
ret.push_back(Pair("ismine", (mapPubKeys.count(hash160) > 0)));
|
ret.push_back(Pair("ismine", (mapPubKeys.count(hash160) > 0)));
|
||||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
|
||||||
{
|
{
|
||||||
if (mapAddressBook.count(currentAddress))
|
if (pwalletMain->mapAddressBook.count(currentAddress))
|
||||||
ret.push_back(Pair("account", mapAddressBook[currentAddress]));
|
ret.push_back(Pair("account", pwalletMain->mapAddressBook[currentAddress]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -1325,7 +1326,7 @@ Value getwork(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
static map<uint256, pair<CBlock*, unsigned int> > mapNewBlock;
|
static map<uint256, pair<CBlock*, unsigned int> > mapNewBlock;
|
||||||
static vector<CBlock*> vNewBlock;
|
static vector<CBlock*> vNewBlock;
|
||||||
static CReserveKey reservekey;
|
static CReserveKey reservekey(pwalletMain);
|
||||||
|
|
||||||
if (params.size() == 0)
|
if (params.size() == 0)
|
||||||
{
|
{
|
||||||
@ -1406,7 +1407,7 @@ Value getwork(const Array& params, bool fHelp)
|
|||||||
pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce);
|
pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce);
|
||||||
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
||||||
|
|
||||||
return CheckWork(pblock, reservekey);
|
return CheckWork(pblock, *pwalletMain, reservekey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,7 +1021,7 @@ bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet)
|
bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet)
|
||||||
{
|
{
|
||||||
scriptSigRet.clear();
|
scriptSigRet.clear();
|
||||||
|
|
||||||
@ -1030,7 +1030,7 @@ bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& s
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Compile solution
|
// Compile solution
|
||||||
CRITICAL_BLOCK(cs_mapKeys)
|
CRITICAL_BLOCK(keystore.cs_mapKeys)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
|
BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
|
||||||
{
|
{
|
||||||
@ -1038,12 +1038,13 @@ bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& s
|
|||||||
{
|
{
|
||||||
// Sign
|
// Sign
|
||||||
const valtype& vchPubKey = item.second;
|
const valtype& vchPubKey = item.second;
|
||||||
if (!mapKeys.count(vchPubKey))
|
CPrivKey privkey;
|
||||||
|
if (!keystore.GetPrivKey(vchPubKey, privkey))
|
||||||
return false;
|
return false;
|
||||||
if (hash != 0)
|
if (hash != 0)
|
||||||
{
|
{
|
||||||
vector<unsigned char> vchSig;
|
vector<unsigned char> vchSig;
|
||||||
if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig))
|
if (!CKey::Sign(privkey, hash, vchSig))
|
||||||
return false;
|
return false;
|
||||||
vchSig.push_back((unsigned char)nHashType);
|
vchSig.push_back((unsigned char)nHashType);
|
||||||
scriptSigRet << vchSig;
|
scriptSigRet << vchSig;
|
||||||
@ -1056,12 +1057,13 @@ bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& s
|
|||||||
if (mi == mapPubKeys.end())
|
if (mi == mapPubKeys.end())
|
||||||
return false;
|
return false;
|
||||||
const vector<unsigned char>& vchPubKey = (*mi).second;
|
const vector<unsigned char>& vchPubKey = (*mi).second;
|
||||||
if (!mapKeys.count(vchPubKey))
|
CPrivKey privkey;
|
||||||
|
if (!keystore.GetPrivKey(vchPubKey, privkey))
|
||||||
return false;
|
return false;
|
||||||
if (hash != 0)
|
if (hash != 0)
|
||||||
{
|
{
|
||||||
vector<unsigned char> vchSig;
|
vector<unsigned char> vchSig;
|
||||||
if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig))
|
if (!CKey::Sign(privkey, hash, vchSig))
|
||||||
return false;
|
return false;
|
||||||
vchSig.push_back((unsigned char)nHashType);
|
vchSig.push_back((unsigned char)nHashType);
|
||||||
scriptSigRet << vchSig << vchPubKey;
|
scriptSigRet << vchSig << vchPubKey;
|
||||||
@ -1085,14 +1087,14 @@ bool IsStandard(const CScript& scriptPubKey)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IsMine(const CScript& scriptPubKey)
|
bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||||
{
|
{
|
||||||
CScript scriptSig;
|
CScript scriptSig;
|
||||||
return Solver(scriptPubKey, 0, 0, scriptSig);
|
return Solver(keystore, scriptPubKey, 0, 0, scriptSig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet)
|
bool ExtractPubKey(const CScript& scriptPubKey, const CKeyStore* keystore, vector<unsigned char>& vchPubKeyRet)
|
||||||
{
|
{
|
||||||
vchPubKeyRet.clear();
|
vchPubKeyRet.clear();
|
||||||
|
|
||||||
@ -1100,7 +1102,7 @@ bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned
|
|||||||
if (!Solver(scriptPubKey, vSolution))
|
if (!Solver(scriptPubKey, vSolution))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_mapKeys)
|
CRITICAL_BLOCK(cs_mapPubKeys)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
|
BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
|
||||||
{
|
{
|
||||||
@ -1116,7 +1118,7 @@ bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned
|
|||||||
continue;
|
continue;
|
||||||
vchPubKey = (*mi).second;
|
vchPubKey = (*mi).second;
|
||||||
}
|
}
|
||||||
if (!fMineOnly || mapKeys.count(vchPubKey))
|
if (keystore == NULL || keystore->HaveKey(vchPubKey))
|
||||||
{
|
{
|
||||||
vchPubKeyRet = vchPubKey;
|
vchPubKeyRet = vchPubKey;
|
||||||
return true;
|
return true;
|
||||||
@ -1160,7 +1162,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
|
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
|
||||||
{
|
{
|
||||||
assert(nIn < txTo.vin.size());
|
assert(nIn < txTo.vin.size());
|
||||||
CTxIn& txin = txTo.vin[nIn];
|
CTxIn& txin = txTo.vin[nIn];
|
||||||
@ -1171,7 +1173,7 @@ bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int
|
|||||||
// The checksig op will also drop the signatures from its hash.
|
// The checksig op will also drop the signatures from its hash.
|
||||||
uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType);
|
uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType);
|
||||||
|
|
||||||
if (!Solver(txout.scriptPubKey, hash, nHashType, txin.scriptSig))
|
if (!Solver(keystore, txout.scriptPubKey, hash, nHashType, txin.scriptSig))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
txin.scriptSig = scriptPrereq + txin.scriptSig;
|
txin.scriptSig = scriptPrereq + txin.scriptSig;
|
||||||
@ -1199,10 +1201,5 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig
|
|||||||
if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, nHashType))
|
if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, nHashType))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Anytime a signature is successfully verified, it's proof the outpoint is spent,
|
|
||||||
// so lets update the wallet spent flag if it doesn't know due to wallet.dat being
|
|
||||||
// restored from backup or the user making copies of wallet.dat.
|
|
||||||
WalletUpdateSpent(txin.prevout);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#define H_BITCOIN_SCRIPT
|
#define H_BITCOIN_SCRIPT
|
||||||
|
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
|
#include "keystore.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -707,12 +708,11 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
|
|
||||||
bool IsStandard(const CScript& scriptPubKey);
|
bool IsStandard(const CScript& scriptPubKey);
|
||||||
bool IsMine(const CScript& scriptPubKey);
|
bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
|
||||||
bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, std::vector<unsigned char>& vchPubKeyRet);
|
bool ExtractPubKey(const CScript& scriptPubKey, const CKeyStore* pkeystore, std::vector<unsigned char>& vchPubKeyRet);
|
||||||
bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret);
|
bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret);
|
||||||
bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript());
|
bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript());
|
||||||
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);
|
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "strlcpy.h"
|
#include "strlcpy.h"
|
||||||
#include <boost/program_options/detail/config_file.hpp>
|
#include <boost/program_options/detail/config_file.hpp>
|
||||||
#include <boost/program_options/parsers.hpp>
|
#include <boost/program_options/parsers.hpp>
|
||||||
#include <boost/filesystem/operations.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#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>
|
||||||
|
@ -139,14 +139,12 @@ inline int myclosesocket(SOCKET& hSocket)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#define closesocket(s) myclosesocket(s)
|
#define closesocket(s) myclosesocket(s)
|
||||||
#if 0
|
#if !defined(QT_GUI) && !defined(GUI)
|
||||||
#ifndef GUI
|
|
||||||
inline const char* _(const char* psz)
|
inline const char* _(const char* psz)
|
||||||
{
|
{
|
||||||
return psz;
|
return psz;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1176
src/wallet.cpp
Normal file
1176
src/wallet.cpp
Normal file
File diff suppressed because it is too large
Load Diff
611
src/wallet.h
Normal file
611
src/wallet.h
Normal file
@ -0,0 +1,611 @@
|
|||||||
|
// Copyright (c) 2009-2011 Satoshi Nakamoto & 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_WALLET_H
|
||||||
|
#define BITCOIN_WALLET_H
|
||||||
|
|
||||||
|
#include "bignum.h"
|
||||||
|
#include "key.h"
|
||||||
|
#include "script.h"
|
||||||
|
|
||||||
|
class CWalletTx;
|
||||||
|
class CReserveKey;
|
||||||
|
class CWalletDB;
|
||||||
|
|
||||||
|
class CWallet : public CKeyStore
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
|
||||||
|
bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool fFileBacked;
|
||||||
|
std::string strWalletFile;
|
||||||
|
|
||||||
|
std::set<int64> setKeyPool;
|
||||||
|
CCriticalSection cs_setKeyPool;
|
||||||
|
|
||||||
|
CWallet()
|
||||||
|
{
|
||||||
|
fFileBacked = false;
|
||||||
|
}
|
||||||
|
CWallet(std::string strWalletFileIn)
|
||||||
|
{
|
||||||
|
strWalletFile = strWalletFileIn;
|
||||||
|
fFileBacked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable CCriticalSection cs_mapWallet;
|
||||||
|
std::map<uint256, CWalletTx> mapWallet;
|
||||||
|
std::vector<uint256> vWalletUpdated;
|
||||||
|
|
||||||
|
std::map<uint256, int> mapRequestCount;
|
||||||
|
mutable CCriticalSection cs_mapRequestCount;
|
||||||
|
|
||||||
|
std::map<std::string, std::string> mapAddressBook;
|
||||||
|
mutable CCriticalSection cs_mapAddressBook;
|
||||||
|
|
||||||
|
std::vector<unsigned char> vchDefaultKey;
|
||||||
|
|
||||||
|
bool AddKey(const CKey& key);
|
||||||
|
bool AddToWallet(const CWalletTx& wtxIn);
|
||||||
|
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false);
|
||||||
|
bool EraseFromWallet(uint256 hash);
|
||||||
|
void WalletUpdateSpent(const CTransaction& prevout);
|
||||||
|
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
|
||||||
|
void ReacceptWalletTransactions();
|
||||||
|
void ResendWalletTransactions();
|
||||||
|
int64 GetBalance() const;
|
||||||
|
bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
|
||||||
|
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
|
||||||
|
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
|
||||||
|
bool BroadcastTransaction(CWalletTx& wtxNew);
|
||||||
|
std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
||||||
|
std::string SendMoneyToBitcoinAddress(std::string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
||||||
|
|
||||||
|
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
|
||||||
|
void KeepKey(int64 nIndex);
|
||||||
|
void ReturnKey(int64 nIndex);
|
||||||
|
std::vector<unsigned char> GetKeyFromKeyPool();
|
||||||
|
int64 GetOldestKeyPoolTime();
|
||||||
|
|
||||||
|
bool IsMine(const CTxIn& txin) const;
|
||||||
|
int64 GetDebit(const CTxIn& txin) const;
|
||||||
|
bool IsMine(const CTxOut& txout) const
|
||||||
|
{
|
||||||
|
return ::IsMine(*this, txout.scriptPubKey);
|
||||||
|
}
|
||||||
|
int64 GetCredit(const CTxOut& txout) const
|
||||||
|
{
|
||||||
|
if (!MoneyRange(txout.nValue))
|
||||||
|
throw std::runtime_error("CWallet::GetCredit() : value out of range");
|
||||||
|
return (IsMine(txout) ? txout.nValue : 0);
|
||||||
|
}
|
||||||
|
bool IsChange(const CTxOut& txout) const
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> vchPubKey;
|
||||||
|
if (ExtractPubKey(txout.scriptPubKey, this, vchPubKey))
|
||||||
|
CRITICAL_BLOCK(cs_mapAddressBook)
|
||||||
|
if (!mapAddressBook.count(PubKeyToAddress(vchPubKey)))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int64 GetChange(const CTxOut& txout) const
|
||||||
|
{
|
||||||
|
if (!MoneyRange(txout.nValue))
|
||||||
|
throw std::runtime_error("CWallet::GetChange() : value out of range");
|
||||||
|
return (IsChange(txout) ? txout.nValue : 0);
|
||||||
|
}
|
||||||
|
bool IsMine(const CTransaction& tx) const
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(const CTxOut& txout, tx.vout)
|
||||||
|
if (IsMine(txout))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool IsFromMe(const CTransaction& tx) const
|
||||||
|
{
|
||||||
|
return (GetDebit(tx) > 0);
|
||||||
|
}
|
||||||
|
int64 GetDebit(const CTransaction& tx) const
|
||||||
|
{
|
||||||
|
int64 nDebit = 0;
|
||||||
|
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||||
|
{
|
||||||
|
nDebit += GetDebit(txin);
|
||||||
|
if (!MoneyRange(nDebit))
|
||||||
|
throw std::runtime_error("CWallet::GetDebit() : value out of range");
|
||||||
|
}
|
||||||
|
return nDebit;
|
||||||
|
}
|
||||||
|
int64 GetCredit(const CTransaction& tx) const
|
||||||
|
{
|
||||||
|
int64 nCredit = 0;
|
||||||
|
BOOST_FOREACH(const CTxOut& txout, tx.vout)
|
||||||
|
{
|
||||||
|
nCredit += GetCredit(txout);
|
||||||
|
if (!MoneyRange(nCredit))
|
||||||
|
throw std::runtime_error("CWallet::GetCredit() : value out of range");
|
||||||
|
}
|
||||||
|
return nCredit;
|
||||||
|
}
|
||||||
|
int64 GetChange(const CTransaction& tx) const
|
||||||
|
{
|
||||||
|
int64 nChange = 0;
|
||||||
|
BOOST_FOREACH(const CTxOut& txout, tx.vout)
|
||||||
|
{
|
||||||
|
nChange += GetChange(txout);
|
||||||
|
if (!MoneyRange(nChange))
|
||||||
|
throw std::runtime_error("CWallet::GetChange() : value out of range");
|
||||||
|
}
|
||||||
|
return nChange;
|
||||||
|
}
|
||||||
|
void SetBestChain(const CBlockLocator& loc)
|
||||||
|
{
|
||||||
|
CWalletDB walletdb(strWalletFile);
|
||||||
|
walletdb.WriteBestBlock(loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadWallet(bool& fFirstRunRet);
|
||||||
|
// bool BackupWallet(const std::string& strDest);
|
||||||
|
bool SetAddressBookName(const std::string& strAddress, const std::string& strName);
|
||||||
|
bool EraseAddressBookName(const std::string& strAddress);
|
||||||
|
std::string GetDefaultAddress();
|
||||||
|
bool SetDefaultAddress(const std::string& strAddress);
|
||||||
|
|
||||||
|
void UpdatedTransaction(const uint256 &hashTx)
|
||||||
|
{
|
||||||
|
CRITICAL_BLOCK(cs_mapWallet)
|
||||||
|
vWalletUpdated.push_back(hashTx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintWallet(const CBlock& block);
|
||||||
|
|
||||||
|
void Inventory(const uint256 &hash)
|
||||||
|
{
|
||||||
|
CRITICAL_BLOCK(cs_mapRequestCount)
|
||||||
|
{
|
||||||
|
std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
|
||||||
|
if (mi != mapRequestCount.end())
|
||||||
|
(*mi).second++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CReserveKey
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
CWallet* pwallet;
|
||||||
|
int64 nIndex;
|
||||||
|
std::vector<unsigned char> vchPubKey;
|
||||||
|
public:
|
||||||
|
CReserveKey(CWallet* pwalletIn)
|
||||||
|
{
|
||||||
|
nIndex = -1;
|
||||||
|
pwallet = pwalletIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
~CReserveKey()
|
||||||
|
{
|
||||||
|
if (!fShutdown)
|
||||||
|
ReturnKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReturnKey();
|
||||||
|
std::vector<unsigned char> GetReservedKey();
|
||||||
|
void KeepKey();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// A transaction with a bunch of additional info that only the owner cares
|
||||||
|
// about. It includes any unrecorded transactions needed to link it back
|
||||||
|
// to the block chain.
|
||||||
|
//
|
||||||
|
class CWalletTx : public CMerkleTx
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const CWallet* pwallet;
|
||||||
|
|
||||||
|
std::vector<CMerkleTx> vtxPrev;
|
||||||
|
std::map<std::string, std::string> mapValue;
|
||||||
|
std::vector<std::pair<std::string, std::string> > vOrderForm;
|
||||||
|
unsigned int fTimeReceivedIsTxTime;
|
||||||
|
unsigned int nTimeReceived; // time received by this node
|
||||||
|
char fFromMe;
|
||||||
|
std::string strFromAccount;
|
||||||
|
std::vector<char> vfSpent;
|
||||||
|
|
||||||
|
// memory only
|
||||||
|
mutable char fDebitCached;
|
||||||
|
mutable char fCreditCached;
|
||||||
|
mutable char fAvailableCreditCached;
|
||||||
|
mutable char fChangeCached;
|
||||||
|
mutable int64 nDebitCached;
|
||||||
|
mutable int64 nCreditCached;
|
||||||
|
mutable int64 nAvailableCreditCached;
|
||||||
|
mutable int64 nChangeCached;
|
||||||
|
|
||||||
|
// memory only UI hints
|
||||||
|
mutable unsigned int nTimeDisplayed;
|
||||||
|
mutable int nLinesDisplayed;
|
||||||
|
mutable char fConfirmedDisplayed;
|
||||||
|
|
||||||
|
CWalletTx()
|
||||||
|
{
|
||||||
|
Init(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CWalletTx(const CWallet* pwalletIn)
|
||||||
|
{
|
||||||
|
Init(pwalletIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
|
||||||
|
{
|
||||||
|
Init(pwalletIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
|
||||||
|
{
|
||||||
|
Init(pwalletIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init(const CWallet* pwalletIn)
|
||||||
|
{
|
||||||
|
pwallet = pwalletIn;
|
||||||
|
vtxPrev.clear();
|
||||||
|
mapValue.clear();
|
||||||
|
vOrderForm.clear();
|
||||||
|
fTimeReceivedIsTxTime = false;
|
||||||
|
nTimeReceived = 0;
|
||||||
|
fFromMe = false;
|
||||||
|
strFromAccount.clear();
|
||||||
|
vfSpent.clear();
|
||||||
|
fDebitCached = false;
|
||||||
|
fCreditCached = false;
|
||||||
|
fAvailableCreditCached = false;
|
||||||
|
fChangeCached = false;
|
||||||
|
nDebitCached = 0;
|
||||||
|
nCreditCached = 0;
|
||||||
|
nAvailableCreditCached = 0;
|
||||||
|
nChangeCached = 0;
|
||||||
|
nTimeDisplayed = 0;
|
||||||
|
nLinesDisplayed = 0;
|
||||||
|
fConfirmedDisplayed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
CWalletTx* pthis = const_cast<CWalletTx*>(this);
|
||||||
|
if (fRead)
|
||||||
|
pthis->Init(NULL);
|
||||||
|
char fSpent = false;
|
||||||
|
|
||||||
|
if (!fRead)
|
||||||
|
{
|
||||||
|
pthis->mapValue["fromaccount"] = pthis->strFromAccount;
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
BOOST_FOREACH(char f, vfSpent)
|
||||||
|
{
|
||||||
|
str += (f ? '1' : '0');
|
||||||
|
if (f)
|
||||||
|
fSpent = true;
|
||||||
|
}
|
||||||
|
pthis->mapValue["spent"] = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
|
||||||
|
READWRITE(vtxPrev);
|
||||||
|
READWRITE(mapValue);
|
||||||
|
READWRITE(vOrderForm);
|
||||||
|
READWRITE(fTimeReceivedIsTxTime);
|
||||||
|
READWRITE(nTimeReceived);
|
||||||
|
READWRITE(fFromMe);
|
||||||
|
READWRITE(fSpent);
|
||||||
|
|
||||||
|
if (fRead)
|
||||||
|
{
|
||||||
|
pthis->strFromAccount = pthis->mapValue["fromaccount"];
|
||||||
|
|
||||||
|
if (mapValue.count("spent"))
|
||||||
|
BOOST_FOREACH(char c, pthis->mapValue["spent"])
|
||||||
|
pthis->vfSpent.push_back(c != '0');
|
||||||
|
else
|
||||||
|
pthis->vfSpent.assign(vout.size(), fSpent);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthis->mapValue.erase("fromaccount");
|
||||||
|
pthis->mapValue.erase("version");
|
||||||
|
pthis->mapValue.erase("spent");
|
||||||
|
)
|
||||||
|
|
||||||
|
// marks certain txout's as spent
|
||||||
|
// returns true if any update took place
|
||||||
|
bool UpdateSpent(const std::vector<char>& vfNewSpent)
|
||||||
|
{
|
||||||
|
bool fReturn = false;
|
||||||
|
for (int i=0; i < vfNewSpent.size(); i++)
|
||||||
|
{
|
||||||
|
if (i == vfSpent.size())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (vfNewSpent[i] && !vfSpent[i])
|
||||||
|
{
|
||||||
|
vfSpent[i] = true;
|
||||||
|
fReturn = true;
|
||||||
|
fAvailableCreditCached = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarkDirty()
|
||||||
|
{
|
||||||
|
fCreditCached = false;
|
||||||
|
fAvailableCreditCached = false;
|
||||||
|
fDebitCached = false;
|
||||||
|
fChangeCached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarkSpent(unsigned int nOut)
|
||||||
|
{
|
||||||
|
if (nOut >= vout.size())
|
||||||
|
throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range");
|
||||||
|
vfSpent.resize(vout.size());
|
||||||
|
if (!vfSpent[nOut])
|
||||||
|
{
|
||||||
|
vfSpent[nOut] = true;
|
||||||
|
fAvailableCreditCached = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSpent(unsigned int nOut) const
|
||||||
|
{
|
||||||
|
if (nOut >= vout.size())
|
||||||
|
throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range");
|
||||||
|
if (nOut >= vfSpent.size())
|
||||||
|
return false;
|
||||||
|
return (!!vfSpent[nOut]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 GetDebit() const
|
||||||
|
{
|
||||||
|
if (vin.empty())
|
||||||
|
return 0;
|
||||||
|
if (fDebitCached)
|
||||||
|
return nDebitCached;
|
||||||
|
nDebitCached = pwallet->GetDebit(*this);
|
||||||
|
fDebitCached = true;
|
||||||
|
return nDebitCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 GetCredit(bool fUseCache=true) const
|
||||||
|
{
|
||||||
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
|
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// GetBalance can assume transactions in mapWallet won't change
|
||||||
|
if (fUseCache && fCreditCached)
|
||||||
|
return nCreditCached;
|
||||||
|
nCreditCached = pwallet->GetCredit(*this);
|
||||||
|
fCreditCached = true;
|
||||||
|
return nCreditCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 GetAvailableCredit(bool fUseCache=true) const
|
||||||
|
{
|
||||||
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
|
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fUseCache && fAvailableCreditCached)
|
||||||
|
return nAvailableCreditCached;
|
||||||
|
|
||||||
|
int64 nCredit = 0;
|
||||||
|
for (int i = 0; i < vout.size(); i++)
|
||||||
|
{
|
||||||
|
if (!IsSpent(i))
|
||||||
|
{
|
||||||
|
const CTxOut &txout = vout[i];
|
||||||
|
nCredit += pwallet->GetCredit(txout);
|
||||||
|
if (!MoneyRange(nCredit))
|
||||||
|
throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nAvailableCreditCached = nCredit;
|
||||||
|
fAvailableCreditCached = true;
|
||||||
|
return nCredit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64 GetChange() const
|
||||||
|
{
|
||||||
|
if (fChangeCached)
|
||||||
|
return nChangeCached;
|
||||||
|
nChangeCached = pwallet->GetChange(*this);
|
||||||
|
fChangeCached = true;
|
||||||
|
return nChangeCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<std::string /* address */, int64> >& listReceived,
|
||||||
|
std::list<std::pair<std::string /* address */, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
|
||||||
|
|
||||||
|
void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived,
|
||||||
|
int64& nSent, int64& nFee) const;
|
||||||
|
|
||||||
|
bool IsFromMe() const
|
||||||
|
{
|
||||||
|
return (GetDebit() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsConfirmed() const
|
||||||
|
{
|
||||||
|
// Quick answer in most cases
|
||||||
|
if (!IsFinal())
|
||||||
|
return false;
|
||||||
|
if (GetDepthInMainChain() >= 1)
|
||||||
|
return true;
|
||||||
|
if (!IsFromMe()) // using wtx's cached debit
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If no confirmations but it's from us, we can still
|
||||||
|
// consider it confirmed if all dependencies are confirmed
|
||||||
|
std::map<uint256, const CMerkleTx*> mapPrev;
|
||||||
|
std::vector<const CMerkleTx*> vWorkQueue;
|
||||||
|
vWorkQueue.reserve(vtxPrev.size()+1);
|
||||||
|
vWorkQueue.push_back(this);
|
||||||
|
for (int i = 0; i < vWorkQueue.size(); i++)
|
||||||
|
{
|
||||||
|
const CMerkleTx* ptx = vWorkQueue[i];
|
||||||
|
|
||||||
|
if (!ptx->IsFinal())
|
||||||
|
return false;
|
||||||
|
if (ptx->GetDepthInMainChain() >= 1)
|
||||||
|
continue;
|
||||||
|
if (!pwallet->IsFromMe(*ptx))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mapPrev.empty())
|
||||||
|
BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
|
||||||
|
mapPrev[tx.GetHash()] = &tx;
|
||||||
|
|
||||||
|
BOOST_FOREACH(const CTxIn& txin, ptx->vin)
|
||||||
|
{
|
||||||
|
if (!mapPrev.count(txin.prevout.hash))
|
||||||
|
return false;
|
||||||
|
vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteToDisk();
|
||||||
|
|
||||||
|
int64 GetTxTime() const;
|
||||||
|
int GetRequestCount() const;
|
||||||
|
|
||||||
|
void AddSupportingTransactions(CTxDB& txdb);
|
||||||
|
|
||||||
|
bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
|
||||||
|
bool AcceptWalletTransaction();
|
||||||
|
|
||||||
|
void RelayWalletTransaction(CTxDB& txdb);
|
||||||
|
void RelayWalletTransaction();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private key that includes an expiration date in case it never gets used.
|
||||||
|
//
|
||||||
|
class CWalletKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CPrivKey vchPrivKey;
|
||||||
|
int64 nTimeCreated;
|
||||||
|
int64 nTimeExpires;
|
||||||
|
std::string strComment;
|
||||||
|
//// todo: add something to note what created it (user, getnewaddress, change)
|
||||||
|
//// maybe should have a map<string, string> property map
|
||||||
|
|
||||||
|
CWalletKey(int64 nExpires=0)
|
||||||
|
{
|
||||||
|
nTimeCreated = (nExpires ? GetTime() : 0);
|
||||||
|
nTimeExpires = nExpires;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
if (!(nType & SER_GETHASH))
|
||||||
|
READWRITE(nVersion);
|
||||||
|
READWRITE(vchPrivKey);
|
||||||
|
READWRITE(nTimeCreated);
|
||||||
|
READWRITE(nTimeExpires);
|
||||||
|
READWRITE(strComment);
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Account information.
|
||||||
|
// Stored in wallet with key "acc"+string account name
|
||||||
|
//
|
||||||
|
class CAccount
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<unsigned char> vchPubKey;
|
||||||
|
|
||||||
|
CAccount()
|
||||||
|
{
|
||||||
|
SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetNull()
|
||||||
|
{
|
||||||
|
vchPubKey.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
if (!(nType & SER_GETHASH))
|
||||||
|
READWRITE(nVersion);
|
||||||
|
READWRITE(vchPubKey);
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal transfers.
|
||||||
|
// Database key is acentry<account><counter>
|
||||||
|
//
|
||||||
|
class CAccountingEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string strAccount;
|
||||||
|
int64 nCreditDebit;
|
||||||
|
int64 nTime;
|
||||||
|
std::string strOtherAccount;
|
||||||
|
std::string strComment;
|
||||||
|
|
||||||
|
CAccountingEntry()
|
||||||
|
{
|
||||||
|
SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetNull()
|
||||||
|
{
|
||||||
|
nCreditDebit = 0;
|
||||||
|
nTime = 0;
|
||||||
|
strAccount.clear();
|
||||||
|
strOtherAccount.clear();
|
||||||
|
strComment.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
if (!(nType & SER_GETHASH))
|
||||||
|
READWRITE(nVersion);
|
||||||
|
// Note: strAccount is serialized as part of the key, not here.
|
||||||
|
READWRITE(nCreditDebit);
|
||||||
|
READWRITE(nTime);
|
||||||
|
READWRITE(strOtherAccount);
|
||||||
|
READWRITE(strComment);
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user