changeset 157:d77ac3c6ee9a draft

use seed nodes as fallback if IRC fails or with TOR -- version 0.2.12
author s_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>
date Fri, 18 Jun 2010 03:14:24 +0000
parents ccff4d632dfa
children f1ae39828c3b
files main.cpp net.cpp net.h serialize.h
diffstat 4 files changed, 95 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/main.cpp
+++ b/main.cpp
@@ -493,7 +493,7 @@
     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 @@
             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 @@
             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<int, CNode*> 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<uint256, CNode*> mapMix;
                     foreach(CNode* pnode, vNodes)
-                        mapMix.insert(make_pair(GetRand(INT_MAX), pnode));
-                    int nRelayNodes = 5;
-                    for (multimap<int, CNode*>::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<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
                         ((*mi).second)->PushAddress(addr);
                 }
             }
@@ -2158,8 +2164,10 @@
 
     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 @@
                     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);
 
--- a/net.cpp
+++ b/net.cpp
@@ -223,14 +223,12 @@
 
 
 
-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<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
@@ -252,6 +250,7 @@
                 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 @@
 
 
 
+
+
+
+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 @@
     }
 
     // Initiate network connections
+    int64 nStart = GetTime();
     loop
     {
         // Wait
@@ -874,6 +893,55 @@
         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<unsigned int> 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<unsigned char>, 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 @@
                 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
--- a/net.h
+++ b/net.h
@@ -24,7 +24,7 @@
 
 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);
--- a/serialize.h
+++ b/serialize.h
@@ -19,8 +19,8 @@
 class CDataStream;
 class CAutoFile;
 
-static const int VERSION = 211;
-static const char* pszSubVer = ".0";
+static const int VERSION = 212;
+static const char* pszSubVer = "";