internal async Task StartProtocolAsync() { if (!await SendMessageAsync("version", VersionPayload.Create(localNode.LocalEndpoint.Port, localNode.UserAgent, Blockchain.Default.Height))) return; Message message = await ReceiveMessageAsync(); if (message == null) return; if (message.Command != "version") { Disconnect(true); return; } try { Version = message.Payload.AsSerializable<VersionPayload>(); } catch (FormatException) { Disconnect(true); return; } if (RemoteEndpoint != null && RemoteEndpoint.Port != Version.Port) { Disconnect(true); return; } if (RemoteEndpoint == null) { IPEndPoint remoteEndpoint = new IPEndPoint(((IPEndPoint)tcp.Client.RemoteEndPoint).Address, Version.Port); lock (localNode.pendingPeers) { lock (localNode.connectedPeers) { if (localNode.pendingPeers.All(p => p.RemoteEndpoint != remoteEndpoint) && !localNode.connectedPeers.ContainsKey(remoteEndpoint)) { RemoteEndpoint = remoteEndpoint; } } } if (RemoteEndpoint == null) { Disconnect(false); return; } } if (!await SendMessageAsync("verack")) return; message = await ReceiveMessageAsync(); if (message == null) return; if (message.Command != "verack") { Disconnect(true); return; } lock (localNode.pendingPeers) { lock (localNode.connectedPeers) { localNode.connectedPeers.Add(RemoteEndpoint, this); } localNode.pendingPeers.Remove(this); } Thread thread = new Thread(ReceiveLoop); thread.Name = string.Format("ReceiveLoop@{0}", RemoteEndpoint); thread.Start(); }
internal async void StartProtocol() { if (!await SendMessageAsync("version", VersionPayload.Create(localNode.LocalEndpoint.Port, localNode.UserAgent, Blockchain.Default.Height))) return; Message message = await ReceiveMessageAsync(); if (message == null) return; if (message.Command != "version") { Disconnect(true); return; } try { Version = message.Payload.AsSerializable<VersionPayload>(); } catch (FormatException) { Disconnect(true); return; } if (RemoteEndpoint != null && RemoteEndpoint.Port != Version.Port) { Disconnect(true); return; } if (RemoteEndpoint == null) { IPEndPoint remoteEndpoint = new IPEndPoint(((IPEndPoint)tcp.Client.RemoteEndPoint).Address, Version.Port); lock (localNode.pendingPeers) { lock (localNode.connectedPeers) { if (localNode.pendingPeers.All(p => p.RemoteEndpoint != remoteEndpoint) && !localNode.connectedPeers.ContainsKey(remoteEndpoint)) { RemoteEndpoint = remoteEndpoint; } } } if (RemoteEndpoint == null) { Disconnect(false); return; } } if (!await SendMessageAsync("verack")) return; message = await ReceiveMessageAsync(); if (message == null) return; if (message.Command != "verack") { Disconnect(true); return; } lock (localNode.pendingPeers) { lock (localNode.connectedPeers) { localNode.connectedPeers.Add(RemoteEndpoint, this); } localNode.pendingPeers.Remove(this); } while (disposed == 0) { await CheckMissionsAsync(); message = await ReceiveMessageAsync(); if (message == null) break; try { await OnMessageReceivedAsync(message); } catch (FormatException) { Disconnect(true); break; } } }