flush wallet.dat, multi-proc, reorg options, revert to startup folder shortcut
Commit by Satoshi Nakamoto (s_nakamoto) on 21 October 2009 · SVN r15 · release v0.2.0 · 20 files, +1,968 −1,373
Open in Satoshi Mail View on GitHub
Files changed
build.txt
@@ -1,4 +1,4 @@
-BitCoin v0.1.5 ALPHA
+BitCoin v0.1.6 ALPHA
Copyright (c) 2009 Satoshi Nakamoto
Distributed under the MIT/X11 software license, see the accompanying
@@ -10,7 +10,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com).
Compilers Supported
-------------------
-MinGW GCC (v3.4.5)
+MinGW GCC (currently v3.4.5)
Microsoft Visual C++ 6.0 SP6
@@ -31,6 +31,16 @@ Berkeley DB New BSD license with additional requirement that linked software
Boost MIT-like license
+Notes
+-----
+The UI layout is edited with wxFormBuilder. Open the project file
+uiproject.fbp. It generates uibase.cpp and uibase.h, which define base
+classes that do the rote work of constructing all the UI elements.
+
+The release is built with GCC and then "strip bitcoin.exe" to strip the debug
+symbols, which reduces the executable size by about 90%.
+
+
OpenSSL
-------
Bitcoin does not use any encryption. If you want to do a no-everything
@@ -47,7 +57,7 @@ Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line:
Edit ms\mingw32.bat and replace the Configure line's parameters with this
no-everything list. You have to put this in the batch file because batch
-files can't handle more than 9 parameters.
+files can't take more than 9 command line parameters.
perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh
Also REM out the following line in ms\mingw32.bat. The build fails after it's
@@ -64,7 +74,7 @@ If you want to use it with MSVC, generate the .lib file
Berkeley DB
-----------
-MinGW with MSYS:
+Using MinGW and MSYS:
cd \DB\build_unix
sh ../dist/configure --enable-mingw --enable-cxx
make
@@ -72,5 +82,6 @@ make
Boost
-----
-You may need Boost version 1.35 to build with MSVC 6.0. I couldn't get
-version 1.37 to compile with MSVC 6.0.
+If you have trouble compiling Boost with Microsoft Visual C++ 6.0, try going
+back to Boost version 1.35. It looks like they may be starting to reduce
+support for MSVC 6.0.
db.cpp
@@ -453,11 +453,7 @@ bool CAddrDB::LoadAddresses()
}
}
- //// debug print
- printf("mapAddresses:\n");
- foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
- item.second.print();
- printf("-----\n");
+ printf("Loaded %d addresses\n", mapAddresses.size());
// Fix for possible bug that manifests in mapAddresses.count in irc.cpp,
// just need to call count here and it doesn't happen there. The bug was the
@@ -501,6 +497,26 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews)
// CWalletDB
//
+CWalletDB::~CWalletDB()
+{
+ // Flush whenever all handles to wallet.dat are closed
+ Close();
+ CRITICAL_BLOCK(cs_db)
+ {
+ map<string, int>::iterator mi = mapFileUseCount.find(strFile);
+ if (mi != mapFileUseCount.end())
+ {
+ int nRefCount = (*mi).second;
+ if (nRefCount == 0)
+ {
+ dbenv.txn_checkpoint(0, 0, 0);
+ dbenv.lsn_reset(strFile.c_str(), 0);
+ mapFileUseCount.erase(mi++);
+ }
+ }
+ }
+}
+
bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
{
vchDefaultKeyRet.clear();
@@ -568,34 +584,51 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
{
ssValue >> vchDefaultKeyRet;
}
- else if (strType == "setting") /// or settings or option or options or config?
+ else if (strType == "setting")
{
string strKey;
ssKey >> strKey;
+
+ // Menu state
+ if (strKey == "fShowGenerated") ssValue >> fShowGenerated;
if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins;
+
+ // Options
if (strKey == "nTransactionFee") ssValue >> nTransactionFee;
if (strKey == "addrIncoming") ssValue >> addrIncoming;
- if (strKey == "minimizeToTray") ssValue >> minimizeToTray;
- if (strKey == "closeToTray") ssValue >> closeToTray;
- if (strKey == "startOnSysBoot") ssValue >> startOnSysBoot;
- if (strKey == "askBeforeClosing") ssValue >> askBeforeClosing;
- if (strKey == "alwaysShowTrayIcon") ssValue >> alwaysShowTrayIcon;
+ if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors;
+ if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors;
+ if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray;
+ if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose;
}
}
}
+ printf("fShowGenerated = %d\n", fShowGenerated);
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
printf("nTransactionFee = %I64d\n", nTransactionFee);
printf("addrIncoming = %s\n", addrIncoming.ToString().c_str());
+ printf("fMinimizeToTray = %d\n", fMinimizeToTray);
+ printf("fMinimizeOnClose = %d\n", fMinimizeOnClose);
+
+ // The transaction fee setting won't be needed for many years to come.
+ // Setting it to zero here in case they set it to something in an earlier version.
+ if (nTransactionFee != 0)
+ {
+ nTransactionFee = 0;
+ WriteSetting("nTransactionFee", nTransactionFee);
+ }
return true;
}
-bool LoadWallet()
+bool LoadWallet(bool& fFirstRunRet)
{
+ fFirstRunRet = false;
vector<unsigned char> vchDefaultKey;
if (!CWalletDB("cr").LoadWallet(vchDefaultKey))
return false;
+ fFirstRunRet = vchDefaultKey.empty();
if (mapKeys.count(vchDefaultKey))
{
db.h
@@ -338,6 +338,7 @@ class CWalletDB : public CDB
{
public:
CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { }
+ ~CWalletDB();
private:
CWalletDB(const CWalletDB&);
void operator=(const CWalletDB&);
@@ -412,7 +413,7 @@ public:
bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet);
};
-bool LoadWallet();
+bool LoadWallet(bool& fFirstRunRet);
inline bool SetAddressBookName(const string& strAddress, const string& strName)
{
headers.h
@@ -10,11 +10,11 @@
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x0400
#ifdef _WIN32_IE
#undef _WIN32_IE
#endif
-#define _WIN32_IE 0x0500
+#define _WIN32_IE 0x0400
#define WIN32_LEAN_AND_MEAN 1
#include <wx/wx.h>
#include <wx/clipbrd.h>
@@ -28,6 +28,8 @@
#include <windows.h>
#include <winsock2.h>
#include <mswsock.h>
+#include <shlobj.h>
+#include <shlwapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
irc.cpp
@@ -52,7 +52,7 @@ bool DecodeAddress(string str, CAddress& addr)
static bool Send(SOCKET hSocket, const char* pszSend)
{
if (strstr(pszSend, "PONG") != pszSend)
- printf("SENDING: %s\n", pszSend);
+ printf("IRC SENDING: %s\n", pszSend);
const char* psz = pszSend;
const char* pszEnd = psz + strlen(psz);
while (psz < pszEnd)
@@ -145,7 +145,7 @@ bool Wait(int nSeconds)
{
if (fShutdown)
return false;
- printf("Waiting %d seconds to reconnect to IRC\n", nSeconds);
+ printf("IRC waiting %d seconds to reconnect\n", nSeconds);
for (int i = 0; i < nSeconds; i++)
{
if (fShutdown)
@@ -220,7 +220,6 @@ void ThreadIRCSeed(void* parg)
{
if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
continue;
- printf("IRC %s\n", strLine.c_str());
vector<string> vWords;
ParseString(strLine, ' ', vWords);
@@ -235,7 +234,7 @@ void ThreadIRCSeed(void* parg)
// index 7 is limited to 16 characters
// could get full length name at index 10, but would be different from join messages
strcpy(pszName, vWords[7].c_str());
- printf("GOT WHO: [%s] ", pszName);
+ printf("IRC got who\n");
}
if (vWords[1] == "JOIN" && vWords[0].size() > 1)
@@ -244,7 +243,7 @@ void ThreadIRCSeed(void* parg)
strcpy(pszName, vWords[0].c_str() + 1);
if (strchr(pszName, '!'))
*strchr(pszName, '!') = '\0';
- printf("GOT JOIN: [%s] ", pszName);
+ printf("IRC got join\n");
}
if (pszName[0] == 'u')
@@ -254,7 +253,7 @@ void ThreadIRCSeed(void* parg)
{
CAddrDB addrdb;
if (AddAddress(addrdb, addr))
- printf("new ");
+ printf("IRC got new address\n");
else
{
// make it try connecting again
@@ -262,14 +261,13 @@ void ThreadIRCSeed(void* parg)
if (mapAddresses.count(addr.GetKey()))
mapAddresses[addr.GetKey()].nLastFailed = 0;
}
- addr.print();
CRITICAL_BLOCK(cs_mapIRCAddresses)
mapIRCAddresses.insert(make_pair(addr.GetKey(), addr));
}
else
{
- printf("decode failed\n");
+ printf("IRC decode failed\n");
}
}
}
key.h
@@ -44,6 +44,7 @@ class CKey
{
protected:
EC_KEY* pkey;
+ bool fSet;
public:
CKey()
@@ -51,6 +52,7 @@ public:
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
if (pkey == NULL)
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
+ fSet = false;
}
CKey(const CKey& b)
@@ -58,12 +60,14 @@ public:
pkey = EC_KEY_dup(b.pkey);
if (pkey == NULL)
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
+ fSet = b.fSet;
}
CKey& operator=(const CKey& b)
{
if (!EC_KEY_copy(pkey, b.pkey))
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
+ fSet = b.fSet;
return (*this);
}
@@ -72,10 +76,16 @@ public:
EC_KEY_free(pkey);
}
+ bool IsNull() const
+ {
+ return !fSet;
+ }
+
void MakeNewKey()
{
if (!EC_KEY_generate_key(pkey))
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
+ fSet = true;
}
bool SetPrivKey(const CPrivKey& vchPrivKey)
@@ -83,6 +93,7 @@ public:
const unsigned char* pbegin = &vchPrivKey[0];
if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
return false;
+ fSet = true;
return true;
}
@@ -103,6 +114,7 @@ public:
const unsigned char* pbegin = &vchPubKey[0];
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
return false;
+ fSet = true;
return true;
}
main.cpp
@@ -34,7 +34,7 @@ map<uint256, CDataStream*> mapOrphanTransactions;
multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
map<uint256, CWalletTx> mapWallet;
-vector<pair<uint256, bool> > vWalletUpdated;
+vector<uint256> vWalletUpdated;
CCriticalSection cs_mapWallet;
map<vector<unsigned char>, CPrivKey> mapKeys;
@@ -46,9 +46,12 @@ string strSetDataDir;
int nDropMessagesTest = 0;
// Settings
-int fGenerateBitcoins;
+int fGenerateBitcoins = false;
int64 nTransactionFee = 0;
CAddress addrIncoming;
+int fLimitProcessors = false;
+int nLimitProcessors = 1;
+
@@ -135,7 +138,7 @@ bool AddToWallet(const CWalletTx& wtxIn)
return false;
// Notify UI
- vWalletUpdated.push_back(make_pair(hash, fInsertedNew));
+ vWalletUpdated.push_back(hash);
}
// Refresh UI
@@ -1126,6 +1129,9 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
}
}
+ // Notify UI to update prev block coinbase if it was ours
+ vWalletUpdated.push_back(hashBestChain);
+
// New best link
hashBestChain = hash;
pindexBest = pindexNew;
@@ -1702,7 +1708,7 @@ bool ProcessMessages(CNode* pfrom)
}
CATCH_PRINT_EXCEPTION("ProcessMessage()")
if (!fRet)
- printf("ProcessMessage(%s, %d bytes) from %s to %s FAILED\n", strCommand.c_str(), nMessageSize, pfrom->addr.ToString().c_str(), addrLocalHost.ToString().c_str());
+ printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize);
}
vRecv.Compact();
@@ -1715,10 +1721,7 @@ bool ProcessMessages(CNode* pfrom)
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
static map<unsigned int, vector<unsigned char> > mapReuseKey;
- printf("received: %-12s (%d bytes) ", strCommand.c_str(), vRecv.size());
- for (int i = 0; i < min(vRecv.size(), (unsigned int)20); i++)
- printf("%02x ", vRecv[i] & 0xff);
- printf("\n");
+ printf("received: %-12s (%d bytes)\n", strCommand.c_str(), vRecv.size());
if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
{
printf("dropmessages DROPPING RECV MESSAGE\n");
@@ -1759,7 +1762,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0));
}
- printf("version message: %s has version %d, addrMe=%s\n", pfrom->addr.ToString().c_str(), pfrom->nVersion, addrMe.ToString().c_str());
+ printf("version message: version %d\n", pfrom->nVersion);
}
@@ -1775,13 +1778,24 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vector<CAddress> vAddr;
vRecv >> vAddr;
+ // Clear addrknown lists periodically to allow refresh broadcasts
+ static int64 nLastClearedAddrKnown;
+ if (nLastClearedAddrKnown < GetAdjustedTime() - 24 * 60 * 60)
+ {
+ nLastClearedAddrKnown = GetAdjustedTime();
+ CRITICAL_BLOCK(cs_vNodes)
+ foreach(CNode* pnode, vNodes)
+ pnode->setAddrKnown.clear();
+ }
+
// Store the new addresses
CAddrDB addrdb;
foreach(const CAddress& addr, vAddr)
{
if (fShutdown)
return true;
- if (AddAddress(addrdb, addr))
+ AddAddress(addrdb, addr);
+ if (addr.IsRoutable() && addr.ip != addrLocalHost.ip)
{
// Put on lists to send to other nodes
pfrom->setAddrKnown.insert(addr);
@@ -1989,8 +2003,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (fShutdown)
return true;
const CAddress& addr = item.second;
- //// will need this if we lose IRC
- //if (addr.nTime > nSince || (rand() % nSize) < 500)
if (addr.nTime > nSince)
pfrom->vAddrToSend.push_back(addr);
}
@@ -2132,9 +2144,11 @@ bool SendMessages(CNode* pto)
while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
{
const CInv& inv = (*pto->mapAskFor.begin()).second;
- printf("sending getdata: %s\n", inv.ToString().c_str());
if (!AlreadyHave(txdb, inv))
+ {
+ printf("sending getdata: %s\n", inv.ToString().c_str());
vAskFor.push_back(inv);
+ }
pto->mapAskFor.erase(pto->mapAskFor.begin());
}
if (!vAskFor.empty())
@@ -2162,6 +2176,49 @@ bool SendMessages(CNode* pto)
// BitcoinMiner
//
+void GenerateBitcoins(bool fGenerate)
+{
+ if (fGenerateBitcoins != fGenerate)
+ {
+ fGenerateBitcoins = fGenerate;
+ CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
+ MainFrameRepaint();
+ }
+ if (fGenerateBitcoins)
+ {
+ int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS"));
+ printf("%d processors\n", nProcessors);
+ if (nProcessors < 1)
+ nProcessors = 1;
+ if (fLimitProcessors && nProcessors > nLimitProcessors)
+ nProcessors = nLimitProcessors;
+ int nAddThreads = nProcessors - vnThreadsRunning[3];
+ printf("starting %d bitcoinminer threads\n", nAddThreads);
+ for (int i = 0; i < nAddThreads; i++)
+ if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)
+ printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");
+ }
+}
+
+void ThreadBitcoinMiner(void* parg)
+{
+ vnThreadsRunning[3]++;
+ CheckForShutdown(3);
+ try
+ {
+ bool fRet = BitcoinMiner();
+ printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false");
+ vnThreadsRunning[3]--;
+ }
+ catch (std::exception& e) {
+ vnThreadsRunning[3]--;
+ PrintException(&e, "ThreadBitcoinMiner()");
+ } catch (...) {
+ vnThreadsRunning[3]--;
+ PrintException(NULL, "ThreadBitcoinMiner()");
+ }
+}
+
int FormatHashBlocks(void* pbuffer, unsigned int len)
{
unsigned char* pdata = (unsigned char*)pbuffer;
@@ -2210,13 +2267,13 @@ void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout)
bool BitcoinMiner()
{
printf("BitcoinMiner started\n");
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
CKey key;
key.MakeNewKey();
CBigNum bnExtraNonce = 0;
while (fGenerateBitcoins)
{
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
Sleep(50);
CheckForShutdown(3);
while (vNodes.empty())
@@ -2338,7 +2395,6 @@ bool BitcoinMiner()
BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1);
BlockSHA256(&tmp.hash1, nBlocks1, &hash);
-
if (hash <= hashTarget)
{
pblock->nNonce = tmp.block.nNonce;
@@ -2352,6 +2408,12 @@ bool BitcoinMiner()
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
CRITICAL_BLOCK(cs_main)
{
+ if (pindexPrev != pindexBest)
+ {
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
+ break;
+ }
+
// Save key
if (!AddKey(key))
return false;
@@ -2368,7 +2430,7 @@ bool BitcoinMiner()
}
// Update nTime every few seconds
- if ((++tmp.block.nNonce & 0x3ffff) == 0)
+ if ((++tmp.block.nNonce & 0xffff) == 0)
{
CheckForShutdown(3);
if (tmp.block.nNonce == 0)
@@ -2379,6 +2441,8 @@ bool BitcoinMiner()
break;
if (!fGenerateBitcoins)
break;
+ if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
+ return true;
tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
}
}
@@ -2538,7 +2602,7 @@ bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
-bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, int64& nFeeRequiredRet)
+bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet)
{
nFeeRequiredRet = 0;
CRITICAL_BLOCK(cs_main)
@@ -2565,30 +2629,28 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in
foreach(CWalletTx* pcoin, setCoins)
nValueIn += pcoin->GetCredit();
- // Fill vout[0] to the payee
- wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
+ // Fill a vout to the payee
+ bool fChangeFirst = GetRand(2);
+ if (!fChangeFirst)
+ wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
- // Fill vout[1] back to self with any change
+ // Fill a vout back to self with any change
if (nValueIn > nValue)
{
- /// todo: for privacy, should randomize the order of outputs,
- // would also have to use a new key for the change.
- // Use the same key as one of the coins
- vector<unsigned char> vchPubKey;
- CTransaction& txFirst = *(*setCoins.begin());
- foreach(const CTxOut& txout, txFirst.vout)
- if (txout.IsMine())
- if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
- break;
- if (vchPubKey.empty())
- return false;
+ // New private key
+ if (keyRet.IsNull())
+ keyRet.MakeNewKey();
- // Fill vout[1] to ourself
+ // Fill a vout to ourself
CScript scriptPubKey;
- scriptPubKey << vchPubKey << OP_CHECKSIG;
+ scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG;
wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey));
}
+ // Fill a vout to the payee
+ if (fChangeFirst)
+ wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
+
// Fill vin
foreach(CWalletTx* pcoin, setCoins)
for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
@@ -2621,13 +2683,24 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in
}
// Call after CreateTransaction unless you want to abort
-bool CommitTransactionSpent(const CWalletTx& wtxNew)
+bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key)
{
CRITICAL_BLOCK(cs_main)
CRITICAL_BLOCK(cs_mapWallet)
{
- //// todo: make this transactional, never want to add a transaction
- //// without marking spent transactions
+ //// todo: eventually should make this transactional, never want to add a
+ //// transaction without marking spent transactions, although the risk of
+ //// interruption during this step is remote.
+
+ // This is only to keep the database open to defeat the auto-flush for the
+ // duration of this scope. This is the only place where this optimization
+ // maybe makes sense; please don't do it anywhere else. Keeping databases
+ // open longer than necessary can create deadlocks.
+ CWalletDB walletdb("r");
+
main.h
@@ -41,6 +41,9 @@ extern int nDropMessagesTest;
extern int fGenerateBitcoins;
extern int64 nTransactionFee;
extern CAddress addrIncoming;
+extern int fLimitProcessors;
+extern int nLimitProcessors;
+
@@ -58,14 +61,17 @@ void ReacceptWalletTransactions();
void RelayWalletTransactions();
bool LoadBlockIndex(bool fAllowNew=true);
void PrintBlockTree();
-bool BitcoinMiner();
bool ProcessMessages(CNode* pfrom);
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
bool SendMessages(CNode* pto);
int64 GetBalance();
-bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& txNew, int64& nFeeRequiredRet);
-bool CommitTransactionSpent(const CWalletTx& wtxNew);
+bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet);
+bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key);
bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew);
+void GenerateBitcoins(bool fGenerate);
+void ThreadBitcoinMiner(void* parg);
+bool BitcoinMiner();
+
@@ -1320,7 +1326,7 @@ public:
extern map<uint256, CTransaction> mapTransactions;
extern map<uint256, CWalletTx> mapWallet;
-extern vector<pair<uint256, bool> > vWalletUpdated;
+extern vector<uint256> vWalletUpdated;
extern CCriticalSection cs_mapWallet;
extern map<vector<unsigned char>, CPrivKey> mapKeys;
extern map<uint160, vector<unsigned char> > mapPubKeys;
makefile
@@ -12,7 +12,7 @@ ifeq "$(BUILD)" "debug"
D=d
# note: gcc 3.x profile doesn't work
#DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__
-DEBUGFLAGS=-g -D__WXDEBUG__ -Wall -Wextra
+DEBUGFLAGS=-g -D__WXDEBUG__
endif
@@ -23,7 +23,7 @@ LIBS= \
-l db_cxx \
-l eay32 \
-l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \
- -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32
+ -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
makefile.vc
@@ -18,8 +18,8 @@ LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:
LIBS= \
libdb47s$(D).lib \
libeay32.lib \
- wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).lib \
- kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib
+ wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).lib \
+ kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
net.cpp
@@ -23,7 +23,8 @@ CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
CNode* pnodeLocalHost = &nodeLocalHost;
bool fShutdown = false;
-array<bool, 10> vfThreadRunning;
+array<int, 10> vnThreadsRunning;
+
vector<CNode*> vNodes;
CCriticalSection cs_vNodes;
map<vector<unsigned char>, CAddress> mapAddresses;
@@ -57,7 +58,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
if (fProxy)
{
- printf("Proxy connecting to %s\n", addrConnect.ToString().c_str());
+ printf("Proxy connecting %s\n", addrConnect.ToStringLog().c_str());
char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
@@ -81,7 +82,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
closesocket(hSocket);
return error("Proxy returned error %d\n", pchRet[1]);
}
- printf("Proxy connection established %s\n", addrConnect.ToString().c_str());
+ printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str());
}
hSocketRet = hSocket;
@@ -219,6 +220,13 @@ bool AddAddress(CAddrDB& addrdb, const CAddress& addr)
addrdb.WriteAddress(addrFound);
return true;
}
+ else if (addrFound.nTime < GetAdjustedTime() - 24 * 60 * 60)
+ {
+ // Periodically update most recently seen time
+ addrFound.nTime = GetAdjustedTime();
+ addrdb.WriteAddress(addrFound);
+ return false;
+ }
}
}
return false;
@@ -373,14 +381,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
}
/// debug print
- printf("trying %s\n", addrConnect.ToString().c_str());
+ printf("trying connection %s\n", addrConnect.ToStringLog().c_str());
// Connect
SOCKET hSocket;
if (ConnectSocket(addrConnect, hSocket))
{
/// debug print
- printf("connected %s\n", addrConnect.ToString().c_str());
+ printf("connected %s\n", addrConnect.ToStringLog().c_str());
// Set to nonblocking
u_long nOne = 1;
@@ -410,7 +418,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
void CNode::Disconnect()
{
- printf("disconnecting node %s\n", addr.ToString().c_str());
+ printf("disconnecting node %s\n", addr.ToStringLog().c_str());
closesocket(hSocket);
@@ -450,14 +458,20 @@ void ThreadSocketHandler(void* parg)
loop
{
- vfThreadRunning[0] = true;
+ vnThreadsRunning[0] = true;
CheckForShutdown(0);
try
{
ThreadSocketHandler2(parg);
+ vnThreadsRunning[0] = false;
+ }
+ catch (std::exception& e) {
+ vnThreadsRunning[0] = false;
+ PrintException(&e, "ThreadSocketHandler()");
+ } catch (...) {
+ vnThreadsRunning[0] = false;
+ PrintException(NULL, "ThreadSocketHandler()");
}
- CATCH_PRINT_EXCEPTION("ThreadSocketHandler()")
- vfThreadRunning[0] = false;
Sleep(5000);
}
}
@@ -548,9 +562,9 @@ void ThreadSocketHandler2(void* parg)
}
}
- vfThreadRunning[0] = false;
+ vnThreadsRunning[0] = false;
int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout);
- vfThreadRunning[0] = true;
+ vnThreadsRunning[0] = true;
CheckForShutdown(0);
if (nSelect == SOCKET_ERROR)
{
@@ -590,7 +604,7 @@ void ThreadSocketHandler2(void* parg)
}
else
{
- printf("accepted connection from %s\n", addr.ToString().c_str());
+ printf("accepted connection %s\n", addr.ToStringLog().c_str());
CNode* pnode = new CNode(hSocket, addr, true);
pnode->AddRef();
CRITICAL_BLOCK(cs_vNodes)
@@ -697,14 +711,20 @@ void ThreadOpenConnections(void* parg)
loop
{
- vfThreadRunning[1] = true;
+ vnThreadsRunning[1] = true;
CheckForShutdown(1);
try
{
ThreadOpenConnections2(parg);
+ vnThreadsRunning[1] = false;
+ }
+ catch (std::exception& e) {
+ vnThreadsRunning[1] = false;
+ PrintException(&e, "ThreadOpenConnections()");
+ } catch (...) {
+ vnThreadsRunning[1] = false;
+ PrintException(NULL, "ThreadOpenConnections()");
}
- CATCH_PRINT_EXCEPTION("ThreadOpenConnections()")
- vfThreadRunning[1] = false;
Sleep(5000);
}
}
@@ -720,14 +740,14 @@ void ThreadOpenConnections2(void* parg)
loop
{
// Wait
- vfThreadRunning[1] = false;
+ vnThreadsRunning[1] = false;
Sleep(500);
while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size())
{
CheckForShutdown(1);
Sleep(2000);
}
- vfThreadRunning[1] = true;
+ vnThreadsRunning[1] = true;
CheckForShutdown(1);
@@ -823,9 +843,9 @@ void ThreadOpenConnections2(void* parg)
if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
continue;
- vfThreadRunning[1] = false;
+ vnThreadsRunning[1] = false;
CNode* pnode = ConnectNode(addrConnect);
- vfThreadRunning[1] = true;
+ vnThreadsRunning[1] = true;
CheckForShutdown(1);
if (!pnode)
continue;
@@ -867,14 +887,20 @@ void ThreadMessageHandler(void* parg)
loop
{
- vfThreadRunning[2] = true;
+ vnThreadsRunning[2] = true;
CheckForShutdown(2);
try
{
ThreadMessageHandler2(parg);
+ vnThreadsRunning[2] = false;
+ }
+ catch (std::exception& e) {
+ vnThreadsRunning[2] = false;
+ PrintException(&e, "ThreadMessageHandler()");
+ } catch (...) {
+ vnThreadsRunning[2] = false;
+ PrintException(NULL, "ThreadMessageHandler()");
}
- CATCH_PRINT_EXCEPTION("ThreadMessageHandler()")
- vfThreadRunning[2] = false;
Sleep(5000);
}
}
@@ -905,9 +931,9 @@ void ThreadMessageHandler2(void* parg)
}
// Wait and allow messages to bunch up
- vfThreadRunning[2] = false;
+ vnThreadsRunning[2] = false;
Sleep(100);
- vfThreadRunning[2] = true;
+ vnThreadsRunning[2] = true;
CheckForShutdown(2);
}
}
@@ -920,29 +946,6 @@ void ThreadMessageHandler2(void* parg)
-//// todo: start one thread per processor, use getenv("NUMBER_OF_PROCESSORS")
-void ThreadBitcoinMiner(void* parg)
-{
- vfThreadRunning[3] = true;
- CheckForShutdown(3);
- try
- {
- bool fRet = BitcoinMiner();
- printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false");
- }
- CATCH_PRINT_EXCEPTION("BitcoinMiner()")
- vfThreadRunning[3] = false;
-}
-
-
-
-
-
-
-
-
-
-
bool StartNode(string& strError)
{
@@ -1067,17 +1070,17 @@ bool StopNode()
fShutdown = true;
nTransactionsUpdated++;
int64 nStart = GetTime();
- while (vfThreadRunning[0] || vfThreadRunning[2] || vfThreadRunning[3])
+ while (vnThreadsRunning[0] || vnThreadsRunning[2] || vnThreadsRunning[3])
{
if (GetTime() - nStart > 15)
break;
Sleep(20);
}
- if (vfThreadRunning[0]) printf("ThreadSocketHandler still running\n");
- if (vfThreadRunning[1]) printf("ThreadOpenConnections still running\n");
- if (vfThreadRunning[2]) printf("ThreadMessageHandler still running\n");
- if (vfThreadRunning[3]) printf("ThreadBitcoinMiner still running\n");
- while (vfThreadRunning[2])
+ if (vnThreadsRunning[0]) printf("ThreadSocketHandler still running\n");
+ if (vnThreadsRunning[1]) printf("ThreadOpenConnections still running\n");
+ if (vnThreadsRunning[2]) printf("ThreadMessageHandler still running\n");
+ if (vnThreadsRunning[3]) printf("ThreadBitcoinMiner still running\n");
+ while (vnThreadsRunning[2])
Sleep(20);
Sleep(50);
@@ -1091,7 +1094,7 @@ void CheckForShutdown(int n)
if (fShutdown)
{
if (n != -1)
- vfThreadRunning[n] = false;
+ vnThreadsRunning[n] = false;
if (n == 0)
foreach(CNode* pnode, vNodes)
closesocket(pnode->hSocket);
net.h
@@ -20,8 +20,6 @@ enum
-
-
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
bool GetMyExternalIP(unsigned int& ipRet);
bool AddAddress(CAddrDB& addrdb, const CAddress& addr);
@@ -29,7 +27,6 @@ CNode* FindNode(unsigned int ip);
CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
bool AnySubscribed(unsigned int nChannel);
-void ThreadBitcoinMiner(void* parg);
bool StartNode(string& strError=REF(string()));
bool StopNode();
void CheckForShutdown(int n);
@@ -206,7 +203,7 @@ public:
READWRITE(nTime);
}
READWRITE(nServices);
- READWRITE(FLATDATA(pchReserved));
+ READWRITE(FLATDATA(pchReserved)); // for IPv6
READWRITE(ip);
READWRITE(port);
)
@@ -280,10 +277,14 @@ public:
return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
}
+ string ToStringLog() const
+ {
+ return "";
+ }
+
string ToString() const
{
return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
- //return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
}
void print() const
@@ -416,7 +417,7 @@ extern uint64 nLocalServices;
extern CAddress addrLocalHost;
extern CNode* pnodeLocalHost;
extern bool fShutdown;
-extern array<bool, 10> vfThreadRunning;
+extern array<int, 10> vnThreadsRunning;
extern vector<CNode*> vNodes;
extern CCriticalSection cs_vNodes;
extern map<vector<unsigned char>, CAddress> mapAddresses;
@@ -599,9 +600,7 @@ public:
unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);
memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
- printf("(%d bytes) ", nSize);
- //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++)
- // printf("%02x ", vSend[i] & 0xff);
+ printf("(%d bytes) ", nSize);
printf("\n");
nPushPos = -1;
readme.txt
serialize.h
@@ -19,7 +19,7 @@ class CScript;
class CDataStream;
class CAutoFile;
-static const int VERSION = 105;
+static const int VERSION = 106;
ui.cpp
@@ -7,6 +7,13 @@
#include <crtdbg.h>
#endif
+void ThreadRequestProductDetails(void* parg);
+void ThreadRandSendTest(void* parg);
+bool GetStartOnSystemStartup();
+void SetStartOnSystemStartup(bool fAutoStart);
+
+
+
DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL)
DEFINE_EVENT_TYPE(wxEVT_REPLY1)
DEFINE_EVENT_TYPE(wxEVT_REPLY2)
@@ -16,22 +23,21 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED)
DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED)
CMainFrame* pframeMain = NULL;
+CMyTaskBarIcon* ptaskbaricon = NULL;
map<string, string> mapAddressBook;
-CBitcoinTBIcon* taskBarIcon = NULL; // Tray icon
-
-
-void ThreadRequestProductDetails(void* parg);
-void ThreadRandSendTest(void* parg);
+map<string, string> mapArgs;
bool fRandSendTest = false;
void RandSend();
extern int g_isPainting;
-// UI settings and their default values
-int minimizeToTray = 1;
-int closeToTray = 1;
-int startOnSysBoot = 1;
-int askBeforeClosing = 1;
-int alwaysShowTrayIcon = 1;
+// Settings
+int fShowGenerated = true;
+int fMinimizeToTray = true;
+int fMinimizeOnClose = true;
+
+
+
+
@@ -282,7 +288,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
m_listCtrl->SetFocus();
SetIcon(wxICON(bitcoin));
- m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins);
+ ptaskbaricon = new CMyTaskBarIcon();
// Init toolbar with transparency masked bitmaps
m_toolBar->ClearTools();
@@ -327,7 +333,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
//m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100);
// Init status bar
- int pnWidths[3] = { -100, 81, 286 };
+ int pnWidths[3] = { -100, 88, 290 };
m_statusBar->SetFieldsCount(3, pnWidths);
// Fill your address text box
@@ -342,6 +348,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
CMainFrame::~CMainFrame()
{
pframeMain = NULL;
+ delete ptaskbaricon;
+ ptaskbaricon = NULL;
}
void Shutdown(void* parg)
@@ -362,28 +370,24 @@ void Shutdown(void* parg)
void CMainFrame::OnClose(wxCloseEvent& event)
{
- if (closeToTray && event.CanVeto()) {
- event.Veto();
- SendToTray();
- }
- else if (!event.CanVeto() || !askBeforeClosing || wxMessageBox("Quit program?", "Confirm", wxYES_NO, this) == wxYES) {
- delete taskBarIcon;
- Destroy();
- _beginthread(Shutdown, 0, NULL);
- }
+ if (fMinimizeToTray && fMinimizeOnClose && event.CanVeto() && !IsIconized())
+ {
+ // Divert close to minimize
+ event.Veto();
+ Iconize(true);
+ }
+ else
+ {
+ Destroy();
+ _beginthread(Shutdown, 0, NULL);
+ }
}
void CMainFrame::OnIconize(wxIconizeEvent& event)
{
- if (minimizeToTray) {
- SendToTray();
- }
-}
-
-void CMainFrame::SendToTray()
-{
- Hide();
- taskBarIcon->Show();
+ // Hide the task bar button when minimized.
+ // Event is sent when the frame is minimized or restored.
+ Show(!fMinimizeToTray || !event.Iconized());
}
void CMainFrame::OnMouseEvents(wxMouseEvent& event)
@@ -405,25 +409,21 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo
string str0 = strSort;
long nData = *(long*)&hashKey;
- if (fNew)
+ // Find item
+ if (!fNew && nIndex == -1)
+ {
+ while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1)
+ if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString())
+ break;
+ }
+
+ // fNew is for blind insert, only use if you're sure it's new
+ if (fNew || nIndex == -1)
{
nIndex = m_listCtrl->InsertItem(0, str0);
}
else
{
- if (nIndex == -1)
- {
- // Find item
- while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1)
- if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString())
- break;
- if (nIndex == -1)
- {
- printf("CMainFrame::InsertLine : Couldn't find item to be updated\n");
- return;
- }
- }
-
// If sort key changed, must delete and reinsert to make it relocate
if (GetItemText(m_listCtrl, nIndex, 0) != str0)
{
@@ -484,6 +484,28 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
string strStatus = FormatTxStatus(wtx);
map<string, string> mapValue = wtx.mapValue;
+ // Filter
+ if (wtx.IsCoinBase())
+ {
+ // View->Show Generated
+ if (!fShowGenerated)
+ return;
+
+ // Don't show generated coin until confirmed by at least one block after it
+ // so we don't get the user's hopes up until it looks like it's probably accepted.
+ //
+ // It is not an error when generated blocks are not accepted. By design,
+ // some percentage of blocks, like 10% or more, will end up not accepted.
+ // This is the normal mechanism by which the network copes with latency.
+ //
+ // We display regular transactions right away before any confirmation
+ // because they can always get into some block eventually. Generated coins
+ // are special because if their block is not accepted, they are not valid.
+ //
+ if (wtx.GetDepthInMainChain() < 2)
+ return;
+ }
+
// Find the block the tx is in
CBlockIndex* pindex = NULL;
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock);
@@ -785,16 +807,11 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
{
TRY_CRITICAL_BLOCK(cs_mapWallet)
{
- pair<uint256, bool> item;
- foreach(item, vWalletUpdated)
+ foreach(uint256 hash, vWalletUpdated)
{
- bool fNew = item.second;
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(item.first);
+ map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
if (mi != mapWallet.end())
- {
- printf("vWalletUpdated: %s %s\n", (*mi).second.GetHash().ToString().substr(0,6).c_str(), fNew ? "new" : "");
- InsertTransaction((*mi).second, fNew);
- }
+ InsertTransaction((*mi).second, false);
}
m_listCtrl->ScrollList(0, INT_MAX);
vWalletUpdated.clear();
@@ -807,7 +824,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
// Update status bar
string strGen = "";
if (fGenerateBitcoins)
- strGen = " Generating";
+ strGen = " Generating";
if (fGenerateBitcoins && vNodes.empty())
strGen = "(not connected)";
m_statusBar->SetStatusText(strGen, 1);
@@ -856,39 +873,54 @@ void CMainFrame::OnCrossThreadCall(wxCommandEvent& event)
void CMainFrame::OnMenuFileExit(wxCommandEvent& event)
{
+ // File->Exit
Close(true);
}
+void CMainFrame::OnMenuViewShowGenerated(wxCommandEvent& event)
+{
+ // View->Show Generated
+ fShowGenerated = event.IsChecked();
+ CWalletDB().WriteSetting("fShowGenerated", fShowGenerated);
+ RefreshListCtrl();
+}
+
+void CMainFrame::OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event)
+{
+ event.Check(fShowGenerated);
+}
+
void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event)
{
+ // Options->Generate Coins
GenerateBitcoins(event.IsChecked());
+}
- Refresh();
- wxPaintEvent eventPaint;
- AddPendingEvent(eventPaint);
+void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event)
+{
+ event.Check(fGenerateBitcoins);
}
void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event)
{
+ // Options->Change Your Address
OnButtonChange(event);
}
void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event)
{
+ // Options->Options
COptionsDialog dialog(this);
dialog.ShowModal();
}
void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event)
{
+ // Help->About
CAboutDialog dialog(this);
dialog.ShowModal();
}
-void CMainFrame::OnUpdateMenuGenerate( wxUpdateUIEvent& event ) {
- event.Check(fGenerateBitcoins);
-}
-
void CMainFrame::OnButtonSend(wxCommandEvent& event)
{
/// debug test
@@ -1252,58 +1284,74 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event)
COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent)
{
+ // Set up list box of page choices
+ m_listBox->Append("Main");
+ //m_listBox->Append("Test 2");
+ m_listBox->SetSelection(0);
+ SelectPage(0);
+
+ // Init values
+ m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee));
+ m_checkBoxLimitProcessors->SetValue(fLimitProcessors);
+ m_spinCtrlLimitProcessors->Enable(fLimitProcessors);
+ m_spinCtrlLimitProcessors->SetValue(nLimitProcessors);
+ int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS"));
+ if (nProcessors < 1)
+ nProcessors = 999;
+ m_spinCtrlLimitProcessors->SetRange(1, nProcessors);
+ m_checkBoxStartOnSystemStartup->SetValue(fTmpStartOnSystemStartup = GetStartOnSystemStartup());
+ m_checkBoxMinimizeToTray->SetValue(fMinimizeToTray);
+ m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray);
+ m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose);
+ fTmpMinimizeOnClose = fMinimizeOnClose;
m_buttonOK->SetFocus();
- m_treeCtrl->AddRoot(wxT("Settings"));
- m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("Bitcoin"));
ui.h
@@ -21,21 +21,25 @@ enum
+
+extern map<string, string> mapArgs;
+
+// Settings
+extern int fShowGenerated;
+extern int fMinimizeToTray;
+extern int fMinimizeOnClose;
+
+
+
extern void HandleCtrlA(wxKeyEvent& event);
extern string DateTimeStr(int64 nTime);
extern string FormatTxStatus(const CWalletTx& wtx);
extern void CrossThreadCall(int nID, void* pdata);
extern void MainFrameRepaint();
extern void Shutdown(void* parg);
-void ApplyUISettings();
-void GenerateBitcoins(bool flag);
-// UI settings
-extern int minimizeToTray;
-extern int closeToTray;
-extern int startOnSysBoot;
-extern int askBeforeClosing;
-extern int alwaysShowTrayIcon;
+
+
@@ -44,14 +48,17 @@ class CMainFrame : public CMainFrameBase
protected:
// Event handlers
void OnClose(wxCloseEvent& event);
- void OnIconize( wxIconizeEvent& event );
+ void OnIconize(wxIconizeEvent& event);
void OnMouseEvents(wxMouseEvent& event);
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
void OnIdle(wxIdleEvent& event);
void OnPaint(wxPaintEvent& event);
void OnPaintListCtrl(wxPaintEvent& event);
void OnMenuFileExit(wxCommandEvent& event);
+ void OnMenuViewShowGenerated(wxCommandEvent& event);
+ void OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event);
void OnMenuOptionsGenerate(wxCommandEvent& event);
+ void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event);
void OnMenuOptionsChangeYourAddress(wxCommandEvent& event);
void OnMenuOptionsOptions(wxCommandEvent& event);
void OnMenuHelpAbout(wxCommandEvent& event);
@@ -66,7 +73,6 @@ protected:
void OnListItemActivatedProductsSent(wxListEvent& event);
void OnListItemActivatedOrdersSent(wxListEvent& event);
void OnListItemActivatedOrdersReceived(wxListEvent& event);
- void OnUpdateMenuGenerate( wxUpdateUIEvent& event );
public:
/** Constructor */
@@ -85,7 +91,6 @@ public:
void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
void RefreshListCtrl();
void RefreshStatus();
- void SendToTray();
};
@@ -107,47 +112,26 @@ public:
-class COptionsPanelBitcoin : public COptionsPanelBitcoinBase
-{
-protected:
- // Event handlers
- void OnKillFocusTransactionFee( wxFocusEvent& event );
-
-public:
- /** Constructor */
- COptionsPanelBitcoin(wxWindow* parent);
-};
-
-
-
-class COptionsPanelUI : public COptionsPanelUIBase
-{
-protected:
- // Event handlers
- void OnOptionsChanged( wxCommandEvent& event );
-
-public:
- /** Constructor */
- COptionsPanelUI(wxWindow* parent);
-};
-
-
-
class COptionsDialog : public COptionsDialogBase
{
protected:
// Event handlers
- void MenuSelChanged( wxTreeEvent& event );
+ void OnListBox(wxCommandEvent& event);
+ void OnKillFocusTransactionFee(wxFocusEvent& event);
+ void OnCheckBoxLimitProcessors(wxCommandEvent& event);
+ void OnCheckBoxMinimizeToTray(wxCommandEvent& event);
void OnButtonOK(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
+ void OnButtonApply(wxCommandEvent& event);
- // Panels
- COptionsPanelBitcoin* panelBitcoin;
- COptionsPanelUI* panelUI;
- wxPanel* currentPanel;
public:
/** Constructor */
COptionsDialog(wxWindow* parent);
+
+ // Custom
+ bool fTmpStartOnSystemStartup;
+ bool fTmpMinimizeOnClose;
+ void SelectPage(int nPage);
};
@@ -180,6 +164,11 @@ protected:
public:
/** Constructor */
CSendDialog(wxWindow* parent, const wxString& strAddress="");
+
+ // Custom
+ bool fEnabledPrev;
+ string strFromSave;
+ string strMessageSave;
};
@@ -455,22 +444,33 @@ public:
-class CBitcoinTBIcon : public wxTaskBarIcon
+class CMyTaskBarIcon : public wxTaskBarIcon
{
protected:
- void Restore();
-
- // Event handlers
- void OnLeftButtonDClick(wxTaskBarIconEvent&);
- void OnMenuExit(wxCommandEvent&);
- void OnMenuGenerate(wxCommandEvent&);
- void OnMenuRestore(wxCommandEvent&);
+ // Event handlers
+ void OnLeftButtonDClick(wxTaskBarIconEvent& event);
+ void OnMenuRestore(wxCommandEvent& event);
+ void OnUpdateUIGenerate(wxUpdateUIEvent& event);
+ void OnMenuGenerate(wxCommandEvent& event);
+ void OnMenuExit(wxCommandEvent& event);
public:
- void Show();
- void Hide();
uibase.cpp
uibase.h
uiproject.fbp
util.cpp