mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-22 08:09:19 +01:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40fd689eb1 | ||
|
|
aaff04791d | ||
|
|
f0f1b3775e | ||
|
|
ca0816152d | ||
|
|
91b13a0dff | ||
|
|
8f9123a157 | ||
|
|
8ff1873096 | ||
|
|
5e27f737fa | ||
|
|
05ff9680ba | ||
|
|
dfdaee9310 |
@@ -1,6 +1,6 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
VERSION = 0.6.1
|
||||
VERSION = 0.6.2.2
|
||||
INCLUDEPATH += src src/json src/qt
|
||||
DEFINES += QT_GUI BOOST_THREAD_USE_LIB
|
||||
CONFIG += no_include_pwd
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Bitcoin 0.6.1 BETA
|
||||
Bitcoin 0.6.2 BETA
|
||||
|
||||
Copyright (c) 2009-2012 Bitcoin Developers
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Bitcoin 0.6.1 BETA
|
||||
Bitcoin 0.6.2 BETA
|
||||
|
||||
Copyright (c) 2009-2012 Bitcoin Developers
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
|
||||
@@ -5,7 +5,7 @@ SetCompressor /SOLID lzma
|
||||
|
||||
# General Symbol Definitions
|
||||
!define REGKEY "SOFTWARE\$(^Name)"
|
||||
!define VERSION 0.6.1
|
||||
!define VERSION 0.6.2
|
||||
!define COMPANY "Bitcoin project"
|
||||
!define URL http://www.bitcoin.org/
|
||||
|
||||
@@ -45,13 +45,13 @@ Var StartMenuGroup
|
||||
!insertmacro MUI_LANGUAGE English
|
||||
|
||||
# Installer attributes
|
||||
OutFile bitcoin-0.6.1-win32-setup.exe
|
||||
OutFile bitcoin-0.6.2-win32-setup.exe
|
||||
InstallDir $PROGRAMFILES\Bitcoin
|
||||
CRCCheck on
|
||||
XPStyle on
|
||||
BrandingText " "
|
||||
ShowInstDetails show
|
||||
VIProductVersion 0.6.1.3
|
||||
VIProductVersion 0.6.2.0
|
||||
VIAddVersionKey ProductName Bitcoin
|
||||
VIAddVersionKey ProductVersion "${VERSION}"
|
||||
VIAddVersionKey CompanyName "${COMPANY}"
|
||||
|
||||
@@ -107,9 +107,15 @@ void CAddrMan::SwapRandom(int nRndPos1, int nRndPos2)
|
||||
if (nRndPos1 == nRndPos2)
|
||||
return;
|
||||
|
||||
assert(nRndPos1 >= 0 && nRndPos2 >= 0);
|
||||
assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size());
|
||||
|
||||
int nId1 = vRandom[nRndPos1];
|
||||
int nId2 = vRandom[nRndPos2];
|
||||
|
||||
assert(mapInfo.count(nId1) == 1);
|
||||
assert(mapInfo.count(nId2) == 1);
|
||||
|
||||
mapInfo[nId1].nRandomPos = nRndPos2;
|
||||
mapInfo[nId2].nRandomPos = nRndPos1;
|
||||
|
||||
@@ -124,26 +130,32 @@ int CAddrMan::SelectTried(int nKBucket)
|
||||
// random shuffle the first few elements (using the entire list)
|
||||
// find the least recently tried among them
|
||||
int64 nOldest = -1;
|
||||
int nOldestPos = -1;
|
||||
for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++)
|
||||
{
|
||||
int nPos = GetRandInt(vTried.size() - i) + i;
|
||||
int nTemp = vTried[nPos];
|
||||
vTried[nPos] = vTried[i];
|
||||
vTried[i] = nTemp;
|
||||
if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess)
|
||||
assert(nOldest == -1 || mapInfo.count(nTemp) == 1);
|
||||
if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) {
|
||||
nOldest = nTemp;
|
||||
nOldestPos = nPos;
|
||||
}
|
||||
}
|
||||
|
||||
return nOldest;
|
||||
return nOldestPos;
|
||||
}
|
||||
|
||||
int CAddrMan::ShrinkNew(int nUBucket)
|
||||
{
|
||||
assert(nUBucket >= 0 && nUBucket < vvNew.size());
|
||||
std::set<int> &vNew = vvNew[nUBucket];
|
||||
|
||||
// first look for deletable items
|
||||
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++)
|
||||
{
|
||||
assert(mapInfo.count(*it));
|
||||
CAddrInfo &info = mapInfo[*it];
|
||||
if (info.IsTerrible())
|
||||
{
|
||||
@@ -168,11 +180,13 @@ int CAddrMan::ShrinkNew(int nUBucket)
|
||||
{
|
||||
if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3])
|
||||
{
|
||||
assert(nOldest == -1 || mapInfo.count(*it) == 1);
|
||||
if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime)
|
||||
nOldest = *it;
|
||||
}
|
||||
nI++;
|
||||
}
|
||||
assert(mapInfo.count(nOldest) == 1);
|
||||
CAddrInfo &info = mapInfo[nOldest];
|
||||
if (--info.nRefCount == 0)
|
||||
{
|
||||
@@ -189,6 +203,8 @@ int CAddrMan::ShrinkNew(int nUBucket)
|
||||
|
||||
void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
|
||||
{
|
||||
assert(vvNew[nOrigin].count(nId) == 1);
|
||||
|
||||
// remove the entry from all new buckets
|
||||
for (std::vector<std::set<int> >::iterator it = vvNew.begin(); it != vvNew.end(); it++)
|
||||
{
|
||||
@@ -197,6 +213,8 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
|
||||
}
|
||||
nNew--;
|
||||
|
||||
assert(info.nRefCount == 0);
|
||||
|
||||
// what tried bucket to move the entry to
|
||||
int nKBucket = info.GetTriedBucket(nKey);
|
||||
std::vector<int> &vTried = vvTried[nKBucket];
|
||||
@@ -214,6 +232,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
|
||||
int nPos = SelectTried(nKBucket);
|
||||
|
||||
// find which new bucket it belongs to
|
||||
assert(mapInfo.count(vTried[nPos]) == 1);
|
||||
int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey);
|
||||
std::set<int> &vNew = vvNew[nUBucket];
|
||||
|
||||
@@ -385,6 +404,7 @@ CAddress CAddrMan::Select_(int nUnkBias)
|
||||
std::vector<int> &vTried = vvTried[nKBucket];
|
||||
if (vTried.size() == 0) continue;
|
||||
int nPos = GetRandInt(vTried.size());
|
||||
assert(mapInfo.count(vTried[nPos]) == 1);
|
||||
CAddrInfo &info = mapInfo[vTried[nPos]];
|
||||
if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30))
|
||||
return info;
|
||||
@@ -402,6 +422,7 @@ CAddress CAddrMan::Select_(int nUnkBias)
|
||||
std::set<int>::iterator it = vNew.begin();
|
||||
while (nPos--)
|
||||
it++;
|
||||
assert(mapInfo.count(*it) == 1);
|
||||
CAddrInfo &info = mapInfo[*it];
|
||||
if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30))
|
||||
return info;
|
||||
@@ -481,6 +502,7 @@ void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr)
|
||||
{
|
||||
int nRndPos = GetRandInt(vRandom.size() - n) + n;
|
||||
SwapRandom(n, nRndPos);
|
||||
assert(mapInfo.count(vRandom[n]) == 1);
|
||||
vAddr.push_back(mapInfo[vRandom[n]]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
nRandomPos = -1;
|
||||
}
|
||||
|
||||
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn)
|
||||
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
69
src/net.cpp
69
src/net.cpp
@@ -35,7 +35,7 @@ void ThreadOpenAddedConnections2(void* parg);
|
||||
void ThreadMapPort2(void* parg);
|
||||
#endif
|
||||
void ThreadDNSAddressSeed2(void* parg);
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect);
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect, bool fUseGrant = true);
|
||||
|
||||
|
||||
|
||||
@@ -64,10 +64,7 @@ map<CInv, int64> mapAlreadyAskedFor;
|
||||
set<CNetAddr> setservAddNodeAddresses;
|
||||
CCriticalSection cs_setservAddNodeAddresses;
|
||||
|
||||
static CWaitableCriticalSection csOutbound;
|
||||
static int nOutbound = 0;
|
||||
static CConditionVariable condOutbound;
|
||||
|
||||
static CSemaphore *semOutbound = NULL;
|
||||
|
||||
unsigned short GetListenPort()
|
||||
{
|
||||
@@ -368,10 +365,6 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
|
||||
LOCK(cs_vNodes);
|
||||
vNodes.push_back(pnode);
|
||||
}
|
||||
{
|
||||
WAITABLE_LOCK(csOutbound);
|
||||
nOutbound++;
|
||||
}
|
||||
|
||||
pnode->nTimeConnected = GetTime();
|
||||
return pnode;
|
||||
@@ -517,14 +510,9 @@ void ThreadSocketHandler2(void* parg)
|
||||
// remove from vNodes
|
||||
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
|
||||
|
||||
if (!pnode->fInbound)
|
||||
{
|
||||
WAITABLE_LOCK(csOutbound);
|
||||
nOutbound--;
|
||||
|
||||
// Connection slot(s) were removed, notify connection creator(s)
|
||||
NOTIFY(condOutbound);
|
||||
}
|
||||
if (pnode->fHasGrant)
|
||||
semOutbound->post();
|
||||
pnode->fHasGrant = false;
|
||||
|
||||
// close socket and cleanup
|
||||
pnode->CloseSocketDisconnect();
|
||||
@@ -1201,7 +1189,7 @@ void ThreadOpenConnections2(void* parg)
|
||||
{
|
||||
CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
|
||||
if (addr.IsValid())
|
||||
OpenNetworkConnection(addr);
|
||||
OpenNetworkConnection(addr, false);
|
||||
for (int i = 0; i < 10 && i < nLoop; i++)
|
||||
{
|
||||
Sleep(500);
|
||||
@@ -1222,13 +1210,9 @@ void ThreadOpenConnections2(void* parg)
|
||||
if (fShutdown)
|
||||
return;
|
||||
|
||||
// Limit outbound connections
|
||||
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
|
||||
|
||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
|
||||
{
|
||||
WAITABLE_LOCK(csOutbound);
|
||||
WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
|
||||
}
|
||||
semOutbound->wait();
|
||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
|
||||
if (fShutdown)
|
||||
return;
|
||||
@@ -1261,11 +1245,15 @@ void ThreadOpenConnections2(void* parg)
|
||||
|
||||
// Only connect to one address per a.b.?.? range.
|
||||
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
|
||||
int nOutbound = 0;
|
||||
set<vector<unsigned char> > setConnected;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
setConnected.insert(pnode->addr.GetGroup());
|
||||
if (!pnode->fInbound)
|
||||
nOutbound++;
|
||||
}
|
||||
}
|
||||
|
||||
int64 nANow = GetAdjustedTime();
|
||||
@@ -1296,6 +1284,8 @@ void ThreadOpenConnections2(void* parg)
|
||||
|
||||
if (addrConnect.IsValid())
|
||||
OpenNetworkConnection(addrConnect);
|
||||
else
|
||||
semOutbound->post();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1358,6 +1348,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||
}
|
||||
BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
|
||||
{
|
||||
semOutbound->wait();
|
||||
OpenNetworkConnection(CAddress(*(vserv.begin())));
|
||||
Sleep(500);
|
||||
if (fShutdown)
|
||||
@@ -1373,7 +1364,14 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect)
|
||||
bool static ReleaseGrant(bool fUseGrant) {
|
||||
if (fUseGrant)
|
||||
semOutbound->post();
|
||||
return false;
|
||||
}
|
||||
|
||||
// only call this function when semOutbound has been waited for
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect, bool fUseGrant)
|
||||
{
|
||||
//
|
||||
// Initiate outbound network connection
|
||||
@@ -1382,7 +1380,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect)
|
||||
return false;
|
||||
if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
|
||||
FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
|
||||
return false;
|
||||
return ReleaseGrant(fUseGrant);
|
||||
|
||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
|
||||
CNode* pnode = ConnectNode(addrConnect);
|
||||
@@ -1390,7 +1388,13 @@ bool OpenNetworkConnection(const CAddress& addrConnect)
|
||||
if (fShutdown)
|
||||
return false;
|
||||
if (!pnode)
|
||||
return false;
|
||||
return ReleaseGrant(fUseGrant);
|
||||
if (pnode->fHasGrant) {
|
||||
// node already has connection grant, release the one that was passed to us
|
||||
ReleaseGrant(fUseGrant);
|
||||
} else {
|
||||
pnode->fHasGrant = fUseGrant;
|
||||
}
|
||||
pnode->fNetworkNode = true;
|
||||
|
||||
return true;
|
||||
@@ -1567,6 +1571,12 @@ bool BindListenPort(string& strError)
|
||||
|
||||
void StartNode(void* parg)
|
||||
{
|
||||
if (semOutbound == NULL) {
|
||||
// initialize semaphore
|
||||
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
|
||||
semOutbound = new CSemaphore(nMaxOutbound);
|
||||
}
|
||||
|
||||
#ifdef USE_UPNP
|
||||
#if USE_UPNP
|
||||
fUseUPnP = GetBoolArg("-upnp", true);
|
||||
@@ -1693,7 +1703,8 @@ bool StopNode()
|
||||
fShutdown = true;
|
||||
nTransactionsUpdated++;
|
||||
int64 nStart = GetTime();
|
||||
NOTIFY_ALL(condOutbound);
|
||||
for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
|
||||
semOutbound->post();
|
||||
do
|
||||
{
|
||||
int nThreadsRunning = 0;
|
||||
|
||||
@@ -127,6 +127,7 @@ public:
|
||||
bool fNetworkNode;
|
||||
bool fSuccessfullyConnected;
|
||||
bool fDisconnect;
|
||||
bool fHasGrant; // whether to call semOutbound.post() at disconnect
|
||||
protected:
|
||||
int nRefCount;
|
||||
|
||||
@@ -171,6 +172,7 @@ public:
|
||||
nVersion = 0;
|
||||
strSubVer = "";
|
||||
fClient = false; // set by version message
|
||||
fHasGrant = false;
|
||||
fInbound = fInboundIn;
|
||||
fNetworkNode = false;
|
||||
fSuccessfullyConnected = false;
|
||||
|
||||
57
src/util.h
57
src/util.h
@@ -23,7 +23,7 @@ typedef int pid_t; /* define for windows compatiblity */
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_condition.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
|
||||
#include <boost/interprocess/sync/lock_options.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian_types.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
@@ -270,24 +270,10 @@ public:
|
||||
};
|
||||
|
||||
typedef CMutexLock<CCriticalSection> CCriticalBlock;
|
||||
typedef CMutexLock<CWaitableCriticalSection> CWaitableCriticalBlock;
|
||||
typedef boost::interprocess::interprocess_condition CConditionVariable;
|
||||
|
||||
/** Wait for a given condition inside a WAITABLE_CRITICAL_BLOCK */
|
||||
#define WAIT(name,condition) \
|
||||
do { while(!(condition)) { (name).wait(waitablecriticalblock.GetLock()); } } while(0)
|
||||
|
||||
/** Notify waiting threads that a condition may hold now */
|
||||
#define NOTIFY(name) \
|
||||
do { (name).notify_one(); } while(0)
|
||||
|
||||
#define NOTIFY_ALL(name) \
|
||||
do { (name).notify_all(); } while(0)
|
||||
|
||||
#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__)
|
||||
#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__)
|
||||
#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true)
|
||||
#define WAITABLE_LOCK(cs) CWaitableCriticalBlock waitablecriticalblock(cs, #cs, __FILE__, __LINE__)
|
||||
|
||||
#define ENTER_CRITICAL_SECTION(cs) \
|
||||
{ \
|
||||
@@ -301,6 +287,47 @@ typedef boost::interprocess::interprocess_condition CConditionVariable;
|
||||
LeaveCritical(); \
|
||||
}
|
||||
|
||||
#ifdef MAC_OSX
|
||||
// boost::interprocess::interprocess_semaphore seems to spinlock on OSX; prefer polling instead
|
||||
class CSemaphore
|
||||
{
|
||||
private:
|
||||
CCriticalSection cs;
|
||||
int val;
|
||||
|
||||
public:
|
||||
CSemaphore(int init) : val(init) {}
|
||||
|
||||
void wait() {
|
||||
do {
|
||||
{
|
||||
LOCK(cs);
|
||||
if (val>0) {
|
||||
val--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Sleep(100);
|
||||
} while(1);
|
||||
}
|
||||
|
||||
bool try_wait() {
|
||||
LOCK(cs);
|
||||
if (val>0) {
|
||||
val--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void post() {
|
||||
LOCK(cs);
|
||||
val++;
|
||||
}
|
||||
};
|
||||
#else
|
||||
typedef boost::interprocess::interprocess_semaphore CSemaphore;
|
||||
#endif
|
||||
|
||||
inline std::string i64tostr(int64 n)
|
||||
{
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
static const int CLIENT_VERSION_MAJOR = 0;
|
||||
static const int CLIENT_VERSION_MINOR = 6;
|
||||
static const int CLIENT_VERSION_REVISION = 1;
|
||||
static const int CLIENT_VERSION_BUILD = 3;
|
||||
static const int CLIENT_VERSION_REVISION = 2;
|
||||
static const int CLIENT_VERSION_BUILD = 2;
|
||||
|
||||
static const int CLIENT_VERSION =
|
||||
1000000 * CLIENT_VERSION_MAJOR
|
||||
|
||||
Reference in New Issue
Block a user