bugfix Db::open/close and zombie sockets bugs fix double-close of socket handle,
keep databases open, close db cursors, initial block download in batches of 500 blocks, fix misc warnings, subver linux-test8
This commit is contained in:
parent
01fe1d2137
commit
e4db374421
@ -13,18 +13,18 @@ UNIX BUILD NOTES
|
|||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
------------
|
------------
|
||||||
Install the dev files for the shared libraries:
|
|
||||||
apt-get install build-essential
|
apt-get install build-essential
|
||||||
apt-get install libgtk2.0-dev
|
apt-get install libgtk2.0-dev
|
||||||
apt-get install libssl-dev
|
apt-get install libssl-dev
|
||||||
|
apt-get install libdb4.7-dev
|
||||||
|
apt-get install libdb4.7++-dev
|
||||||
|
apt-get install libboost-dev
|
||||||
|
|
||||||
Libraries you need to obtain separately and build:
|
Libraries you need to obtain separately and build:
|
||||||
default path download
|
default path download
|
||||||
wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/
|
wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/
|
||||||
Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html
|
|
||||||
Boost \boost http://www.boost.org/users/download/
|
|
||||||
|
|
||||||
Their licenses:
|
Licenses:
|
||||||
wxWidgets LGPL 2.1 with very liberal exceptions
|
wxWidgets LGPL 2.1 with very liberal exceptions
|
||||||
Berkeley DB New BSD license with additional requirement that linked software must be free open source
|
Berkeley DB New BSD license with additional requirement that linked software must be free open source
|
||||||
Boost MIT-like license
|
Boost MIT-like license
|
||||||
@ -59,15 +59,9 @@ make install
|
|||||||
ldconfig
|
ldconfig
|
||||||
|
|
||||||
|
|
||||||
Berkeley DB
|
|
||||||
-----------
|
|
||||||
cd /usr/local/db-4.7.25.NC/build_unix
|
|
||||||
../dist/configure --enable-cxx
|
|
||||||
make
|
|
||||||
|
|
||||||
|
|
||||||
Boost
|
Boost
|
||||||
-----
|
-----
|
||||||
|
If you download and build Boost yourself
|
||||||
cd /usr/local/boost_1_40_0
|
cd /usr/local/boost_1_40_0
|
||||||
su
|
su
|
||||||
./bootstrap.sh
|
./bootstrap.sh
|
||||||
|
136
db.cpp
136
db.cpp
@ -20,6 +20,7 @@ static CCriticalSection cs_db;
|
|||||||
static bool fDbEnvInit = false;
|
static bool fDbEnvInit = false;
|
||||||
DbEnv dbenv(0);
|
DbEnv dbenv(0);
|
||||||
static map<string, int> mapFileUseCount;
|
static map<string, int> mapFileUseCount;
|
||||||
|
static map<string, Db*> mapDb;
|
||||||
|
|
||||||
class CDBInit
|
class CDBInit
|
||||||
{
|
{
|
||||||
@ -39,21 +40,17 @@ public:
|
|||||||
instance_of_cdbinit;
|
instance_of_cdbinit;
|
||||||
|
|
||||||
|
|
||||||
CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
|
CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
if (pszFile == NULL)
|
if (pszFile == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
|
||||||
bool fCreate = strchr(pszMode, 'c');
|
bool fCreate = strchr(pszMode, 'c');
|
||||||
bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
|
|
||||||
unsigned int nFlags = DB_THREAD;
|
unsigned int nFlags = DB_THREAD;
|
||||||
if (fCreate)
|
if (fCreate)
|
||||||
nFlags |= DB_CREATE;
|
nFlags |= DB_CREATE;
|
||||||
else if (fReadOnly)
|
|
||||||
nFlags |= DB_RDONLY;
|
|
||||||
if (!fReadOnly || fTxn)
|
|
||||||
nFlags |= DB_AUTO_COMMIT;
|
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_db)
|
CRITICAL_BLOCK(cs_db)
|
||||||
{
|
{
|
||||||
@ -72,7 +69,7 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
|
|||||||
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(strErrorFile.c_str(), "a")); /// debug
|
dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug
|
||||||
///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption
|
dbenv.set_flags(DB_AUTO_COMMIT, 1);
|
||||||
ret = dbenv.open(strDataDir.c_str(),
|
ret = dbenv.open(strDataDir.c_str(),
|
||||||
DB_CREATE |
|
DB_CREATE |
|
||||||
DB_INIT_LOCK |
|
DB_INIT_LOCK |
|
||||||
@ -90,31 +87,39 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
|
|||||||
|
|
||||||
strFile = pszFile;
|
strFile = pszFile;
|
||||||
++mapFileUseCount[strFile];
|
++mapFileUseCount[strFile];
|
||||||
|
pdb = mapDb[strFile];
|
||||||
|
if (pdb == NULL)
|
||||||
|
{
|
||||||
|
pdb = new Db(&dbenv, 0);
|
||||||
|
|
||||||
|
ret = pdb->open(NULL, // Txn pointer
|
||||||
|
pszFile, // Filename
|
||||||
|
"main", // Logical db name
|
||||||
|
DB_BTREE, // Database type
|
||||||
|
nFlags, // Flags
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
delete pdb;
|
||||||
|
pdb = NULL;
|
||||||
|
CRITICAL_BLOCK(cs_db)
|
||||||
|
--mapFileUseCount[strFile];
|
||||||
|
strFile = "";
|
||||||
|
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fCreate && !Exists(string("version")))
|
||||||
|
{
|
||||||
|
bool fTmp = fReadOnly;
|
||||||
|
fReadOnly = false;
|
||||||
|
WriteVersion(VERSION);
|
||||||
|
fReadOnly = fTmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapDb[strFile] = pdb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pdb = new Db(&dbenv, 0);
|
|
||||||
|
|
||||||
ret = pdb->open(NULL, // Txn pointer
|
|
||||||
pszFile, // Filename
|
|
||||||
"main", // Logical db name
|
|
||||||
DB_BTREE, // Database type
|
|
||||||
nFlags, // Flags
|
|
||||||
0);
|
|
||||||
|
|
||||||
if (ret > 0)
|
|
||||||
{
|
|
||||||
delete pdb;
|
|
||||||
pdb = NULL;
|
|
||||||
CRITICAL_BLOCK(cs_db)
|
|
||||||
--mapFileUseCount[strFile];
|
|
||||||
strFile = "";
|
|
||||||
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fCreate && !Exists(string("version")))
|
|
||||||
WriteVersion(VERSION);
|
|
||||||
|
|
||||||
RandAddSeed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDB::Close()
|
void CDB::Close()
|
||||||
@ -124,8 +129,6 @@ void CDB::Close()
|
|||||||
if (!vTxn.empty())
|
if (!vTxn.empty())
|
||||||
vTxn.front()->abort();
|
vTxn.front()->abort();
|
||||||
vTxn.clear();
|
vTxn.clear();
|
||||||
pdb->close(0);
|
|
||||||
delete pdb;
|
|
||||||
pdb = NULL;
|
pdb = NULL;
|
||||||
dbenv.txn_checkpoint(0, 0, 0);
|
dbenv.txn_checkpoint(0, 0, 0);
|
||||||
|
|
||||||
@ -135,6 +138,21 @@ void CDB::Close()
|
|||||||
RandAddSeed();
|
RandAddSeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CloseDb(const string& strFile)
|
||||||
|
{
|
||||||
|
CRITICAL_BLOCK(cs_db)
|
||||||
|
{
|
||||||
|
if (mapDb[strFile] != NULL)
|
||||||
|
{
|
||||||
|
// Close the database handle
|
||||||
|
Db* pdb = mapDb[strFile];
|
||||||
|
pdb->close(0);
|
||||||
|
delete pdb;
|
||||||
|
mapDb[strFile] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DBFlush(bool fShutdown)
|
void DBFlush(bool fShutdown)
|
||||||
{
|
{
|
||||||
// Flush log data to the actual data file
|
// Flush log data to the actual data file
|
||||||
@ -144,14 +162,18 @@ void DBFlush(bool fShutdown)
|
|||||||
return;
|
return;
|
||||||
CRITICAL_BLOCK(cs_db)
|
CRITICAL_BLOCK(cs_db)
|
||||||
{
|
{
|
||||||
dbenv.txn_checkpoint(0, 0, 0);
|
|
||||||
map<string, int>::iterator mi = mapFileUseCount.begin();
|
map<string, int>::iterator mi = mapFileUseCount.begin();
|
||||||
while (mi != mapFileUseCount.end())
|
while (mi != mapFileUseCount.end())
|
||||||
{
|
{
|
||||||
string strFile = (*mi).first;
|
string strFile = (*mi).first;
|
||||||
int nRefCount = (*mi).second;
|
int nRefCount = (*mi).second;
|
||||||
|
printf("%s refcount=%d\n", strFile.c_str(), nRefCount);
|
||||||
if (nRefCount == 0)
|
if (nRefCount == 0)
|
||||||
{
|
{
|
||||||
|
// Move log data to the dat file
|
||||||
|
CloseDb(strFile);
|
||||||
|
dbenv.txn_checkpoint(0, 0, 0);
|
||||||
|
printf("%s flush\n", strFile.c_str());
|
||||||
dbenv.lsn_reset(strFile.c_str(), 0);
|
dbenv.lsn_reset(strFile.c_str(), 0);
|
||||||
mapFileUseCount.erase(mi++);
|
mapFileUseCount.erase(mi++);
|
||||||
}
|
}
|
||||||
@ -238,7 +260,10 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>&
|
|||||||
if (ret == DB_NOTFOUND)
|
if (ret == DB_NOTFOUND)
|
||||||
break;
|
break;
|
||||||
else if (ret != 0)
|
else if (ret != 0)
|
||||||
|
{
|
||||||
|
pcursor->close();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Unserialize
|
// Unserialize
|
||||||
string strType;
|
string strType;
|
||||||
@ -255,9 +280,14 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>&
|
|||||||
{
|
{
|
||||||
vtx.resize(vtx.size()+1);
|
vtx.resize(vtx.size()+1);
|
||||||
if (!vtx.back().ReadFromDisk(pos))
|
if (!vtx.back().ReadFromDisk(pos))
|
||||||
|
{
|
||||||
|
pcursor->close();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcursor->close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,6 +409,7 @@ bool CTxDB::LoadBlockIndex()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pcursor->close();
|
||||||
|
|
||||||
if (!ReadHashBestChain(hashBestChain))
|
if (!ReadHashBestChain(hashBestChain))
|
||||||
{
|
{
|
||||||
@ -391,7 +422,7 @@ bool CTxDB::LoadBlockIndex()
|
|||||||
return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found");
|
return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found");
|
||||||
pindexBest = mapBlockIndex[hashBestChain];
|
pindexBest = mapBlockIndex[hashBestChain];
|
||||||
nBestHeight = pindexBest->nHeight;
|
nBestHeight = pindexBest->nHeight;
|
||||||
printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
|
printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -456,6 +487,7 @@ bool CAddrDB::LoadAddresses()
|
|||||||
mapAddresses.insert(make_pair(addr.GetKey(), addr));
|
mapAddresses.insert(make_pair(addr.GetKey(), addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pcursor->close();
|
||||||
|
|
||||||
printf("Loaded %d addresses\n", mapAddresses.size());
|
printf("Loaded %d addresses\n", mapAddresses.size());
|
||||||
|
|
||||||
@ -558,7 +590,7 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
|
|||||||
//printf(" %12I64d %s %s %s\n",
|
//printf(" %12I64d %s %s %s\n",
|
||||||
// wtx.vout[0].nValue,
|
// wtx.vout[0].nValue,
|
||||||
// DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(),
|
// DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(),
|
||||||
// wtx.hashBlock.ToString().substr(0,14).c_str(),
|
// wtx.hashBlock.ToString().substr(0,16).c_str(),
|
||||||
// wtx.mapValue["message"].c_str());
|
// wtx.mapValue["message"].c_str());
|
||||||
}
|
}
|
||||||
else if (strType == "key")
|
else if (strType == "key")
|
||||||
@ -596,6 +628,7 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pcursor->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("fShowGenerated = %d\n", fShowGenerated);
|
printf("fShowGenerated = %d\n", fShowGenerated);
|
||||||
@ -655,6 +688,8 @@ void ThreadFlushWalletDB(void* parg)
|
|||||||
if (fOneThread)
|
if (fOneThread)
|
||||||
return;
|
return;
|
||||||
fOneThread = true;
|
fOneThread = true;
|
||||||
|
if (mapArgs.count("-noflushwallet"))
|
||||||
|
return;
|
||||||
|
|
||||||
unsigned int nLastSeen = nWalletDBUpdated;
|
unsigned int nLastSeen = nWalletDBUpdated;
|
||||||
unsigned int nLastFlushed = nWalletDBUpdated;
|
unsigned int nLastFlushed = nWalletDBUpdated;
|
||||||
@ -669,24 +704,37 @@ void ThreadFlushWalletDB(void* parg)
|
|||||||
nLastWalletUpdate = GetTime();
|
nLastWalletUpdate = GetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nLastFlushed != nWalletDBUpdated && nLastWalletUpdate < GetTime() - 1)
|
if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2)
|
||||||
{
|
{
|
||||||
TRY_CRITICAL_BLOCK(cs_db)
|
TRY_CRITICAL_BLOCK(cs_db)
|
||||||
{
|
{
|
||||||
string strFile = "wallet.dat";
|
// Don't do this if any databases are in use
|
||||||
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
|
int nRefCount = 0;
|
||||||
if (mi != mapFileUseCount.end())
|
map<string, int>::iterator mi = mapFileUseCount.begin();
|
||||||
|
while (mi != mapFileUseCount.end())
|
||||||
{
|
{
|
||||||
int nRefCount = (*mi).second;
|
nRefCount += (*mi).second;
|
||||||
if (nRefCount == 0 && !fShutdown)
|
mi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nRefCount == 0 && !fShutdown)
|
||||||
|
{
|
||||||
|
string strFile = "wallet.dat";
|
||||||
|
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
|
||||||
|
if (mi != mapFileUseCount.end())
|
||||||
{
|
{
|
||||||
// Flush wallet.dat so it's self contained
|
printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
|
||||||
|
printf("Flushing wallet.dat\n");
|
||||||
nLastFlushed = nWalletDBUpdated;
|
nLastFlushed = nWalletDBUpdated;
|
||||||
int64 nStart = GetTimeMillis();
|
int64 nStart = GetTimeMillis();
|
||||||
|
|
||||||
|
// Flush wallet.dat so it's self contained
|
||||||
|
CloseDb(strFile);
|
||||||
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 %"PRI64d"ms\n", GetTimeMillis() - nStart);
|
|
||||||
mapFileUseCount.erase(mi++);
|
mapFileUseCount.erase(mi++);
|
||||||
|
printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
db.h
17
db.h
@ -32,8 +32,9 @@ protected:
|
|||||||
Db* pdb;
|
Db* pdb;
|
||||||
string strFile;
|
string strFile;
|
||||||
vector<DbTxn*> vTxn;
|
vector<DbTxn*> vTxn;
|
||||||
|
bool fReadOnly;
|
||||||
|
|
||||||
explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false);
|
explicit CDB(const char* pszFile, const char* pszMode="r+");
|
||||||
~CDB() { Close(); }
|
~CDB() { Close(); }
|
||||||
public:
|
public:
|
||||||
void Close();
|
void Close();
|
||||||
@ -77,6 +78,8 @@ protected:
|
|||||||
{
|
{
|
||||||
if (!pdb)
|
if (!pdb)
|
||||||
return false;
|
return false;
|
||||||
|
if (fReadOnly)
|
||||||
|
assert(("Write called on database in read-only mode", false));
|
||||||
|
|
||||||
// Key
|
// Key
|
||||||
CDataStream ssKey(SER_DISK);
|
CDataStream ssKey(SER_DISK);
|
||||||
@ -104,6 +107,8 @@ protected:
|
|||||||
{
|
{
|
||||||
if (!pdb)
|
if (!pdb)
|
||||||
return false;
|
return false;
|
||||||
|
if (fReadOnly)
|
||||||
|
assert(("Erase called on database in read-only mode", false));
|
||||||
|
|
||||||
// Key
|
// Key
|
||||||
CDataStream ssKey(SER_DISK);
|
CDataStream ssKey(SER_DISK);
|
||||||
@ -254,7 +259,7 @@ public:
|
|||||||
class CTxDB : public CDB
|
class CTxDB : public CDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { }
|
CTxDB(const char* pszMode="r+") : CDB(!fClient ? "blkindex.dat" : NULL, pszMode) { }
|
||||||
private:
|
private:
|
||||||
CTxDB(const CTxDB&);
|
CTxDB(const CTxDB&);
|
||||||
void operator=(const CTxDB&);
|
void operator=(const CTxDB&);
|
||||||
@ -283,7 +288,7 @@ public:
|
|||||||
class CReviewDB : public CDB
|
class CReviewDB : public CDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { }
|
CReviewDB(const char* pszMode="r+") : CDB("reviews.dat", pszMode) { }
|
||||||
private:
|
private:
|
||||||
CReviewDB(const CReviewDB&);
|
CReviewDB(const CReviewDB&);
|
||||||
void operator=(const CReviewDB&);
|
void operator=(const CReviewDB&);
|
||||||
@ -309,7 +314,7 @@ public:
|
|||||||
class CMarketDB : public CDB
|
class CMarketDB : public CDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { }
|
CMarketDB(const char* pszMode="r+") : CDB("market.dat", pszMode) { }
|
||||||
private:
|
private:
|
||||||
CMarketDB(const CMarketDB&);
|
CMarketDB(const CMarketDB&);
|
||||||
void operator=(const CMarketDB&);
|
void operator=(const CMarketDB&);
|
||||||
@ -322,7 +327,7 @@ private:
|
|||||||
class CAddrDB : public CDB
|
class CAddrDB : public CDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { }
|
CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
|
||||||
private:
|
private:
|
||||||
CAddrDB(const CAddrDB&);
|
CAddrDB(const CAddrDB&);
|
||||||
void operator=(const CAddrDB&);
|
void operator=(const CAddrDB&);
|
||||||
@ -341,7 +346,7 @@ bool LoadAddresses();
|
|||||||
class CWalletDB : public CDB
|
class CWalletDB : public CDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { }
|
CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode) { }
|
||||||
private:
|
private:
|
||||||
CWalletDB(const CWalletDB&);
|
CWalletDB(const CWalletDB&);
|
||||||
void operator=(const CWalletDB&);
|
void operator=(const CWalletDB&);
|
||||||
|
14
irc.cpp
14
irc.cpp
@ -159,15 +159,12 @@ void ThreadIRCSeed(void* parg)
|
|||||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||||
int nErrorWait = 10;
|
int nErrorWait = 10;
|
||||||
int nRetryWait = 10;
|
int nRetryWait = 10;
|
||||||
|
bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
|
||||||
// IRC server blocks TOR users
|
|
||||||
if (fUseProxy && addrProxy.port == htons(9050))
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (!fShutdown)
|
while (!fShutdown)
|
||||||
{
|
{
|
||||||
CAddress addrConnect("216.155.130.130:6667");
|
CAddress addrConnect("216.155.130.130:6667");
|
||||||
if (!(fUseProxy && addrProxy.port == htons(9050)))
|
if (!fTOR)
|
||||||
{
|
{
|
||||||
struct hostent* phostent = gethostbyname("chat.freenode.net");
|
struct hostent* phostent = gethostbyname("chat.freenode.net");
|
||||||
if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
|
if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
|
||||||
@ -188,6 +185,7 @@ void ThreadIRCSeed(void* parg)
|
|||||||
if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname"))
|
if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname"))
|
||||||
{
|
{
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
|
hSocket = INVALID_SOCKET;
|
||||||
nErrorWait = nErrorWait * 11 / 10;
|
nErrorWait = nErrorWait * 11 / 10;
|
||||||
if (Wait(nErrorWait += 60))
|
if (Wait(nErrorWait += 60))
|
||||||
continue;
|
continue;
|
||||||
@ -208,6 +206,7 @@ void ThreadIRCSeed(void* parg)
|
|||||||
if (!RecvUntil(hSocket, " 004 "))
|
if (!RecvUntil(hSocket, " 004 "))
|
||||||
{
|
{
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
|
hSocket = INVALID_SOCKET;
|
||||||
nErrorWait = nErrorWait * 11 / 10;
|
nErrorWait = nErrorWait * 11 / 10;
|
||||||
if (Wait(nErrorWait += 60))
|
if (Wait(nErrorWait += 60))
|
||||||
continue;
|
continue;
|
||||||
@ -269,6 +268,11 @@ void ThreadIRCSeed(void* parg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
|
hSocket = INVALID_SOCKET;
|
||||||
|
|
||||||
|
// IRC usually blocks TOR, so only try once
|
||||||
|
if (fTOR)
|
||||||
|
return;
|
||||||
|
|
||||||
if (GetTime() - nStart > 20 * 60)
|
if (GetTime() - nStart > 20 * 60)
|
||||||
{
|
{
|
||||||
|
87
main.cpp
87
main.cpp
@ -760,7 +760,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
|
|||||||
bnNew = bnProofOfWorkLimit;
|
bnNew = bnProofOfWorkLimit;
|
||||||
|
|
||||||
/// debug print
|
/// debug print
|
||||||
printf("\n\n\nGetNextWorkRequired RETARGET *****\n");
|
printf("GetNextWorkRequired RETARGET\n");
|
||||||
printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
|
printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
|
||||||
printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
|
printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
|
||||||
printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
|
printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
|
||||||
@ -1013,7 +1013,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
|
|||||||
|
|
||||||
bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
|
bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
|
||||||
{
|
{
|
||||||
printf("*** REORGANIZE ***\n");
|
printf("REORGANIZE\n");
|
||||||
|
|
||||||
// Find the fork
|
// Find the fork
|
||||||
CBlockIndex* pfork = pindexBest;
|
CBlockIndex* pfork = pindexBest;
|
||||||
@ -1114,7 +1114,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
|
|||||||
// Check for duplicate
|
// Check for duplicate
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
if (mapBlockIndex.count(hash))
|
if (mapBlockIndex.count(hash))
|
||||||
return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,14).c_str());
|
return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,16).c_str());
|
||||||
|
|
||||||
// Construct new block index object
|
// Construct new block index object
|
||||||
CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
|
CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
|
||||||
@ -1174,7 +1174,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
|
|||||||
pindexBest = pindexNew;
|
pindexBest = pindexNew;
|
||||||
nBestHeight = pindexBest->nHeight;
|
nBestHeight = pindexBest->nHeight;
|
||||||
nTransactionsUpdated++;
|
nTransactionsUpdated++;
|
||||||
printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
|
printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
txdb.TxnCommit();
|
txdb.TxnCommit();
|
||||||
@ -1294,9 +1294,9 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
|
|||||||
// Check for duplicate
|
// Check for duplicate
|
||||||
uint256 hash = pblock->GetHash();
|
uint256 hash = pblock->GetHash();
|
||||||
if (mapBlockIndex.count(hash))
|
if (mapBlockIndex.count(hash))
|
||||||
return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,14).c_str());
|
return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,16).c_str());
|
||||||
if (mapOrphanBlocks.count(hash))
|
if (mapOrphanBlocks.count(hash))
|
||||||
return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,14).c_str());
|
return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,16).c_str());
|
||||||
|
|
||||||
// Preliminary checks
|
// Preliminary checks
|
||||||
if (!pblock->CheckBlock())
|
if (!pblock->CheckBlock())
|
||||||
@ -1308,7 +1308,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
|
|||||||
// If don't already have its previous block, shunt it off to holding area until we get it
|
// If don't already have its previous block, shunt it off to holding area until we get it
|
||||||
if (!mapBlockIndex.count(pblock->hashPrevBlock))
|
if (!mapBlockIndex.count(pblock->hashPrevBlock))
|
||||||
{
|
{
|
||||||
printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,14).c_str());
|
printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,16).c_str());
|
||||||
mapOrphanBlocks.insert(make_pair(hash, pblock));
|
mapOrphanBlocks.insert(make_pair(hash, pblock));
|
||||||
mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock));
|
mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock));
|
||||||
|
|
||||||
@ -1503,11 +1503,11 @@ bool LoadBlockIndex(bool fAllowNew)
|
|||||||
// vMerkleTree: 4a5e1e
|
// vMerkleTree: 4a5e1e
|
||||||
|
|
||||||
// Genesis block
|
// Genesis block
|
||||||
char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
|
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
|
||||||
CTransaction txNew;
|
CTransaction txNew;
|
||||||
txNew.vin.resize(1);
|
txNew.vin.resize(1);
|
||||||
txNew.vout.resize(1);
|
txNew.vout.resize(1);
|
||||||
txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp));
|
txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
|
||||||
txNew.vout[0].nValue = 50 * COIN;
|
txNew.vout[0].nValue = 50 * COIN;
|
||||||
txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG;
|
txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG;
|
||||||
CBlock block;
|
CBlock block;
|
||||||
@ -1519,7 +1519,7 @@ bool LoadBlockIndex(bool fAllowNew)
|
|||||||
block.nBits = 0x1d00ffff;
|
block.nBits = 0x1d00ffff;
|
||||||
block.nNonce = 2083236893;
|
block.nNonce = 2083236893;
|
||||||
|
|
||||||
//// debug print, delete this later
|
//// debug print
|
||||||
printf("%s\n", block.GetHash().ToString().c_str());
|
printf("%s\n", block.GetHash().ToString().c_str());
|
||||||
printf("%s\n", block.hashMerkleRoot.ToString().c_str());
|
printf("%s\n", block.hashMerkleRoot.ToString().c_str());
|
||||||
printf("%s\n", hashGenesisBlock.ToString().c_str());
|
printf("%s\n", hashGenesisBlock.ToString().c_str());
|
||||||
@ -1592,7 +1592,7 @@ void PrintBlockTree()
|
|||||||
pindex->nHeight,
|
pindex->nHeight,
|
||||||
pindex->nFile,
|
pindex->nFile,
|
||||||
pindex->nBlockPos,
|
pindex->nBlockPos,
|
||||||
block.GetHash().ToString().substr(0,14).c_str(),
|
block.GetHash().ToString().substr(0,16).c_str(),
|
||||||
DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(),
|
DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(),
|
||||||
block.vtx.size());
|
block.vtx.size());
|
||||||
|
|
||||||
@ -1912,6 +1912,18 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
CBlock block;
|
CBlock block;
|
||||||
block.ReadFromDisk((*mi).second, !pfrom->fClient);
|
block.ReadFromDisk((*mi).second, !pfrom->fClient);
|
||||||
pfrom->PushMessage("block", block);
|
pfrom->PushMessage("block", block);
|
||||||
|
|
||||||
|
// Trigger them to send a getblocks request for the next batch of inventory
|
||||||
|
if (inv.hash == pfrom->hashContinue)
|
||||||
|
{
|
||||||
|
// Bypass PushInventory, this must send even if redundant,
|
||||||
|
// and we want it right after the last block so they don't
|
||||||
|
// wait for other stuff first.
|
||||||
|
vector<CInv> vInv;
|
||||||
|
vInv.push_back(CInv(MSG_BLOCK, hashBestChain));
|
||||||
|
pfrom->PushMessage("inv", vInv);
|
||||||
|
pfrom->hashContinue = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (inv.IsKnownType())
|
else if (inv.IsKnownType())
|
||||||
@ -1948,25 +1960,23 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
// Send the rest of the chain
|
// Send the rest of the chain
|
||||||
if (pindex)
|
if (pindex)
|
||||||
pindex = pindex->pnext;
|
pindex = pindex->pnext;
|
||||||
printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,14).c_str());
|
printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str());
|
||||||
|
int nLimit = 500;
|
||||||
for (; pindex; pindex = pindex->pnext)
|
for (; pindex; pindex = pindex->pnext)
|
||||||
{
|
{
|
||||||
if (pindex->GetBlockHash() == hashStop)
|
if (pindex->GetBlockHash() == hashStop)
|
||||||
{
|
{
|
||||||
printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str());
|
printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
|
||||||
// Bypass setInventoryKnown in case an inventory message got lost
|
if (--nLimit <= 0)
|
||||||
CRITICAL_BLOCK(pfrom->cs_inventory)
|
|
||||||
{
|
{
|
||||||
CInv inv(MSG_BLOCK, pindex->GetBlockHash());
|
// When this block is requested, we'll send an inv that'll make them
|
||||||
// returns true if wasn't already contained in the set
|
// getblocks the next batch of inventory.
|
||||||
if (pfrom->setInventoryKnown2.insert(inv).second)
|
printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str());
|
||||||
{
|
pfrom->hashContinue = pindex->GetBlockHash();
|
||||||
pfrom->setInventoryKnown.erase(inv);
|
break;
|
||||||
pfrom->vInventoryToSend.push_back(inv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2049,7 +2059,13 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
vRecv >> *pblock;
|
vRecv >> *pblock;
|
||||||
|
|
||||||
//// debug print
|
//// debug print
|
||||||
printf("received block:\n"); pblock->print();
|
if (false)
|
||||||
|
{
|
||||||
|
printf("received block:\n");
|
||||||
|
pblock->print();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str());
|
||||||
|
|
||||||
CInv inv(MSG_BLOCK, pblock->GetHash());
|
CInv inv(MSG_BLOCK, pblock->GetHash());
|
||||||
pfrom->AddInventoryKnown(inv);
|
pfrom->AddInventoryKnown(inv);
|
||||||
@ -2175,9 +2191,13 @@ bool SendMessages(CNode* pto)
|
|||||||
if (pto->nVersion == 0)
|
if (pto->nVersion == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Keep-alive ping
|
||||||
|
if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty())
|
||||||
|
pto->PushMessage("ping");
|
||||||
|
|
||||||
// Address refresh broadcast
|
// Address refresh broadcast
|
||||||
static int64 nLastRebroadcast;
|
static int64 nLastRebroadcast;
|
||||||
if (nLastRebroadcast < GetTime() - 24 * 60 * 60) // every 24 hours
|
if (GetTime() - nLastRebroadcast > 24 * 60 * 60) // every 24 hours
|
||||||
{
|
{
|
||||||
nLastRebroadcast = GetTime();
|
nLastRebroadcast = GetTime();
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
CRITICAL_BLOCK(cs_vNodes)
|
||||||
@ -2194,9 +2214,16 @@ bool SendMessages(CNode* pto)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep-alive ping
|
// Clear inventory known periodically in case an inv message was missed,
|
||||||
if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty())
|
// although usually they would just get it from another node.
|
||||||
pto->PushMessage("ping");
|
static int64 nLastInventoryKnownClear;
|
||||||
|
if (GetTime() - nLastInventoryKnownClear > 2 * 60 * 60) // every 2 hours
|
||||||
|
{
|
||||||
|
nLastInventoryKnownClear = GetTime();
|
||||||
|
CRITICAL_BLOCK(cs_vNodes)
|
||||||
|
foreach(CNode* pnode, vNodes)
|
||||||
|
pnode->setInventoryKnown.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -2243,7 +2270,6 @@ bool SendMessages(CNode* pto)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pto->vInventoryToSend.clear();
|
pto->vInventoryToSend.clear();
|
||||||
pto->setInventoryKnown2.clear();
|
|
||||||
}
|
}
|
||||||
if (!vInventoryToSend.empty())
|
if (!vInventoryToSend.empty())
|
||||||
pto->PushMessage("inv", vInventoryToSend);
|
pto->PushMessage("inv", vInventoryToSend);
|
||||||
@ -2817,8 +2843,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key)
|
|||||||
|
|
||||||
// This is only to keep the database open to defeat the auto-flush for the
|
// This is only to keep the database open to defeat the auto-flush for the
|
||||||
// duration of this scope. This is the only place where this optimization
|
// duration of this scope. This is the only place where this optimization
|
||||||
// maybe makes sense; please don't do it anywhere else. Keeping databases
|
// maybe makes sense; please don't do it anywhere else.
|
||||||
// open longer than necessary can create deadlocks.
|
|
||||||
CWalletDB walletdb("r");
|
CWalletDB walletdb("r");
|
||||||
|
|
||||||
// Add the change's private key to wallet
|
// Add the change's private key to wallet
|
||||||
|
10
main.h
10
main.h
@ -1009,9 +1009,9 @@ public:
|
|||||||
void print() const
|
void print() const
|
||||||
{
|
{
|
||||||
printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
|
printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
|
||||||
GetHash().ToString().substr(0,14).c_str(),
|
GetHash().ToString().substr(0,16).c_str(),
|
||||||
nVersion,
|
nVersion,
|
||||||
hashPrevBlock.ToString().substr(0,14).c_str(),
|
hashPrevBlock.ToString().substr(0,16).c_str(),
|
||||||
hashMerkleRoot.ToString().substr(0,6).c_str(),
|
hashMerkleRoot.ToString().substr(0,6).c_str(),
|
||||||
nTime, nBits, nNonce,
|
nTime, nBits, nNonce,
|
||||||
vtx.size());
|
vtx.size());
|
||||||
@ -1159,7 +1159,7 @@ public:
|
|||||||
return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
|
return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
|
||||||
pprev, pnext, nFile, nBlockPos, nHeight,
|
pprev, pnext, nFile, nBlockPos, nHeight,
|
||||||
hashMerkleRoot.ToString().substr(0,6).c_str(),
|
hashMerkleRoot.ToString().substr(0,6).c_str(),
|
||||||
GetBlockHash().ToString().substr(0,14).c_str());
|
GetBlockHash().ToString().substr(0,16).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void print() const
|
void print() const
|
||||||
@ -1229,8 +1229,8 @@ public:
|
|||||||
str += CBlockIndex::ToString();
|
str += CBlockIndex::ToString();
|
||||||
str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
|
str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
|
||||||
GetBlockHash().ToString().c_str(),
|
GetBlockHash().ToString().c_str(),
|
||||||
hashPrev.ToString().substr(0,14).c_str(),
|
hashPrev.ToString().substr(0,16).c_str(),
|
||||||
hashNext.ToString().substr(0,14).c_str());
|
hashNext.ToString().substr(0,16).c_str());
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,24 +17,21 @@ endif
|
|||||||
|
|
||||||
INCLUDEPATHS= \
|
INCLUDEPATHS= \
|
||||||
-I"/usr/include" \
|
-I"/usr/include" \
|
||||||
-I"/usr/local/boost_1_40_0" \
|
|
||||||
-I"/usr/local/db-4.7.25.NC/build_unix" \
|
|
||||||
-I"/usr/local/include/wx-2.8" \
|
-I"/usr/local/include/wx-2.8" \
|
||||||
-I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8"
|
-I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8"
|
||||||
|
|
||||||
LIBPATHS= \
|
LIBPATHS= \
|
||||||
-L"/usr/lib" \
|
-L"/usr/lib" \
|
||||||
-L"/usr/local/lib" \
|
-L"/usr/local/lib" \
|
||||||
-L"/usr/local/db-4.7.25.NC/build_unix"
|
|
||||||
|
|
||||||
LIBS= \
|
LIBS= \
|
||||||
-Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \
|
-Wl,-Bstatic -l boost_system -l boost_filesystem -Wl,-Bdynamic \
|
||||||
-Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \
|
-Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \
|
||||||
-l crypto \
|
-l crypto \
|
||||||
-l gtk-x11-2.0 -l gthread-2.0 -l SM
|
-l gtk-x11-2.0 -l gthread-2.0 -l SM
|
||||||
|
|
||||||
WXDEFS=-D__WXGTK__ -DNOPCH
|
WXDEFS=-D__WXGTK__ -DNOPCH
|
||||||
CFLAGS=-O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||||
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
|
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
|
||||||
|
|
||||||
|
|
||||||
|
110
net.cpp
110
net.cpp
@ -148,8 +148,8 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha
|
|||||||
bool GetMyExternalIP(unsigned int& ipRet)
|
bool GetMyExternalIP(unsigned int& ipRet)
|
||||||
{
|
{
|
||||||
CAddress addrConnect;
|
CAddress addrConnect;
|
||||||
char* pszGet;
|
const char* pszGet;
|
||||||
char* pszKeyword;
|
const char* pszKeyword;
|
||||||
|
|
||||||
if (fUseProxy)
|
if (fUseProxy)
|
||||||
return false;
|
return false;
|
||||||
@ -463,14 +463,21 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNode::DoDisconnect()
|
void CNode::CloseSocketDisconnect()
|
||||||
{
|
{
|
||||||
if (fDebug)
|
fDisconnect = true;
|
||||||
printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
|
if (hSocket != INVALID_SOCKET)
|
||||||
printf("disconnecting node %s\n", addr.ToStringLog().c_str());
|
{
|
||||||
|
if (fDebug)
|
||||||
closesocket(hSocket);
|
printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
|
||||||
|
printf("disconnecting node %s\n", addr.ToStringLog().c_str());
|
||||||
|
closesocket(hSocket);
|
||||||
|
hSocket = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNode::Cleanup()
|
||||||
|
{
|
||||||
// All of a nodes broadcasts and subscriptions are automatically torn down
|
// All of a nodes broadcasts and subscriptions are automatically torn down
|
||||||
// when it goes down, so a node has to stay up to keep its broadcast going.
|
// when it goes down, so a node has to stay up to keep its broadcast going.
|
||||||
|
|
||||||
@ -540,11 +547,12 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
// remove from vNodes
|
// remove from vNodes
|
||||||
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
|
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
|
||||||
|
|
||||||
// close socket
|
// close socket and cleanup
|
||||||
pnode->DoDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
|
pnode->Cleanup();
|
||||||
|
|
||||||
// hold in disconnected pool until all refs are released
|
// hold in disconnected pool until all refs are released
|
||||||
pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60);
|
pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
|
||||||
if (pnode->fNetworkNode || pnode->fInbound)
|
if (pnode->fNetworkNode || pnode->fInbound)
|
||||||
pnode->Release();
|
pnode->Release();
|
||||||
vNodesDisconnected.push_back(pnode);
|
vNodesDisconnected.push_back(pnode);
|
||||||
@ -599,6 +607,8 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
{
|
{
|
||||||
foreach(CNode* pnode, vNodes)
|
foreach(CNode* pnode, vNodes)
|
||||||
{
|
{
|
||||||
|
if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
|
||||||
|
continue;
|
||||||
FD_SET(pnode->hSocket, &fdsetRecv);
|
FD_SET(pnode->hSocket, &fdsetRecv);
|
||||||
FD_SET(pnode->hSocket, &fdsetError);
|
FD_SET(pnode->hSocket, &fdsetError);
|
||||||
hSocketMax = max(hSocketMax, pnode->hSocket);
|
hSocketMax = max(hSocketMax, pnode->hSocket);
|
||||||
@ -659,17 +669,22 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
//
|
//
|
||||||
vector<CNode*> vNodesCopy;
|
vector<CNode*> vNodesCopy;
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
CRITICAL_BLOCK(cs_vNodes)
|
||||||
|
{
|
||||||
vNodesCopy = vNodes;
|
vNodesCopy = vNodes;
|
||||||
|
foreach(CNode* pnode, vNodesCopy)
|
||||||
|
pnode->AddRef();
|
||||||
|
}
|
||||||
foreach(CNode* pnode, vNodesCopy)
|
foreach(CNode* pnode, vNodesCopy)
|
||||||
{
|
{
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return;
|
return;
|
||||||
SOCKET hSocket = pnode->hSocket;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Receive
|
// Receive
|
||||||
//
|
//
|
||||||
if (FD_ISSET(hSocket, &fdsetRecv) || FD_ISSET(hSocket, &fdsetError))
|
if (pnode->hSocket == INVALID_SOCKET)
|
||||||
|
continue;
|
||||||
|
if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
|
||||||
{
|
{
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
||||||
{
|
{
|
||||||
@ -678,7 +693,7 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
|
|
||||||
// typical socket buffer is 8K-64K
|
// typical socket buffer is 8K-64K
|
||||||
char pchBuf[0x10000];
|
char pchBuf[0x10000];
|
||||||
int nBytes = recv(hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
|
int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
|
||||||
if (nBytes > 0)
|
if (nBytes > 0)
|
||||||
{
|
{
|
||||||
vRecv.resize(nPos + nBytes);
|
vRecv.resize(nPos + nBytes);
|
||||||
@ -690,7 +705,7 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
// socket closed gracefully
|
// socket closed gracefully
|
||||||
if (!pnode->fDisconnect)
|
if (!pnode->fDisconnect)
|
||||||
printf("socket closed\n");
|
printf("socket closed\n");
|
||||||
pnode->fDisconnect = true;
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
else if (nBytes < 0)
|
else if (nBytes < 0)
|
||||||
{
|
{
|
||||||
@ -700,7 +715,7 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
{
|
{
|
||||||
if (!pnode->fDisconnect)
|
if (!pnode->fDisconnect)
|
||||||
printf("socket recv error %d\n", nErr);
|
printf("socket recv error %d\n", nErr);
|
||||||
pnode->fDisconnect = true;
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -709,14 +724,16 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
//
|
//
|
||||||
// Send
|
// Send
|
||||||
//
|
//
|
||||||
if (FD_ISSET(hSocket, &fdsetSend))
|
if (pnode->hSocket == INVALID_SOCKET)
|
||||||
|
continue;
|
||||||
|
if (FD_ISSET(pnode->hSocket, &fdsetSend))
|
||||||
{
|
{
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
||||||
{
|
{
|
||||||
CDataStream& vSend = pnode->vSend;
|
CDataStream& vSend = pnode->vSend;
|
||||||
if (!vSend.empty())
|
if (!vSend.empty())
|
||||||
{
|
{
|
||||||
int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
|
int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
|
||||||
if (nBytes > 0)
|
if (nBytes > 0)
|
||||||
{
|
{
|
||||||
vSend.erase(vSend.begin(), vSend.begin() + nBytes);
|
vSend.erase(vSend.begin(), vSend.begin() + nBytes);
|
||||||
@ -729,7 +746,7 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
||||||
{
|
{
|
||||||
printf("socket send error %d\n", nErr);
|
printf("socket send error %d\n", nErr);
|
||||||
pnode->fDisconnect = true;
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -760,18 +777,12 @@ void ThreadSocketHandler2(void* parg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CRITICAL_BLOCK(cs_vNodes)
|
||||||
|
|
||||||
//// debug heartbeat
|
|
||||||
static int64 nHeartbeat1;
|
|
||||||
if (GetTime() - nHeartbeat1 >= 5 * 60)
|
|
||||||
{
|
{
|
||||||
printf("%s sendrecv\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
|
foreach(CNode* pnode, vNodesCopy)
|
||||||
nHeartbeat1 = GetTime();
|
pnode->Release();
|
||||||
fDebug = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nThreadSocketHandlerHeartbeat = GetTime();
|
nThreadSocketHandlerHeartbeat = GetTime();
|
||||||
Sleep(10);
|
Sleep(10);
|
||||||
}
|
}
|
||||||
@ -812,18 +823,21 @@ void ThreadOpenConnections2(void* parg)
|
|||||||
printf("ThreadOpenConnections started\n");
|
printf("ThreadOpenConnections started\n");
|
||||||
|
|
||||||
// Connect to specific addresses
|
// Connect to specific addresses
|
||||||
while (mapArgs.count("-connect"))
|
if (mapArgs.count("-connect"))
|
||||||
{
|
{
|
||||||
foreach(string strAddr, mapMultiArgs["-connect"])
|
for (int64 nLoop = 0;; nLoop++)
|
||||||
{
|
{
|
||||||
CAddress addr(strAddr, NODE_NETWORK);
|
foreach(string strAddr, mapMultiArgs["-connect"])
|
||||||
if (addr.IsValid())
|
|
||||||
OpenNetworkConnection(addr);
|
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
{
|
{
|
||||||
Sleep(1000);
|
CAddress addr(strAddr, NODE_NETWORK);
|
||||||
if (fShutdown)
|
if (addr.IsValid())
|
||||||
return;
|
OpenNetworkConnection(addr);
|
||||||
|
for (int i = 0; i < 10 && i < nLoop; i++)
|
||||||
|
{
|
||||||
|
Sleep(500);
|
||||||
|
if (fShutdown)
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -837,7 +851,7 @@ void ThreadOpenConnections2(void* parg)
|
|||||||
if (addr.IsValid())
|
if (addr.IsValid())
|
||||||
{
|
{
|
||||||
OpenNetworkConnection(addr);
|
OpenNetworkConnection(addr);
|
||||||
Sleep(1000);
|
Sleep(500);
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -898,7 +912,7 @@ void ThreadOpenConnections2(void* parg)
|
|||||||
// 30 days 27 hours
|
// 30 days 27 hours
|
||||||
// 90 days 46 hours
|
// 90 days 46 hours
|
||||||
// 365 days 93 hours
|
// 365 days 93 hours
|
||||||
int64 nDelay = 3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer;
|
int64 nDelay = (int64)(3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer);
|
||||||
|
|
||||||
// Fast reconnect for one hour after last seen
|
// Fast reconnect for one hour after last seen
|
||||||
if (nSinceLastSeen < 60 * 60)
|
if (nSinceLastSeen < 60 * 60)
|
||||||
@ -1013,11 +1027,13 @@ void ThreadMessageHandler2(void* parg)
|
|||||||
// Poll the connected nodes for messages
|
// Poll the connected nodes for messages
|
||||||
vector<CNode*> vNodesCopy;
|
vector<CNode*> vNodesCopy;
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
CRITICAL_BLOCK(cs_vNodes)
|
||||||
|
{
|
||||||
vNodesCopy = vNodes;
|
vNodesCopy = vNodes;
|
||||||
|
foreach(CNode* pnode, vNodesCopy)
|
||||||
|
pnode->AddRef();
|
||||||
|
}
|
||||||
foreach(CNode* pnode, vNodesCopy)
|
foreach(CNode* pnode, vNodesCopy)
|
||||||
{
|
{
|
||||||
pnode->AddRef();
|
|
||||||
|
|
||||||
// Receive messages
|
// Receive messages
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
||||||
ProcessMessages(pnode);
|
ProcessMessages(pnode);
|
||||||
@ -1029,8 +1045,11 @@ void ThreadMessageHandler2(void* parg)
|
|||||||
SendMessages(pnode);
|
SendMessages(pnode);
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
pnode->Release();
|
CRITICAL_BLOCK(cs_vNodes)
|
||||||
|
{
|
||||||
|
foreach(CNode* pnode, vNodesCopy)
|
||||||
|
pnode->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait and allow messages to bunch up
|
// Wait and allow messages to bunch up
|
||||||
@ -1257,8 +1276,7 @@ void StartNode(void* parg)
|
|||||||
if (!fGot)
|
if (!fGot)
|
||||||
{
|
{
|
||||||
printf("*** closing socket\n");
|
printf("*** closing socket\n");
|
||||||
closesocket(pnode->hSocket);
|
pnode->CloseSocketDisconnect();
|
||||||
pnode->fDisconnect = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1292,7 +1310,7 @@ bool StopNode()
|
|||||||
int64 nStart = GetTime();
|
int64 nStart = GetTime();
|
||||||
while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0)
|
while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0)
|
||||||
{
|
{
|
||||||
if (GetTime() - nStart > 15)
|
if (GetTime() - nStart > 20)
|
||||||
break;
|
break;
|
||||||
Sleep(20);
|
Sleep(20);
|
||||||
}
|
}
|
||||||
|
16
net.h
16
net.h
@ -414,7 +414,7 @@ public:
|
|||||||
|
|
||||||
string ToString() const
|
string ToString() const
|
||||||
{
|
{
|
||||||
return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str());
|
return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,16).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void print() const
|
void print() const
|
||||||
@ -504,6 +504,7 @@ public:
|
|||||||
int64 nReleaseTime;
|
int64 nReleaseTime;
|
||||||
map<uint256, CRequestTracker> mapRequests;
|
map<uint256, CRequestTracker> mapRequests;
|
||||||
CCriticalSection cs_mapRequests;
|
CCriticalSection cs_mapRequests;
|
||||||
|
uint256 hashContinue;
|
||||||
|
|
||||||
// flood
|
// flood
|
||||||
vector<CAddress> vAddrToSend;
|
vector<CAddress> vAddrToSend;
|
||||||
@ -512,7 +513,6 @@ public:
|
|||||||
|
|
||||||
// inventory based relay
|
// inventory based relay
|
||||||
set<CInv> setInventoryKnown;
|
set<CInv> setInventoryKnown;
|
||||||
set<CInv> setInventoryKnown2;
|
|
||||||
vector<CInv> vInventoryToSend;
|
vector<CInv> vInventoryToSend;
|
||||||
CCriticalSection cs_inventory;
|
CCriticalSection cs_inventory;
|
||||||
multimap<int64, CInv> mapAskFor;
|
multimap<int64, CInv> mapAskFor;
|
||||||
@ -541,6 +541,7 @@ public:
|
|||||||
fDisconnect = false;
|
fDisconnect = false;
|
||||||
nRefCount = 0;
|
nRefCount = 0;
|
||||||
nReleaseTime = 0;
|
nReleaseTime = 0;
|
||||||
|
hashContinue = 0;
|
||||||
fGetAddr = false;
|
fGetAddr = false;
|
||||||
vfSubscribe.assign(256, false);
|
vfSubscribe.assign(256, false);
|
||||||
|
|
||||||
@ -550,13 +551,16 @@ public:
|
|||||||
CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
|
CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
|
||||||
CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
|
CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
|
||||||
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
|
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
|
||||||
PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string("test5"));
|
PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string(pszSubVer));
|
||||||
}
|
}
|
||||||
|
|
||||||
~CNode()
|
~CNode()
|
||||||
{
|
{
|
||||||
if (hSocket != INVALID_SOCKET)
|
if (hSocket != INVALID_SOCKET)
|
||||||
|
{
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
|
hSocket = INVALID_SOCKET;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -570,12 +574,13 @@ public:
|
|||||||
return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
|
return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddRef(int64 nTimeout=0)
|
CNode* AddRef(int64 nTimeout=0)
|
||||||
{
|
{
|
||||||
if (nTimeout != 0)
|
if (nTimeout != 0)
|
||||||
nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);
|
nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);
|
||||||
else
|
else
|
||||||
nRefCount++;
|
nRefCount++;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Release()
|
void Release()
|
||||||
@ -899,7 +904,8 @@ public:
|
|||||||
bool IsSubscribed(unsigned int nChannel);
|
bool IsSubscribed(unsigned int nChannel);
|
||||||
void Subscribe(unsigned int nChannel, unsigned int nHops=0);
|
void Subscribe(unsigned int nChannel, unsigned int nHops=0);
|
||||||
void CancelSubscribe(unsigned int nChannel);
|
void CancelSubscribe(unsigned int nChannel);
|
||||||
void DoDisconnect();
|
void CloseSocketDisconnect();
|
||||||
|
void Cleanup();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ class CDataStream;
|
|||||||
class CAutoFile;
|
class CAutoFile;
|
||||||
|
|
||||||
static const int VERSION = 106;
|
static const int VERSION = 106;
|
||||||
|
static const char* pszSubVer = " linux-test8";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
27
ui.cpp
27
ui.cpp
@ -1664,7 +1664,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
|
|||||||
|
|
||||||
CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
|
CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
|
||||||
{
|
{
|
||||||
m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Beta", VERSION/100, VERSION%100));
|
m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d beta", VERSION/100, VERSION%100));
|
||||||
|
|
||||||
// Workaround until upgrade to wxWidgets supporting UTF-8
|
// Workaround until upgrade to wxWidgets supporting UTF-8
|
||||||
wxString str = m_staticTextMain->GetLabel();
|
wxString str = m_staticTextMain->GetLabel();
|
||||||
@ -2030,7 +2030,7 @@ void CSendingDialog::StartTransfer()
|
|||||||
// We may have connected already for product details
|
// We may have connected already for product details
|
||||||
if (!Status("Connecting..."))
|
if (!Status("Connecting..."))
|
||||||
return;
|
return;
|
||||||
CNode* pnode = ConnectNode(addr, 5 * 60);
|
CNode* pnode = ConnectNode(addr, 15 * 60);
|
||||||
if (!pnode)
|
if (!pnode)
|
||||||
{
|
{
|
||||||
Error("Unable to connect");
|
Error("Unable to connect");
|
||||||
@ -2075,14 +2075,6 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should already be connected
|
|
||||||
CNode* pnode = ConnectNode(addr, 5 * 60);
|
|
||||||
if (!pnode)
|
|
||||||
{
|
|
||||||
Error("Lost connection");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pause to give the user a chance to cancel
|
// Pause to give the user a chance to cancel
|
||||||
while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000))
|
while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000))
|
||||||
{
|
{
|
||||||
@ -2112,6 +2104,14 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we're still connected
|
||||||
|
CNode* pnode = ConnectNode(addr, 2 * 60 * 60);
|
||||||
|
if (!pnode)
|
||||||
|
{
|
||||||
|
Error("Lost connection, transaction cancelled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Last chance to cancel
|
// Last chance to cancel
|
||||||
Sleep(50);
|
Sleep(50);
|
||||||
if (!Status())
|
if (!Status())
|
||||||
@ -3495,12 +3495,14 @@ bool CMyApp::OnInit2()
|
|||||||
|
|
||||||
if (mapArgs.count("-debug"))
|
if (mapArgs.count("-debug"))
|
||||||
fDebug = true;
|
fDebug = true;
|
||||||
|
if (strstr(pszSubVer, "test"))
|
||||||
|
fDebug = true;
|
||||||
|
|
||||||
if (mapArgs.count("-printtodebugger"))
|
if (mapArgs.count("-printtodebugger"))
|
||||||
fPrintToDebugger = true;
|
fPrintToDebugger = true;
|
||||||
|
|
||||||
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
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, OS version %s\n", VERSION, wxGetOsDescription().mb_str());
|
printf("Bitcoin version %d%s, OS version %s\n", VERSION, pszSubVer, wxGetOsDescription().mb_str());
|
||||||
|
|
||||||
if (mapArgs.count("-loadblockindextest"))
|
if (mapArgs.count("-loadblockindextest"))
|
||||||
{
|
{
|
||||||
@ -3843,9 +3845,8 @@ void SetStartOnSystemStartup(bool fAutoStart)
|
|||||||
CoInitialize(NULL);
|
CoInitialize(NULL);
|
||||||
|
|
||||||
// Get a pointer to the IShellLink interface.
|
// Get a pointer to the IShellLink interface.
|
||||||
HRESULT hres = NULL;
|
|
||||||
IShellLink* psl = NULL;
|
IShellLink* psl = NULL;
|
||||||
hres = CoCreateInstance(CLSID_ShellLink, NULL,
|
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
|
||||||
CLSCTX_INPROC_SERVER, IID_IShellLink,
|
CLSCTX_INPROC_SERVER, IID_IShellLink,
|
||||||
reinterpret_cast<void**>(&psl));
|
reinterpret_cast<void**>(&psl));
|
||||||
|
|
||||||
|
10
util.cpp
10
util.cpp
@ -56,9 +56,11 @@ public:
|
|||||||
|
|
||||||
// Close sockets
|
// Close sockets
|
||||||
foreach(CNode* pnode, vNodes)
|
foreach(CNode* pnode, vNodes)
|
||||||
closesocket(pnode->hSocket);
|
if (pnode->hSocket != INVALID_SOCKET)
|
||||||
if (closesocket(hListenSocket) == SOCKET_ERROR)
|
closesocket(pnode->hSocket);
|
||||||
printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
|
if (hListenSocket != INVALID_SOCKET)
|
||||||
|
if (closesocket(hListenSocket) == SOCKET_ERROR)
|
||||||
|
printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
// Shutdown Windows Sockets
|
// Shutdown Windows Sockets
|
||||||
@ -348,7 +350,7 @@ void ParseParameters(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
char psz[10000];
|
char psz[10000];
|
||||||
strlcpy(psz, argv[i], sizeof(psz));
|
strlcpy(psz, argv[i], sizeof(psz));
|
||||||
char* pszValue = "";
|
char* pszValue = (char*)"";
|
||||||
if (strchr(psz, '='))
|
if (strchr(psz, '='))
|
||||||
{
|
{
|
||||||
pszValue = strchr(psz, '=');
|
pszValue = strchr(psz, '=');
|
||||||
|
23
util.h
23
util.h
@ -57,9 +57,11 @@ inline T& REF(const T& val)
|
|||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
#define MSG_NOSIGNAL 0
|
#define MSG_NOSIGNAL 0
|
||||||
#define MSG_DONTWAIT 0
|
#define MSG_DONTWAIT 0
|
||||||
|
#ifndef UINT64_MAX
|
||||||
#define UINT64_MAX _UI64_MAX
|
#define UINT64_MAX _UI64_MAX
|
||||||
#define INT64_MAX _I64_MAX
|
#define INT64_MAX _I64_MAX
|
||||||
#define INT64_MIN _I64_MIN
|
#define INT64_MIN _I64_MIN
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define WSAGetLastError() errno
|
#define WSAGetLastError() errno
|
||||||
#define WSAEWOULDBLOCK EWOULDBLOCK
|
#define WSAEWOULDBLOCK EWOULDBLOCK
|
||||||
@ -67,7 +69,7 @@ inline T& REF(const T& val)
|
|||||||
#define WSAEINTR EINTR
|
#define WSAEINTR EINTR
|
||||||
#define WSAEINPROGRESS EINPROGRESS
|
#define WSAEINPROGRESS EINPROGRESS
|
||||||
#define WSAEADDRINUSE EADDRINUSE
|
#define WSAEADDRINUSE EADDRINUSE
|
||||||
#define closesocket(s) close(s)
|
#define WSAENOTSOCK EBADF
|
||||||
#define INVALID_SOCKET (SOCKET)(~0)
|
#define INVALID_SOCKET (SOCKET)(~0)
|
||||||
#define SOCKET_ERROR -1
|
#define SOCKET_ERROR -1
|
||||||
typedef u_int SOCKET;
|
typedef u_int SOCKET;
|
||||||
@ -80,6 +82,23 @@ typedef u_int SOCKET;
|
|||||||
#define Beep(n1,n2) (0)
|
#define Beep(n1,n2) (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
inline int myclosesocket(SOCKET& hSocket)
|
||||||
|
{
|
||||||
|
if (hSocket == INVALID_SOCKET)
|
||||||
|
return WSAENOTSOCK;
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
int ret = closesocket(hSocket);
|
||||||
|
#else
|
||||||
|
int ret = close(hSocket);
|
||||||
|
#endif
|
||||||
|
hSocket = INVALID_SOCKET;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#define closesocket(s) myclosesocket(s)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -149,7 +168,7 @@ public:
|
|||||||
bool TryEnter() { return mutex.TryLock() == wxMUTEX_NO_ERROR; }
|
bool TryEnter() { return mutex.TryLock() == wxMUTEX_NO_ERROR; }
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
char* pszFile;
|
const char* pszFile;
|
||||||
int nLine;
|
int nLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * addressbook16_xpm[] = {
|
static const char * addressbook16_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"16 16 256 2",
|
"16 16 256 2",
|
||||||
" c #FFFFFF",
|
" c #FFFFFF",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * addressbook20_xpm[] = {
|
static const char * addressbook20_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"20 20 256 2",
|
"20 20 256 2",
|
||||||
" c #FFFFFF",
|
" c #FFFFFF",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * bitcoin16_xpm[] = {
|
static const char * bitcoin16_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"16 16 181 2",
|
"16 16 181 2",
|
||||||
" c #775605",
|
" c #775605",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * bitcoin20_xpm[] = {
|
static const char * bitcoin20_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"20 20 200 2",
|
"20 20 200 2",
|
||||||
" c #7B5500",
|
" c #7B5500",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * bitcoin32_xpm[] = {
|
static const char * bitcoin32_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"32 32 185 2",
|
"32 32 185 2",
|
||||||
" c #715103",
|
" c #715103",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * bitcoin48_xpm[] = {
|
static const char * bitcoin48_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"48 48 224 2",
|
"48 48 224 2",
|
||||||
" c #715103",
|
" c #715103",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * check_xpm[] = {
|
static const char * check_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"32 32 3 1",
|
"32 32 3 1",
|
||||||
" c #008000",
|
" c #008000",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * send16_xpm[] = {
|
static const char * send16_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"16 16 256 2",
|
"16 16 256 2",
|
||||||
" c #ADF7AD",
|
" c #ADF7AD",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * send16noshadow_xpm[] = {
|
static const char * send16noshadow_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"16 16 256 2",
|
"16 16 256 2",
|
||||||
" c #ADF7AD",
|
" c #ADF7AD",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * send20_xpm[] = {
|
static const char * send20_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
/* columns rows colors chars-per-pixel */
|
||||||
"20 20 256 2",
|
"20 20 256 2",
|
||||||
" c #CEFFCE",
|
" c #CEFFCE",
|
||||||
|
Loading…
Reference in New Issue
Block a user