Beispiel #1
0
        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);
        }