Browse Source

CWallet class

* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
pull/1/head
Pieter Wuille 12 years ago
parent
commit
64c7ee7e6b
  1. 65
      src/db.cpp
  2. 94
      src/db.h
  3. 22
      src/init.cpp
  4. 2
      src/init.h
  5. 6
      src/keystore.cpp
  6. 20
      src/keystore.h
  7. 256
      src/main.cpp
  8. 131
      src/main.h
  9. 4
      src/net.cpp
  10. 148
      src/rpc.cpp
  11. 31
      src/script.cpp
  12. 7
      src/script.h
  13. 186
      src/ui.cpp
  14. 273
      src/wallet.cpp
  15. 248
      src/wallet.h

65
src/db.cpp

@ -10,8 +10,6 @@ @@ -10,8 +10,6 @@
using namespace std;
using namespace boost;
void ThreadFlushWalletDB(void* parg);
unsigned int nWalletDBUpdated;
uint64 nAccountingEntryNumber = 0;
@ -150,7 +148,7 @@ void CDB::Close() @@ -150,7 +148,7 @@ void CDB::Close()
--mapFileUseCount[strFile];
}
void CloseDb(const string& strFile)
void static CloseDb(const string& strFile)
{
CRITICAL_BLOCK(cs_db)
{
@ -359,7 +357,7 @@ bool CTxDB::WriteBestInvalidWork(CBigNum bnBestInvalidWork) @@ -359,7 +357,7 @@ bool CTxDB::WriteBestInvalidWork(CBigNum bnBestInvalidWork)
return Write(string("bnBestInvalidWork"), bnBestInvalidWork);
}
CBlockIndex* InsertBlockIndex(uint256 hash)
CBlockIndex static * InsertBlockIndex(uint256 hash)
{
if (hash == 0)
return NULL;
@ -584,6 +582,20 @@ bool LoadAddresses() @@ -584,6 +582,20 @@ bool LoadAddresses()
// CWalletDB
//
bool CWalletDB::WriteName(const string& strAddress, const string& strName)
{
nWalletDBUpdated++;
return Write(make_pair(string("name"), strAddress), strName);
}
bool CWalletDB::EraseName(const string& strAddress)
{
// This should only be used for sending addresses, never for receiving addresses,
// receiving addresses must always have an address book entry if they're not change return.
nWalletDBUpdated++;
return Erase(make_pair(string("name"), strAddress));
}
bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account)
{
account.SetNull();
@ -657,9 +669,9 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin @@ -657,9 +669,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;
vector<uint256> vWalletUpgrade;
@ -671,8 +683,8 @@ bool CWalletDB::LoadWallet() @@ -671,8 +683,8 @@ bool CWalletDB::LoadWallet()
#endif
//// todo: shouldn't we catch exceptions and try to recover and continue?
CRITICAL_BLOCK(cs_mapWallet)
CRITICAL_BLOCK(cs_mapKeys)
CRITICAL_BLOCK(pwallet->cs_mapWallet)
CRITICAL_BLOCK(pwallet->cs_mapKeys)
{
// Get cursor
Dbc* pcursor = GetCursor();
@ -699,14 +711,15 @@ bool CWalletDB::LoadWallet() @@ -699,14 +711,15 @@ bool CWalletDB::LoadWallet()
{
string strAddress;
ssKey >> strAddress;
ssValue >> mapAddressBook[strAddress];
ssValue >> pwallet->mapAddressBook[strAddress];
}
else if (strType == "tx")
{
uint256 hash;
ssKey >> hash;
CWalletTx& wtx = mapWallet[hash];
CWalletTx& wtx = pwallet->mapWallet[hash];
ssValue >> wtx;
wtx.pwallet = pwallet;
if (wtx.GetHash() != hash)
printf("Error in wallet.dat, hash mismatch\n");
@ -757,18 +770,18 @@ bool CWalletDB::LoadWallet() @@ -757,18 +770,18 @@ bool CWalletDB::LoadWallet()
else
ssValue >> wkey;
mapKeys[vchPubKey] = wkey.vchPrivKey;
pwallet->mapKeys[vchPubKey] = wkey.vchPrivKey;
mapPubKeys[Hash160(vchPubKey)] = vchPubKey;
}
else if (strType == "defaultkey")
{
ssValue >> vchDefaultKey;
ssValue >> pwallet->vchDefaultKey;
}
else if (strType == "pool")
{
int64 nIndex;
ssKey >> nIndex;
setKeyPool.insert(nIndex);
pwallet->setKeyPool.insert(nIndex);
}
else if (strType == "version")
{
@ -800,7 +813,7 @@ bool CWalletDB::LoadWallet() @@ -800,7 +813,7 @@ bool CWalletDB::LoadWallet()
}
BOOST_FOREACH(uint256 hash, vWalletUpgrade)
WriteTx(hash, mapWallet[hash]);
WriteTx(hash, pwallet->mapWallet[hash]);
printf("nFileVersion = %d\n", nFileVersion);
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
@ -830,6 +843,7 @@ bool CWalletDB::LoadWallet() @@ -830,6 +843,7 @@ bool CWalletDB::LoadWallet()
void ThreadFlushWalletDB(void* parg)
{
const string& strFile = ((const string*)parg)[0];
static bool fOneThread;
if (fOneThread)
return;
@ -865,7 +879,6 @@ void ThreadFlushWalletDB(void* parg) @@ -865,7 +879,6 @@ void ThreadFlushWalletDB(void* parg)
if (nRefCount == 0 && !fShutdown)
{
string strFile = "wallet.dat";
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
if (mi != mapFileUseCount.end())
{
@ -888,26 +901,27 @@ void ThreadFlushWalletDB(void* parg) @@ -888,26 +901,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)
{
CRITICAL_BLOCK(cs_db)
{
const string strFile = "wallet.dat";
if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0)
if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0)
{
// Flush log data to the dat file
CloseDb(strFile);
CloseDb(wallet.strWalletFile);
dbenv.txn_checkpoint(0, 0, 0);
dbenv.lsn_reset(strFile.c_str(), 0);
mapFileUseCount.erase(strFile);
dbenv.lsn_reset(wallet.strWalletFile.c_str(), 0);
mapFileUseCount.erase(wallet.strWalletFile);
// Copy wallet.dat
filesystem::path pathSrc(GetDataDir() + "/" + strFile);
filesystem::path pathSrc(GetDataDir() + "/" + wallet.strWalletFile);
filesystem::path pathDest(strDest);
if (filesystem::is_directory(pathDest))
pathDest = pathDest / strFile;
pathDest = pathDest / wallet.strWalletFile;
#if BOOST_VERSION >= 104000
filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
#else
@ -915,11 +929,10 @@ void BackupWallet(const string& strDest) @@ -915,11 +929,10 @@ void BackupWallet(const string& strDest)
#endif
printf("copied wallet.dat to %s\n", pathDest.string().c_str());
return;
return true;
}
}
Sleep(100);
}
return false;
}

94
src/db.h

@ -12,33 +12,25 @@ @@ -12,33 +12,25 @@
#include <db_cxx.h>
class CTransaction;
class CTxIndex;
class CDiskBlockIndex;
class CDiskTxPos;
class COutPoint;
class CUser;
class CReview;
class CAddress;
class CWalletTx;
class CWallet;
class CAccount;
class CAccountingEntry;
class CBlockLocator;
extern std::vector<unsigned char> vchDefaultKey;
extern bool fClient;
extern int nBestHeight;
extern unsigned int nWalletDBUpdated;
extern DbEnv dbenv;
extern void DBFlush(bool fShutdown);
extern std::vector<unsigned char> GetKeyFromKeyPool();
extern int64 GetOldestKeyPoolTime();
extern void ThreadFlushWalletDB(void* parg);
void ThreadFlushWalletDB(void* parg);
bool BackupWallet(const CWallet& wallet, const std::string& strDest);
@ -321,9 +313,6 @@ bool LoadAddresses(); @@ -321,9 +313,6 @@ bool LoadAddresses();
class CKeyPool
{
public:
@ -356,7 +345,7 @@ public: @@ -356,7 +345,7 @@ public:
class CWalletDB : public CDB
{
public:
CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode)
CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
{
}
private:
@ -369,23 +358,9 @@ public: @@ -369,23 +358,9 @@ public:
return Read(std::make_pair(std::string("name"), strAddress), 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 WriteName(const std::string& strAddress, const std::string& strName);
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 EraseName(const std::string& strAddress);
bool ReadTx(uint256 hash, CWalletTx& wtx)
{
@ -435,11 +410,27 @@ public: @@ -435,11 +410,27 @@ public:
bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
{
vchDefaultKey = vchPubKey;
nWalletDBUpdated++;
return Write(std::string("defaultkey"), vchPubKey);
}
bool ReadPool(int64 nPool, CKeyPool& keypool)
{
return Read(std::make_pair(std::string("pool"), nPool), keypool);
}
bool WritePool(int64 nPool, const CKeyPool& keypool)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("pool"), nPool), keypool);
}
bool ErasePool(int64 nPool)
{
nWalletDBUpdated++;
return Erase(std::make_pair(std::string("pool"), nPool));
}
template<typename T>
bool ReadSetting(const std::string& strKey, T& value)
{
@ -459,44 +450,7 @@ public: @@ -459,44 +450,7 @@ public:
int64 GetAccountCreditDebit(const std::string& strAccount);
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
bool LoadWallet();
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();
void KeepKey();
void ReturnKey();
bool LoadWallet(CWallet* pwallet);
};
#endif

22
src/init.cpp

@ -13,6 +13,8 @@ @@ -13,6 +13,8 @@
using namespace std;
using namespace boost;
CWallet* pwalletMain;
//////////////////////////////////////////////////////////////////////////////
//
// Shutdown
@ -45,6 +47,8 @@ void Shutdown(void* parg) @@ -45,6 +47,8 @@ void Shutdown(void* parg)
StopNode();
DBFlush(true);
boost::filesystem::remove(GetPidFile());
UnregisterWallet(pwalletMain);
delete pwalletMain;
CreateThread(ExitTimeout, NULL);
Sleep(50);
printf("Bitcoin exiting\n\n");
@ -372,16 +376,19 @@ bool AppInit2(int argc, char* argv[]) @@ -372,16 +376,19 @@ bool AppInit2(int argc, char* argv[])
printf("Loading wallet...\n");
nStart = GetTimeMillis();
bool fFirstRun;
if (!LoadWallet(fFirstRun))
pwalletMain = new CWallet("wallet.dat");
if (!pwalletMain->LoadWallet(fFirstRun))
strErrors += _("Error loading wallet.dat \n");
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
RegisterWallet(pwalletMain);
CBlockIndex *pindexRescan = pindexBest;
if (GetBoolArg("-rescan"))
pindexRescan = pindexGenesisBlock;
else
{
CWalletDB walletdb;
CWalletDB walletdb("wallet.dat");
CBlockLocator locator;
if (walletdb.ReadBestBlock(locator))
pindexRescan = locator.GetBlockIndex();
@ -390,7 +397,7 @@ bool AppInit2(int argc, char* argv[]) @@ -390,7 +397,7 @@ bool AppInit2(int argc, char* argv[])
{
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
nStart = GetTimeMillis();
ScanForWalletTransactions(pindexRescan, true);
pwalletMain->ScanForWalletTransactions(pindexRescan, true);
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
}
@ -399,10 +406,11 @@ bool AppInit2(int argc, char* argv[]) @@ -399,10 +406,11 @@ bool AppInit2(int argc, char* argv[])
//// debug print
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
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("mapWallet.size() = %d\n", mapWallet.size());
printf("mapAddressBook.size() = %d\n", mapAddressBook.size());
printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
if (!strErrors.empty())
{
@ -411,7 +419,7 @@ bool AppInit2(int argc, char* argv[]) @@ -411,7 +419,7 @@ bool AppInit2(int argc, char* argv[])
}
// Add wallet transactions that aren't already in a block to mapTransactions
ReacceptWalletTransactions();
pwalletMain->ReacceptWalletTransactions();
//
// Parameters

2
src/init.h

@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
#ifndef BITCOIN_INIT_H
#define BITCOIN_INIT_H
extern CWallet* pwalletMain;
void Shutdown(void* parg);
bool AppInit(int argc, char* argv[]);
bool AppInit2(int argc, char* argv[]);

6
src/keystore.cpp

@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
// mapKeys
//
std::vector<unsigned char> GenerateNewKey()
std::vector<unsigned char> CKeyStore::GenerateNewKey()
{
RandAddSeedPerfmon();
CKey key;
@ -22,12 +22,12 @@ std::vector<unsigned char> GenerateNewKey() @@ -22,12 +22,12 @@ std::vector<unsigned char> GenerateNewKey()
return key.GetPubKey();
}
bool AddKey(const CKey& key)
bool CKeyStore::AddKey(const CKey& key)
{
CRITICAL_BLOCK(cs_mapKeys)
{
mapKeys[key.GetPubKey()] = key.GetPrivKey();
mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey();
}
return CWalletDB().WriteKey(key.GetPubKey(), key.GetPrivKey());
}

20
src/keystore.h

@ -4,7 +4,23 @@ @@ -4,7 +4,23 @@
#ifndef BITCOIN_KEYSTORE_H
#define BITCOIN_KEYSTORE_H
bool AddKey(const CKey& key);
std::vector<unsigned char> GenerateNewKey();
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);
}
CPrivKey GetPrivKey(const std::vector<unsigned char> &vchPubKey) const
{
std::map<std::vector<unsigned char>, CPrivKey>::const_iterator mi = mapKeys.find(vchPubKey);
if (mi != mapKeys.end())
return (*mi).second;
}
std::vector<unsigned char> GenerateNewKey();
};
#endif

256
src/main.cpp

@ -15,8 +15,14 @@ using namespace boost; @@ -15,8 +15,14 @@ using namespace boost;
// Global state
//
CCriticalSection cs_setpwalletRegistered;
set<CWallet*> setpwalletRegistered;
CCriticalSection cs_main;
CCriticalSection cs_mapPubKeys;
map<uint160, vector<unsigned char> > mapPubKeys;
map<uint256, CTransaction> mapTransactions;
CCriticalSection cs_mapTransactions;
unsigned int nTransactionsUpdated = 0;
@ -39,25 +45,6 @@ multimap<uint256, CBlock*> mapOrphanBlocksByPrev; @@ -39,25 +45,6 @@ multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
map<uint256, CDataStream*> mapOrphanTransactions;
multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
map<uint256, CWalletTx> mapWallet;
vector<uint256> vWalletUpdated;
CCriticalSection cs_mapWallet;
map<vector<unsigned char>, CPrivKey> mapKeys;
map<uint160, vector<unsigned char> > mapPubKeys;
CCriticalSection cs_mapKeys;
CKey keyUser;
map<uint256, int> mapRequestCount;
CCriticalSection cs_mapRequestCount;
map<string, string> mapAddressBook;
CCriticalSection cs_mapAddressBook;
set<int64> setKeyPool;
CCriticalSection cs_setKeyPool;
vector<unsigned char> vchDefaultKey;
double dHashesPerSec;
int64 nHPSTimerStart;
@ -82,12 +69,97 @@ int fUseUPnP = false; @@ -82,12 +69,97 @@ int fUseUPnP = false;
//////////////////////////////////////////////////////////////////////////////
//
// dispatching functions
//
void RegisterWallet(CWallet* pwalletIn)
{
CRITICAL_BLOCK(cs_setpwalletRegistered)
{
setpwalletRegistered.insert(pwalletIn);
}
}
void UnregisterWallet(CWallet* pwalletIn)
{
CRITICAL_BLOCK(cs_setpwalletRegistered)
{
setpwalletRegistered.erase(pwalletIn);
}
}
bool static IsFromMe(CTransaction& tx)
{
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
if (pwallet->IsFromMe(tx))
return true;
return false;
}
bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx)
{
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
if (pwallet->GetTransaction(hashTx,wtx))
return true;
return false;
}
void static EraseFromWallets(uint256 hash)
{
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->EraseFromWallet(hash);
}
void static SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false)
{
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate);
}
void static SetBestChain(const CBlockLocator& loc)
{
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->SetBestChain(loc);
}
void static UpdatedTransaction(const uint256& hashTx)
{
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->UpdatedTransaction(hashTx);
}
void static PrintWallets(const CBlock& block)
{
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->PrintWallet(block);
}
void static Inventory(const uint256& hash)
{
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->Inventory(hash);
}
void static ResendWalletTransactions()
{
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
pwallet->ResendWalletTransactions();
}
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
//
void AddOrphanTx(const CDataStream& vMsg)
void static AddOrphanTx(const CDataStream& vMsg)
{
CTransaction tx;
CDataStream(vMsg) >> tx;
@ -99,7 +171,7 @@ void AddOrphanTx(const CDataStream& vMsg) @@ -99,7 +171,7 @@ void AddOrphanTx(const CDataStream& vMsg)
mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
}
void EraseOrphanTx(uint256 hash)
void static EraseOrphanTx(uint256 hash)
{
if (!mapOrphanTransactions.count(hash))
return;
@ -357,7 +429,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi @@ -357,7 +429,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
nLastTime = nNow;
// -limitfreerelay unit is thousand-bytes-per-minute
// At default rate it would take over a month to fill 1GB
if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe())
if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(*this))
return error("AcceptToMemoryPool() : free transaction rejected by rate limiter");
if (fDebug)
printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
@ -380,7 +452,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi @@ -380,7 +452,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
///// are we sure this is ok when loading transactions or restoring block txes
// If updated, erase old tx from wallet
if (ptxOld)
EraseFromWallet(ptxOld->GetHash());
EraseFromWallets(ptxOld->GetHash());
printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,10).c_str());
return true;
@ -551,8 +623,7 @@ bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions) @@ -551,8 +623,7 @@ bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions)
return true;
}
uint256 GetOrphanRoot(const CBlock* pblock)
uint256 static GetOrphanRoot(const CBlock* pblock)
{
// Work back to the first block in the orphan chain
while (mapOrphanBlocks.count(pblock->hashPrevBlock))
@ -560,7 +631,7 @@ uint256 GetOrphanRoot(const CBlock* pblock) @@ -560,7 +631,7 @@ uint256 GetOrphanRoot(const CBlock* pblock)
return pblock->GetHash();
}
int64 GetBlockValue(int nHeight, int64 nFees)
int64 static GetBlockValue(int nHeight, int64 nFees)
{
int64 nSubsidy = 50 * COIN;
@ -570,7 +641,7 @@ int64 GetBlockValue(int nHeight, int64 nFees) @@ -570,7 +641,7 @@ int64 GetBlockValue(int nHeight, int64 nFees)
return nSubsidy + nFees;
}
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast)
{
const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
const int64 nTargetSpacing = 10 * 60;
@ -647,7 +718,7 @@ bool IsInitialBlockDownload() @@ -647,7 +718,7 @@ bool IsInitialBlockDownload()
pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60);
}
void InvalidChainFound(CBlockIndex* pindexNew)
void static InvalidChainFound(CBlockIndex* pindexNew)
{
if (pindexNew->bnChainWork > bnBestInvalidWork)
{
@ -923,12 +994,12 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) @@ -923,12 +994,12 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
// Watch for transactions paying to me
BOOST_FOREACH(CTransaction& tx, vtx)
AddToWalletIfInvolvingMe(tx, this, true);
SyncWithWallets(tx, this, true);
return true;
}
bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
{
printf("REORGANIZE\n");
@ -1066,10 +1137,8 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) @@ -1066,10 +1137,8 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
// Update best block in wallet (so we can detect restored wallets)
if (!IsInitialBlockDownload())
{
CWalletDB walletdb;
const CBlockLocator locator(pindexNew);
if (!walletdb.WriteBestBlock(locator))
return error("SetBestChain() : WriteWalletBest failed");
::SetBestChain(locator);
}
// New best block
@ -1123,8 +1192,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) @@ -1123,8 +1192,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
{
// Notify UI to display prev block's coinbase if it was ours
static uint256 hashPrevBestCoinBase;
CRITICAL_BLOCK(cs_mapWallet)
vWalletUpdated.push_back(hashPrevBestCoinBase);
UpdatedTransaction(hashPrevBestCoinBase);
hashPrevBestCoinBase = vtx[0].GetHash();
}
@ -1233,7 +1301,7 @@ bool CBlock::AcceptBlock() @@ -1233,7 +1301,7 @@ bool CBlock::AcceptBlock()
return true;
}
bool ProcessBlock(CNode* pfrom, CBlock* pblock)
bool static ProcessBlock(CNode* pfrom, CBlock* pblock)
{
// Check for duplicate
uint256 hash = pblock->GetHash();
@ -1295,7 +1363,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) @@ -1295,7 +1363,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
template<typename Stream>
bool ScanMessageStart(Stream& s)
bool static ScanMessageStart(Stream& s)
{
// Scan ahead to the next pchMessageStart, which should normally be immediately
// at the file pointer. Leaves file pointer at end of pchMessageStart.
@ -1510,7 +1578,7 @@ void PrintBlockTree() @@ -1510,7 +1578,7 @@ void PrintBlockTree()
for (int i = 0; i < nCol; i++)
printf("| ");
printf("|\n");
}
}
nPrevCol = nCol;
// print columns
@ -1528,16 +1596,7 @@ void PrintBlockTree() @@ -1528,16 +1596,7 @@ void PrintBlockTree()
DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
block.vtx.size());
CRITICAL_BLOCK(cs_mapWallet)
{
if (mapWallet.count(block.vtx[0].GetHash()))
{
CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
}
}
printf("\n");
PrintWallets(block);
// put the main timechain first
vector<CBlockIndex*>& vNext = mapNext[pindex];
@ -1677,7 +1736,7 @@ bool CAlert::ProcessAlert() @@ -1677,7 +1736,7 @@ bool CAlert::ProcessAlert()
//
bool AlreadyHave(CTxDB& txdb, const CInv& inv)
bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
{
switch (inv.type)
{
@ -1697,7 +1756,7 @@ bool AlreadyHave(CTxDB& txdb, const CInv& inv) @@ -1697,7 +1756,7 @@ bool AlreadyHave(CTxDB& txdb, const CInv& inv)
char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
static map<unsigned int, vector<unsigned char> > mapReuseKey;
RandAddSeedPerfmon();
@ -1894,12 +1953,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) @@ -1894,12 +1953,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
// Track requests for our stuff
CRITICAL_BLOCK(cs_mapRequestCount)
{
map<uint256, int>::iterator mi = mapRequestCount.find(inv.hash);
if (mi != mapRequestCount.end())
(*mi).second++;
}
Inventory(inv.hash);
}
}
@ -1952,12 +2006,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) @@ -1952,12 +2006,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
// Track requests for our stuff
CRITICAL_BLOCK(cs_mapRequestCount)
{
map<uint256, int>::iterator mi = mapRequestCount.find(inv.hash);
if (mi != mapRequestCount.end())
(*mi).second++;
}
Inventory(inv.hash);
}
}
@ -2045,7 +2094,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) @@ -2045,7 +2094,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
bool fMissingInputs = false;
if (tx.AcceptToMemoryPool(true, &fMissingInputs))
{
AddToWalletIfInvolvingMe(tx, NULL, true);
SyncWithWallets(tx, NULL, true);
RelayMessage(inv, vMsg);
mapAlreadyAskedFor.erase(inv);
vWorkQueue.push_back(inv.hash);
@ -2066,7 +2115,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) @@ -2066,7 +2115,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (tx.AcceptToMemoryPool(true))
{
printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
AddToWalletIfInvolvingMe(tx, NULL, true);
SyncWithWallets(tx, NULL, true);
RelayMessage(inv, vMsg);
mapAlreadyAskedFor.erase(inv);
vWorkQueue.push_back(inv.hash);
@ -2143,7 +2192,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) @@ -2143,7 +2192,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Keep giving the same key to the same ip until they use it
if (!mapReuseKey.count(pfrom->addr.ip))
mapReuseKey[pfrom->addr.ip] = GetKeyFromKeyPool();
mapReuseKey[pfrom->addr.ip] = pwalletMain->GetKeyFromKeyPool();
// Send back approval of order and pubkey to use
CScript scriptPubKey;
@ -2152,37 +2201,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) @@ -2152,37 +2201,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
else if (strCommand == "submitorder")
{
uint256 hashReply;
vRecv >> hashReply;
if (!GetBoolArg("-allowreceivebyip"))
{
pfrom->PushMessage("reply", hashReply, (int)2);
return true;
}
CWalletTx wtxNew;
vRecv >> wtxNew;
wtxNew.fFromMe = false;
// Broadcast
if (!wtxNew.AcceptWalletTransaction())
{
pfrom->PushMessage("reply", hashReply, (int)1);
return error("submitorder AcceptWalletTransaction() failed, returning error 1");
}
wtxNew.fTimeReceivedIsTxTime = true;
AddToWallet(wtxNew);
wtxNew.RelayWalletTransaction();
mapReuseKey.erase(pfrom->addr.ip);
// Send back confirmation
pfrom->PushMessage("reply", hashReply, (int)0);
}
else if (strCommand == "reply")
{
uint256 hashReply;
@ -2239,7 +2257,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) @@ -2239,7 +2257,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
return true;
}
bool ProcessMessages(CNode* pfrom)
{
CDataStream& vRecv = pfrom->vRecv;
@ -2359,8 +2376,6 @@ bool ProcessMessages(CNode* pfrom) @@ -2359,8 +2376,6 @@ bool ProcessMessages(CNode* pfrom)
}
bool SendMessages(CNode* pto, bool fSendTrickle)
{
CRITICAL_BLOCK(cs_main)
@ -2483,16 +2498,10 @@ bool SendMessages(CNode* pto, bool fSendTrickle) @@ -2483,16 +2498,10 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
// always trickle our own transactions
if (!fTrickleWait)
{
TRY_CRITICAL_BLOCK(cs_mapWallet)
{
map<uint256, CWalletTx>::iterator mi = mapWallet.find(inv.hash);
if (mi != mapWallet.end())
{
CWalletTx& wtx = (*mi).second;
if (wtx.fFromMe)
fTrickleWait = true;
}
}
CWalletTx wtx;
if (GetTransaction(inv.hash, wtx))
if (wtx.fFromMe)
fTrickleWait = true;
}
if (fTrickleWait)
@ -2565,7 +2574,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) @@ -2565,7 +2574,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
// BitcoinMiner
//
int FormatHashBlocks(void* pbuffer, unsigned int len)
int static FormatHashBlocks(void* pbuffer, unsigned int len)
{
unsigned char* pdata = (unsigned char*)pbuffer;
unsigned int blocks = 1 + ((len + 8) / 64);
@ -2598,7 +2607,7 @@ inline void SHA256Transform(void* pstate, void* pinput, const void* pinit) @@ -2598,7 +2607,7 @@ inline void SHA256Transform(void* pstate, void* pinput, const void* pinit)
// between calls, but periodically or if nNonce is 0xffff0000 or above,
// the block is rebuilt and nNonce starts over at zero.
//
unsigned int ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
{
unsigned int& nNonce = *(unsigned int*)(pdata + 12);
for (;;)
@ -2855,7 +2864,7 @@ void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash @@ -2855,7 +2864,7 @@ void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash
}
bool CheckWork(CBlock* pblock, CReserveKey& reservekey)
bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
{
uint256 hash = pblock->GetHash();
uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
@ -2880,8 +2889,8 @@ bool CheckWork(CBlock* pblock, CReserveKey& reservekey) @@ -2880,8 +2889,8 @@ bool CheckWork(CBlock* pblock, CReserveKey& reservekey)
reservekey.KeepKey();
// Track how many getdata requests this block gets
CRITICAL_BLOCK(cs_mapRequestCount)
mapRequestCount[pblock->GetHash()] = 0;
CRITICAL_BLOCK(wallet.cs_mapRequestCount)
wallet.mapRequestCount[pblock->GetHash()] = 0;
// Process this block the same as if we had received it from another node
if (!ProcessBlock(NULL, pblock))
@ -2892,13 +2901,15 @@ bool CheckWork(CBlock* pblock, CReserveKey& reservekey) @@ -2892,13 +2901,15 @@ bool CheckWork(CBlock* pblock, CReserveKey& reservekey)
return true;
}
void BitcoinMiner()
void static ThreadBitcoinMiner(void* parg);
void static BitcoinMiner(CWallet *pwallet)
{
printf("BitcoinMiner started\n");
SetThreadPriority(THREAD_PRIORITY_LOWEST);
// Each thread has its own key and counter
CReserveKey reservekey;
CReserveKey reservekey(pwallet);
unsigned int nExtraNonce = 0;
int64 nPrevTime = 0;
@ -2974,7 +2985,7 @@ void BitcoinMiner() @@ -2974,7 +2985,7 @@ void BitcoinMiner()
assert(hash == pblock->GetHash());
SetThreadPriority(THREAD_PRIORITY_NORMAL);
CheckWork(pblock.get(), reservekey);
CheckWork(pblock.get(), *pwalletMain, reservekey);
SetThreadPriority(THREAD_PRIORITY_LOWEST);
break;
}
@ -3035,12 +3046,13 @@ void BitcoinMiner() @@ -3035,12 +3046,13 @@ void BitcoinMiner()
}
}
void ThreadBitcoinMiner(void* parg)
void static ThreadBitcoinMiner(void* parg)
{
CWallet* pwallet = (CWallet*)parg;
try
{
vnThreadsRunning[3]++;
BitcoinMiner();
BitcoinMiner(pwallet);
vnThreadsRunning[3]--;
}
catch (std::exception& e) {
@ -3058,12 +3070,12 @@ void ThreadBitcoinMiner(void* parg) @@ -3058,12 +3070,12 @@ void ThreadBitcoinMiner(void* parg)
}
void GenerateBitcoins(bool fGenerate)
void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
{
if (fGenerateBitcoins != fGenerate)
{
fGenerateBitcoins = fGenerate;
CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
MainFrameRepaint();
}
if (fGenerateBitcoins)
@ -3078,7 +3090,7 @@ void GenerateBitcoins(bool fGenerate) @@ -3078,7 +3090,7 @@ void GenerateBitcoins(bool fGenerate)
printf("Starting %d BitcoinMiner threads\n", nAddThreads);
for (int i = 0; i < nAddThreads; i++)
{
if (!CreateThread(ThreadBitcoinMiner, NULL))
if (!CreateThread(ThreadBitcoinMiner, pwallet))
printf("Error: CreateThread(ThreadBitcoinMiner) failed\n");
Sleep(10);
}

131
src/main.h

@ -8,21 +8,17 @@ @@ -8,21 +8,17 @@
#include "net.h"
#include "key.h"
#include "script.h"
#include "db.h"
#include <list>
class COutPoint;
class CInPoint;
class CDiskTxPos;
class CCoinBase;
class CTxIn;
class CTxOut;
class CTransaction;
class CBlock;
class CBlockIndex;
class CWalletTx;
class CWallet;
class CKeyItem;
class CReserveKey;
class CWalletDB;
class CMessageHeader;
class CAddress;
@ -62,15 +58,12 @@ extern CBigNum bnBestChainWork; @@ -62,15 +58,12 @@ extern CBigNum bnBestChainWork;
extern CBigNum bnBestInvalidWork;
extern uint256 hashBestChain;
extern CBlockIndex* pindexBest;
extern std::set<int64> setKeyPool;
extern CCriticalSection cs_setKeyPool;
extern unsigned int nTransactionsUpdated;
extern double dHashesPerSec;
extern int64 nHPSTimerStart;
extern int64 nTimeBestReceived;
extern std::map<std::string, std::string> mapAddressBook;
extern CCriticalSection cs_mapAddressBook;
extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered;
// Settings
extern int fGenerateBitcoins;
@ -90,21 +83,20 @@ class CReserveKey; @@ -90,21 +83,20 @@ class CReserveKey;
class CTxDB;
class CTxIndex;
void RegisterWallet(CWallet* pwalletIn);
void UnregisterWallet(CWallet* pwalletIn);
bool CheckDiskSpace(uint64 nAdditionalBytes=0);
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
FILE* AppendBlockFile(unsigned int& nFileRet);
bool LoadBlockIndex(bool fAllowNew=true);
void PrintBlockTree();
bool ProcessMessages(CNode* pfrom);
bool ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vRecv);
bool SendMessages(CNode* pto, bool fSendTrickle);
void GenerateBitcoins(bool fGenerate);
void ThreadBitcoinMiner(void* parg);
void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
CBlock* CreateNewBlock(CReserveKey& reservekey);
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime);
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
bool CheckWork(CBlock* pblock, CReserveKey& reservekey);
void BitcoinMiner();
bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
bool IsInitialBlockDownload();
std::string GetWarnings(std::string strFor);
@ -120,6 +112,23 @@ std::string GetWarnings(std::string strFor); @@ -120,6 +112,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
{
public:
@ -302,9 +311,6 @@ public: @@ -302,9 +311,6 @@ public:
{
printf("%s\n", ToString().c_str());
}
bool IsMine() const;
int64 GetDebit() const;
};
@ -353,36 +359,6 @@ public: @@ -353,36 +359,6 @@ public:
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)
{
return (a.nValue == b.nValue &&
@ -527,57 +503,6 @@ public: @@ -527,57 +503,6 @@ public:
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 nValueOut = 0;
@ -1639,9 +1564,9 @@ public: @@ -1639,9 +1564,9 @@ public:
extern std::map<uint256, CTransaction> mapTransactions;
extern std::map<std::vector<unsigned char>, CPrivKey> mapKeys;
extern std::map<uint160, std::vector<unsigned char> > mapPubKeys;
extern CCriticalSection cs_mapKeys;
extern CCriticalSection cs_mapPubKeys;
#endif

4
src/net.cpp

@ -1117,7 +1117,7 @@ void MapPort(bool fMapPort) @@ -1117,7 +1117,7 @@ void MapPort(bool fMapPort)
if (fUseUPnP != fMapPort)
{
fUseUPnP = fMapPort;
CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
WriteSetting("fUseUPnP", fUseUPnP);
}
if (fUseUPnP && vnThreadsRunning[5] < 1)
{
@ -1698,7 +1698,7 @@ void StartNode(void* parg) @@ -1698,7 +1698,7 @@ void StartNode(void* parg)
printf("Error: CreateThread(ThreadMessageHandler) failed\n");
// Generate coins in the background
GenerateBitcoins(fGenerateBitcoins);
GenerateBitcoins(fGenerateBitcoins, pwalletMain);
}
bool StopNode()

148
src/rpc.cpp

@ -264,14 +264,14 @@ Value setgenerate(const Array& params, bool fHelp) @@ -264,14 +264,14 @@ Value setgenerate(const Array& params, bool fHelp)
{
int nGenProcLimit = params[1].get_int();
fLimitProcessors = (nGenProcLimit != -1);
CWalletDB().WriteSetting("fLimitProcessors", fLimitProcessors);
WriteSetting("fLimitProcessors", fLimitProcessors);
if (nGenProcLimit != -1)
CWalletDB().WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
if (nGenProcLimit == 0)
fGenerate = false;
}
GenerateBitcoins(fGenerate);
GenerateBitcoins(fGenerate, pwalletMain);
return Value::null;
}
@ -298,7 +298,7 @@ Value getinfo(const Array& params, bool fHelp) @@ -298,7 +298,7 @@ Value getinfo(const Array& params, bool fHelp)
Object obj;
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("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
@ -307,7 +307,7 @@ Value getinfo(const Array& params, bool fHelp) @@ -307,7 +307,7 @@ Value getinfo(const Array& params, bool fHelp)