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>()); }
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); }
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)); }
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)); } }