Example #1
0
        public void DeserializeAndSerialize()
        {
            var test = new GetBlockByIndexPayload()
            {
                Count = -1, IndexStart = int.MaxValue
            };
            var clone = test.ToArray().AsSerializable <GetBlockByIndexPayload>();

            Assert.AreEqual(test.Count, clone.Count);
            Assert.AreEqual(test.IndexStart, clone.IndexStart);

            test = new GetBlockByIndexPayload()
            {
                Count = -2, IndexStart = int.MaxValue
            };
            Assert.ThrowsException <FormatException>(() => test.ToArray().AsSerializable <GetBlockByIndexPayload>());

            test = new GetBlockByIndexPayload()
            {
                Count = 0, IndexStart = int.MaxValue
            };
            Assert.ThrowsException <FormatException>(() => test.ToArray().AsSerializable <GetBlockByIndexPayload>());

            test = new GetBlockByIndexPayload()
            {
                Count = HeadersPayload.MaxHeadersCount + 1, IndexStart = int.MaxValue
            };
            Assert.ThrowsException <FormatException>(() => test.ToArray().AsSerializable <GetBlockByIndexPayload>());
        }
Example #2
0
        public void Size_Get()
        {
            var test = new GetBlockByIndexPayload()
            {
                Count = 5, IndexStart = 5
            };

            test.Size.Should().Be(6);

            test = GetBlockByIndexPayload.Create(1, short.MaxValue);
            test.Size.Should().Be(6);
        }
Example #3
0
 private bool AssignSyncTask(uint index, TaskSession filterSession = null)
 {
     if (index <= Blockchain.Singleton.Height || sessions.Values.Any(p => p != filterSession && p.IndexTasks.ContainsKey(index)))
         return true;
     Random rand = new Random();
     KeyValuePair<IActorRef, TaskSession> remoteNode = sessions.Where(p => p.Value != filterSession && p.Value.LastBlockIndex >= index)
         .OrderBy(p => p.Value.IndexTasks.Count)
         .ThenBy(s => rand.Next())
         .FirstOrDefault();
     if (remoteNode.Value == null)
     {
         failedSyncTasks.Add(index);
         return false;
     }
     TaskSession session = remoteNode.Value;
     session.IndexTasks.TryAdd(index, TimeProvider.Current.UtcNow);
     remoteNode.Key.Tell(Message.Create(MessageCommand.GetBlockByIndex, GetBlockByIndexPayload.Create(index, 1)));
     failedSyncTasks.Remove(index);
     return true;
 }
 private void OnBroadcastGetHeadersCommand(uint index)
 {
     OnBroadcastCommand(MessageCommand.GetHeaders, GetBlockByIndexPayload.Create(index));
 }
Example #5
0
        private void RequestTasks(IActorRef remoteNode, TaskSession session)
        {
            if (session.HasTooManyTasks)
            {
                return;
            }

            DataCache snapshot = system.StoreView;

            // If there are pending tasks of InventoryType.Block we should process them
            if (session.AvailableTasks.Count > 0)
            {
                session.AvailableTasks.Remove(knownHashes);
                // Search any similar hash that is on Singleton's knowledge, which means, on the way or already processed
                session.AvailableTasks.RemoveWhere(p => NativeContract.Ledger.ContainsBlock(snapshot, p));
                HashSet <UInt256> hashes = new HashSet <UInt256>(session.AvailableTasks);
                if (hashes.Count > 0)
                {
                    foreach (UInt256 hash in hashes.ToArray())
                    {
                        if (!IncrementGlobalTask(hash))
                        {
                            hashes.Remove(hash);
                        }
                    }
                    session.AvailableTasks.Remove(hashes);
                    foreach (UInt256 hash in hashes)
                    {
                        session.InvTasks[hash] = DateTime.UtcNow;
                    }
                    foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray()))
                    {
                        remoteNode.Tell(Message.Create(MessageCommand.GetData, group));
                    }
                    return;
                }
            }

            uint currentHeight = NativeContract.Ledger.CurrentIndex(snapshot);
            uint headerHeight  = system.HeaderCache.Last?.Index ?? currentHeight;

            // When the number of AvailableTasks is no more than 0, no pending tasks of InventoryType.Block, it should process pending the tasks of headers
            // If not HeaderTask pending to be processed it should ask for more Blocks
            if ((!HasHeaderTask || globalInvTasks[HeaderTaskHash] < MaxConncurrentTasks) && headerHeight < session.LastBlockIndex && !system.HeaderCache.Full)
            {
                session.InvTasks[HeaderTaskHash] = DateTime.UtcNow;
                IncrementGlobalTask(HeaderTaskHash);
                remoteNode.Tell(Message.Create(MessageCommand.GetHeaders, GetBlockByIndexPayload.Create(headerHeight)));
            }
            else if (currentHeight < session.LastBlockIndex)
            {
                uint startHeight = currentHeight;
                while (globalIndexTasks.ContainsKey(++startHeight))
                {
                }
                if (startHeight > session.LastBlockIndex || startHeight >= currentHeight + InvPayload.MaxHashesCount)
                {
                    return;
                }
                uint endHeight = startHeight;
                while (!globalIndexTasks.ContainsKey(++endHeight) && endHeight <= session.LastBlockIndex && endHeight <= currentHeight + InvPayload.MaxHashesCount)
                {
                }
                uint count = Math.Min(endHeight - startHeight, InvPayload.MaxHashesCount);
                for (uint i = 0; i < count; i++)
                {
                    session.IndexTasks[startHeight + i] = TimeProvider.Current.UtcNow;
                    IncrementGlobalTask(startHeight + i);
                }
                remoteNode.Tell(Message.Create(MessageCommand.GetBlockByIndex, GetBlockByIndexPayload.Create(startHeight, (short)count)));
            }
            else if (!session.MempoolSent)
            {
                session.MempoolSent = true;
                remoteNode.Tell(Message.Create(MessageCommand.Mempool));
            }
        }