changeset 23688:66370fb8e249

XThinblock preferential downloader Thinblocks will be preferentially downloaded from nodes that are connected and that support thinblocks. If the timer is exceeded then a regular block is downloaded instead.
author Peter Tschipper <peter.tschipper@gmailcom>
date Tue, 16 Feb 2016 11:00:41 -0800
parents 86220af27a3e
children 3241c82e16eb
files src/main.cpp src/unlimited.cpp src/unlimited.h
diffstat 3 files changed, 53 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/main.cpp	Tue Feb 16 09:26:28 2016 -0800
+++ b/src/main.cpp	Tue Feb 16 11:00:41 2016 -0800
@@ -4597,7 +4597,7 @@
                         // BUIP010 Xtreme Thinblocks: begin section
                         CInv inv2(inv);
                         if (IsThinBlocksEnabled() && IsChainNearlySyncd()) {
-                            if (HaveThinblockNodeConnections()) {
+                            if (HaveConnectThinblockNodes() || (HaveThinblockNodes() && CheckThinblockTimer(inv.hash))) {
                                 // Must download a block from a ThinBlock peer
                                 if (pfrom->mapThinBlocksInFlight.size() < 1 && pfrom->nVersion >= THINBLOCKS_VERSION) { // We can only send one thinblock per peer at a time
                                     pfrom->mapThinBlocksInFlight[inv2.hash] = GetTime();
@@ -5947,7 +5947,7 @@
             BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
                 // BUIP010 Xtreme Thinblocks: begin section
                 if (IsThinBlocksEnabled() && IsChainNearlySyncd()) {
-                    if (HaveThinblockNodeConnections()) {
+                    if (HaveConnectThinblockNodes() || (HaveThinblockNodes() && CheckThinblockTimer(pindex->GetBlockHash()))) {
                         // Must download a block from a ThinBlock peer
                         if (pto->mapThinBlocksInFlight.size() < 1 && pto->nVersion >= THINBLOCKS_VERSION) { // We can only send one thinblock per peer at a time
                             pto->mapThinBlocksInFlight[pindex->GetBlockHash()] = GetTime();
--- a/src/unlimited.cpp	Tue Feb 16 09:26:28 2016 -0800
+++ b/src/unlimited.cpp	Tue Feb 16 11:00:41 2016 -0800
@@ -42,6 +42,9 @@
 
 void UnlimitedPushTxns(CNode* dest);
 
+// BUIP010 Xtreme Thinblocks Variables
+std::map<uint256, uint64_t> mapThinBlockTimer;
+
 std::string UnlimitedCmdLineHelp()
 {
     std::string strUsage;
@@ -492,7 +495,7 @@
 /**
  *  BUIP010 Xtreme Thinblocks Section 
  */
-bool HaveThinblockNodeConnections()
+bool HaveConnectThinblockNodes()
 {
     // Strip the port from then list of all the current in and outbound ip addresses
     std::vector<std::string> vNodesIP;
@@ -540,6 +543,44 @@
     return false; // Connections are either not open or they are cross connected.
 } 
 
+bool HaveThinblockNodes()
+{
+    {
+        LOCK(cs_vNodes);
+        BOOST_FOREACH (CNode* pnode, vNodes)
+            if (pnode->nVersion >= THINBLOCKS_VERSION)
+                return true;
+    }
+    return false;
+}
+
+bool CheckThinblockTimer(uint256 hash)
+{
+    if (!mapThinBlockTimer.count(hash)) {
+        mapThinBlockTimer[hash] = GetTimeMillis();
+        LogPrint("thin", "Starting Preferential Thinblock timer\n");
+    }
+    else {
+        // Check that we have not exceeded the 10 second limit.
+        // If we have then we want to return false so that we can
+        // proceed to download a regular block instead.
+        uint64_t elapsed = GetTimeMillis() - mapThinBlockTimer[hash];
+        if (elapsed > 10000) {
+            LogPrint("thin", "Preferential Thinblock timer exceeded - downloading regular block instead\n");
+            return false;
+        }
+    }
+    return true;
+}
+
+bool ClearThinBlockTimer(uint256 hash)
+{
+    if (mapThinBlockTimer.count(hash)) {
+        mapThinBlockTimer.erase(hash);
+        LogPrint("thin", "Clearing Preferential Thinblock timer\n");
+    }
+}
+
 bool IsThinBlocksEnabled() 
 {
     return GetBoolArg("-use-thinblocks", true);
@@ -617,6 +658,9 @@
             }
         }
     }
+
+    // Clear the thinblock timer used for preferential download
+    ClearThinBlockTimer(inv.hash);
 }
 
 bool ThinBlockMessageHandler(vector<CNode*>& vNodesCopy)
--- a/src/unlimited.h	Tue Feb 16 09:26:28 2016 -0800
+++ b/src/unlimited.h	Tue Feb 16 11:00:41 2016 -0800
@@ -58,8 +58,11 @@
 extern CLeakyBucket sendShaper;
 
 // BUIP010 Xtreme Thinblocks:
-extern bool HaveThinblockNodeConnections();
-extern bool IsThinBlocksEnabled();  // has the user enabled thin blocks for this node (command line option)
+extern bool HaveConnectThinblockNodes();
+extern bool HaveThinblockNodes();
+extern bool CheckThinblockTimer(uint256 hash);
+extern bool ClearThinblockTimer(uint256 hash);
+extern bool IsThinBlocksEnabled();
 extern bool IsChainNearlySyncd();
 extern void SendSeededBloomFilter(CNode *pto);
 extern void HandleBlockMessage(CNode *pfrom, const std::string &strCommand, CBlock &block, const CInv &inv);
@@ -69,5 +72,6 @@
 
 // Handle receiving and sending messages from thin block capable nodes only (so that thin block nodes capable nodes are preferred)
 extern bool ThinBlockMessageHandler(std::vector<CNode*>& vNodesCopy);
+extern std::map<uint256, uint64_t> mapThinBlockTimer;
 
 #endif