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); } } }
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); }
private void OnTimer() { SendMessage(Message.Create(MessageType.Ping, PingPayload.Create())); Interlocked.Exchange(ref tx_rate, tx_bytes / TimerInterval.TotalSeconds); tx_bytes = 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; }
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); }
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); }
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); }
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))); } } }
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); }
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); }
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(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))); } } }
private void OnPingMessageReceived(PingPayload payload) { Context.Parent.Tell(payload); Context.Parent.Tell(Message.Create(MessageCommand.Pong, PingPayload.Create(Blockchain.Singleton.Height, payload.Nonce))); }