Exemple #1
0
        private void OnRegister(VersionPayload version)
        {
            Context.Watch(Sender);
            TaskSession session = new TaskSession(Sender, version);

            sessions.Add(Sender, session);
            RequestTasks(session);
        }
Exemple #2
0
 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)));
     }
 }
Exemple #3
0
 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)));
      *         }*/
 }
Exemple #5
0
 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)));
     }
 }
Exemple #6
0
        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);
        }
Exemple #7
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;
 }
Exemple #8
0
        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)));
            }
        }
Exemple #9
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));
            }
        }
Exemple #10
0
 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)));
         }
     }
 }