diff --git a/main.cpp b/main.cpp index 13b7828dd593e..37f7742b66660 100644 --- a/main.cpp +++ b/main.cpp @@ -493,7 +493,7 @@ bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMis if (!CheckTransaction()) return error("AcceptTransaction() : CheckTransaction failed"); - // To help v0.1.5 clients who would see it as negative number. please delete this later. + // To help v0.1.5 clients who would see it as a negative number if (nLockTime > INT_MAX) return error("AcceptTransaction() : not accepting nLockTime beyond 2038"); @@ -1896,10 +1896,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); // Ask the first connected node for block updates - static bool fAskedForBlocks; - if (!fAskedForBlocks && !pfrom->fClient) + static int nAskedForBlocks; + if (!pfrom->fClient && (nAskedForBlocks < 1 || vNodes.size() <= 1)) { - fAskedForBlocks = true; + nAskedForBlocks++; pfrom->PushGetBlocks(pindexBest, uint256(0)); } @@ -1939,18 +1939,24 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) addr.nTime = GetAdjustedTime() - 2 * 60 * 60; if (pfrom->fGetAddr || vAddr.size() > 10) addr.nTime -= 5 * 24 * 60 * 60; - AddAddress(addr, false); + AddAddress(addr); pfrom->AddAddressKnown(addr); if (!pfrom->fGetAddr && addr.IsRoutable()) { // Relay to a limited number of other nodes CRITICAL_BLOCK(cs_vNodes) { - multimap mapMix; + // Use deterministic randomness to send to + // the same places for an hour at a time + static uint256 hashSalt; + if (hashSalt == 0) + RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt)); + uint256 hashRand = addr.ip ^ (GetTime()/3600) ^ hashSalt; + multimap mapMix; foreach(CNode* pnode, vNodes) - mapMix.insert(make_pair(GetRand(INT_MAX), pnode)); - int nRelayNodes = 5; - for (multimap::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) + mapMix.insert(make_pair(hashRand = Hash(BEGIN(hashRand), END(hashRand)), pnode)); + int nRelayNodes = 10; // reduce this to 5 when the network is large + for (multimap::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) ((*mi).second)->PushAddress(addr); } } @@ -2158,8 +2164,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) else if (strCommand == "getaddr") { + // This includes all nodes that are currently online, + // since they rebroadcast an addr every 24 hours pfrom->vAddrToSend.clear(); - int64 nSince = GetAdjustedTime() - 5 * 24 * 60 * 60; // in the last 5 days + int64 nSince = GetAdjustedTime() - 24 * 60 * 60; // in the last 24 hours CRITICAL_BLOCK(cs_mapAddresses) { unsigned int nSize = mapAddresses.size(); @@ -2348,7 +2356,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) static uint256 hashSalt; if (hashSalt == 0) RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt)); - uint256 hashRand = (inv.hash ^ hashSalt); + uint256 hashRand = inv.hash ^ hashSalt; hashRand = Hash(BEGIN(hashRand), END(hashRand)); bool fTrickleWait = ((hashRand & 3) != 0); diff --git a/net.cpp b/net.cpp index 59d40dc121d0d..7539066dabbd4 100644 --- a/net.cpp +++ b/net.cpp @@ -223,14 +223,12 @@ bool GetMyExternalIP(unsigned int& ipRet) -bool AddAddress(CAddress addr, bool fCurrentlyOnline) +bool AddAddress(CAddress addr) { if (!addr.IsRoutable()) return false; if (addr.ip == addrLocalHost.ip) return false; - if (fCurrentlyOnline) - addr.nTime = GetAdjustedTime(); CRITICAL_BLOCK(cs_mapAddresses) { map, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); @@ -252,6 +250,7 @@ bool AddAddress(CAddress addr, bool fCurrentlyOnline) addrFound.nServices |= addr.nServices; fUpdated = true; } + bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60); int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); if (addrFound.nTime < addr.nTime - nUpdateInterval) { @@ -798,6 +797,25 @@ void ThreadSocketHandler2(void* parg) + + + +unsigned int pnSeed[] = +{ + 0x35218252, 0x9c9c9618, 0xda6bacad, 0xb9aca862, 0x97c235c6, + 0x146f9562, 0xb67b9e4b, 0x87cf4bc0, 0xb83945d0, 0x984333ad, + 0xbbeec555, 0x6f0eb440, 0xe0005318, 0x7797e460, 0xddc60fcc, + 0xb3bbd24a, 0x1ac85746, 0x641846a6, 0x85ee1155, 0xbb2e7a4c, + 0x9cb8514b, 0xfc342648, 0x62958fae, 0xd0a8c87a, 0xa800795b, + 0xda8c814e, 0x256a0c80, 0x3f23ec63, 0xd565df43, 0x997d9044, + 0xaa121448, 0xbed8688e, 0x59d09a5e, 0xb2931243, 0x3730ba18, + 0xdd3462d0, 0x4e4d1448, 0x171df645, 0x84ee1155, + 0x248ac445, 0x0e634444, 0x0ded1b63, 0x30c01e60, + 0xa2b9a094, 0x29e4fd43, 0x9ce61b4c, 0xdae09744, +}; + + + void ThreadOpenConnections(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); @@ -858,6 +876,7 @@ void ThreadOpenConnections2(void* parg) } // Initiate network connections + int64 nStart = GetTime(); loop { // Wait @@ -874,6 +893,55 @@ void ThreadOpenConnections2(void* parg) if (fShutdown) return; + CRITICAL_BLOCK(cs_mapAddresses) + { + // Add seed nodes if IRC isn't working + static bool fSeedUsed; + bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); + if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR)) + { + for (int i = 0; i < ARRAYLEN(pnSeed); i++) + { + // It'll only connect to one or two seed nodes because once it connects, + // it'll get a pile of addresses with newer timestamps. + CAddress addr; + addr.ip = pnSeed[i]; + addr.nTime = 0; + AddAddress(addr); + } + fSeedUsed = true; + } + + if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100) + { + // Disconnect seed nodes + set setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed)); + static int64 nSeedDisconnected; + if (nSeedDisconnected == 0) + { + nSeedDisconnected = GetTime(); + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (setSeed.count(pnode->addr.ip)) + pnode->fDisconnect = true; + } + + // Keep setting timestamps to 0 so they won't reconnect + if (GetTime() - nSeedDisconnected < 60 * 60) + { + foreach(PAIRTYPE(const vector, CAddress)& item, mapAddresses) + { + if (setSeed.count(item.second.ip)) + { + item.second.nTime = 0; + CAddrDB().WriteAddress(item.second); + } + } + } + } + } + + // // Choose an address to connect to based on most recently seen // @@ -897,9 +965,9 @@ void ThreadOpenConnections2(void* parg) int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry; // Randomize the order in a deterministic way, putting the standard port first - int64 nRandomizer = (uint64)(addr.nLastTry * 9567851 + addr.ip * 7789) % (30 * 60); + int64 nRandomizer = (uint64)(nStart + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60); if (addr.port != DEFAULT_PORT) - nRandomizer += 30 * 60; + nRandomizer += 2 * 60 * 60; // Last seen Base retry frequency // <1 hour 10 min diff --git a/net.h b/net.h index 11197cc429032..f0e183d9c0d23 100644 --- a/net.h +++ b/net.h @@ -24,7 +24,7 @@ enum bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); bool GetMyExternalIP(unsigned int& ipRet); -bool AddAddress(CAddress addr, bool fCurrentlyOnline=true); +bool AddAddress(CAddress addr); void AddressCurrentlyConnected(const CAddress& addr); CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); diff --git a/serialize.h b/serialize.h index f2d368986a868..39fe57c908d50 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 211; -static const char* pszSubVer = ".0"; +static const int VERSION = 212; +static const char* pszSubVer = "";