private void OnRegister(VersionPayload version) { Context.Watch(Sender); TaskSession session = new TaskSession(Sender, version); sessions.Add(Sender, session); RequestTasks(session); }
private void RequestTasks(TaskSession session) { if (session.HasTask) { return; } if (session.AvailableTasks.Count > 0) { session.AvailableTasks.Remove(knownHashes); session.AvailableTasks.RemoveWhere(p => Blockchain.Singleton.ContainsBlock(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.Tasks[hash] = DateTime.UtcNow; } foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray())) { session.RemoteNode.Tell(Message.Create(MessageCommand.GetData, group)); } return; } } if ((!HasHeaderTask || globalTasks[HeaderTaskHash] < MaxConncurrentTasks) && Blockchain.Singleton.HeaderHeight < session.LastBlockIndex) { session.Tasks[HeaderTaskHash] = DateTime.UtcNow; IncrementGlobalTask(HeaderTaskHash); session.RemoteNode.Tell(Message.Create(MessageCommand.GetHeaders, GetBlocksPayload.Create(Blockchain.Singleton.CurrentHeaderHash))); } else if (Blockchain.Singleton.Height < session.LastBlockIndex) { UInt256 hash = Blockchain.Singleton.CurrentBlockHash; for (uint i = Blockchain.Singleton.Height + 1; i <= Blockchain.Singleton.HeaderHeight; i++) { hash = Blockchain.Singleton.GetBlockHash(i); if (!globalTasks.ContainsKey(hash)) { hash = Blockchain.Singleton.GetBlockHash(i - 1); break; } } session.RemoteNode.Tell(Message.Create(MessageCommand.GetBlocks, GetBlocksPayload.Create(hash))); } else if (Blockchain.Singleton.HeaderHeight >= session.LastBlockIndex && TimeProvider.Current.UtcNow.ToTimestamp() - PingCoolingOffPeriod >= Blockchain.Singleton.GetBlock(Blockchain.Singleton.CurrentHeaderHash)?.Timestamp) { session.RemoteNode.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(Blockchain.Singleton.Height))); } }
private void OnRegister(VersionPayload version) { Context.Watch(Sender); TaskSession session = new TaskSession(version); if (session.IsFullNode) session.InvTasks.TryAdd(MemPoolTaskHash, TimeProvider.Current.UtcNow); sessions.TryAdd(Sender, session); RequestTasks(); }
private void RequestTasks(TaskSession session) { /* if (session.HasTask) return; * // 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 => DagSystem.Singleton.Storage.ContainsBlock(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.Tasks[hash] = DateTime.UtcNow; * foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray())) * session.RemoteNode.Tell(Message.Create(MessageCommand.GetData, group)); * return; * } * } * * // 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 || globalTasks[HeaderTaskHash] < MaxConncurrentTasks) && DagSystem.Singleton.Storage.HeaderHeight < session.LastBlockIndex) * { * session.Tasks[HeaderTaskHash] = DateTime.UtcNow; * IncrementGlobalTask(HeaderTaskHash); * session.RemoteNode.Tell(Message.Create(MessageCommand.GetHeaders, GetBlocksPayload.Create(DagSystem.Singleton.Storage.CurrentHeaderHash))); * } * else if (DagSystem.Singleton.Storage.Height < session.LastBlockIndex) * { * UInt256 hash = DagSystem.Singleton.Storage.CurrentBlockHash; * for (uint i = DagSystem.Singleton.Storage.Height + 1; i <= DagSystem.Singleton.Storage.HeaderHeight; i++) * { * hash = DagSystem.Singleton.Storage.GetBlockHash(i); * if (!globalTasks.ContainsKey(hash)) * { * hash = DagSystem.Singleton.Storage.GetBlockHash(i - 1); * break; * } * } * session.RemoteNode.Tell(Message.Create(MessageCommand.GetBlocks, GetBlocksPayload.Create(hash))); * } * else if (DagSystem.Singleton.Storage.HeaderHeight >= session.LastBlockIndex * && TimeProvider.Current.UtcNow.ToTimestamp() - PingCoolingOffPeriod >= DagSystem.Singleton.Storage.GetBlock(DagSystem.Singleton.Storage.CurrentHeaderHash)?.Timestamp) * { * session.RemoteNode.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(DagSystem.Singleton.Storage.Height))); * }*/ }
private void RequestTasks(TaskSession session) { if (session.HasTask) { return; } if (session.AvailableTasks.Count > 0) { session.AvailableTasks.ExceptWith(knownHashes); session.AvailableTasks.RemoveWhere(p => Blockchain.Singleton.ContainsBlock(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.ExceptWith(hashes); foreach (UInt256 hash in hashes) { session.Tasks[hash] = DateTime.UtcNow; } foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray())) { session.RemoteNode.Tell(Message.Create("getdata", group)); } return; } } if ((!HasHeaderTask || globalTasks[HeaderTaskHash] < MaxConncurrentTasks) && Blockchain.Singleton.HeaderHeight < session.Version.StartHeight) { session.Tasks[HeaderTaskHash] = DateTime.UtcNow; IncrementGlobalTask(HeaderTaskHash); session.RemoteNode.Tell(Message.Create("getheaders", GetBlocksPayload.Create(Blockchain.Singleton.CurrentHeaderHash))); } else if (Blockchain.Singleton.Height < session.Version.StartHeight) { UInt256 hash = Blockchain.Singleton.CurrentBlockHash; for (uint i = Blockchain.Singleton.Height + 1; i <= Blockchain.Singleton.HeaderHeight; i++) { hash = Blockchain.Singleton.GetBlockHash(i); if (!globalTasks.ContainsKey(hash)) { hash = Blockchain.Singleton.GetBlockHash(i - 1); break; } } session.RemoteNode.Tell(Message.Create("getblocks", GetBlocksPayload.Create(hash))); } }
private void OnRegister(VersionPayload version) { Context.Watch(Sender); TaskSession session = new TaskSession(Sender, version); if (session.IsFullNode) { session.AvailableTasks.Add(TaskManager.MemPoolTaskHash); } sessions.Add(Sender, session); RequestTasks(session); }
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 RequestTasks(TaskSession session) { if (session.HasTask) { return; } // 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 => Blockchain.Singleton.ContainsBlock(p)); HashSet <UInt256> hashes = new HashSet <UInt256>(session.AvailableTasks); hashes.Remove(MemPoolTaskHash); 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.Tasks[hash] = DateTime.UtcNow; } foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray())) { session.RemoteNode.Tell(Message.Create(MessageCommand.GetData, group)); } return; } } // 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 || globalTasks[HeaderTaskHash] < MaxConncurrentTasks) && Blockchain.Singleton.HeaderHeight < session.LastBlockIndex) { session.Tasks[HeaderTaskHash] = DateTime.UtcNow; IncrementGlobalTask(HeaderTaskHash); session.RemoteNode.Tell(Message.Create(MessageCommand.GetHeaders, GetBlocksPayload.Create(Blockchain.Singleton.CurrentHeaderHash))); } else if (Blockchain.Singleton.Height < session.LastBlockIndex) { UInt256 hash = Blockchain.Singleton.CurrentBlockHash; for (uint i = Blockchain.Singleton.Height + 1; i <= Blockchain.Singleton.HeaderHeight; i++) { hash = Blockchain.Singleton.GetBlockHash(i); if (!globalTasks.ContainsKey(hash)) { hash = Blockchain.Singleton.GetBlockHash(i - 1); break; } } session.RemoteNode.Tell(Message.Create(MessageCommand.GetBlocks, GetBlocksPayload.Create(hash))); } else if (Blockchain.Singleton.HeaderHeight >= session.LastBlockIndex && TimeProvider.Current.UtcNow.ToTimestampMS() - PingCoolingOffPeriod >= Blockchain.Singleton.GetBlock(Blockchain.Singleton.CurrentHeaderHash)?.Timestamp) { if (session.AvailableTasks.Remove(MemPoolTaskHash)) { session.RemoteNode.Tell(Message.Create(MessageCommand.Mempool)); } session.RemoteNode.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(Blockchain.Singleton.Height))); } }
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)); } }
private void RequestTasks(TaskSession session) { if (!_expiredTimes.TryGetValue(session.RemoteNode.Path, out var expireTime) || expireTime < DateTime.UtcNow) { session.RemoteNode.Tell(Message.Create("ping", PingPayload.Create(Blockchain.Singleton.Height))); _expiredTimes[session.RemoteNode.Path] = DateTime.UtcNow.AddSeconds(PingCoolingOffPeriod); } if (session.HasTask) { return; } if (session.AvailableTasks.Count > 0) { session.AvailableTasks.Remove(knownHashes); session.AvailableTasks.RemoveWhere(p => Blockchain.Singleton.ContainsBlock(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.Tasks[hash] = DateTime.UtcNow; } foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray())) { session.RemoteNode.Tell(Message.Create("getdata", group)); } return; } } if ((!HasHeaderTask || globalTasks[HeaderTaskHash] < MaxConncurrentTasks) && Blockchain.Singleton.HeaderHeight < session.LastBlockIndex) { session.Tasks[HeaderTaskHash] = DateTime.UtcNow; IncrementGlobalTask(HeaderTaskHash); session.RemoteNode.Tell(Message.Create("getheaders", GetBlocksPayload.Create(Blockchain.Singleton.CurrentHeaderHash))); } else if (Blockchain.Singleton.Height < session.LastBlockIndex) { UInt256 hash = Blockchain.Singleton.CurrentBlockHash; for (uint i = Blockchain.Singleton.Height + 1; i <= Blockchain.Singleton.HeaderHeight; i++) { hash = Blockchain.Singleton.GetBlockHash(i); if (!globalTasks.ContainsKey(hash)) { hash = Blockchain.Singleton.GetBlockHash(i - 1); break; } } session.RemoteNode.Tell(Message.Create("getblocks", GetBlocksPayload.Create(hash))); } if (!HasStateRootTask) { if (Blockchain.Singleton.ExpectStateRootIndex < Blockchain.Singleton.Height) { var state_root_state = Blockchain.Singleton.GetStateRoot(Blockchain.Singleton.ExpectStateRootIndex); if (state_root_state is null || state_root_state.Flag == StateRootVerifyFlag.Invalid) { return; } var start_index = Blockchain.Singleton.ExpectStateRootIndex; var count = Math.Min(Blockchain.Singleton.Height - start_index, StateRootsPayload.MaxStateRootsCount); StateRootSyncTime = DateTime.UtcNow; IncrementGlobalTask(StateRootTaskHash); system.LocalNode.Tell(Message.Create("getroots", GetStateRootsPayload.Create(start_index, count))); } } }