move debug.log and db.log to data dir, portable GetDataDir, optimize GetBalance, fix repaint bogdown, -addnode and -? switches
git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@25 1a98c847-1fd6-4fd8-948a-caf3550aa51b
This commit is contained in:
parent
5750932cdf
commit
4ac57f013e
@ -10,7 +10,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com).
|
|||||||
|
|
||||||
Compilers Supported
|
Compilers Supported
|
||||||
-------------------
|
-------------------
|
||||||
MinGW GCC
|
MinGW GCC (v3.4.5)
|
||||||
Microsoft Visual C++ 6.0 SP6
|
Microsoft Visual C++ 6.0 SP6
|
||||||
|
|
||||||
|
|
||||||
|
19
db.cpp
19
db.cpp
@ -61,18 +61,19 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
|
|||||||
{
|
{
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return;
|
return;
|
||||||
string strAppDir = GetAppDir();
|
string strDataDir = GetDataDir();
|
||||||
string strLogDir = strAppDir + "\\database";
|
string strLogDir = strDataDir + "\\database";
|
||||||
_mkdir(strLogDir.c_str());
|
_mkdir(strLogDir.c_str());
|
||||||
printf("dbenv.open strAppDir=%s\n", strAppDir.c_str());
|
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());
|
dbenv.set_lg_dir(strLogDir.c_str());
|
||||||
dbenv.set_lg_max(10000000);
|
dbenv.set_lg_max(10000000);
|
||||||
dbenv.set_lk_max_locks(10000);
|
dbenv.set_lk_max_locks(10000);
|
||||||
dbenv.set_lk_max_objects(10000);
|
dbenv.set_lk_max_objects(10000);
|
||||||
dbenv.set_errfile(fopen("db.log", "a")); /// debug
|
dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug
|
||||||
///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption
|
///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption
|
||||||
ret = dbenv.open(strAppDir.c_str(),
|
ret = dbenv.open(strDataDir.c_str(),
|
||||||
DB_CREATE |
|
DB_CREATE |
|
||||||
DB_INIT_LOCK |
|
DB_INIT_LOCK |
|
||||||
DB_INIT_LOG |
|
DB_INIT_LOG |
|
||||||
@ -139,6 +140,8 @@ void DBFlush(bool fShutdown)
|
|||||||
// Flush log data to the actual data file
|
// Flush log data to the actual data file
|
||||||
// on all files that are not in use
|
// on all files that are not in use
|
||||||
printf("DBFlush(%s)\n", fShutdown ? "true" : "false");
|
printf("DBFlush(%s)\n", fShutdown ? "true" : "false");
|
||||||
|
if (!fDbEnvInit)
|
||||||
|
return;
|
||||||
CRITICAL_BLOCK(cs_db)
|
CRITICAL_BLOCK(cs_db)
|
||||||
{
|
{
|
||||||
dbenv.txn_checkpoint(0, 0, 0);
|
dbenv.txn_checkpoint(0, 0, 0);
|
||||||
@ -421,7 +424,7 @@ bool CAddrDB::LoadAddresses()
|
|||||||
while (fgets(psz, sizeof(psz), filein))
|
while (fgets(psz, sizeof(psz), filein))
|
||||||
{
|
{
|
||||||
CAddress addr(psz, NODE_NETWORK);
|
CAddress addr(psz, NODE_NETWORK);
|
||||||
if (addr.ip != 0)
|
if (addr.IsValid())
|
||||||
{
|
{
|
||||||
AddAddress(*this, addr);
|
AddAddress(*this, addr);
|
||||||
mapIRCAddresses.insert(make_pair(addr.GetKey(), addr));
|
mapIRCAddresses.insert(make_pair(addr.GetKey(), addr));
|
||||||
@ -676,10 +679,10 @@ void ThreadFlushWalletDB(void* parg)
|
|||||||
{
|
{
|
||||||
// Flush wallet.dat so it's self contained
|
// Flush wallet.dat so it's self contained
|
||||||
nLastFlushed == nWalletDBUpdated;
|
nLastFlushed == nWalletDBUpdated;
|
||||||
int64 nStart = PerformanceCounter();
|
int64 nStart = GetTimeMillis();
|
||||||
dbenv.txn_checkpoint(0, 0, 0);
|
dbenv.txn_checkpoint(0, 0, 0);
|
||||||
dbenv.lsn_reset(strFile.c_str(), 0);
|
dbenv.lsn_reset(strFile.c_str(), 0);
|
||||||
printf("Flushed wallet.dat %15"PRI64d"\n", PerformanceCounter() - nStart);
|
printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
mapFileUseCount.erase(mi++);
|
mapFileUseCount.erase(mi++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
irc.cpp
7
irc.cpp
@ -40,7 +40,7 @@ bool DecodeAddress(string str, CAddress& addr)
|
|||||||
return false;
|
return false;
|
||||||
memcpy(&tmp, &vch[0], sizeof(tmp));
|
memcpy(&tmp, &vch[0], sizeof(tmp));
|
||||||
|
|
||||||
addr = CAddress(tmp.ip, tmp.port);
|
addr = CAddress(tmp.ip, tmp.port, NODE_NETWORK);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +163,7 @@ void ThreadIRCSeed(void* parg)
|
|||||||
int nErrorWait = 10;
|
int nErrorWait = 10;
|
||||||
int nRetryWait = 10;
|
int nRetryWait = 10;
|
||||||
|
|
||||||
|
// IRC server blocks TOR users
|
||||||
if (fUseProxy && addrProxy.port == htons(9050))
|
if (fUseProxy && addrProxy.port == htons(9050))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -237,14 +238,14 @@ void ThreadIRCSeed(void* parg)
|
|||||||
{
|
{
|
||||||
// index 7 is limited to 16 characters
|
// index 7 is limited to 16 characters
|
||||||
// could get full length name at index 10, but would be different from join messages
|
// could get full length name at index 10, but would be different from join messages
|
||||||
strcpy(pszName, vWords[7].c_str());
|
strlcpy(pszName, vWords[7].c_str(), sizeof(pszName));
|
||||||
printf("IRC got who\n");
|
printf("IRC got who\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vWords[1] == "JOIN" && vWords[0].size() > 1)
|
if (vWords[1] == "JOIN" && vWords[0].size() > 1)
|
||||||
{
|
{
|
||||||
// :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
|
// :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
|
||||||
strcpy(pszName, vWords[0].c_str() + 1);
|
strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName));
|
||||||
if (strchr(pszName, '!'))
|
if (strchr(pszName, '!'))
|
||||||
*strchr(pszName, '!') = '\0';
|
*strchr(pszName, '!') = '\0';
|
||||||
printf("IRC got join\n");
|
printf("IRC got join\n");
|
||||||
|
5
irc.h
5
irc.h
@ -2,11 +2,6 @@
|
|||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#ifndef __WXMSW__
|
|
||||||
#define closesocket(s) close(s)
|
|
||||||
typedef u_int SOCKET;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern bool RecvLine(SOCKET hSocket, string& strLine);
|
extern bool RecvLine(SOCKET hSocket, string& strLine);
|
||||||
extern void ThreadIRCSeed(void* parg);
|
extern void ThreadIRCSeed(void* parg);
|
||||||
extern bool fRestartIRCSeed;
|
extern bool fRestartIRCSeed;
|
||||||
|
50
main.cpp
50
main.cpp
@ -42,7 +42,6 @@ map<uint160, vector<unsigned char> > mapPubKeys;
|
|||||||
CCriticalSection cs_mapKeys;
|
CCriticalSection cs_mapKeys;
|
||||||
CKey keyUser;
|
CKey keyUser;
|
||||||
|
|
||||||
string strSetDataDir;
|
|
||||||
int nDropMessagesTest = 0;
|
int nDropMessagesTest = 0;
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
@ -1361,52 +1360,17 @@ bool ScanMessageStart(Stream& s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetAppDir()
|
|
||||||
{
|
|
||||||
string strDir;
|
|
||||||
if (!strSetDataDir.empty())
|
|
||||||
{
|
|
||||||
strDir = strSetDataDir;
|
|
||||||
}
|
|
||||||
else if (getenv("APPDATA"))
|
|
||||||
{
|
|
||||||
strDir = strprintf("%s\\Bitcoin", getenv("APPDATA"));
|
|
||||||
}
|
|
||||||
else if (getenv("USERPROFILE"))
|
|
||||||
{
|
|
||||||
string strAppData = strprintf("%s\\Application Data", getenv("USERPROFILE"));
|
|
||||||
static bool fMkdirDone;
|
|
||||||
if (!fMkdirDone)
|
|
||||||
{
|
|
||||||
fMkdirDone = true;
|
|
||||||
_mkdir(strAppData.c_str());
|
|
||||||
}
|
|
||||||
strDir = strprintf("%s\\Bitcoin", strAppData.c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ".";
|
|
||||||
}
|
|
||||||
static bool fMkdirDone;
|
|
||||||
if (!fMkdirDone)
|
|
||||||
{
|
|
||||||
fMkdirDone = true;
|
|
||||||
_mkdir(strDir.c_str());
|
|
||||||
}
|
|
||||||
return strDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckDiskSpace(int64 nAdditionalBytes)
|
bool CheckDiskSpace(int64 nAdditionalBytes)
|
||||||
{
|
{
|
||||||
wxLongLong nFreeBytesAvailable = 0;
|
wxLongLong nFreeBytesAvailable = 0;
|
||||||
if (!wxGetDiskSpace(wxStandardPaths::Get().GetDataDir(), NULL, &nFreeBytesAvailable))
|
if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable))
|
||||||
{
|
{
|
||||||
printf("ERROR: wxGetDiskSpace() failed\n");
|
printf("ERROR: wxGetDiskSpace() failed\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for 15MB because database could create another 10MB log file at any time
|
// Check for 15MB because database could create another 10MB log file at any time
|
||||||
if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes)
|
if (nFreeBytesAvailable.GetValue() < (int64)15000000 + nAdditionalBytes)
|
||||||
{
|
{
|
||||||
fShutdown = true;
|
fShutdown = true;
|
||||||
wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION);
|
wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION);
|
||||||
@ -1420,7 +1384,7 @@ FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszM
|
|||||||
{
|
{
|
||||||
if (nFile == -1)
|
if (nFile == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetAppDir().c_str(), nFile).c_str(), pszMode);
|
FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode);
|
||||||
if (!file)
|
if (!file)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
|
if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
|
||||||
@ -1719,7 +1683,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||||||
if (strstr(e.what(), "CDataStream::read() : end of data"))
|
if (strstr(e.what(), "CDataStream::read() : end of data"))
|
||||||
{
|
{
|
||||||
// Allow exceptions from underlength message on vRecv
|
// Allow exceptions from underlength message on vRecv
|
||||||
LogException(&e, "ProcessMessage()");
|
printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
PrintException(&e, "ProcessMessage()");
|
PrintException(&e, "ProcessMessage()");
|
||||||
@ -2512,7 +2476,7 @@ bool BitcoinMiner()
|
|||||||
|
|
||||||
int64 GetBalance()
|
int64 GetBalance()
|
||||||
{
|
{
|
||||||
int64 nStart = PerformanceCounter();
|
int64 nStart = GetTimeMillis();
|
||||||
|
|
||||||
int64 nTotal = 0;
|
int64 nTotal = 0;
|
||||||
CRITICAL_BLOCK(cs_mapWallet)
|
CRITICAL_BLOCK(cs_mapWallet)
|
||||||
@ -2522,11 +2486,11 @@ int64 GetBalance()
|
|||||||
CWalletTx* pcoin = &(*it).second;
|
CWalletTx* pcoin = &(*it).second;
|
||||||
if (!pcoin->IsFinal() || pcoin->fSpent)
|
if (!pcoin->IsFinal() || pcoin->fSpent)
|
||||||
continue;
|
continue;
|
||||||
nTotal += pcoin->GetCredit();
|
nTotal += pcoin->GetCredit(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///printf(" GetBalance() time = %15"PRI64d"\n", PerformanceCounter() - nStart);
|
//printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
return nTotal;
|
return nTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
main.h
20
main.h
@ -34,7 +34,6 @@ extern int nBestHeight;
|
|||||||
extern uint256 hashBestChain;
|
extern uint256 hashBestChain;
|
||||||
extern CBlockIndex* pindexBest;
|
extern CBlockIndex* pindexBest;
|
||||||
extern unsigned int nTransactionsUpdated;
|
extern unsigned int nTransactionsUpdated;
|
||||||
extern string strSetDataDir;
|
|
||||||
extern int nDropMessagesTest;
|
extern int nDropMessagesTest;
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
@ -50,7 +49,6 @@ extern int nLimitProcessors;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
string GetAppDir();
|
|
||||||
bool CheckDiskSpace(int64 nAdditionalBytes=0);
|
bool CheckDiskSpace(int64 nAdditionalBytes=0);
|
||||||
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
|
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
|
||||||
FILE* AppendBlockFile(unsigned int& nFileRet);
|
FILE* AppendBlockFile(unsigned int& nFileRet);
|
||||||
@ -405,10 +403,10 @@ public:
|
|||||||
{
|
{
|
||||||
// Time based nLockTime implemented in 0.1.6,
|
// Time based nLockTime implemented in 0.1.6,
|
||||||
// do not use time based until most 0.1.5 nodes have upgraded.
|
// do not use time based until most 0.1.5 nodes have upgraded.
|
||||||
if (nBlockTime == 0)
|
|
||||||
nBlockTime = GetAdjustedTime();
|
|
||||||
if (nLockTime == 0)
|
if (nLockTime == 0)
|
||||||
return true;
|
return true;
|
||||||
|
if (nBlockTime == 0)
|
||||||
|
nBlockTime = GetAdjustedTime();
|
||||||
if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime))
|
if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime))
|
||||||
return true;
|
return true;
|
||||||
foreach(const CTxIn& txin, vin)
|
foreach(const CTxIn& txin, vin)
|
||||||
@ -627,6 +625,8 @@ public:
|
|||||||
|
|
||||||
// memory only
|
// memory only
|
||||||
mutable bool fMerkleVerified;
|
mutable bool fMerkleVerified;
|
||||||
|
mutable bool fGetCreditCached;
|
||||||
|
mutable int64 nGetCreditCached;
|
||||||
|
|
||||||
|
|
||||||
CMerkleTx()
|
CMerkleTx()
|
||||||
@ -644,14 +644,22 @@ public:
|
|||||||
hashBlock = 0;
|
hashBlock = 0;
|
||||||
nIndex = -1;
|
nIndex = -1;
|
||||||
fMerkleVerified = false;
|
fMerkleVerified = false;
|
||||||
|
fGetCreditCached = false;
|
||||||
|
nGetCreditCached = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 GetCredit() const
|
int64 GetCredit(bool fUseCache=false) const
|
||||||
{
|
{
|
||||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||||
return 0;
|
return 0;
|
||||||
return CTransaction::GetCredit();
|
|
||||||
|
// GetBalance can assume transactions in mapWallet won't change
|
||||||
|
if (fUseCache && fGetCreditCached)
|
||||||
|
return nGetCreditCached;
|
||||||
|
nGetCreditCached = CTransaction::GetCredit();
|
||||||
|
fGetCreditCached = true;
|
||||||
|
return nGetCreditCached;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
IMPLEMENT_SERIALIZE
|
||||||
|
34
net.cpp
34
net.cpp
@ -21,8 +21,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect);
|
|||||||
bool fClient = false;
|
bool fClient = false;
|
||||||
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
|
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
|
||||||
CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
|
CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
|
||||||
CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
|
CNode* pnodeLocalHost = NULL;
|
||||||
CNode* pnodeLocalHost = &nodeLocalHost;
|
|
||||||
uint64 nLocalHostNonce = 0;
|
uint64 nLocalHostNonce = 0;
|
||||||
bool fShutdown = false;
|
bool fShutdown = false;
|
||||||
array<int, 10> vnThreadsRunning;
|
array<int, 10> vnThreadsRunning;
|
||||||
@ -129,7 +128,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha
|
|||||||
strLine = wxString(strLine).Trim();
|
strLine = wxString(strLine).Trim();
|
||||||
CAddress addr(strLine.c_str());
|
CAddress addr(strLine.c_str());
|
||||||
printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
|
printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
|
||||||
if (addr.ip == 0 || !addr.IsRoutable())
|
if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
|
||||||
return false;
|
return false;
|
||||||
ipRet = addr.ip;
|
ipRet = addr.ip;
|
||||||
return true;
|
return true;
|
||||||
@ -740,10 +739,29 @@ void ThreadOpenConnections2(void* parg)
|
|||||||
printf("ThreadOpenConnections started\n");
|
printf("ThreadOpenConnections started\n");
|
||||||
|
|
||||||
// Connect to one specified address
|
// Connect to one specified address
|
||||||
while (mapArgs.count("/connect"))
|
while (mapArgs.count("-connect"))
|
||||||
{
|
{
|
||||||
OpenNetworkConnection(CAddress(mapArgs["/connect"].c_str()));
|
OpenNetworkConnection(CAddress(mapArgs["-connect"]));
|
||||||
Sleep(10000);
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
Sleep(1000);
|
||||||
|
CheckForShutdown(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to manually added nodes first
|
||||||
|
if (mapArgs.count("-addnode"))
|
||||||
|
{
|
||||||
|
foreach(string strAddr, mapMultiArgs["-addnode"])
|
||||||
|
{
|
||||||
|
CAddress addr(strAddr, NODE_NETWORK);
|
||||||
|
if (addr.IsValid())
|
||||||
|
{
|
||||||
|
OpenNetworkConnection(addr);
|
||||||
|
Sleep(1000);
|
||||||
|
CheckForShutdown(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initiate network connections
|
// Initiate network connections
|
||||||
@ -967,6 +985,8 @@ void ThreadMessageHandler2(void* parg)
|
|||||||
|
|
||||||
bool StartNode(string& strError)
|
bool StartNode(string& strError)
|
||||||
{
|
{
|
||||||
|
if (pnodeLocalHost == NULL)
|
||||||
|
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
|
||||||
strError = "";
|
strError = "";
|
||||||
|
|
||||||
// Sockets startup
|
// Sockets startup
|
||||||
@ -1031,7 +1051,7 @@ bool StartNode(string& strError)
|
|||||||
printf("%s\n", strError.c_str());
|
printf("%s\n", strError.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
printf("bound to addrLocalHost = %s\n\n", addrLocalHost.ToString().c_str());
|
printf("bound to addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
|
||||||
|
|
||||||
// Listen for incoming connections
|
// Listen for incoming connections
|
||||||
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
|
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
|
||||||
|
78
net.h
78
net.h
@ -2,12 +2,6 @@
|
|||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#ifndef __WXMSW__
|
|
||||||
#define closesocket(s) close(s)
|
|
||||||
#define INVALID_SOCKET (SOCKET)(~0)
|
|
||||||
typedef u_int SOCKET;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class CMessageHeader;
|
class CMessageHeader;
|
||||||
class CAddress;
|
class CAddress;
|
||||||
class CInv;
|
class CInv;
|
||||||
@ -148,61 +142,73 @@ public:
|
|||||||
|
|
||||||
CAddress()
|
CAddress()
|
||||||
{
|
{
|
||||||
nServices = 0;
|
Init();
|
||||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
|
||||||
ip = 0;
|
|
||||||
port = DEFAULT_PORT;
|
|
||||||
nTime = GetAdjustedTime();
|
|
||||||
nLastFailed = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=0)
|
CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=NODE_NETWORK)
|
||||||
{
|
{
|
||||||
nServices = nServicesIn;
|
Init();
|
||||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
|
||||||
ip = ipIn;
|
ip = ipIn;
|
||||||
port = portIn;
|
port = portIn;
|
||||||
nTime = GetAdjustedTime();
|
nServices = nServicesIn;
|
||||||
nLastFailed = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0)
|
explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK)
|
||||||
{
|
{
|
||||||
nServices = nServicesIn;
|
Init();
|
||||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
|
||||||
ip = sockaddr.sin_addr.s_addr;
|
ip = sockaddr.sin_addr.s_addr;
|
||||||
port = sockaddr.sin_port;
|
port = sockaddr.sin_port;
|
||||||
nTime = GetAdjustedTime();
|
nServices = nServicesIn;
|
||||||
nLastFailed = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit CAddress(const char* pszIn, uint64 nServicesIn=0)
|
explicit CAddress(const char* pszIn, uint64 nServicesIn=NODE_NETWORK)
|
||||||
{
|
{
|
||||||
|
Init();
|
||||||
|
SetAddress(pszIn);
|
||||||
nServices = nServicesIn;
|
nServices = nServicesIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit CAddress(string strIn, uint64 nServicesIn=NODE_NETWORK)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
SetAddress(strIn.c_str());
|
||||||
|
nServices = nServicesIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
nServices = NODE_NETWORK;
|
||||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
||||||
ip = INADDR_NONE;
|
ip = INADDR_NONE;
|
||||||
port = DEFAULT_PORT;
|
port = DEFAULT_PORT;
|
||||||
nTime = GetAdjustedTime();
|
nTime = GetAdjustedTime();
|
||||||
nLastFailed = 0;
|
nLastFailed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetAddress(const char* pszIn)
|
||||||
|
{
|
||||||
|
ip = INADDR_NONE;
|
||||||
|
port = DEFAULT_PORT;
|
||||||
char psz[100];
|
char psz[100];
|
||||||
if (strlen(pszIn) > ARRAYLEN(psz)-1)
|
strlcpy(psz, pszIn, sizeof(psz));
|
||||||
return;
|
|
||||||
strcpy(psz, pszIn);
|
|
||||||
unsigned int a=0, b=0, c=0, d=0, e=0;
|
unsigned int a=0, b=0, c=0, d=0, e=0;
|
||||||
if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4)
|
if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4)
|
||||||
return;
|
return false;
|
||||||
char* pszPort = strchr(psz, ':');
|
char* pszPort = strchr(psz, ':');
|
||||||
if (pszPort)
|
if (pszPort)
|
||||||
{
|
{
|
||||||
*pszPort++ = '\0';
|
*pszPort++ = '\0';
|
||||||
port = htons(atoi(pszPort));
|
port = htons(atoi(pszPort));
|
||||||
if (atoi(pszPort) > USHRT_MAX)
|
if (atoi(pszPort) < 0 || atoi(pszPort) > USHRT_MAX)
|
||||||
port = htons(USHRT_MAX);
|
port = htons(USHRT_MAX);
|
||||||
if (atoi(pszPort) < 0)
|
|
||||||
port = htons(0);
|
|
||||||
}
|
}
|
||||||
ip = inet_addr(psz);
|
ip = inet_addr(psz);
|
||||||
|
return IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetAddress(string strIn)
|
||||||
|
{
|
||||||
|
return SetAddress(strIn.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
IMPLEMENT_SERIALIZE
|
||||||
@ -274,7 +280,17 @@ public:
|
|||||||
|
|
||||||
bool IsRoutable() const
|
bool IsRoutable() const
|
||||||
{
|
{
|
||||||
return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168) || GetByte(3) == 127 || GetByte(3) == 0);
|
return !(GetByte(3) == 10 ||
|
||||||
|
(GetByte(3) == 192 && GetByte(2) == 168) ||
|
||||||
|
GetByte(3) == 127 ||
|
||||||
|
GetByte(3) == 0 ||
|
||||||
|
ip == 0 ||
|
||||||
|
ip == INADDR_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid() const
|
||||||
|
{
|
||||||
|
return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char GetByte(int n) const
|
unsigned char GetByte(int n) const
|
||||||
|
455
ui.cpp
455
ui.cpp
@ -25,7 +25,6 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED)
|
|||||||
CMainFrame* pframeMain = NULL;
|
CMainFrame* pframeMain = NULL;
|
||||||
CMyTaskBarIcon* ptaskbaricon = NULL;
|
CMyTaskBarIcon* ptaskbaricon = NULL;
|
||||||
map<string, string> mapAddressBook;
|
map<string, string> mapAddressBook;
|
||||||
map<string, string> mapArgs;
|
|
||||||
bool fRandSendTest = false;
|
bool fRandSendTest = false;
|
||||||
void RandSend();
|
void RandSend();
|
||||||
extern int g_isPainting;
|
extern int g_isPainting;
|
||||||
@ -283,7 +282,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
|
|||||||
fRefreshListCtrl = false;
|
fRefreshListCtrl = false;
|
||||||
fRefreshListCtrlRunning = false;
|
fRefreshListCtrlRunning = false;
|
||||||
fOnSetFocusAddress = false;
|
fOnSetFocusAddress = false;
|
||||||
pindexBestLast = NULL;
|
|
||||||
m_choiceFilter->SetSelection(0);
|
m_choiceFilter->SetSelection(0);
|
||||||
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
|
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
|
||||||
m_listCtrl->SetFocus();
|
m_listCtrl->SetFocus();
|
||||||
@ -507,6 +505,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
|||||||
string strStatus = FormatTxStatus(wtx);
|
string strStatus = FormatTxStatus(wtx);
|
||||||
map<string, string> mapValue = wtx.mapValue;
|
map<string, string> mapValue = wtx.mapValue;
|
||||||
wtx.nLinesDisplayed = 1;
|
wtx.nLinesDisplayed = 1;
|
||||||
|
nListViewUpdated++;
|
||||||
|
|
||||||
// Filter
|
// Filter
|
||||||
if (wtx.IsCoinBase())
|
if (wtx.IsCoinBase())
|
||||||
@ -712,48 +711,6 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMainFrame::RefreshStatus()
|
|
||||||
{
|
|
||||||
static int nLastTop;
|
|
||||||
int nTop = max((int)m_listCtrl->GetTopItem(), 0);
|
|
||||||
if (nTop == nLastTop && pindexBestLast == pindexBest)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
|
||||||
{
|
|
||||||
int nStart = nTop;
|
|
||||||
int nEnd = min(nStart + 100, m_listCtrl->GetItemCount());
|
|
||||||
if (pindexBestLast == pindexBest)
|
|
||||||
{
|
|
||||||
if (nStart >= nLastTop && nStart < nLastTop + 100)
|
|
||||||
nStart = nLastTop + 100;
|
|
||||||
if (nEnd >= nLastTop && nEnd < nLastTop + 100)
|
|
||||||
nEnd = nLastTop;
|
|
||||||
}
|
|
||||||
nLastTop = nTop;
|
|
||||||
pindexBestLast = pindexBest;
|
|
||||||
|
|
||||||
for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++)
|
|
||||||
{
|
|
||||||
uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1));
|
|
||||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
|
||||||
if (mi == mapWallet.end())
|
|
||||||
{
|
|
||||||
printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CWalletTx& wtx = (*mi).second;
|
|
||||||
if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed)
|
|
||||||
{
|
|
||||||
if (!InsertTransaction(wtx, false, nIndex))
|
|
||||||
m_listCtrl->DeleteItem(nIndex--);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMainFrame::RefreshListCtrl()
|
void CMainFrame::RefreshListCtrl()
|
||||||
{
|
{
|
||||||
fRefreshListCtrl = true;
|
fRefreshListCtrl = true;
|
||||||
@ -832,21 +789,104 @@ void CMainFrame::OnIdle(wxIdleEvent& event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMainFrame::RefreshStatusColumn()
|
||||||
|
{
|
||||||
|
static int nLastTop;
|
||||||
|
static CBlockIndex* pindexLastBest;
|
||||||
|
static unsigned int nLastRefreshed;
|
||||||
|
|
||||||
|
int nTop = max((int)m_listCtrl->GetTopItem(), 0);
|
||||||
|
if (nTop == nLastTop && pindexLastBest == pindexBest)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
||||||
|
{
|
||||||
|
int nStart = nTop;
|
||||||
|
int nEnd = min(nStart + 100, m_listCtrl->GetItemCount());
|
||||||
|
|
||||||
|
if (pindexLastBest == pindexBest && nLastRefreshed == nListViewUpdated)
|
||||||
|
{
|
||||||
|
// If no updates, only need to do the part that moved onto the screen
|
||||||
|
if (nStart >= nLastTop && nStart < nLastTop + 100)
|
||||||
|
nStart = nLastTop + 100;
|
||||||
|
if (nEnd >= nLastTop && nEnd < nLastTop + 100)
|
||||||
|
nEnd = nLastTop;
|
||||||
|
}
|
||||||
|
nLastTop = nTop;
|
||||||
|
pindexLastBest = pindexBest;
|
||||||
|
nLastRefreshed = nListViewUpdated;
|
||||||
|
|
||||||
|
for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++)
|
||||||
|
{
|
||||||
|
uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1));
|
||||||
|
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
||||||
|
if (mi == mapWallet.end())
|
||||||
|
{
|
||||||
|
printf("CMainFrame::RefreshStatusColumn() : tx not found in mapWallet\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CWalletTx& wtx = (*mi).second;
|
||||||
|
if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed)
|
||||||
|
{
|
||||||
|
if (!InsertTransaction(wtx, false, nIndex))
|
||||||
|
m_listCtrl->DeleteItem(nIndex--);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CMainFrame::OnPaint(wxPaintEvent& event)
|
void CMainFrame::OnPaint(wxPaintEvent& event)
|
||||||
{
|
{
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelayedRepaint(void* parg)
|
|
||||||
|
unsigned int nNeedRepaint = 0;
|
||||||
|
unsigned int nLastRepaint = 0;
|
||||||
|
int64 nLastRepaintTime = 0;
|
||||||
|
int64 nRepaintInterval = 500;
|
||||||
|
|
||||||
|
void ThreadDelayedRepaint(void* parg)
|
||||||
{
|
{
|
||||||
static bool fOneThread;
|
while (!fShutdown)
|
||||||
if (fOneThread)
|
{
|
||||||
return;
|
if (nLastRepaint != nNeedRepaint && GetTimeMillis() - nLastRepaintTime >= nRepaintInterval)
|
||||||
fOneThread = true;
|
{
|
||||||
Sleep(1000);
|
nLastRepaint = nNeedRepaint;
|
||||||
printf("DelayedRepaint()\n");
|
if (pframeMain)
|
||||||
MainFrameRepaint();
|
{
|
||||||
fOneThread = false;
|
printf("DelayedRepaint\n");
|
||||||
|
wxPaintEvent event;
|
||||||
|
pframeMain->Refresh();
|
||||||
|
pframeMain->AddPendingEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sleep(nRepaintInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainFrameRepaint()
|
||||||
|
{
|
||||||
|
// This is called by network code that shouldn't access pframeMain
|
||||||
|
// directly because it could still be running after the UI is closed.
|
||||||
|
if (pframeMain)
|
||||||
|
{
|
||||||
|
// Don't repaint too often
|
||||||
|
static int64 nLastRepaintRequest;
|
||||||
|
if (GetTimeMillis() - nLastRepaintRequest < 100)
|
||||||
|
{
|
||||||
|
nNeedRepaint++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nLastRepaintRequest = GetTimeMillis();
|
||||||
|
|
||||||
|
printf("MainFrameRepaint\n");
|
||||||
|
wxPaintEvent event;
|
||||||
|
pframeMain->Refresh();
|
||||||
|
pframeMain->AddPendingEvent(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
||||||
@ -854,43 +894,54 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
|||||||
if (ptaskbaricon)
|
if (ptaskbaricon)
|
||||||
ptaskbaricon->UpdateTooltip();
|
ptaskbaricon->UpdateTooltip();
|
||||||
|
|
||||||
// Update listctrl contents
|
//
|
||||||
if (!vWalletUpdated.empty())
|
// Slower stuff
|
||||||
|
//
|
||||||
|
static int nTransactionCount;
|
||||||
|
bool fPaintedBalance = false;
|
||||||
|
if (GetTimeMillis() - nLastRepaintTime >= nRepaintInterval)
|
||||||
{
|
{
|
||||||
|
nLastRepaint = nNeedRepaint;
|
||||||
|
nLastRepaintTime = GetTimeMillis();
|
||||||
|
|
||||||
|
// Update listctrl contents
|
||||||
|
if (!vWalletUpdated.empty())
|
||||||
|
{
|
||||||
|
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
||||||
|
{
|
||||||
|
bool fInserted = false;
|
||||||
|
foreach(uint256 hash, vWalletUpdated)
|
||||||
|
{
|
||||||
|
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
||||||
|
if (mi != mapWallet.end())
|
||||||
|
fInserted |= InsertTransaction((*mi).second, false);
|
||||||
|
}
|
||||||
|
vWalletUpdated.clear();
|
||||||
|
if (fInserted)
|
||||||
|
m_listCtrl->ScrollList(0, INT_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Balance total
|
||||||
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
||||||
{
|
{
|
||||||
bool fInserted = false;
|
fPaintedBalance = true;
|
||||||
foreach(uint256 hash, vWalletUpdated)
|
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
|
||||||
|
|
||||||
|
// Count hidden and multi-line transactions
|
||||||
|
nTransactionCount = 0;
|
||||||
|
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
CWalletTx& wtx = (*it).second;
|
||||||
if (mi != mapWallet.end())
|
nTransactionCount += wtx.nLinesDisplayed;
|
||||||
fInserted |= InsertTransaction((*mi).second, false);
|
|
||||||
}
|
}
|
||||||
vWalletUpdated.clear();
|
|
||||||
if (fInserted)
|
|
||||||
m_listCtrl->ScrollList(0, INT_MAX);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!vWalletUpdated.empty() || !fPaintedBalance)
|
||||||
|
nNeedRepaint++;
|
||||||
|
|
||||||
// Update status column of visible items only
|
// Update status column of visible items only
|
||||||
RefreshStatus();
|
RefreshStatusColumn();
|
||||||
|
|
||||||
// Balance total
|
|
||||||
bool fRefreshed = false;
|
|
||||||
static int nTransactionCount;
|
|
||||||
TRY_CRITICAL_BLOCK(cs_mapWallet)
|
|
||||||
{
|
|
||||||
fRefreshed = true;
|
|
||||||
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
|
|
||||||
|
|
||||||
// Count hidden and multi-line transactions
|
|
||||||
nTransactionCount = 0;
|
|
||||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
|
||||||
{
|
|
||||||
CWalletTx& wtx = (*it).second;
|
|
||||||
nTransactionCount += wtx.nLinesDisplayed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update status bar
|
// Update status bar
|
||||||
string strGen = "";
|
string strGen = "";
|
||||||
@ -903,13 +954,10 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
|||||||
string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount);
|
string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount);
|
||||||
m_statusBar->SetStatusText(strStatus, 2);
|
m_statusBar->SetStatusText(strStatus, 2);
|
||||||
|
|
||||||
// mapWallet was locked, try again later
|
|
||||||
if (!vWalletUpdated.empty() || !fRefreshed)
|
|
||||||
_beginthread(DelayedRepaint, 0, NULL);
|
|
||||||
|
|
||||||
m_listCtrl->OnPaint(event);
|
m_listCtrl->OnPaint(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CrossThreadCall(wxCommandEvent& event)
|
void CrossThreadCall(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
if (pframeMain)
|
if (pframeMain)
|
||||||
@ -994,13 +1042,6 @@ void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event)
|
|||||||
|
|
||||||
void CMainFrame::OnButtonSend(wxCommandEvent& event)
|
void CMainFrame::OnButtonSend(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
/// debug test
|
|
||||||
if (fRandSendTest)
|
|
||||||
{
|
|
||||||
RandSend();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toolbar: Send
|
// Toolbar: Send
|
||||||
CSendDialog dialog(this);
|
CSendDialog dialog(this);
|
||||||
dialog.ShowModal();
|
dialog.ShowModal();
|
||||||
@ -1684,8 +1725,8 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Parse IP address
|
// Parse IP address
|
||||||
CAddress addr(strAddress.c_str());
|
CAddress addr(strAddress);
|
||||||
if (addr.ip == 0)
|
if (!addr.IsValid())
|
||||||
{
|
{
|
||||||
wxMessageBox("Invalid address ", "Send Coins");
|
wxMessageBox("Invalid address ", "Send Coins");
|
||||||
return;
|
return;
|
||||||
@ -1818,14 +1859,6 @@ void CSendingDialog::OnPaint(wxPaintEvent& event)
|
|||||||
wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this);
|
wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this);
|
||||||
}
|
}
|
||||||
event.Skip();
|
event.Skip();
|
||||||
|
|
||||||
/// debug test
|
|
||||||
if (fRandSendTest && fWorkDone && fSuccess)
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
Sleep(1000);
|
|
||||||
RandSend();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3305,27 +3338,6 @@ bool CMyApp::OnInit()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<string, string> ParseParameters(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
map<string, string> mapArgs;
|
|
||||||
for (int i = 0; i < argc; i++)
|
|
||||||
{
|
|
||||||
char psz[10000];
|
|
||||||
strcpy(psz, argv[i]);
|
|
||||||
char* pszValue = "";
|
|
||||||
if (strchr(psz, '='))
|
|
||||||
{
|
|
||||||
pszValue = strchr(psz, '=');
|
|
||||||
*pszValue++ = '\0';
|
|
||||||
}
|
|
||||||
strlwr(psz);
|
|
||||||
if (psz[0] == '-')
|
|
||||||
psz[0] = '/';
|
|
||||||
mapArgs[psz] = pszValue;
|
|
||||||
}
|
|
||||||
return mapArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMyApp::OnInit2()
|
bool CMyApp::OnInit2()
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -3337,10 +3349,27 @@ bool CMyApp::OnInit2()
|
|||||||
// Disable malfunctioning wxWidgets debug assertion
|
// Disable malfunctioning wxWidgets debug assertion
|
||||||
g_isPainting = 10000;
|
g_isPainting = 10000;
|
||||||
#endif
|
#endif
|
||||||
|
wxImage::AddHandler(new wxPNGHandler);
|
||||||
|
SetAppName("Bitcoin");
|
||||||
|
|
||||||
//// debug print
|
ParseParameters(argc, argv);
|
||||||
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
||||||
printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion());
|
{
|
||||||
|
string strUsage =
|
||||||
|
"Usage: bitcoin [options]\t\t\t\t\t\t\n"
|
||||||
|
"Options:\n"
|
||||||
|
" -gen\t\t Generate coins\n"
|
||||||
|
" -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"
|
||||||
|
" -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";
|
||||||
|
wxMessageBox(strUsage, "Bitcoin", wxOK);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Limit to single instance per user
|
// Limit to single instance per user
|
||||||
@ -3382,31 +3411,31 @@ bool CMyApp::OnInit2()
|
|||||||
//
|
//
|
||||||
// Parameters
|
// Parameters
|
||||||
//
|
//
|
||||||
wxImage::AddHandler(new wxPNGHandler);
|
if (mapArgs.count("-datadir"))
|
||||||
mapArgs = ParseParameters(argc, argv);
|
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
|
||||||
|
|
||||||
if (mapArgs.count("/datadir"))
|
if (mapArgs.count("-debug"))
|
||||||
strSetDataDir = mapArgs["/datadir"];
|
|
||||||
|
|
||||||
if (mapArgs.count("/debug"))
|
|
||||||
fDebug = true;
|
fDebug = true;
|
||||||
|
|
||||||
if (mapArgs.count("/printtodebugger"))
|
if (mapArgs.count("-printtodebugger"))
|
||||||
fPrintToDebugger = true;
|
fPrintToDebugger = true;
|
||||||
|
|
||||||
if (mapArgs.count("/dropmessages"))
|
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());
|
||||||
|
|
||||||
|
if (mapArgs.count("-dropmessages"))
|
||||||
{
|
{
|
||||||
nDropMessagesTest = atoi(mapArgs["/dropmessages"]);
|
nDropMessagesTest = atoi(mapArgs["-dropmessages"]);
|
||||||
if (nDropMessagesTest == 0)
|
if (nDropMessagesTest == 0)
|
||||||
nDropMessagesTest = 20;
|
nDropMessagesTest = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapArgs.count("/loadblockindextest"))
|
if (mapArgs.count("-loadblockindextest"))
|
||||||
{
|
{
|
||||||
CTxDB txdb("r");
|
CTxDB txdb("r");
|
||||||
txdb.LoadBlockIndex();
|
txdb.LoadBlockIndex();
|
||||||
PrintBlockTree();
|
PrintBlockTree();
|
||||||
ExitProcess(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -3417,22 +3446,22 @@ bool CMyApp::OnInit2()
|
|||||||
int64 nStart;
|
int64 nStart;
|
||||||
|
|
||||||
printf("Loading addresses...\n");
|
printf("Loading addresses...\n");
|
||||||
nStart = PerformanceCounter();
|
nStart = GetTimeMillis();
|
||||||
if (!LoadAddresses())
|
if (!LoadAddresses())
|
||||||
strErrors += "Error loading addr.dat \n";
|
strErrors += "Error loading addr.dat \n";
|
||||||
printf(" addresses %15"PRI64d"\n", PerformanceCounter() - nStart);
|
printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
|
|
||||||
printf("Loading block index...\n");
|
printf("Loading block index...\n");
|
||||||
nStart = PerformanceCounter();
|
nStart = GetTimeMillis();
|
||||||
if (!LoadBlockIndex())
|
if (!LoadBlockIndex())
|
||||||
strErrors += "Error loading blkindex.dat \n";
|
strErrors += "Error loading blkindex.dat \n";
|
||||||
printf(" block index %15"PRI64d"\n", PerformanceCounter() - nStart);
|
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
|
|
||||||
printf("Loading wallet...\n");
|
printf("Loading wallet...\n");
|
||||||
nStart = PerformanceCounter();
|
nStart = GetTimeMillis();
|
||||||
if (!LoadWallet(fFirstRun))
|
if (!LoadWallet(fFirstRun))
|
||||||
strErrors += "Error loading wallet.dat \n";
|
strErrors += "Error loading wallet.dat \n";
|
||||||
printf(" wallet %15"PRI64d"\n", PerformanceCounter() - nStart);
|
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
|
|
||||||
printf("Done loading\n");
|
printf("Done loading\n");
|
||||||
|
|
||||||
@ -3457,45 +3486,59 @@ bool CMyApp::OnInit2()
|
|||||||
//
|
//
|
||||||
// Parameters
|
// Parameters
|
||||||
//
|
//
|
||||||
if (mapArgs.count("/printblockindex") || mapArgs.count("/printblocktree"))
|
if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree"))
|
||||||
{
|
{
|
||||||
PrintBlockTree();
|
PrintBlockTree();
|
||||||
OnExit();
|
OnExit();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapArgs.count("/proxy"))
|
if (mapArgs.count("-gen"))
|
||||||
|
{
|
||||||
|
if (mapArgs["-gen"].empty())
|
||||||
|
fGenerateBitcoins = true;
|
||||||
|
else
|
||||||
|
fGenerateBitcoins = atoi(mapArgs["-gen"].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapArgs.count("-proxy"))
|
||||||
{
|
{
|
||||||
fUseProxy = true;
|
fUseProxy = true;
|
||||||
addrProxy = CAddress(mapArgs["/proxy"].c_str());
|
addrProxy = CAddress(mapArgs["-proxy"]);
|
||||||
if (addrProxy.ip == INADDR_NONE)
|
if (!addrProxy.IsValid())
|
||||||
{
|
{
|
||||||
wxMessageBox("Invalid /proxy address", "Bitcoin");
|
wxMessageBox("Invalid -proxy address", "Bitcoin");
|
||||||
OnExit();
|
OnExit();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
CWalletDB walletdb;
|
CWalletDB walletdb;
|
||||||
walletdb.WriteSetting("fUseProxy", fUseProxy);
|
walletdb.WriteSetting("fUseProxy", fUseProxy);
|
||||||
walletdb.WriteSetting("addrProxy", addrProxy);
|
walletdb.WriteSetting("addrProxy", addrProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapArgs.count("/gen"))
|
if (mapArgs.count("-addnode"))
|
||||||
{
|
{
|
||||||
if (mapArgs["/gen"].empty())
|
CAddrDB addrdb;
|
||||||
fGenerateBitcoins = true;
|
foreach(string strAddr, mapMultiArgs["-addnode"])
|
||||||
else
|
{
|
||||||
fGenerateBitcoins = atoi(mapArgs["/gen"].c_str());
|
CAddress addr(strAddr, NODE_NETWORK);
|
||||||
|
if (addr.IsValid())
|
||||||
|
AddAddress(addrdb, addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create the main frame window
|
// Create the main frame window
|
||||||
//
|
//
|
||||||
pframeMain = new CMainFrame(NULL);
|
pframeMain = new CMainFrame(NULL);
|
||||||
if (mapArgs.count("/min"))
|
if (mapArgs.count("-min"))
|
||||||
pframeMain->Iconize(true);
|
pframeMain->Iconize(true);
|
||||||
pframeMain->Show(true); // have to show first to get taskbar button to hide
|
pframeMain->Show(true); // have to show first to get taskbar button to hide
|
||||||
pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized());
|
pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized());
|
||||||
ptaskbaricon->Show(fMinimizeToTray);
|
ptaskbaricon->Show(fMinimizeToTray);
|
||||||
|
|
||||||
|
_beginthread(ThreadDelayedRepaint, 0, NULL);
|
||||||
|
|
||||||
if (!CheckDiskSpace())
|
if (!CheckDiskSpace())
|
||||||
{
|
{
|
||||||
OnExit();
|
OnExit();
|
||||||
@ -3516,7 +3559,7 @@ bool CMyApp::OnInit2()
|
|||||||
//
|
//
|
||||||
// Tests
|
// Tests
|
||||||
//
|
//
|
||||||
if (argc >= 2 && stricmp(argv[1], "/send") == 0)
|
if (argc >= 2 && stricmp(argv[1], "-send") == 0)
|
||||||
{
|
{
|
||||||
int64 nValue = 1;
|
int64 nValue = 1;
|
||||||
if (argc >= 3)
|
if (argc >= 3)
|
||||||
@ -3525,7 +3568,7 @@ bool CMyApp::OnInit2()
|
|||||||
string strAddress;
|
string strAddress;
|
||||||
if (argc >= 4)
|
if (argc >= 4)
|
||||||
strAddress = argv[3];
|
strAddress = argv[3];
|
||||||
CAddress addr(strAddress.c_str());
|
CAddress addr(strAddress);
|
||||||
|
|
||||||
CWalletTx wtx;
|
CWalletTx wtx;
|
||||||
wtx.mapValue["to"] = strAddress;
|
wtx.mapValue["to"] = strAddress;
|
||||||
@ -3538,15 +3581,6 @@ bool CMyApp::OnInit2()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapArgs.count("/randsendtest"))
|
|
||||||
{
|
|
||||||
if (!mapArgs["/randsendtest"].empty())
|
|
||||||
_beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"]));
|
|
||||||
else
|
|
||||||
fRandSendTest = true;
|
|
||||||
fDebug = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3610,19 +3644,6 @@ void CMyApp::OnFatalException()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MainFrameRepaint()
|
|
||||||
{
|
|
||||||
// This is called by network code that shouldn't access pframeMain
|
|
||||||
// directly because it could still be running after the UI is closed.
|
|
||||||
if (pframeMain)
|
|
||||||
{
|
|
||||||
printf("MainFrameRepaint()\n");
|
|
||||||
wxPaintEvent event;
|
|
||||||
pframeMain->Refresh();
|
|
||||||
pframeMain->AddPendingEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
|
typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
|
||||||
@ -3666,7 +3687,7 @@ string StartupShortcutPath()
|
|||||||
|
|
||||||
bool GetStartOnSystemStartup()
|
bool GetStartOnSystemStartup()
|
||||||
{
|
{
|
||||||
return FileExists(StartupShortcutPath().c_str());
|
return wxFileExists(StartupShortcutPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetStartOnSystemStartup(bool fAutoStart)
|
void SetStartOnSystemStartup(bool fAutoStart)
|
||||||
@ -3727,79 +3748,3 @@ void SetStartOnSystemStartup(bool fAutoStart)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// randsendtest to bitcoin address
|
|
||||||
void ThreadRandSendTest(void* parg)
|
|
||||||
{
|
|
||||||
string strAddress = *(string*)parg;
|
|
||||||
uint160 hash160;
|
|
||||||
if (!AddressToHash160(strAddress, hash160))
|
|
||||||
{
|
|
||||||
wxMessageBox(strprintf("ThreadRandSendTest: Bitcoin address '%s' not valid ", strAddress.c_str()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!fShutdown)
|
|
||||||
{
|
|
||||||
Sleep(GetRand(30) * 1000 + 100);
|
|
||||||
|
|
||||||
// Message
|
|
||||||
CWalletTx wtx;
|
|
||||||
wtx.mapValue["to"] = strAddress;
|
|
||||||
wtx.mapValue["from"] = addrLocalHost.ToString();
|
|
||||||
static int nRep;
|
|
||||||
wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep);
|
|
||||||
|
|
||||||
// Value
|
|
||||||
int64 nValue = (GetRand(9) + 1) * 100 * CENT;
|
|
||||||
if (GetBalance() < nValue)
|
|
||||||
{
|
|
||||||
wxMessageBox("Out of money ");
|
|
||||||
while (GetBalance() < 1000)
|
|
||||||
Sleep(1000);
|
|
||||||
}
|
|
||||||
nValue += (nRep % 100) * CENT;
|
|
||||||
|
|
||||||
// Send to bitcoin address
|
|
||||||
CScript scriptPubKey;
|
|
||||||
scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
|
|
||||||
|
|
||||||
if (fShutdown)
|
|
||||||
return;
|
|
||||||
if (!SendMoney(scriptPubKey, nValue, wtx))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// randsendtest to any connected node
|
|
||||||
void RandSend()
|
|
||||||
{
|
|
||||||
while (vNodes.empty())
|
|
||||||
Sleep(1000);
|
|
||||||
CAddress addr;
|
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
addr = vNodes[GetRand(vNodes.size())]->addr;
|
|
||||||
|
|
||||||
// Message
|
|
||||||
CWalletTx wtx;
|
|
||||||
wtx.mapValue["to"] = addr.ToString();
|
|
||||||
wtx.mapValue["from"] = addrLocalHost.ToString();
|
|
||||||
static int nRep;
|
|
||||||
wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep);
|
|
||||||
|
|
||||||
// Value
|
|
||||||
int64 nValue = (GetRand(999) + 1) * CENT;
|
|
||||||
if (GetBalance() < nValue)
|
|
||||||
{
|
|
||||||
wxMessageBox("Out of money ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send to IP address
|
|
||||||
if (fShutdown)
|
|
||||||
return;
|
|
||||||
CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx);
|
|
||||||
if (!pdialog->Show())
|
|
||||||
wxMessageBox("ShowModal Failed ");
|
|
||||||
}
|
|
||||||
|
5
ui.h
5
ui.h
@ -83,15 +83,14 @@ public:
|
|||||||
bool fRefreshListCtrl;
|
bool fRefreshListCtrl;
|
||||||
bool fRefreshListCtrlRunning;
|
bool fRefreshListCtrlRunning;
|
||||||
bool fOnSetFocusAddress;
|
bool fOnSetFocusAddress;
|
||||||
CBlockIndex* pindexBestLast;
|
unsigned int nListViewUpdated;
|
||||||
set<uint256> setUnmaturedDisplayed;
|
|
||||||
|
|
||||||
void OnCrossThreadCall(wxCommandEvent& event);
|
void OnCrossThreadCall(wxCommandEvent& event);
|
||||||
void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5);
|
void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5);
|
||||||
bool DeleteLine(uint256 hashKey);
|
bool DeleteLine(uint256 hashKey);
|
||||||
bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
|
bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
|
||||||
void RefreshListCtrl();
|
void RefreshListCtrl();
|
||||||
void RefreshStatus();
|
void RefreshStatusColumn();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
82
util.cpp
82
util.cpp
@ -5,9 +5,13 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
|
|
||||||
|
map<string, string> mapArgs;
|
||||||
|
map<string, vector<string> > mapMultiArgs;
|
||||||
bool fDebug = false;
|
bool fDebug = false;
|
||||||
bool fPrintToDebugger = false;
|
bool fPrintToDebugger = false;
|
||||||
bool fPrintToConsole = false;
|
bool fPrintToConsole = false;
|
||||||
|
char pszSetDataDir[MAX_PATH] = "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -68,6 +72,8 @@ void RandAddSeed()
|
|||||||
|
|
||||||
void RandAddSeedPerfmon()
|
void RandAddSeedPerfmon()
|
||||||
{
|
{
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
|
||||||
// This can take up to 2 seconds, so only do it every 10 minutes
|
// This can take up to 2 seconds, so only do it every 10 minutes
|
||||||
static int64 nLastPerfmon;
|
static int64 nLastPerfmon;
|
||||||
if (GetTime() < nLastPerfmon + 10 * 60)
|
if (GetTime() < nLastPerfmon + 10 * 60)
|
||||||
@ -95,6 +101,7 @@ void RandAddSeedPerfmon()
|
|||||||
strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime);
|
strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime);
|
||||||
printf("%s RandAddSeed() %d bytes\n", pszTime, nSize);
|
printf("%s RandAddSeed() %d bytes\n", pszTime, nSize);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -304,6 +311,32 @@ vector<unsigned char> ParseHex(const std::string& str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ParseParameters(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
mapArgs.clear();
|
||||||
|
mapMultiArgs.clear();
|
||||||
|
for (int i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
char psz[10000];
|
||||||
|
strlcpy(psz, argv[i], sizeof(psz));
|
||||||
|
char* pszValue = "";
|
||||||
|
if (strchr(psz, '='))
|
||||||
|
{
|
||||||
|
pszValue = strchr(psz, '=');
|
||||||
|
*pszValue++ = '\0';
|
||||||
|
}
|
||||||
|
strlwr(psz);
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
if (psz[0] == '/')
|
||||||
|
psz[0] = '-';
|
||||||
|
#endif
|
||||||
|
mapArgs[psz] = pszValue;
|
||||||
|
mapMultiArgs[psz].push_back(pszValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -346,15 +379,6 @@ void PrintException(std::exception* pex, const char* pszThread)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool FileExists(const char* psz)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
return GetFileAttributes(psz) != -1;
|
|
||||||
#else
|
|
||||||
return access(psz, 0) != -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetFilesize(FILE* file)
|
int GetFilesize(FILE* file)
|
||||||
{
|
{
|
||||||
int nSavePos = ftell(file);
|
int nSavePos = ftell(file);
|
||||||
@ -365,6 +389,46 @@ int GetFilesize(FILE* file)
|
|||||||
return nFilesize;
|
return nFilesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetDataDir(char* pszDir)
|
||||||
|
{
|
||||||
|
// pszDir must be at least MAX_PATH length.
|
||||||
|
if (pszSetDataDir[0] != 0)
|
||||||
|
{
|
||||||
|
strlcpy(pszDir, pszSetDataDir, MAX_PATH);
|
||||||
|
static bool fMkdirDone;
|
||||||
|
if (!fMkdirDone)
|
||||||
|
{
|
||||||
|
fMkdirDone = true;
|
||||||
|
_mkdir(pszDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This can be called during exceptions by printf, so we cache the
|
||||||
|
// value so we don't have to do memory allocations after that.
|
||||||
|
// wxStandardPaths::GetUserDataDir
|
||||||
|
// Return the directory for the user-dependent application data files:
|
||||||
|
// Unix: ~/.appname
|
||||||
|
// Windows: C:\Documents and Settings\username\Application Data\appname
|
||||||
|
// Mac: ~/Library/Application Support/appname
|
||||||
|
static char pszCachedDir[MAX_PATH];
|
||||||
|
if (pszCachedDir[0] == 0)
|
||||||
|
{
|
||||||
|
strlcpy(pszCachedDir, wxStandardPaths::Get().GetUserDataDir().c_str(), sizeof(pszCachedDir));
|
||||||
|
_mkdir(pszCachedDir);
|
||||||
|
}
|
||||||
|
strlcpy(pszDir, pszCachedDir, MAX_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
string GetDataDir()
|
||||||
|
{
|
||||||
|
char pszDir[MAX_PATH];
|
||||||
|
GetDataDir(pszDir);
|
||||||
|
return pszDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
35
util.h
35
util.h
@ -54,16 +54,23 @@ inline T& REF(const T& val)
|
|||||||
return (T&)val;
|
return (T&)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __WXMSW__
|
||||||
|
#define closesocket(s) close(s)
|
||||||
|
#define INVALID_SOCKET (SOCKET)(~0)
|
||||||
|
typedef u_int SOCKET;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern map<string, string> mapArgs;
|
||||||
|
extern map<string, vector<string> > mapMultiArgs;
|
||||||
extern bool fDebug;
|
extern bool fDebug;
|
||||||
extern bool fPrintToDebugger;
|
extern bool fPrintToDebugger;
|
||||||
extern bool fPrintToConsole;
|
extern bool fPrintToConsole;
|
||||||
extern map<string, string> mapArgs;
|
extern char pszSetDataDir[MAX_PATH];
|
||||||
|
|
||||||
void RandAddSeed();
|
void RandAddSeed();
|
||||||
void RandAddSeedPerfmon();
|
void RandAddSeedPerfmon();
|
||||||
@ -77,8 +84,10 @@ string FormatMoney(int64 n, bool fPlus=false);
|
|||||||
bool ParseMoney(const char* pszIn, int64& nRet);
|
bool ParseMoney(const char* pszIn, int64& nRet);
|
||||||
vector<unsigned char> ParseHex(const char* psz);
|
vector<unsigned char> ParseHex(const char* psz);
|
||||||
vector<unsigned char> ParseHex(const std::string& str);
|
vector<unsigned char> ParseHex(const std::string& str);
|
||||||
bool FileExists(const char* psz);
|
void ParseParameters(int argc, char* argv[]);
|
||||||
int GetFilesize(FILE* file);
|
int GetFilesize(FILE* file);
|
||||||
|
void GetDataDir(char* pszDirRet);
|
||||||
|
string GetDataDir();
|
||||||
uint64 GetRand(uint64 nMax);
|
uint64 GetRand(uint64 nMax);
|
||||||
int64 GetTime();
|
int64 GetTime();
|
||||||
int64 GetAdjustedTime();
|
int64 GetAdjustedTime();
|
||||||
@ -172,9 +181,14 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
|||||||
if (!fPrintToConsole)
|
if (!fPrintToConsole)
|
||||||
{
|
{
|
||||||
// print to debug.log
|
// print to debug.log
|
||||||
FILE* fileout = fopen("debug.log", "a");
|
char pszFile[MAX_PATH+100];
|
||||||
|
GetDataDir(pszFile);
|
||||||
|
strlcat(pszFile, "\\debug.log", sizeof(pszFile));
|
||||||
|
FILE* fileout = fopen(pszFile, "a");
|
||||||
if (fileout)
|
if (fileout)
|
||||||
{
|
{
|
||||||
|
//// Debug print useful for profiling
|
||||||
|
//fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue());
|
||||||
va_list arg_ptr;
|
va_list arg_ptr;
|
||||||
va_start(arg_ptr, pszFormat);
|
va_start(arg_ptr, pszFormat);
|
||||||
ret = vfprintf(fileout, pszFormat, arg_ptr);
|
ret = vfprintf(fileout, pszFormat, arg_ptr);
|
||||||
@ -322,21 +336,24 @@ inline void PrintHex(vector<unsigned char> vch, const char* pszFormat="%s", bool
|
|||||||
printf(pszFormat, HexStr(vch, fSpaces).c_str());
|
printf(pszFormat, HexStr(vch, fSpaces).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline int64 PerformanceCounter()
|
inline int64 PerformanceCounter()
|
||||||
{
|
{
|
||||||
int64 nCounter = 0;
|
int64 nCounter = 0;
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
|
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
|
||||||
#else
|
#else
|
||||||
// this could be changed to reading /dev/urandom
|
timeval t;
|
||||||
timeval t;
|
gettimeofday(&t, NULL);
|
||||||
gettimeofday(&t, NULL);
|
nCounter = t.tv_sec * 1000000 + t.tv_usec;
|
||||||
nCounter += t.tv_sec * 1000000 + t.tv_usec;
|
|
||||||
#endif
|
#endif
|
||||||
return nCounter;
|
return nCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int64 GetTimeMillis()
|
||||||
|
{
|
||||||
|
return wxGetLocalTimeMillis().GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef __WXMSW__
|
#ifndef __WXMSW__
|
||||||
inline void Sleep(unsigned int nMilliseconds)
|
inline void Sleep(unsigned int nMilliseconds)
|
||||||
{
|
{
|
||||||
@ -354,8 +371,10 @@ inline void Sleep(unsigned int nMilliseconds)
|
|||||||
|
|
||||||
inline void heapchk()
|
inline void heapchk()
|
||||||
{
|
{
|
||||||
|
#ifdef __WXMSW__
|
||||||
if (_heapchk() != _HEAPOK)
|
if (_heapchk() != _HEAPOK)
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Randomize the stack to help protect against buffer overrun exploits
|
// Randomize the stack to help protect against buffer overrun exploits
|
||||||
|
Loading…
Reference in New Issue
Block a user