diff --git a/src/neo/Network/P2P/TaskManager.cs b/src/neo/Network/P2P/TaskManager.cs index 73fa49441a..442efc8a68 100644 --- a/src/neo/Network/P2P/TaskManager.cs +++ b/src/neo/Network/P2P/TaskManager.cs @@ -24,11 +24,13 @@ private class Timer { } private static readonly TimeSpan TimerInterval = TimeSpan.FromSeconds(30); private static readonly TimeSpan TaskTimeout = TimeSpan.FromMinutes(1); + private static readonly UInt256 HeaderTaskHash = UInt256.Zero; + private static readonly UInt256 MemPoolTaskHash = UInt256.Parse("0x0000000000000000000000000000000000000000000000000000000000000001"); private readonly NeoSystem system; private const int MaxConncurrentTasks = 3; - private const int PingCoolingOffPeriod = 60; // in secconds. + private const int PingCoolingOffPeriod = 60_000; // in ms. /// /// A set of known hashes, of inventories or payloads, already received. /// @@ -37,7 +39,6 @@ private class Timer { } private readonly Dictionary sessions = new Dictionary(); private readonly ICancelable timer = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(TimerInterval, TimerInterval, Context.Self, new Timer(), ActorRefs.NoSender); - private readonly UInt256 HeaderTaskHash = UInt256.Zero; private bool HasHeaderTask => globalTasks.ContainsKey(HeaderTaskHash); public TaskManager(NeoSystem system) @@ -126,6 +127,8 @@ 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); } @@ -183,7 +186,6 @@ private bool IncrementGlobalTask(UInt256 hash) return false; globalTasks[hash] = value + 1; - return true; } @@ -230,6 +232,7 @@ private void RequestTasks(TaskSession session) // 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 hashes = new HashSet(session.AvailableTasks); + hashes.Remove(MemPoolTaskHash); if (hashes.Count > 0) { foreach (UInt256 hash in hashes.ToArray()) @@ -269,8 +272,13 @@ private void RequestTasks(TaskSession session) 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) + && 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))); } } diff --git a/src/neo/Network/P2P/TaskSession.cs b/src/neo/Network/P2P/TaskSession.cs index eb0ab631bd..d13c7c82f5 100644 --- a/src/neo/Network/P2P/TaskSession.cs +++ b/src/neo/Network/P2P/TaskSession.cs @@ -16,15 +16,17 @@ internal class TaskSession public bool HasTask => Tasks.Count > 0; public uint StartHeight { get; } + public bool IsFullNode { get; } public uint LastBlockIndex { get; set; } public TaskSession(IActorRef node, VersionPayload version) { + var fullNode = version.Capabilities.OfType().FirstOrDefault(); + + this.IsFullNode = fullNode != null; this.RemoteNode = node; this.Version = version; - this.StartHeight = version.Capabilities - .OfType() - .FirstOrDefault()?.StartHeight ?? 0; + this.StartHeight = fullNode?.StartHeight ?? 0; this.LastBlockIndex = this.StartHeight; } }