private bool requestMissingBlocks() { if (syncDone) { return(false); } if (syncTargetBlockNum == 0) { return(false); } long currentTime = Core.getCurrentTimestamp(); // Check if the block has already been requested lock (requestedBlockTimes) { Dictionary <ulong, long> tmpRequestedBlockTimes = new Dictionary <ulong, long>(requestedBlockTimes); foreach (var entry in tmpRequestedBlockTimes) { ulong blockNum = entry.Key; // Check if the request expired (after 10 seconds) if (currentTime - requestedBlockTimes[blockNum] > 10) { // Re-request block if (ProtocolMessage.broadcastGetBlock(blockNum, null, null, 1, true) == false) { if (watchDogBlockNum > 0 && (blockNum == watchDogBlockNum - 4 || blockNum == watchDogBlockNum + 1)) { watchDogTime = DateTime.UtcNow; } Logging.warn(string.Format("Failed to rebroadcast getBlock request for {0}", blockNum)); Thread.Sleep(500); } else { // Re-set the block request time requestedBlockTimes[blockNum] = currentTime; } } } } ulong syncToBlock = syncTargetBlockNum; ulong firstBlock = getLowestBlockNum(); lock (pendingBlocks) { ulong lastBlock = syncToBlock; if (missingBlocks == null) { missingBlocks = new List <ulong>(Enumerable.Range(0, (int)(lastBlock - firstBlock + 1)).Select(x => (ulong)x + firstBlock)); missingBlocks.Sort(); } int total_count = 0; int requested_count = 0; // whatever is left in missingBlocks is what we need to request Logging.info(String.Format("{0} blocks are missing before node is synchronized...", missingBlocks.Count())); if (missingBlocks.Count() == 0) { receivedAllMissingBlocks = true; return(false); } List <ulong> tmpMissingBlocks = new List <ulong>(missingBlocks); foreach (ulong blockNum in tmpMissingBlocks) { total_count++; lock (requestedBlockTimes) { if (requestedBlockTimes.ContainsKey(blockNum)) { requested_count++; continue; } } bool readFromStorage = false; if (blockNum <= lastBlockToReadFromStorage) { readFromStorage = true; } ulong last_block_height = IxianHandler.getLastBlockHeight(); if (blockNum > last_block_height + (ulong)maxBlockRequests) { if (last_block_height > 0 || (last_block_height == 0 && total_count > 10)) { if (!readFromStorage) { Thread.Sleep(100); } break; } } // First check if the missing block can be found in storage Block block = Node.blockChain.getBlock(blockNum, readFromStorage); if (block != null) { Node.blockSync.onBlockReceived(block, null); } else { if (readFromStorage) { Logging.warn("Expecting block {0} in storage but had to request it from network.", blockNum); } // Didn't find the block in storage, request it from the network if (ProtocolMessage.broadcastGetBlock(blockNum, null, null, 1, true) == false) { if (watchDogBlockNum > 0 && (blockNum == watchDogBlockNum - 4 || blockNum == watchDogBlockNum + 1)) { watchDogTime = DateTime.UtcNow; } Logging.warn(string.Format("Failed to broadcast getBlock request for {0}", blockNum)); Thread.Sleep(500); } else { requested_count++; // Set the block request time lock (requestedBlockTimes) { requestedBlockTimes.Add(blockNum, currentTime); } } } } if (requested_count > 0) { return(true); } } return(false); }