Beispiel #1
0
        private void SendPingMessage()
        {
            TrimmedBlock block;

            using (SnapshotCache snapshot = Blockchain.Singleton.GetSnapshot())
            {
                block = NativeContract.Ledger.GetTrimmedBlock(snapshot, NativeContract.Ledger.CurrentHash(snapshot));
            }

            foreach (KeyValuePair <IActorRef, TaskSession> item in sessions)
            {
                var node    = item.Key;
                var session = item.Value;

                if (session.ExpireTime < TimeProvider.Current.UtcNow ||
                    (block.Index >= session.LastBlockIndex &&
                     TimeProvider.Current.UtcNow.ToTimestampMS() - PingCoolingOffPeriod >= block.Timestamp))
                {
                    if (session.InvTasks.Remove(MemPoolTaskHash))
                    {
                        node.Tell(Message.Create(MessageCommand.Mempool));
                    }
                    node.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(Blockchain.Singleton.Height)));
                    session.ExpireTime = TimeProvider.Current.UtcNow.AddMilliseconds(PingCoolingOffPeriod);
                }
            }
        }
Beispiel #2
0
 private VerifyResult OnNewBlock(Block block)
 {
     if (block.Index <= Height)
     {
         return(VerifyResult.AlreadyExists);
     }
     if (block.Index - 1 > Height)
     {
         AddUnverifiedBlockToCache(block);
         return(VerifyResult.UnableToVerify);
     }
     if (block.Index == Height + 1)
     {
         if (!block.Verify(currentSnapshot))
         {
             return(VerifyResult.Invalid);
         }
         block_cache.TryAdd(block.Hash, block);
         block_cache_unverified.Remove(block.Index);
         // We can store the new block in block_cache and tell the new height to other nodes before Persist().
         system.LocalNode.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(Singleton.Height + 1)));
         Persist(block);
         SaveHeaderHashList();
         if (block_cache_unverified.TryGetValue(Height + 1, out LinkedList <Block> unverifiedBlocks))
         {
             foreach (var unverifiedBlock in unverifiedBlocks)
             {
                 Self.Tell(unverifiedBlock, ActorRefs.NoSender);
             }
             block_cache_unverified.Remove(Height + 1);
         }
     }
     return(VerifyResult.Succeed);
 }
Beispiel #3
0
        private void OnTimer()
        {
            SendMessage(Message.Create(MessageType.Ping, PingPayload.Create()));

            Interlocked.Exchange(ref tx_rate, tx_bytes / TimerInterval.TotalSeconds);
            tx_bytes = 0;
        }
Beispiel #4
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("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)));
     }
     else if (Blockchain.Singleton.HeaderHeight >= session.LastBlockIndex &&
              TimeProvider.Current.UtcNow.ToTimestamp() - PingCoolingOffPeriod >= Blockchain.Singleton.GetBlock(Blockchain.Singleton.CurrentHeaderHash)?.Timestamp)
     {
         session.RemoteNode.Tell(Message.Create("ping", PingPayload.Create(Blockchain.Singleton.Height)));
     }
 }
        private void OnShowStateCommand()
        {
            var cancel = new CancellationTokenSource();

            Console.CursorVisible = false;
            Console.Clear();

            Task broadcast = Task.Run(async() =>
            {
                while (!cancel.Token.IsCancellationRequested)
                {
                    NeoSystem.LocalNode.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(NativeContract.Ledger.CurrentIndex(NeoSystem.StoreView))));
                    await Task.Delay(NeoSystem.Settings.TimePerBlock, cancel.Token);
                }
            });
            Task task = Task.Run(async() =>
            {
                int maxLines = 0;
                while (!cancel.Token.IsCancellationRequested)
                {
                    uint height       = NativeContract.Ledger.CurrentIndex(NeoSystem.StoreView);
                    uint headerHeight = NeoSystem.HeaderCache.Last?.Index ?? height;

                    Console.SetCursorPosition(0, 0);
                    WriteLineWithoutFlicker($"block: {height}/{headerHeight}  connected: {LocalNode.ConnectedCount}  unconnected: {LocalNode.UnconnectedCount}", Console.WindowWidth - 1);

                    int linesWritten = 1;
                    foreach (RemoteNode node in LocalNode.GetRemoteNodes().OrderByDescending(u => u.LastBlockIndex).Take(Console.WindowHeight - 2).ToArray())
                    {
                        ConsoleHelper.Info("  ip: ",
                                           $"{ node.Remote.Address,-15}\t",
                                           "port: ",
                                           $"{node.Remote.Port,-5}\t",
                                           "listen: ",
                                           $"{node.ListenerTcpPort,-5}\t",
                                           "height: ",
                                           $"{node.LastBlockIndex,-7}");
                        linesWritten++;
                    }

                    maxLines = Math.Max(maxLines, linesWritten);

                    while (linesWritten < maxLines)
                    {
                        WriteLineWithoutFlicker("", Console.WindowWidth - 1);
                        maxLines--;
                    }

                    await Task.Delay(500, cancel.Token);
                }
            });

            ReadLine();
            cancel.Cancel();
            try { Task.WaitAll(task, broadcast); } catch { }
            Console.WriteLine();
            Console.CursorVisible = true;
        }
Beispiel #6
0
        public void ToArray()
        {
            var payload = PingPayload.Create(uint.MaxValue);
            var msg     = Message.Create(MessageCommand.Ping, payload);

            _ = msg.ToArray();

            msg.Size.Should().Be(payload.Size + 3);
        }
Beispiel #7
0
        private bool OnShowStateCommand(string[] args)
        {
            var cancel = new CancellationTokenSource();

            Console.CursorVisible = false;
            Console.Clear();
            Task broadcast = Task.Run(async() =>
            {
                while (!cancel.Token.IsCancellationRequested)
                {
                    system.LocalNode.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(Blockchain.Singleton.Height)));
                    await Task.Delay(Blockchain.TimePerBlock, cancel.Token);
                }
            });
            Task task = Task.Run(async() =>
            {
                int maxLines = 0;

                while (!cancel.Token.IsCancellationRequested)
                {
                    Console.SetCursorPosition(0, 0);
                    WriteLineWithoutFlicker($"block: {Blockchain.Singleton.Height}/{Blockchain.Singleton.HeaderHeight}  connected: {LocalNode.Singleton.ConnectedCount}  unconnected: {LocalNode.Singleton.UnconnectedCount}", Console.WindowWidth - 1);

                    int linesWritten = 1;
                    foreach (RemoteNode node in LocalNode.Singleton.GetRemoteNodes().OrderByDescending(u => u.LastBlockIndex).Take(Console.WindowHeight - 2).ToArray())
                    {
                        Console.WriteLine(
                            $"  ip: {node.Remote.Address.ToString().PadRight(15)}\tport: {node.Remote.Port.ToString().PadRight(5)}\tlisten: {node.ListenerTcpPort.ToString().PadRight(5)}\theight: {node.LastBlockIndex.ToString().PadRight(7)}");
                        linesWritten++;
                    }

                    maxLines = Math.Max(maxLines, linesWritten);

                    while (linesWritten < maxLines)
                    {
                        WriteLineWithoutFlicker("", Console.WindowWidth - 1);
                        maxLines--;
                    }

                    await Task.Delay(500, cancel.Token);
                }
            });

            Console.ReadLine();
            cancel.Cancel();
            try { Task.WaitAll(task, broadcast); } catch { }
            Console.WriteLine();
            Console.CursorVisible = true;
            return(true);
        }
Beispiel #8
0
        public void Serialize_Deserialize()
        {
            var payload     = PingPayload.Create(uint.MaxValue);
            var msg         = Message.Create(MessageCommand.Ping, payload);
            var buffer      = msg.ToArray();
            var copy        = buffer.AsSerializable <Message>();
            var payloadCopy = (PingPayload)copy.Payload;

            copy.Command.Should().Be(msg.Command);
            copy.Flags.Should().Be(msg.Flags);

            payloadCopy.LastBlockIndex.Should().Be(payload.LastBlockIndex);
            payloadCopy.Nonce.Should().Be(payload.Nonce);
            payloadCopy.Timestamp.Should().Be(payload.Timestamp);
        }
Beispiel #9
0
 private void SendPingMessage()
 {
     foreach (KeyValuePair <IActorRef, TaskSession> item in sessions)
     {
         var node    = item.Key;
         var session = item.Value;
         if (Blockchain.Singleton.Height >= session.LastBlockIndex &&
             TimeProvider.Current.UtcNow.ToTimestampMS() - PingCoolingOffPeriod >= Blockchain.Singleton.GetBlock(Blockchain.Singleton.CurrentBlockHash)?.Timestamp)
         {
             if (session.InvTasks.Remove(MemPoolTaskHash))
             {
                 node.Tell(Message.Create(MessageCommand.Mempool));
             }
             node.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(Blockchain.Singleton.Height)));
         }
     }
 }
Beispiel #10
0
        public void Serialize_Deserialize_ByteString()
        {
            var payload = PingPayload.Create(uint.MaxValue);
            var msg     = Message.Create(MessageCommand.Ping, payload);
            var buffer  = ByteString.CopyFrom(msg.ToArray());
            var length  = Message.TryDeserialize(buffer, out var copy);

            var payloadCopy = (PingPayload)copy.Payload;

            copy.Command.Should().Be(msg.Command);
            copy.Flags.Should().Be(msg.Flags);

            payloadCopy.LastBlockIndex.Should().Be(payload.LastBlockIndex);
            payloadCopy.Nonce.Should().Be(payload.Nonce);
            payloadCopy.Timestamp.Should().Be(payload.Timestamp);

            buffer.Count.Should().Be(length);
        }
        private static async Task <bool> TryPingAsync(MySqlSession session, CancellationToken cancellationToken)
        {
            await session.SendAsync(PingPayload.Create(), cancellationToken).ConfigureAwait(false);

            try
            {
                var payload = await session.ReceiveReplyAsync(cancellationToken).ConfigureAwait(false);

                OkPayload.Create(payload);
                return(true);
            }
            catch (EndOfStreamException)
            {
            }
            catch (SocketException)
            {
            }

            return(false);
        }
Beispiel #12
0
        public async Task <bool> TryPingAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
        {
            VerifyState(State.Connected);

            // send ping payload to verify client and server socket are still connected
            try
            {
                await SendAsync(PingPayload.Create(), ioBehavior, cancellationToken).ConfigureAwait(false);

                var payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);

                OkPayload.Create(payload);
                return(true);
            }
            catch (IOException)
            {
            }
            catch (SocketException)
            {
            }

            VerifyState(State.Failed);
            return(false);
        }
Beispiel #13
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)));
            }
        }
Beispiel #14
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)));
         }
     }
 }
Beispiel #15
0
 private void OnPingMessageReceived(PingPayload payload)
 {
     Context.Parent.Tell(payload);
     Context.Parent.Tell(Message.Create(MessageCommand.Pong, PingPayload.Create(Blockchain.Singleton.Height, payload.Nonce)));
 }