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
12 changed files with 415 additions and 381 deletions
|
@ -10,7 +10,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com).
|
|||
|
||||
Compilers Supported
|
||||
-------------------
|
||||
MinGW GCC
|
||||
MinGW GCC (v3.4.5)
|
||||
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)
|
||||
return;
|
||||
string strAppDir = GetAppDir();
|
||||
string strLogDir = strAppDir + "\\database";
|
||||
string strDataDir = GetDataDir();
|
||||
string strLogDir = strDataDir + "\\database";
|
||||
_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_max(10000000);
|
||||
dbenv.set_lk_max_locks(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
|
||||
ret = dbenv.open(strAppDir.c_str(),
|
||||
ret = dbenv.open(strDataDir.c_str(),
|
||||
DB_CREATE |
|
||||
DB_INIT_LOCK |
|
||||
DB_INIT_LOG |
|
||||
|
@ -139,6 +140,8 @@ void DBFlush(bool fShutdown)
|
|||
// Flush log data to the actual data file
|
||||
// on all files that are not in use
|
||||
printf("DBFlush(%s)\n", fShutdown ? "true" : "false");
|
||||
if (!fDbEnvInit)
|
||||
return;
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
{
|
||||
dbenv.txn_checkpoint(0, 0, 0);
|
||||
|
@ -421,7 +424,7 @@ bool CAddrDB::LoadAddresses()
|
|||
while (fgets(psz, sizeof(psz), filein))
|
||||
{
|
||||
CAddress addr(psz, NODE_NETWORK);
|
||||
if (addr.ip != 0)
|
||||
if (addr.IsValid())
|
||||
{
|
||||
AddAddress(*this, addr);
|
||||
mapIRCAddresses.insert(make_pair(addr.GetKey(), addr));
|
||||
|
@ -676,10 +679,10 @@ void ThreadFlushWalletDB(void* parg)
|
|||
{
|
||||
// Flush wallet.dat so it's self contained
|
||||
nLastFlushed == nWalletDBUpdated;
|
||||
int64 nStart = PerformanceCounter();
|
||||
int64 nStart = GetTimeMillis();
|
||||
dbenv.txn_checkpoint(0, 0, 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++);
|
||||
}
|
||||
}
|
||||
|
|
7
irc.cpp
7
irc.cpp
|
@ -40,7 +40,7 @@ bool DecodeAddress(string str, CAddress& addr)
|
|||
return false;
|
||||
memcpy(&tmp, &vch[0], sizeof(tmp));
|
||||
|
||||
addr = CAddress(tmp.ip, tmp.port);
|
||||
addr = CAddress(tmp.ip, tmp.port, NODE_NETWORK);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -163,6 +163,7 @@ void ThreadIRCSeed(void* parg)
|
|||
int nErrorWait = 10;
|
||||
int nRetryWait = 10;
|
||||
|
||||
// IRC server blocks TOR users
|
||||
if (fUseProxy && addrProxy.port == htons(9050))
|
||||
return;
|
||||
|
||||
|
@ -237,14 +238,14 @@ void ThreadIRCSeed(void* parg)
|
|||
{
|
||||
// index 7 is limited to 16 characters
|
||||
// could get full length name at index 10, but would be different from join messages
|
||||
strcpy(pszName, vWords[7].c_str());
|
||||
strlcpy(pszName, vWords[7].c_str(), sizeof(pszName));
|
||||
printf("IRC got who\n");
|
||||
}
|
||||
|
||||
if (vWords[1] == "JOIN" && vWords[0].size() > 1)
|
||||
{
|
||||
// :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, '!'))
|
||||
*strchr(pszName, '!') = '\0';
|
||||
printf("IRC got join\n");
|
||||
|
|
5
irc.h
5
irc.h
|
@ -1,11 +1,6 @@
|
|||
// 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.
|
||||
|
||||
#ifndef __WXMSW__
|
||||
#define closesocket(s) close(s)
|
||||
typedef u_int SOCKET;
|
||||
#endif
|
||||
|
||||
extern bool RecvLine(SOCKET hSocket, string& strLine);
|
||||
extern void ThreadIRCSeed(void* parg);
|
||||
|
|
50
main.cpp
50
main.cpp
|
@ -42,7 +42,6 @@ map<uint160, vector<unsigned char> > mapPubKeys;
|
|||
CCriticalSection cs_mapKeys;
|
||||
CKey keyUser;
|
||||
|
||||
string strSetDataDir;
|
||||
int nDropMessagesTest = 0;
|
||||
|
||||
// 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)
|
||||
{
|
||||
wxLongLong nFreeBytesAvailable = 0;
|
||||
if (!wxGetDiskSpace(wxStandardPaths::Get().GetDataDir(), NULL, &nFreeBytesAvailable))
|
||||
if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable))
|
||||
{
|
||||
printf("ERROR: wxGetDiskSpace() failed\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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;
|
||||
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)
|
||||
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)
|
||||
return NULL;
|
||||
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"))
|
||||
{
|
||||
// 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
|
||||
PrintException(&e, "ProcessMessage()");
|
||||
|
@ -2512,7 +2476,7 @@ bool BitcoinMiner()
|
|||
|
||||
int64 GetBalance()
|
||||
{
|
||||
int64 nStart = PerformanceCounter();
|
||||
int64 nStart = GetTimeMillis();
|
||||
|
||||
int64 nTotal = 0;
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
|
@ -2522,11 +2486,11 @@ int64 GetBalance()
|
|||
CWalletTx* pcoin = &(*it).second;
|
||||
if (!pcoin->IsFinal() || pcoin->fSpent)
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
20
main.h
20
main.h
|
@ -34,7 +34,6 @@ extern int nBestHeight;
|
|||
extern uint256 hashBestChain;
|
||||
extern CBlockIndex* pindexBest;
|
||||
extern unsigned int nTransactionsUpdated;
|
||||
extern string strSetDataDir;
|
||||
extern int nDropMessagesTest;
|
||||
|
||||
// Settings
|
||||
|
@ -50,7 +49,6 @@ extern int nLimitProcessors;
|
|||
|
||||
|
||||
|
||||
string GetAppDir();
|
||||
bool CheckDiskSpace(int64 nAdditionalBytes=0);
|
||||
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
|
||||
FILE* AppendBlockFile(unsigned int& nFileRet);
|
||||
|
@ -405,10 +403,10 @@ public:
|
|||
{
|
||||
// Time based nLockTime implemented in 0.1.6,
|
||||
// do not use time based until most 0.1.5 nodes have upgraded.
|
||||
if (nBlockTime == 0)
|
||||
nBlockTime = GetAdjustedTime();
|
||||
if (nLockTime == 0)
|
||||
return true;
|
||||
if (nBlockTime == 0)
|
||||
nBlockTime = GetAdjustedTime();
|
||||
if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime))
|
||||
return true;
|
||||
foreach(const CTxIn& txin, vin)
|
||||
|
@ -627,6 +625,8 @@ public:
|
|||
|
||||
// memory only
|
||||
mutable bool fMerkleVerified;
|
||||
mutable bool fGetCreditCached;
|
||||
mutable int64 nGetCreditCached;
|
||||
|
||||
|
||||
CMerkleTx()
|
||||
|
@ -644,14 +644,22 @@ public:
|
|||
hashBlock = 0;
|
||||
nIndex = -1;
|
||||
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
|
||||
if (IsCoinBase() && GetBlocksToMaturity() > 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
|
||||
|
|
34
net.cpp
34
net.cpp
|
@ -21,8 +21,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect);
|
|||
bool fClient = false;
|
||||
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
|
||||
CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
|
||||
CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
|
||||
CNode* pnodeLocalHost = &nodeLocalHost;
|
||||
CNode* pnodeLocalHost = NULL;
|
||||
uint64 nLocalHostNonce = 0;
|
||||
bool fShutdown = false;
|
||||
array<int, 10> vnThreadsRunning;
|
||||
|
@ -129,7 +128,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha
|
|||
strLine = wxString(strLine).Trim();
|
||||
CAddress addr(strLine.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;
|
||||
ipRet = addr.ip;
|
||||
return true;
|
||||
|
@ -740,10 +739,29 @@ void ThreadOpenConnections2(void* parg)
|
|||
printf("ThreadOpenConnections started\n");
|
||||
|
||||
// Connect to one specified address
|
||||
while (mapArgs.count("/connect"))
|
||||
while (mapArgs.count("-connect"))
|
||||
{
|
||||
OpenNetworkConnection(CAddress(mapArgs["/connect"].c_str()));
|
||||
Sleep(10000);
|
||||
OpenNetworkConnection(CAddress(mapArgs["-connect"]));
|
||||
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
|
||||
|
@ -967,6 +985,8 @@ void ThreadMessageHandler2(void* parg)
|
|||
|
||||
bool StartNode(string& strError)
|
||||
{
|
||||
if (pnodeLocalHost == NULL)
|
||||
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
|
||||
strError = "";
|
||||
|
||||
// Sockets startup
|
||||
|
@ -1031,7 +1051,7 @@ bool StartNode(string& strError)
|
|||
printf("%s\n", strError.c_str());
|
||||
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
|
||||
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
|
||||
|
|
78
net.h
78
net.h
|
@ -1,12 +1,6 @@
|
|||
// 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.
|
||||
|
||||
#ifndef __WXMSW__
|
||||
#define closesocket(s) close(s)
|
||||
#define INVALID_SOCKET (SOCKET)(~0)
|
||||
typedef u_int SOCKET;
|
||||
#endif
|
||||
|
||||
class CMessageHeader;
|
||||
class CAddress;
|
||||
|
@ -148,61 +142,73 @@ public:
|
|||
|
||||
CAddress()
|
||||
{
|
||||
nServices = 0;
|
||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
||||
ip = 0;
|
||||
port = DEFAULT_PORT;
|
||||
nTime = GetAdjustedTime();
|
||||
nLastFailed = 0;
|
||||
Init();
|
||||
}
|
||||
|
||||
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;
|
||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
||||
Init();
|
||||
ip = ipIn;
|
||||
port = portIn;
|
||||
nTime = GetAdjustedTime();
|
||||
nLastFailed = 0;
|
||||
nServices = nServicesIn;
|
||||
}
|
||||
|
||||
explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0)
|
||||
explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK)
|
||||
{
|
||||
nServices = nServicesIn;
|
||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
||||
Init();
|
||||
ip = sockaddr.sin_addr.s_addr;
|
||||
port = sockaddr.sin_port;
|
||||
nTime = GetAdjustedTime();
|
||||
nLastFailed = 0;
|
||||
nServices = nServicesIn;
|
||||
}
|
||||
|
||||
explicit CAddress(const char* pszIn, uint64 nServicesIn=0)
|
||||
explicit CAddress(const char* pszIn, uint64 nServicesIn=NODE_NETWORK)
|
||||
{
|
||||
Init();
|
||||
SetAddress(pszIn);
|
||||
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));
|
||||
ip = INADDR_NONE;
|
||||
port = DEFAULT_PORT;
|
||||
nTime = GetAdjustedTime();
|
||||
nLastFailed = 0;
|
||||
}
|
||||
|
||||
bool SetAddress(const char* pszIn)
|
||||
{
|
||||
ip = INADDR_NONE;
|
||||
port = DEFAULT_PORT;
|
||||
char psz[100];
|
||||
if (strlen(pszIn) > ARRAYLEN(psz)-1)
|
||||
return;
|
||||
strcpy(psz, pszIn);
|
||||
strlcpy(psz, pszIn, sizeof(psz));
|
||||
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)
|
||||
return;
|
||||
return false;
|
||||
char* pszPort = strchr(psz, ':');
|
||||
if (pszPort)
|
||||
{
|
||||
*pszPort++ = '\0';
|
||||
port = htons(atoi(pszPort));
|
||||
if (atoi(pszPort) > USHRT_MAX)
|
||||
if (atoi(pszPort) < 0 || atoi(pszPort) > USHRT_MAX)
|
||||
port = htons(USHRT_MAX);
|
||||
if (atoi(pszPort) < 0)
|
||||
port = htons(0);
|
||||
}
|
||||
ip = inet_addr(psz);
|
||||
return IsValid();
|
||||
}
|
||||
|
||||
bool SetAddress(string strIn)
|
||||
{
|
||||
return SetAddress(strIn.c_str());
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
|
@ -274,7 +280,17 @@ public:
|
|||
|
||||
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
|
||||
|
|
455
ui.cpp
455
ui.cpp
|
@ -25,7 +25,6 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED)
|
|||
CMainFrame* pframeMain = NULL;
|
||||
CMyTaskBarIcon* ptaskbaricon = NULL;
|
||||
map<string, string> mapAddressBook;
|
||||
map<string, string> mapArgs;
|
||||
bool fRandSendTest = false;
|
||||
void RandSend();
|
||||
extern int g_isPainting;
|
||||
|
@ -283,7 +282,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
|
|||
fRefreshListCtrl = false;
|
||||
fRefreshListCtrlRunning = false;
|
||||
fOnSetFocusAddress = false;
|
||||
pindexBestLast = NULL;
|
||||
m_choiceFilter->SetSelection(0);
|
||||
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
|
||||
m_listCtrl->SetFocus();
|
||||
|
@ -507,6 +505,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
|||
string strStatus = FormatTxStatus(wtx);
|
||||
map<string, string> mapValue = wtx.mapValue;
|
||||
wtx.nLinesDisplayed = 1;
|
||||
nListViewUpdated++;
|
||||
|
||||
// Filter
|
||||
if (wtx.IsCoinBase())
|
||||
|
@ -712,48 +711,6 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
|||
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()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (fOneThread)
|
||||
return;
|
||||
fOneThread = true;
|
||||
Sleep(1000);
|
||||
printf("DelayedRepaint()\n");
|
||||
MainFrameRepaint();
|
||||
fOneThread = false;
|
||||
while (!fShutdown)
|
||||
{
|
||||
if (nLastRepaint != nNeedRepaint && GetTimeMillis() - nLastRepaintTime >= nRepaintInterval)
|
||||
{
|
||||
nLastRepaint = nNeedRepaint;
|
||||
if (pframeMain)
|
||||
{
|
||||
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)
|
||||
|
@ -854,43 +894,54 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
|||
if (ptaskbaricon)
|
||||
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)
|
||||
{
|
||||
bool fInserted = false;
|
||||
foreach(uint256 hash, vWalletUpdated)
|
||||
fPaintedBalance = 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)
|
||||
{
|
||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
|
||||
if (mi != mapWallet.end())
|
||||
fInserted |= InsertTransaction((*mi).second, false);
|
||||
CWalletTx& wtx = (*it).second;
|
||||
nTransactionCount += wtx.nLinesDisplayed;
|
||||
}
|
||||
vWalletUpdated.clear();
|
||||
if (fInserted)
|
||||
m_listCtrl->ScrollList(0, INT_MAX);
|
||||
}
|
||||
}
|
||||
if (!vWalletUpdated.empty() || !fPaintedBalance)
|
||||
nNeedRepaint++;
|
||||
|
||||
// Update status column of visible items only
|
||||
RefreshStatus();
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
RefreshStatusColumn();
|
||||
|
||||
// Update status bar
|
||||
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);
|
||||
m_statusBar->SetStatusText(strStatus, 2);
|
||||
|
||||
// mapWallet was locked, try again later
|
||||
if (!vWalletUpdated.empty() || !fRefreshed)
|
||||
_beginthread(DelayedRepaint, 0, NULL);
|
||||
|
||||
m_listCtrl->OnPaint(event);
|
||||
}
|
||||
|
||||
|
||||
void CrossThreadCall(wxCommandEvent& event)
|
||||
{
|
||||
if (pframeMain)
|
||||
|
@ -994,13 +1042,6 @@ void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event)
|
|||
|
||||
void CMainFrame::OnButtonSend(wxCommandEvent& event)
|
||||
{
|
||||
/// debug test
|
||||
if (fRandSendTest)
|
||||
{
|
||||
RandSend();
|
||||
return;
|
||||
}
|
||||
|
||||
// Toolbar: Send
|
||||
CSendDialog dialog(this);
|
||||
dialog.ShowModal();
|
||||
|
@ -1684,8 +1725,8 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event)
|
|||
else
|
||||
{
|
||||
// Parse IP address
|
||||
CAddress addr(strAddress.c_str());
|
||||
if (addr.ip == 0)
|
||||
CAddress addr(strAddress);
|
||||
if (!addr.IsValid())
|
||||
{
|
||||
wxMessageBox("Invalid address ", "Send Coins");
|
||||
return;
|
||||
|
@ -1818,14 +1859,6 @@ void CSendingDialog::OnPaint(wxPaintEvent& event)
|
|||
wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this);
|
||||
}
|
||||
event.Skip();
|
||||
|
||||
/// debug test
|
||||
if (fRandSendTest && fWorkDone && fSuccess)
|
||||
{
|
||||
Close();
|
||||
Sleep(1000);
|
||||
RandSend();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -3305,27 +3338,6 @@ bool CMyApp::OnInit()
|
|||
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()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
|
@ -3337,10 +3349,27 @@ bool CMyApp::OnInit2()
|
|||
// Disable malfunctioning wxWidgets debug assertion
|
||||
g_isPainting = 10000;
|
||||
#endif
|
||||
wxImage::AddHandler(new wxPNGHandler);
|
||||
SetAppName("Bitcoin");
|
||||
|
||||
//// debug print
|
||||
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());
|
||||
ParseParameters(argc, argv);
|
||||
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
||||
{
|
||||
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
|
||||
|
@ -3382,31 +3411,31 @@ bool CMyApp::OnInit2()
|
|||
//
|
||||
// Parameters
|
||||
//
|
||||
wxImage::AddHandler(new wxPNGHandler);
|
||||
mapArgs = ParseParameters(argc, argv);
|
||||
if (mapArgs.count("-datadir"))
|
||||
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
|
||||
|
||||
if (mapArgs.count("/datadir"))
|
||||
strSetDataDir = mapArgs["/datadir"];
|
||||
|
||||
if (mapArgs.count("/debug"))
|
||||
if (mapArgs.count("-debug"))
|
||||
fDebug = true;
|
||||
|
||||
if (mapArgs.count("/printtodebugger"))
|
||||
if (mapArgs.count("-printtodebugger"))
|
||||
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)
|
||||
nDropMessagesTest = 20;
|
||||
}
|
||||
|
||||
if (mapArgs.count("/loadblockindextest"))
|
||||
if (mapArgs.count("-loadblockindextest"))
|
||||
{
|
||||
CTxDB txdb("r");
|
||||
txdb.LoadBlockIndex();
|
||||
PrintBlockTree();
|
||||
ExitProcess(0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3417,22 +3446,22 @@ bool CMyApp::OnInit2()
|
|||
int64 nStart;
|
||||
|
||||
printf("Loading addresses...\n");
|
||||
nStart = PerformanceCounter();
|
||||
nStart = GetTimeMillis();
|
||||
if (!LoadAddresses())
|
||||
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");
|
||||
nStart = PerformanceCounter();
|
||||
nStart = GetTimeMillis();
|
||||
if (!LoadBlockIndex())
|
||||
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");
|
||||
nStart = PerformanceCounter();
|
||||
nStart = GetTimeMillis();
|
||||
if (!LoadWallet(fFirstRun))
|
||||
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");
|
||||
|
||||
|
@ -3457,45 +3486,59 @@ bool CMyApp::OnInit2()
|
|||
//
|
||||
// Parameters
|
||||
//
|
||||
if (mapArgs.count("/printblockindex") || mapArgs.count("/printblocktree"))
|
||||
if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree"))
|
||||
{
|
||||
PrintBlockTree();
|
||||
OnExit();
|
||||
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;
|
||||
addrProxy = CAddress(mapArgs["/proxy"].c_str());
|
||||
if (addrProxy.ip == INADDR_NONE)
|
||||
addrProxy = CAddress(mapArgs["-proxy"]);
|
||||
if (!addrProxy.IsValid())
|
||||
{
|
||||
wxMessageBox("Invalid /proxy address", "Bitcoin");
|
||||
wxMessageBox("Invalid -proxy address", "Bitcoin");
|
||||
OnExit();
|
||||
return false;
|
||||
}
|
||||
CWalletDB walletdb;
|
||||
walletdb.WriteSetting("fUseProxy", fUseProxy);
|
||||
walletdb.WriteSetting("addrProxy", addrProxy);
|
||||
}
|
||||
|
||||
if (mapArgs.count("/gen"))
|
||||
if (mapArgs.count("-addnode"))
|
||||
{
|
||||
if (mapArgs["/gen"].empty())
|
||||
fGenerateBitcoins = true;
|
||||
else
|
||||
fGenerateBitcoins = atoi(mapArgs["/gen"].c_str());
|
||||
CAddrDB addrdb;
|
||||
foreach(string strAddr, mapMultiArgs["-addnode"])
|
||||
{
|
||||
CAddress addr(strAddr, NODE_NETWORK);
|
||||
if (addr.IsValid())
|
||||
AddAddress(addrdb, addr);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Create the main frame window
|
||||
//
|
||||
pframeMain = new CMainFrame(NULL);
|
||||
if (mapArgs.count("/min"))
|
||||
if (mapArgs.count("-min"))
|
||||
pframeMain->Iconize(true);
|
||||
pframeMain->Show(true); // have to show first to get taskbar button to hide
|
||||
pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized());
|
||||
ptaskbaricon->Show(fMinimizeToTray);
|
||||
|
||||
_beginthread(ThreadDelayedRepaint, 0, NULL);
|
||||
|
||||
if (!CheckDiskSpace())
|
||||
{
|
||||
OnExit();
|
||||
|
@ -3516,7 +3559,7 @@ bool CMyApp::OnInit2()
|
|||
//
|
||||
// Tests
|
||||
//
|
||||
if (argc >= 2 && stricmp(argv[1], "/send") == 0)
|
||||
if (argc >= 2 && stricmp(argv[1], "-send") == 0)
|
||||
{
|
||||
int64 nValue = 1;
|
||||
if (argc >= 3)
|
||||
|
@ -3525,7 +3568,7 @@ bool CMyApp::OnInit2()
|
|||
string strAddress;
|
||||
if (argc >= 4)
|
||||
strAddress = argv[3];
|
||||
CAddress addr(strAddress.c_str());
|
||||
CAddress addr(strAddress);
|
||||
|
||||
CWalletTx wtx;
|
||||
wtx.mapValue["to"] = strAddress;
|
||||
|
@ -3538,15 +3581,6 @@ bool CMyApp::OnInit2()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (mapArgs.count("/randsendtest"))
|
||||
{
|
||||
if (!mapArgs["/randsendtest"].empty())
|
||||
_beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"]));
|
||||
else
|
||||
fRandSendTest = true;
|
||||
fDebug = 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);
|
||||
|
@ -3666,7 +3687,7 @@ string StartupShortcutPath()
|
|||
|
||||
bool GetStartOnSystemStartup()
|
||||
{
|
||||
return FileExists(StartupShortcutPath().c_str());
|
||||
return wxFileExists(StartupShortcutPath());
|
||||
}
|
||||
|
||||
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 fRefreshListCtrlRunning;
|
||||
bool fOnSetFocusAddress;
|
||||
CBlockIndex* pindexBestLast;
|
||||
set<uint256> setUnmaturedDisplayed;
|
||||
unsigned int nListViewUpdated;
|
||||
|
||||
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);
|
||||
bool DeleteLine(uint256 hashKey);
|
||||
bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
|
||||
void RefreshListCtrl();
|
||||
void RefreshStatus();
|
||||
void RefreshStatusColumn();
|
||||
};
|
||||
|
||||
|
||||
|
|
82
util.cpp
82
util.cpp
|
@ -5,9 +5,13 @@
|
|||
#include "headers.h"
|
||||
|
||||
|
||||
map<string, string> mapArgs;
|
||||
map<string, vector<string> > mapMultiArgs;
|
||||
bool fDebug = false;
|
||||
bool fPrintToDebugger = false;
|
||||
bool fPrintToConsole = false;
|
||||
char pszSetDataDir[MAX_PATH] = "";
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -68,6 +72,8 @@ void RandAddSeed()
|
|||
|
||||
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
|
||||
static int64 nLastPerfmon;
|
||||
if (GetTime() < nLastPerfmon + 10 * 60)
|
||||
|
@ -95,6 +101,7 @@ void RandAddSeedPerfmon()
|
|||
strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime);
|
||||
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 nSavePos = ftell(file);
|
||||
|
@ -365,6 +389,46 @@ int GetFilesize(FILE* file)
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
39
util.h
39
util.h
|
@ -54,16 +54,23 @@ inline T& REF(const 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 fPrintToDebugger;
|
||||
extern bool fPrintToConsole;
|
||||
extern map<string, string> mapArgs;
|
||||
extern char pszSetDataDir[MAX_PATH];
|
||||
|
||||
void RandAddSeed();
|
||||
void RandAddSeedPerfmon();
|
||||
|
@ -77,8 +84,10 @@ string FormatMoney(int64 n, bool fPlus=false);
|
|||
bool ParseMoney(const char* pszIn, int64& nRet);
|
||||
vector<unsigned char> ParseHex(const char* psz);
|
||||
vector<unsigned char> ParseHex(const std::string& str);
|
||||
bool FileExists(const char* psz);
|
||||
void ParseParameters(int argc, char* argv[]);
|
||||
int GetFilesize(FILE* file);
|
||||
void GetDataDir(char* pszDirRet);
|
||||
string GetDataDir();
|
||||
uint64 GetRand(uint64 nMax);
|
||||
int64 GetTime();
|
||||
int64 GetAdjustedTime();
|
||||
|
@ -172,9 +181,14 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
|||
if (!fPrintToConsole)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
//// Debug print useful for profiling
|
||||
//fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue());
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, pszFormat);
|
||||
ret = vfprintf(fileout, pszFormat, arg_ptr);
|
||||
|
@ -321,22 +335,25 @@ inline void PrintHex(vector<unsigned char> vch, const char* pszFormat="%s", bool
|
|||
{
|
||||
printf(pszFormat, HexStr(vch, fSpaces).c_str());
|
||||
}
|
||||
|
||||
|
||||
inline int64 PerformanceCounter()
|
||||
{
|
||||
int64 nCounter = 0;
|
||||
int64 nCounter = 0;
|
||||
#ifdef __WXMSW__
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
|
||||
#else
|
||||
// this could be changed to reading /dev/urandom
|
||||
timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
nCounter += t.tv_sec * 1000000 + t.tv_usec;
|
||||
timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
nCounter = t.tv_sec * 1000000 + t.tv_usec;
|
||||
#endif
|
||||
return nCounter;
|
||||
}
|
||||
|
||||
inline int64 GetTimeMillis()
|
||||
{
|
||||
return wxGetLocalTimeMillis().GetValue();
|
||||
}
|
||||
|
||||
#ifndef __WXMSW__
|
||||
inline void Sleep(unsigned int nMilliseconds)
|
||||
{
|
||||
|
@ -354,8 +371,10 @@ inline void Sleep(unsigned int nMilliseconds)
|
|||
|
||||
inline void heapchk()
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
if (_heapchk() != _HEAPOK)
|
||||
DebugBreak();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Randomize the stack to help protect against buffer overrun exploits
|
||||
|
|
Loading…
Reference in a new issue