unix build merged in, bitmap resources from xpm instead of rc, better addr relay, better selection of addrs by time last seen for faster connect
Commit by Satoshi Nakamoto (s_nakamoto) on 5 November 2009 · SVN r32 · release v0.2.0 · 23 files, +2,184 −301
Open in Satoshi Mail View on GitHub
Files changed
build-unix.txt
@@ -0,0 +1,73 @@
+Bitcoin v0.2.0 BETA
+
+Copyright (c) 2009 Satoshi Nakamoto
+Distributed under the MIT/X11 software license, see the accompanying
+file license.txt or http://www.opensource.org/licenses/mit-license.php.
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/). This product includes
+cryptographic software written by Eric Young (eay@cryptsoft.com).
+
+
+UNIX BUILD NOTES
+
+
+Dependencies
+------------
+apt-get install build-essential
+apt-get install libgtk2.0-dev
+apt-get install libssl-dev
+
+Libraries you need to obtain separately and build:
+ default path download
+wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/
+Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html
+Boost \boost http://www.boost.org/users/download/
+
+Their licenses:
+wxWidgets LGPL 2.1 with very liberal exceptions
+Berkeley DB New BSD license with additional requirement that linked software must be free open source
+Boost MIT-like license
+
+Versions used in this release:
+GCC 4.3.3
+OpenSSL 0.9.8k
+wxWidgets 2.8.9
+Berkeley DB 4.7.25.NC
+Boost 1.40.0
+
+
+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" to strip the debug
+symbols, which reduces the executable size by about 90%.
+
+
+wxWidgets
+---------
+cd /usr/local/wxWidgets-2.8.9
+mkdir buildgtk
+cd buildgtk
+../configure --with-gtk --enable-debug --disable-shared --enable-monolithic
+make
+su
+make install
+ldconfig
+
+
+Berkeley DB
+-----------
+cd /usr/local/db-4.7.25.NC/build_unix
+../dist/configure --enable-cxx
+make
+
+
+Boost
+-----
+cd /usr/local/boost_1_40_0
+su
+./bootstrap.sh
+./bjam install
build.txt
@@ -1,88 +0,0 @@
-BitCoin v0.1.6 BETA
-
-Copyright (c) 2009 Satoshi Nakamoto
-Distributed under the MIT/X11 software license, see the accompanying
-file license.txt or http://www.opensource.org/licenses/mit-license.php.
-This product includes software developed by the OpenSSL Project for use in
-the OpenSSL Toolkit (http://www.openssl.org/). This product includes
-cryptographic software written by Eric Young (eay@cryptsoft.com).
-
-
-Compilers Supported
--------------------
-MinGW GCC (v3.4.5)
-Microsoft Visual C++ 6.0 SP6
-
-
-Dependencies
-------------
-Libraries you need to obtain separately to build:
-
- default path download
-wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/
- or prebuilt: http://wxpack.sourceforge.net
-OpenSSL \openssl http://www.openssl.org/source/
-Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html
-Boost \boost http://www.boost.org/users/download/
-
-Their licenses:
-wxWidgets LGPL 2.1 with very liberal exceptions
-OpenSSL Old BSD license with the problematic advertising requirement
-Berkeley DB New BSD license with additional requirement that linked software must be free open source
-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
-build of OpenSSL to exclude encryption routines, a few patches are required.
-(OpenSSL v0.9.8h)
-
-Edit engines\e_gmp.c and put this #ifndef around #include <openssl/rsa.h>
- #ifndef OPENSSL_NO_RSA
- #include <openssl/rsa.h>
- #endif
-
-Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line:
- void ERR_load_RSA_strings(void) { }
-
-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 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
-already finished building libeay32, which is all we care about, but the
-failure aborts the script before it runs dllwrap to generate libeay32.dll.
- REM if errorlevel 1 goto end
-
-Build
- ms\mingw32.bat
-
-If you want to use it with MSVC, generate the .lib file
- lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib
-
-
-Berkeley DB
------------
-Using MinGW and MSYS:
-cd \db\build_unix
-sh ../dist/configure --enable-mingw --enable-cxx
-make
-
-
-Boost
------
-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
@@ -62,9 +62,9 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
if (fShutdown)
return;
string strDataDir = GetDataDir();
- string strLogDir = strDataDir + "\\database";
+ string strLogDir = strDataDir + "/database";
_mkdir(strLogDir.c_str());
- string strErrorFile = strDataDir + "\\db.log";
+ string strErrorFile = strDataDir + "/db.log";
printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str());
dbenv.set_lg_dir(strLogDir.c_str());
@@ -411,7 +411,6 @@ bool CAddrDB::WriteAddress(const CAddress& addr)
bool CAddrDB::LoadAddresses()
{
- CRITICAL_BLOCK(cs_mapIRCAddresses)
CRITICAL_BLOCK(cs_mapAddresses)
{
// Load user provided addresses
@@ -425,10 +424,7 @@ bool CAddrDB::LoadAddresses()
{
CAddress addr(psz, NODE_NETWORK);
if (addr.IsValid())
- {
AddAddress(*this, addr);
- mapIRCAddresses.insert(make_pair(addr.GetKey(), addr));
- }
}
}
catch (...) { }
@@ -678,7 +674,7 @@ void ThreadFlushWalletDB(void* parg)
if (nRefCount == 0 && !fShutdown)
{
// Flush wallet.dat so it's self contained
- nLastFlushed == nWalletDBUpdated;
+ nLastFlushed = nWalletDBUpdated;
int64 nStart = GetTimeMillis();
dbenv.txn_checkpoint(0, 0, 0);
dbenv.lsn_reset(strFile.c_str(), 0);
headers.h
@@ -17,16 +17,18 @@
#endif
#define _WIN32_IE 0x0400
#define WIN32_LEAN_AND_MEAN 1
+#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h
#include <wx/wx.h>
#include <wx/clipbrd.h>
#include <wx/snglinst.h>
#include <wx/taskbar.h>
#include <wx/stdpaths.h>
+#include <wx/utils.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
-#include <openssl/ripemd.h>
+#include <openssl/ripemd.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
@@ -50,22 +52,28 @@
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/tuple/tuple_io.hpp>
-#include <boost/array.hpp>
-
+#include <boost/array.hpp>
+
#ifdef __WXMSW__
#include <windows.h>
#include <winsock2.h>
-#include <mswsock.h>
+#include <mswsock.h>
#include <shlobj.h>
-#include <shlwapi.h>
-#include <io.h>
-#include <process.h>
-#else
+#include <shlwapi.h>
+#include <io.h>
+#include <process.h>
+#else
#include <sys/time.h>
+#include <sys/resource.h>
#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#endif
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <errno.h>
+#include <boost/filesystem.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/algorithm/string.hpp>
+#endif
#pragma hdrstop
using namespace std;
@@ -88,3 +96,11 @@ using namespace boost;
#include "market.h"
#include "uibase.h"
#include "ui.h"
+
+#include "xpm/addressbook16.xpm"
+#include "xpm/addressbook20.xpm"
+#include "xpm/bitcoin.xpm"
+#include "xpm/check.xpm"
+#include "xpm/send16.xpm"
+#include "xpm/send16noshadow.xpm"
+#include "xpm/send20.xpm"
irc.cpp
@@ -4,10 +4,7 @@
#include "headers.h"
-
-map<vector<unsigned char>, CAddress> mapIRCAddresses;
-CCriticalSection cs_mapIRCAddresses;
-
+int nGotIRCAddresses = 0;
@@ -259,16 +256,7 @@ void ThreadIRCSeed(void* parg)
CAddrDB addrdb;
if (AddAddress(addrdb, addr))
printf("IRC got new address\n");
- else
- {
- // make it try connecting again
- CRITICAL_BLOCK(cs_mapAddresses)
- if (mapAddresses.count(addr.GetKey()))
- mapAddresses[addr.GetKey()].nLastFailed = 0;
- }
-
- CRITICAL_BLOCK(cs_mapIRCAddresses)
- mapIRCAddresses.insert(make_pair(addr.GetKey(), addr));
+ nGotIRCAddresses++;
}
else
{
irc.h
@@ -4,7 +4,5 @@
extern bool RecvLine(SOCKET hSocket, string& strLine);
extern void ThreadIRCSeed(void* parg);
-extern bool fRestartIRCSeed;
-extern map<vector<unsigned char>, CAddress> mapIRCAddresses;
-extern CCriticalSection cs_mapIRCAddresses;
+extern int nGotIRCAddresses;
main.cpp
@@ -100,13 +100,10 @@ bool AddToWallet(const CWalletTx& wtxIn)
if (fInsertedNew)
wtx.nTimeReceived = GetAdjustedTime();
- //// debug print
- printf("AddToWallet %s %s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), fInsertedNew ? "new" : "update");
-
+ bool fUpdated = false;
if (!fInsertedNew)
{
// Merge
- bool fUpdated = false;
if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
{
wtx.hashBlock = wtxIn.hashBlock;
@@ -128,13 +125,15 @@ bool AddToWallet(const CWalletTx& wtxIn)
wtx.fSpent = wtxIn.fSpent;
fUpdated = true;
}
- if (!fUpdated)
- return true;
}
+ //// debug print
+ printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
+
// Write to disk
- if (!wtx.WriteToDisk())
- return false;
+ if (fInsertedNew || fUpdated)
+ if (!wtx.WriteToDisk())
+ return false;
// Notify UI
vWalletUpdated.push_back(hash);
@@ -820,7 +819,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo
}
if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
- return error("ConnectInputs() : %s prevout.n out of range %d %d %d", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size());
+ return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,6).c_str(), txPrev.ToString().c_str());
// If prev is coinbase, check that it's matured
if (txPrev.IsCoinBase())
@@ -1217,7 +1216,7 @@ bool CBlock::AcceptBlock()
if (nTime <= pindexPrev->GetMedianTimePast())
return error("AcceptBlock() : block's timestamp is too early");
- // Check that all transactions are finalized (starting around 30 Nov 2009)
+ // Check that all transactions are finalized (starting around Dec 2009)
if (nBestHeight > 31000) // 25620 + 5320
foreach(const CTransaction& tx, vtx)
if (!tx.IsFinal(nTime))
@@ -1384,7 +1383,7 @@ FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszM
{
if (nFile == -1)
return NULL;
- FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode);
+ FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode);
if (!file)
return NULL;
if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
@@ -1718,6 +1717,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
+
if (strCommand == "version")
{
// Each connection can only send one version message
@@ -1765,6 +1765,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
pfrom->fSuccessfullyConnected = true;
+ // Update the last seen time
+ if (pfrom->fNetworkNode)
+ AddressCurrentlyConnected(pfrom->addr);
+
printf("version message: version %d\n", pfrom->nVersion);
}
@@ -1781,23 +1785,16 @@ 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)
+ foreach(CAddress& addr, vAddr)
{
if (fShutdown)
return true;
- AddAddress(addrdb, addr);
+ addr.nTime = GetAdjustedTime();
+ if (pfrom->fGetAddr)
+ addr.nTime -= 5 * 24 * 60 * 60;
+ AddAddress(addrdb, addr, false);
pfrom->AddAddressKnown(addr);
if (!pfrom->fGetAddr && addr.IsRoutable())
{
@@ -1816,6 +1813,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vector<CInv> vInv;
vRecv >> vInv;
+ // Update the last seen time for this node's address
+ if (pfrom->fNetworkNode)
+ AddressCurrentlyConnected(pfrom->addr);
+
CTxDB txdb("r");
foreach(const CInv& inv, vInv)
{
@@ -2099,6 +2100,25 @@ bool SendMessages(CNode* pto)
if (pto->nVersion == 0)
return true;
+ // Address refresh broadcast
+ static int64 nLastRebroadcast;
+ if (nLastRebroadcast < GetTime() - 24 * 60 * 60) // every 24 hours
+ {
+ nLastRebroadcast = GetTime();
+ CRITICAL_BLOCK(cs_vNodes)
+ {
+ foreach(CNode* pnode, vNodes)
+ {
+ // Periodically clear setAddrKnown to allow refresh broadcasts
+ pnode->setAddrKnown.clear();
+
+ // Rebroadcast our address
+ if (addrLocalHost.IsRoutable() && !fUseProxy)
+ pnode->PushAddress(addrLocalHost);
+ }
+ }
+ }
+
//
// Message: addr
@@ -2187,7 +2207,7 @@ void GenerateBitcoins(bool fGenerate)
}
if (fGenerateBitcoins)
{
- int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS"));
+ int nProcessors = wxThread::GetCPUCount();
printf("%d processors\n", nProcessors);
if (nProcessors < 1)
nProcessors = 1;
main.h
@@ -968,6 +968,14 @@ public:
return error("CBlock::WriteToDisk() : ftell failed");
fileout << *this;
+ // Flush stdio buffers and commit to disk before returning
+ fflush(fileout);
+#ifdef __WXMSW__
+ _commit(_fileno(fileout));
+#else
+ fsync(fileno(fileout));
+#endif
+
return true;
}
makefile.unix
@@ -0,0 +1,86 @@
+# Copyright (c) 2009 Satoshi Nakamoto
+# Distributed under the MIT/X11 software license, see the accompanying
+# file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+
+ifneq "$(BUILD)" "debug"
+ifneq "$(BUILD)" "release"
+BUILD=debug
+endif
+endif
+ifeq "$(BUILD)" "debug"
+D=d
+DEBUGFLAGS=-g -D__WXDEBUG__
+endif
+
+
+
+INCLUDEPATHS=-I"/usr/include" \
+ -I"/usr/local/boost_1_40_0" \
+ -I"/usr/local/db-4.7.25.NC/build_unix" \
+ -I"/usr/local/include/wx-2.8" \
+ -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8"
+
+LIBPATHS=-L"/usr/lib" \
+ -L"/usr/local/lib" \
+ -L"/usr/local/db-4.7.25.NC/build_unix"
+
+LIBS= \
+ -Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \
+ -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \
+ -l crypto \
+ -l gtk-x11-2.0 -l gthread-2.0 -l SM
+WXDEFS=-D__WXGTK__ -DNOPCH
+CFLAGS=-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
+
+
+
+all: bitcoin
+
+
+headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h
+ g++ -c $(CFLAGS) -o $@ $<
+
+obj/util.o: util.cpp $(HEADERS)
+ g++ -c $(CFLAGS) -o $@ $<
+
+obj/script.o: script.cpp $(HEADERS)
+ g++ -c $(CFLAGS) -o $@ $<
+
+obj/db.o: db.cpp $(HEADERS) market.h
+ g++ -c $(CFLAGS) -o $@ $<
+
+obj/net.o: net.cpp $(HEADERS) net.h
+ g++ -c $(CFLAGS) -o $@ $<
+
+obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h
+ g++ -c $(CFLAGS) -o $@ $<
+
+obj/market.o: market.cpp $(HEADERS) market.h
+ g++ -c $(CFLAGS) -o $@ $<
+
+obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h
+ g++ -c $(CFLAGS) -o $@ $<
+
+obj/uibase.o: uibase.cpp uibase.h
+ g++ -c $(CFLAGS) -o $@ $<
+
+obj/sha.o: sha.cpp sha.h
+ g++ -c $(CFLAGS) -O3 -o $@ $<
+
+obj/irc.o: irc.cpp $(HEADERS)
+ g++ -c $(CFLAGS) -o $@ $<
+
+
+
+
+OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \
+ obj/ui.o obj/uibase.o obj/sha.o obj/irc.o
+
+bitcoin: headers.h.gch $(OBJS)
+ g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
+
+clean:
+ -rm obj/*
+ -rm headers.h.gch
net.cpp
@@ -3,7 +3,6 @@
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
-#include <winsock2.h>
void ThreadMessageHandler2(void* parg);
void ThreadSocketHandler2(void* parg);
@@ -201,12 +200,14 @@ bool GetMyExternalIP(unsigned int& ipRet)
-bool AddAddress(CAddrDB& addrdb, const CAddress& addr)
+bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline)
{
if (!addr.IsRoutable())
return false;
if (addr.ip == addrLocalHost.ip)
return false;
+ if (fCurrentlyOnline)
+ addr.nTime = GetAdjustedTime();
CRITICAL_BLOCK(cs_mapAddresses)
{
map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
@@ -219,24 +220,47 @@ bool AddAddress(CAddrDB& addrdb, const CAddress& addr)
}
else
{
+ bool fUpdated = false;
CAddress& addrFound = (*it).second;
if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
{
// Services have been added
addrFound.nServices |= addr.nServices;
- addrdb.WriteAddress(addrFound);
- return true;
+ fUpdated = true;
+ }
+ int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
+ if (addrFound.nTime < addr.nTime - nUpdateInterval)
+ {
+ // Periodically update most recently seen time
+ addrFound.nTime = addr.nTime;
+ fUpdated = true;
}
- else if (addrFound.nTime < GetAdjustedTime() - 24 * 60 * 60)
+ if (fUpdated)
+ addrdb.WriteAddress(addrFound);
+ }
+ }
+ return false;
+}
+
+void AddressCurrentlyConnected(const CAddress& addr)
+{
+ CRITICAL_BLOCK(cs_mapAddresses)
+ {
+ // Only if it's been published already
+ map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
+ if (it != mapAddresses.end())
+ {
+ CAddress& addrFound = (*it).second;
+ int64 nUpdateInterval = 60 * 60;
+ if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
{
// Periodically update most recently seen time
addrFound.nTime = GetAdjustedTime();
+ CAddrDB addrdb;
addrdb.WriteAddress(addrFound);
- return false;
}
}
}
- return false;
}
@@ -398,9 +422,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
printf("connected %s\n", addrConnect.ToStringLog().c_str());
// Set to nonblocking
- u_long nOne = 1;
+#ifdef __WXMSW__
+ u_long nOne = 1;
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
+#else
+ if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
+ printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
+#endif
// Add node
CNode* pnode = new CNode(hSocket, addrConnect, false);
@@ -418,7 +447,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
else
{
CRITICAL_BLOCK(cs_mapAddresses)
- mapAddresses[addrConnect.GetKey()].nLastFailed = GetTime();
+ mapAddresses[addrConnect.GetKey()].nLastFailed = GetAdjustedTime();
return NULL;
}
}
@@ -432,7 +461,7 @@ void CNode::DoDisconnect()
// If outbound and never got version message, mark address as failed
if (!fInbound && !fSuccessfullyConnected)
CRITICAL_BLOCK(cs_mapAddresses)
- mapAddresses[addr.GetKey()].nLastFailed = GetTime();
+ mapAddresses[addr.GetKey()].nLastFailed = GetAdjustedTime();
// All of a nodes broadcasts and subscriptions are automatically torn down
// when it goes down, so a node has to stay up to keep its broadcast going.
@@ -549,8 +578,8 @@ void ThreadSocketHandler2(void* parg)
timeout.tv_sec = 0;
timeout.tv_usec = 50000; // frequency to poll pnode->vSend
- struct fd_set fdsetRecv;
- struct fd_set fdsetSend;
+ fd_set fdsetRecv;
+ fd_set fdsetSend;
FD_ZERO(&fdsetRecv);
FD_ZERO(&fdsetSend);
SOCKET hSocketMax = 0;
@@ -599,7 +628,11 @@ void ThreadSocketHandler2(void* parg)
if (FD_ISSET(hListenSocket, &fdsetRecv))
{
struct sockaddr_in sockaddr;
+#ifdef __WXMSW__
int len = sizeof(sockaddr);
+#else
+ socklen_t len = sizeof(sockaddr);
+#endif
SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
CAddress addr(sockaddr);
if (hSocket == INVALID_SOCKET)
@@ -765,14 +798,12 @@ void ThreadOpenConnections2(void* parg)
}
// Initiate network connections
- int nTry = 0;
- bool fIRCOnly = false;
- const int nMaxConnections = 15;
loop
{
// Wait
vnThreadsRunning[1]--;
Sleep(500);
+ const int nMaxConnections = 15;
while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size())
{
CheckForShutdown(1);
@@ -781,93 +812,55 @@ void ThreadOpenConnections2(void* parg)
vnThreadsRunning[1]++;
CheckForShutdown(1);
-
//
- // The IP selection process is designed to limit vulnerability to address flooding.
- // Any class C (a.b.c.?) has an equal chance of being chosen, then an IP is
- // chosen within the class C. An attacker may be able to allocate many IPs, but
- // they would normally be concentrated in blocks of class C's. They can hog the
- // attention within their class C, but not the whole IP address space overall.
- // A lone node in a class C will get as much attention as someone holding all 255
- // IPs in another class C.
+ // Choose an address to connect to based on most recently seen
//
+ CAddress addrConnect;
+ int64 nBestTime = 0;
+ int64 nDelay = ((60 * 60) << vNodes.size());
+ if (vNodes.size() >= 3)
+ nDelay *= 4;
+ if (nGotIRCAddresses > 0)
+ nDelay *= 100;
+
+ // Do this here so we don't have to critsect vNodes inside mapAddresses critsect
+ set<unsigned int> setConnected;
+ CRITICAL_BLOCK(cs_vNodes)
+ foreach(CNode* pnode, vNodes)
+ setConnected.insert(pnode->addr.ip);
- // Every other try is with IRC addresses only
- fIRCOnly = !fIRCOnly;
- if (mapIRCAddresses.empty())
- fIRCOnly = false;
- else if (nTry++ < 30 && vNodes.size() < nMaxConnections/2)
- fIRCOnly = true;
-
- // Make a list of unique class C's
- unsigned char pchIPCMask[4] = { 0xff, 0xff, 0xff, 0x00 };
- unsigned int nIPCMask = *(unsigned int*)pchIPCMask;
- vector<unsigned int> vIPC;
- CRITICAL_BLOCK(cs_mapIRCAddresses)
CRITICAL_BLOCK(cs_mapAddresses)
{
- vIPC.reserve(mapAddresses.size());
- unsigned int nPrev = 0;
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
{
const CAddress& addr = item.second;
- if (!addr.IsIPv4())
- continue;
- if (fIRCOnly && !mapIRCAddresses.count(item.first))
+ if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip))
continue;
- // Taking advantage of mapAddresses being in sorted order,
- // with IPs of the same class C grouped together.
- unsigned int ipC = addr.ip & nIPCMask;
- if (ipC != nPrev)
- vIPC.push_back(nPrev = ipC);
- }
- }
- if (vIPC.empty())
- continue;
-
- // Choose a random class C
- unsigned int ipC = vIPC[GetRand(vIPC.size())];
+ // Limit retry frequency
+ if (GetAdjustedTime() < addr.nLastFailed + nDelay)
+ continue;
- // Organize all addresses in the class C by IP
- map<unsigned int, vector<CAddress> > mapIP;
- CRITICAL_BLOCK(cs_mapIRCAddresses)
- CRITICAL_BLOCK(cs_mapAddresses)
- {
- int64 nDelay = ((30 * 60) << vNodes.size());
- if (!fIRCOnly)
- {
- nDelay *= 2;
- if (vNodes.size() >= 3)
- nDelay *= 4;
- if (!mapIRCAddresses.empty())
- nDelay *= 100;
- }
+ // Try again only after all addresses had a first attempt
+ int64 nTime = addr.nTime;
+ if (addr.nLastFailed > addr.nTime)
+ nTime -= 365 * 24 * 60 * 60;
- for (map<vector<unsigned char>, CAddress>::iterator mi = mapAddresses.lower_bound(CAddress(ipC, 0).GetKey());
- mi != mapAddresses.upper_bound(CAddress(ipC | ~nIPCMask, 0xffff).GetKey());
- ++mi)
- {
- const CAddress& addr = (*mi).second;
- if (fIRCOnly && !mapIRCAddresses.count((*mi).first))
- continue;
+ // Randomize the order a little, putting the standard port first
+ nTime += GetRand(1 * 60 * 60);
+ if (addr.port != DEFAULT_PORT)
+ nTime -= 1 * 60 * 60;
- int64 nRandomizer = (addr.nLastFailed * addr.ip * 7777U) % 20000;
- if (GetTime() - addr.nLastFailed > nDelay * nRandomizer / 10000)
- mapIP[addr.ip].push_back(addr);
+ if (nTime > nBestTime)
+ {
+ nBestTime = nTime;
+ addrConnect = addr;
+ }
}
}
- if (mapIP.empty())
- continue;
-
- // Choose a random IP in the class C
- map<unsigned int, vector<CAddress> >::iterator mi = mapIP.begin();
- advance(mi, GetRand(mapIP.size()));
- // Once we've chosen an IP, we'll try every given port before moving on
- foreach(const CAddress& addrConnect, (*mi).second)
- if (OpenNetworkConnection(addrConnect))
- break;
+ if (addrConnect.IsValid())
+ OpenNetworkConnection(addrConnect);
}
}
@@ -989,6 +982,7 @@ bool StartNode(string& strError)
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
strError = "";
+#ifdef __WXMSW__
// Sockets startup
WSADATA wsadata;
int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
@@ -998,6 +992,7 @@ bool StartNode(string& strError)
printf("%s\n", strError.c_str());
return false;
}
+#endif
// Get local host ip
char pszHostName[255];
@@ -1029,10 +1024,14 @@ bool StartNode(string& strError)
}
// Set to nonblocking, incoming connections will also inherit this
+#ifdef __WXMSW__
u_long nOne = 1;
if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR)
net.h
@@ -22,7 +22,8 @@ enum
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
bool GetMyExternalIP(unsigned int& ipRet);
-bool AddAddress(CAddrDB& addrdb, const CAddress& addr);
+bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline=true);
+void AddressCurrentlyConnected(const CAddress& addr);
CNode* FindNode(unsigned int ip);
CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
ui.cpp
@@ -260,7 +260,8 @@ void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv)
CDataStream GetStreamFromEvent(const wxCommandEvent& event)
{
wxString strData = event.GetString();
- return CDataStream(strData.begin(), strData.begin() + event.GetInt(), SER_NETWORK);
+ const char* pszBegin = strData.c_str();
+ return CDataStream(pszBegin, pszBegin + event.GetInt(), SER_NETWORK);
}
@@ -288,20 +289,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
SetIcon(wxICON(bitcoin));
ptaskbaricon = new CMyTaskBarIcon();
- // Init toolbar with transparency masked bitmaps
- m_toolBar->ClearTools();
-
- //// shouldn't have to do mask separately anymore, bitmap alpha support added in wx 2.8.9,
- wxBitmap bmpSend(wxT("send20"), wxBITMAP_TYPE_RESOURCE);
- bmpSend.SetMask(new wxMask(wxBitmap(wxT("send20mask"), wxBITMAP_TYPE_RESOURCE)));
- m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), bmpSend, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString);
-
- wxBitmap bmpAddressBook(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE);
- bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook20mask"), wxBITMAP_TYPE_RESOURCE)));
- m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), bmpAddressBook, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString);
-
- m_toolBar->Realize();
-
// Init column headers
int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8;
if (!strstr(DateTimeStr(1229413914).c_str(), "2008"))
@@ -909,15 +896,17 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
{
TRY_CRITICAL_BLOCK(cs_mapWallet)
{
- bool fInserted = false;
+ string strTop;
+ if (m_listCtrl->GetItemCount())
+ strTop = (string)m_listCtrl->GetItemText(0);
foreach(uint256 hash, vWalletUpdated)
{
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
if (mi != mapWallet.end())
- fInserted |= InsertTransaction((*mi).second, false);
+ InsertTransaction((*mi).second, false);
}
vWalletUpdated.clear();
- if (fInserted)
+ if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0))
m_listCtrl->ScrollList(0, INT_MAX);
}
}
@@ -954,7 +943,9 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount);
m_statusBar->SetStatusText(strStatus, 2);
+#ifdef __WXMSW__
m_listCtrl->OnPaint(event);
+#endif
}
@@ -1407,7 +1398,7 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent)
m_checkBoxLimitProcessors->SetValue(fLimitProcessors);
m_spinCtrlLimitProcessors->Enable(fLimitProcessors);
m_spinCtrlLimitProcessors->SetValue(nLimitProcessors);
- int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS"));
+ int nProcessors = wxThread::GetCPUCount();
if (nProcessors < 1)
nProcessors = 999;
m_spinCtrlLimitProcessors->SetRange(1, nProcessors);
@@ -1549,17 +1540,11 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose);
}
- if (fUseProxy != m_checkBoxUseProxy->GetValue())
- {
- fUseProxy = m_checkBoxUseProxy->GetValue();
- walletdb.WriteSetting("fUseProxy", fUseProxy);
- }
+ fUseProxy = m_checkBoxUseProxy->GetValue();
+ walletdb.WriteSetting("fUseProxy", fUseProxy);
- if (addrProxy != GetProxyAddr())
- {
- addrProxy = GetProxyAddr();
- walletdb.WriteSetting("addrProxy", addrProxy);
- }
+ addrProxy = GetProxyAddr();
+ walletdb.WriteSetting("addrProxy", addrProxy);
}
@@ -1608,10 +1593,8 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi
//// todo: should add a display of your balance for convenience
// Set Icon
- wxBitmap bmpSend(wxT("send16"), wxBITMAP_TYPE_RESOURCE);
- bmpSend.SetMask(new wxMask(wxBitmap(wxT("send16masknoshadow"), wxBITMAP_TYPE_RESOURCE)));
wxIcon iconSend;
- iconSend.CopyFromBitmap(bmpSend);
+ iconSend.CopyFromBitmap(wxBitmap(send16noshadow_xpm));
SetIcon(iconSend);
wxCommandEvent event;
@@ -2231,10 +2214,8 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit
m_listCtrl->SetFocus();
// Set Icon
- wxBitmap bmpAddressBook(wxT("addressbook16"), wxBITMAP_TYPE_RESOURCE);
- bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook16mask"), wxBITMAP_TYPE_RESOURCE)));
wxIcon iconAddressBook;
- iconAddressBook.CopyFromBitmap(bmpAddressBook);
+ iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm));
SetIcon(iconAddressBook);
// Fill listctrl with address book data
@@ -3345,7 +3326,7 @@ bool CMyApp::OnInit2()
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
#endif
-#ifdef __WXDEBUG__
+#if defined(__WXMSW__) && defined(__WXDEBUG__)
// Disable malfunctioning wxWidgets debug assertion
g_isPainting = 10000;
#endif
@@ -3362,8 +3343,7 @@ bool CMyApp::OnInit2()
" -gen=0\t\t Don't generate coins\n"
" -min\t\t Start minimized\n"
" -datadir=<dir>\t Specify data directory\n"
- " -proxy=<ip:port>\t Connect through socks4 proxy,\n"
- " \t\t e.g. -proxy=127.0.0.1:9050 to use TOR\n"
+ " -proxy=<ip:port>\t Connect through socks4 proxy\n"
" -addnode=<ip>\t Add a node to connect to\n"
" -connect=<ip>\t Connect only to the specified node\n"
" -?\t\t This help message\n";
@@ -3386,6 +3366,8 @@ bool CMyApp::OnInit2()
unsigned int nStart = GetTime();
loop
{
+ // TODO: find out how to do this in Linux, or replace with wxWidgets commands
+#ifdef __WXMSW__
// Show the previous instance and exit
HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin");
if (hwndPrev)
@@ -3395,6 +3377,7 @@ bool CMyApp::OnInit2()
SetForegroundWindow(hwndPrev);
return false;
}
+#endif
if (GetTime() > nStart + 60)
return false;
@@ -3421,7 +3404,7 @@ bool CMyApp::OnInit2()
fPrintToDebugger = true;
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
- printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion());
+ printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str());
if (mapArgs.count("-dropmessages"))
{
@@ -3493,12 +3476,36 @@ bool CMyApp::OnInit2()
return false;
}
+ if (mapArgs.count("-printblock"))
+ {
+ string strMatch = mapArgs["-printblock"];
+ int nFound = 0;
+ for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
+ {
+ uint256 hash = (*mi).first;
+ if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
+ {
+ CBlockIndex* pindex = (*mi).second;
+ CBlock block;
+ block.ReadFromDisk(pindex, true);
+ block.BuildMerkleTree();
+ block.print();
+ printf("\n");
+ nFound++;
+ }
+ }
+ if (nFound == 0)
+ printf("No blocks matching %s were found\n", strMatch.c_str());
+ OnExit();
+ return false;
+ }
+
if (mapArgs.count("-gen"))
{
if (mapArgs["-gen"].empty())
fGenerateBitcoins = true;
else
- fGenerateBitcoins = atoi(mapArgs["-gen"].c_str());
+ fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0);
}
if (mapArgs.count("-proxy"))
@@ -3511,9 +3518,6 @@ bool CMyApp::OnInit2()
OnExit();
return false;
}
- CWalletDB walletdb;
- walletdb.WriteSetting("fUseProxy", fUseProxy);
- walletdb.WriteSetting("addrProxy", addrProxy);
}
if (mapArgs.count("-addnode"))
@@ -3522,6 +3526,7 @@ bool CMyApp::OnInit2()
foreach(string strAddr, mapMultiArgs["-addnode"])
{
CAddress addr(strAddr, NODE_NETWORK);
+ addr.nTime = 0; // so it won't relay unless successfully connected
if (addr.IsValid())
AddAddress(addrdb, addr);
}
@@ -3559,7 +3564,11 @@ bool CMyApp::OnInit2()
//
// Tests
//
+#ifdef __WXMSW__
if (argc >= 2 && stricmp(argv[1], "-send") == 0)
+#else
+ if (argc >= 2 && strcmp(argv[1], "-send") == 0)
+#endif
{
int64 nValue = 1;
if (argc >= 3)
@@ -3646,7 +3655,8 @@ void CMyApp::OnFatalException()
-typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
+#ifdef __WXMSW__
+typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
string MyGetSpecialFolderPath(int nFolder, bool fCreate)
{
@@ -3737,7 +3747,10 @@ void SetStartOnSystemStartup(bool fAutoStart)
CoUninitialize();
}
}
-
+#else
+bool GetStartOnSystemStartup() { return false; }
+void SetStartOnSystemStartup(bool fAutoStart) { }
+#endif
uibase.cpp
@@ -7,6 +7,10 @@
#include "uibase.h"
+#include "xpm/addressbook20.xpm"
+#include "xpm/check.xpm"
+#include "xpm/send20.xpm"
+
///////////////////////////////////////////////////////////////////////////
CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
@@ -60,8 +64,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
m_toolBar->SetToolSeparation( 1 );
m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) );
- m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( wxT("send20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString );
- m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString );
+ m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString );
+ m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString );
m_toolBar->Realize();
m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
@@ -666,7 +670,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin
bSizer47->Add( 0, 0, 1, wxEXPAND, 5 );
- m_bitmapCheckMark = new wxStaticBitmap( this, wxID_ANY, wxICON( check ), wxDefaultPosition, wxSize( 16,16 ), 0 );
+ m_bitmapCheckMark = new wxStaticBitmap( this, wxID_ANY, wxBitmap( check_xpm ), wxDefaultPosition, wxSize( 16,16 ), 0 );
bSizer47->Add( m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_staticText36 = new wxStaticText( this, wxID_ANY, wxT("Pay &To:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT );
uiproject.fbp
@@ -225,7 +225,7 @@
</object>
</object>
</object>
- <object class="wxToolBar" expanded="0">
+ <object class="wxToolBar" expanded="1">
<property name="bg"></property>
<property name="bitmapsize">20,20</property>
<property name="context_help"></property>
@@ -273,7 +273,7 @@
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="tool" expanded="1">
- <property name="bitmap">send20; Load From Resource</property>
+ <property name="bitmap">xpm/send20.xpm; Load From File</property>
<property name="id">wxID_BUTTONSEND</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&Send Coins</property>
@@ -287,7 +287,7 @@
<event name="OnUpdateUI"></event>
</object>
<object class="tool" expanded="1">
- <property name="bitmap">addressbook20; Load From Resource</property>
+ <property name="bitmap">xpm/addressbook20.xpm; Load From File</property>
<property name="id">wxID_BUTTONRECEIVE</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&Address Book</property>
@@ -1685,7 +1685,7 @@
</object>
</object>
</object>
- <object class="Dialog" expanded="1">
+ <object class="Dialog" expanded="0">
<property name="bg"></property>
<property name="center"></property>
<property name="context_help"></property>
@@ -3699,7 +3699,7 @@
<property name="proportion">0</property>
<object class="wxStaticBitmap" expanded="1">
<property name="bg"></property>
- <property name="bitmap">check; Load From Icon Resource [-1; -1]</property>
+ <property name="bitmap">xpm/check.xpm; Load From File</property>
<property name="context_help"></property>
<property name="enabled">1</property>
<property name="fg"></property>
util.cpp
@@ -38,8 +38,10 @@ public:
ppmutexOpenSSL[i] = new wxMutex();
CRYPTO_set_locking_callback(locking_callback);
+#ifdef __WXMSW__
// Seed random number generator with screen scrape and other hardware sources
RAND_screen();
+#endif
// Seed random number generator with performance counter
RandAddSeed();
@@ -325,8 +327,8 @@ void ParseParameters(int argc, char* argv[])
pszValue = strchr(psz, '=');
*pszValue++ = '\0';
}
- strlwr(psz);
#ifdef __WXMSW__
+ _strlwr(psz);
if (psz[0] == '/')
psz[0] = '-';
#endif
@@ -343,9 +345,13 @@ void ParseParameters(int argc, char* argv[])
void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
{
+#ifdef __WXMSW__
char pszModule[MAX_PATH];
pszModule[0] = '\0';
GetModuleFileName(NULL, pszModule, sizeof(pszModule));
+#else
+ const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str();
+#endif
if (pex)
snprintf(pszMessage, 1000,
"EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
util.h
@@ -55,9 +55,34 @@ inline T& REF(const T& val)
}
#ifndef __WXMSW__
-#define closesocket(s) close(s)
-#define INVALID_SOCKET (SOCKET)(~0)
+#define _UI64_MAX UINT64_MAX
+#define _I64_MAX INT64_MAX
+#define WSAGetLastError() errno
+#define WSAEWOULDBLOCK EWOULDBLOCK
+#define WSAEMSGSIZE EMSGSIZE
+#define WSAEINTR EINTR
+#define WSAEINPROGRESS EINPROGRESS
+#define WSAEADDRINUSE EADDRINUSE
+#define closesocket(s) close(s)
+#define INVALID_SOCKET (SOCKET)(~0)
+#define SOCKET_ERROR -1
typedef u_int SOCKET;
+#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
+#define strlwr(psz) to_lower(psz)
+#define _strlwr(psz) to_lower(psz)
+#define _mkdir(psz) filesystem::create_directory(psz)
+#define MAX_PATH 1024
+#define Sleep(n) wxMilliSleep(n)
+#define Beep(n1,n2) (0)
+inline int _beginthread(void(*pfn)(void*), unsigned nStack, void* parg) { thread(bind(pfn, parg)); return 0; }
+inline void _endthread() { pthread_exit(NULL); }
+inline int GetCurrentThread() { return 0; }
+// threads are processes on linux, so setpriority affects just the one thread
+inline void SetThreadPriority(int nThread, int nPriority) { setpriority(PRIO_PROCESS, getpid(), nPriority); }
+#define THREAD_PRIORITY_LOWEST PRIO_MIN
+#define THREAD_PRIORITY_BELOW_NORMAL 2
+#define THREAD_PRIORITY_NORMAL 0
+#define THREAD_PRIORITY_ABOVE_NORMAL 0
#endif
@@ -120,7 +145,7 @@ public:
protected:
wxMutex mutex;
public:
- explicit CCriticalSection() { }
+ explicit CCriticalSection() : mutex(wxMUTEX_RECURSIVE) { }
~CCriticalSection() { }
void Enter() { mutex.Lock(); }
void Leave() { mutex.Unlock(); }
@@ -183,7 +208,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
// print to debug.log
char pszFile[MAX_PATH+100];
GetDataDir(pszFile);
- strlcat(pszFile, "\\debug.log", sizeof(pszFile));
+ strlcat(pszFile, "/debug.log", sizeof(pszFile));
FILE* fileout = fopen(pszFile, "a");
if (fileout)
{
@@ -354,13 +379,6 @@ inline int64 GetTimeMillis()
return wxGetLocalTimeMillis().GetValue();
}
-#ifndef __WXMSW__
-inline void Sleep(unsigned int nMilliseconds)
-{
- wxMilliSleep(nMilliseconds);
-}
-#endif
-
xpm/addressbook16.xpm
@@ -0,0 +1,278 @@
+/* XPM */
+static char * addressbook16_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 256 2",
+" c #FFFFFF",
+". c #F7FFFF",
+"X c #F7F7FF",
+"o c #EFF7FF",
+"O c #E6EFF7",
+"+ c #E6E6F7",
+"@ c #CEE6F7",
+"# c #DEDEEF",
+"$ c #D6DEEF",
+"% c #D6DEE6",
+"& c #CEDEF7",
+"* c #CEDEEF",
+"= c #EFF708",
+"- c #C5DEF7",
+"; c #CED6EF",
+": c None",
+"> c #C5D6E6",
+", c #BDD6F7",
+"< c #BDD6EF",
+"1 c #D6CECE",
+"2 c #BDCEE6",
+"3 c #BDC5E6",
+"4 c #B5C5DE",
+"5 c #BDD631",
+"6 c #ADBDDE",
+"7 c #B5B5BD",
+"8 c #A5B5D6",
+"9 c #00FFFF",
+"0 c #9CB5CE",
+"q c #9CADD6",
+"w c #94A5D6",
+"e c #8CA5D6",
+"r c #8CA5CE",
+"t c #8CA5C5",
+"y c #849CC5",
+"u c #7B9CD6",
+"i c #7B9CCE",
+"p c #31BDCE",
+"a c #6B9CD6",
+"s c #00F708",
+"d c #8494AD",
+"f c #7B94B5",
+"g c #6B94D6",
+"h c #6B9C84",
+"j c #7B8CAD",
+"k c #738CAD",
+"l c #638CC5",
+"z c #10CE42",
+"x c #638CBD",
+"c c #7B849C",
+"v c #73849C",
+"b c #6B84A5",
+"n c #7B7BA5",
+"m c #6B849C",
+"M c #7B8C42",
+"N c #5A84C5",
+"B c #29AD6B",
+"V c #F74A4A",
+"C c #6384A5",
+"Z c #5284C5",
+"A c #637BA5",
+"S c #637B9C",
+"D c #9C637B",
+"F c #6B7B5A",
+"G c #637394",
+"H c #52739C",
+"J c #5A7384",
+"K c #526B94",
+"L c #426B94",
+"P c #52638C",
+"I c #426B7B",
+"U c #5A5A8C",
+"Y c #524A7B",
+"T c #425273",
+"R c #21636B",
+"E c #106394",
+"W c #106B52",
+"Q c #3A4273",
+"! c #31426B",
+"~ c #523163",
+"^ c #29426B",
+"/ c #293A63",
+"( c #213A63",
+") c #193A63",
+"_ c #193163",
+"` c #19315A",
+"' c #212963",
+"] c #10315A",
+"[ c #082952",
+"{ c #FFCC33",
+"} c #33FF33",
+"| c #66FF33",
+" . c #99FF33",
+".. c #CCFF33",
+"X. c #FFFF33",
+"o. c #000066",
+"O. c #330066",
+"+. c #660066",
+"@. c #990066",
+"#. c #CC0066",
+"$. c #FF0066",
+"%. c #003366",
+"&. c #333366",
+"*. c #663366",
+"=. c #993366",
+"-. c #CC3366",
+";. c #FF3366",
+":. c #006666",
+">. c #336666",
+",. c #666666",
+"<. c #996666",
+"1. c #CC6666",
+"2. c #009966",
+"3. c #339966",
+"4. c #669966",
+"5. c #999966",
+"6. c #CC9966",
+"7. c #FF9966",
+"8. c #00CC66",
+"9. c #33CC66",
+"0. c #99CC66",
+"q. c #CCCC66",
+"w. c #FFCC66",
+"e. c #00FF66",
+"r. c #33FF66",
+"t. c #99FF66",
+"y. c #CCFF66",
+"u. c #FF00CC",
+"i. c #CC00FF",
+"p. c #009999",
+"a. c #993399",
+"s. c #990099",
+"d. c #CC0099",
+"f. c #000099",
+"g. c #333399",
+"h. c #660099",
+"j. c #CC3399",
+"k. c #FF0099",
+"l. c #006699",
+"z. c #336699",
+"x. c #663399",
+"c. c #996699",
+"v. c #CC6699",
+"b. c #FF3399",
+"n. c #339999",
+"m. c #669999",
+"M. c #999999",
+"N. c #CC9999",
+"B. c #FF9999",
+"V. c #00CC99",
+"C. c #33CC99",
+"Z. c #66CC66",
+"A. c #99CC99",
+"S. c #CCCC99",
+"D. c #FFCC99",
+"F. c #00FF99",
+"G. c #33FF99",
+"H. c #66CC99",
+"J. c #99FF99",
+"K. c #CCFF99",
+"L. c #FFFF99",
+"P. c #0000CC",
+"I. c #330099",
+"U. c #6600CC",
+"Y. c #9900CC",
+"T. c #CC00CC",
+"R. c #003399",
+"E. c #3333CC",
+"W. c #6633CC",
+"Q. c #9933CC",
+"!. c #CC33CC",
+"~. c #FF33CC",
+"^. c #0066CC",
+"/. c #3366CC",
+"(. c #666699",
+"). c #9966CC",
+"_. c #CC66CC",
+"`. c #FF6699",
+"'. c #0099CC",
+"]. c #3399CC",
+"[. c #6699CC",
+"{. c #9999CC",
xpm/addressbook20.xpm
xpm/bitcoin.xpm
xpm/check.xpm
xpm/send16.xpm
xpm/send16noshadow.xpm
xpm/send20.xpm