public static BitcoinVersionPayload CreateVersionPayload(string userAgent, byte[] nonce, IPEndPoint sender, IPEndPoint receiver) { var now = DateTimeOffset.UtcNow; var bitcoinVersionPayload = new BitcoinVersionPayload( new BitcoinVarString(userAgent), nonce, new BitcoinNetworkAddressPayload(now, ChatClientConfiguration.PeerServices, sender.Address, sender.Port), new BitcoinNetworkAddressPayload(now, PeerServices.Network, receiver.Address, receiver.Port)); return(bitcoinVersionPayload); }
public async Task VersionHandshakeAsync(string userAgent, byte[] nonce, CancellationToken cancellationToken) { try { BitcoinVersionPayload outgoingVersionPayload = PayloadFactory.CreateVersionPayload(userAgent, nonce, (IPEndPoint)this._tcpClient.Client.LocalEndPoint, (IPEndPoint)this._tcpClient.Client.RemoteEndPoint); var myVersionMessage = new BitcoinMessage("version", outgoingVersionPayload.Serialize()); this._logger.LogInformation("Sending own version."); await WriteAsync(myVersionMessage.Serialize()); this._logger.LogInformation("'version' sent."); // do it like this so that there is no specific expected order for version and verack, but expect both. while (this.PeerVersionPayload == null || this.PeerVerAckReceived == false) { var reply = await ReadMessageAsync(cancellationToken); if (reply.Command == "version") { this.PeerVersionPayload = new BitcoinVersionPayload(reply.PayloadBytes); this._logger.LogInformation( $"Version payload decoded from {this.PeerVersionPayload.UserAgent.Text} at {this.PeerVersionPayload.Sender}."); this._logger.LogInformation($"Setting own address to {this.PeerVersionPayload.Receiver}."); this.SelfFromPeer = this.PeerVersionPayload.Receiver.ToPeer(); this._logger.LogInformation("Sending version acknowledgement."); await WriteAsync(new BitcoinMessage("verack", new byte[0]).Serialize()); this._logger.LogInformation("'verack' sent."); } else if (reply.Command == "verack") { this.PeerVerAckReceived = true; } else { throw new InvalidOperationException( $"Received unexpected message '{reply.Command}' during handshake."); } } } catch (Exception e) { DisposeAndThrow(e); } }