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