Beispiel #1
0
 public static byte[] EncodeNetworkAddressWithTime(NetworkAddressWithTime networkAddressWithTime)
 {
     using (var stream = new MemoryStream())
     using (var writer = new BinaryWriter(stream))
     {
         EncodeNetworkAddressWithTime(writer, networkAddressWithTime);
         return stream.ToArray();
     }
 }
Beispiel #2
0
 public static void EncodeNetworkAddressWithTime(BinaryWriter writer, NetworkAddressWithTime networkAddressWithTime)
 {
     writer.WriteUInt32(networkAddressWithTime.Time);
     EncodeNetworkAddress(writer, networkAddressWithTime.NetworkAddress);
 }
Beispiel #3
0
 public static void EncodeNetworkAddressWithTime(BinaryWriter writer, NetworkAddressWithTime networkAddressWithTime)
 {
     writer.WriteUInt32((uint)networkAddressWithTime.Time.ToUnixTimeSeconds()); //TODO is time LE or BE on network messages?
     EncodeNetworkAddress(writer, networkAddressWithTime.NetworkAddress);
 }
Beispiel #4
0
        private async Task ConnectAndHandshake(Peer peer)
        {
            peer.OnDisconnect += DisconnectPeer;
            if (peer.IsIncoming)
                Interlocked.Increment(ref this.incomingCount);

            // connect
            await peer.ConnectAsync();

            // notify peer is connected
            PeerConnected?.Invoke(peer);

            // setup task to wait for verack
            var verAckTask = peer.Receiver.WaitForMessage(x => x.Command == "verack", HANDSHAKE_TIMEOUT_MS);

            // setup task to wait for version
            var versionTask = peer.Receiver.WaitForMessage(x => x.Command == "version", HANDSHAKE_TIMEOUT_MS);

            // start listening for messages after tasks have been setup
            peer.Receiver.Listen();

            // send our local version
            var nodeId = random.NextUInt64(); //TODO should be generated and verified on version message

            var currentHeight = this.coreDaemon.CurrentChain.Height;
            await peer.Sender.SendVersion(Messaging.GetExternalIPEndPoint(), peer.RemoteEndPoint, nodeId, (UInt32)currentHeight);

            // wait for our local version to be acknowledged by the remote peer
            // wait for remote peer to send their version
            await Task.WhenAll(verAckTask, versionTask);

            //TODO shouldn't have to decode again
            var versionMessage = versionTask.Result;
            var versionPayload = NodeEncoder.DecodeVersionPayload(versionMessage.Payload.ToArray(), versionMessage.Payload.Length);

            var remoteAddressWithTime = new NetworkAddressWithTime
            (
                Time: DateTimeOffset.Now,
                NetworkAddress: new NetworkAddress
                (
                    Services: versionPayload.LocalAddress.Services,
                    IPv6Address: versionPayload.LocalAddress.IPv6Address,
                    Port: versionPayload.LocalAddress.Port
                )
            );

            // acknowledge their version
            await peer.Sender.SendVersionAcknowledge();
        }