public NetworkPeerStorage(string baseDirectory, ChainType chainType) : base(Path.Combine(baseDirectory, "KnownAddresses"), keyEncoder: key => NetworkEncoder.EncodeNetworkAddressKey(key), keyDecoder: key => NetworkEncoder.DecodeNetworkAddressKey(key), valueEncoder: value => NetworkEncoder.EncodeNetworkAddressWithTime(value), valueDecoder: value => NetworkEncoder.DecodeNetworkAddressWithTime(value)) { }
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 = NetworkEncoder.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(); }
private void OnGetHeaders(RemoteNode remoteNode, GetBlocksPayload payload) { // if in comparison mode, synchronize all work before returning current headers if (this.Type == LocalClientType.ComparisonToolTestNet) { this.blockchainDaemon.WaitForFullUpdate(); } var currentBlockchainLocal = this.blockchainDaemon.CurrentBlockchain; var blockHeaders = new List <BlockHeader>(currentBlockchainLocal.BlockCount); foreach (var chainedBlock in currentBlockchainLocal.BlockList) { BlockHeader blockHeader; if (this.blockchainDaemon.CacheContext.BlockHeaderCache.TryGetValue(chainedBlock.BlockHash, out blockHeader)) { blockHeaders.Add(blockHeader); } else { Debugger.Break(); Debug.WriteLine("Couldn't generate getheaders response"); return; } } var payloadStream = new MemoryStream(); using (var payloadWriter = new BinaryWriter(payloadStream)) { payloadWriter.WriteVarInt((UInt64)blockHeaders.Count); foreach (var blockHeader in blockHeaders) { NetworkEncoder.EncodeBlockHeader(payloadStream, blockHeader); payloadWriter.WriteVarInt(0); } } remoteNode.Sender.SendMessageAsync(Messaging.ConstructMessage("headers", payloadStream.ToArray())).Wait(); }
public void TestWireDecodeGetBlocksPayload() { var actual = NetworkEncoder.EncodeGetBlocksPayload(NetworkEncoder.DecodeGetBlocksPayload(GET_BLOCKS_PAYLOAD_1_BYTES.ToArray())); CollectionAssert.AreEqual(GET_BLOCKS_PAYLOAD_1_BYTES.ToList(), actual.ToList()); }
public void TestWireDecodeAlertPayload() { var actual = NetworkEncoder.EncodeAlertPayload(NetworkEncoder.DecodeAlertPayload(ALERT_PAYLOAD_1_BYTES.ToArray())); CollectionAssert.AreEqual(ALERT_PAYLOAD_1_BYTES.ToList(), actual.ToList()); }
public void TestWireDecodeVersionPayloadWithRelay() { var actual = NetworkEncoder.EncodeVersionPayload(NetworkEncoder.DecodeVersionPayload(VERSION_PAYLOAD_2_RELAY_BYTES.ToArray(), VERSION_PAYLOAD_2_RELAY_BYTES.Length), withRelay: true); CollectionAssert.AreEqual(VERSION_PAYLOAD_2_RELAY_BYTES.ToList(), actual.ToList()); }
public void TestWireEncodeVersionPayloadWithoutRelay() { var actual = NetworkEncoder.EncodeVersionPayload(VERSION_PAYLOAD_1_NO_RELAY, withRelay: false); CollectionAssert.AreEqual(VERSION_PAYLOAD_1_NO_RELAY_BYTES.ToList(), actual.ToList()); }
public void TestWireDecodeNetworkAddressWithTime() { var actual = NetworkEncoder.EncodeNetworkAddressWithTime(NetworkEncoder.DecodeNetworkAddressWithTime(NETWORK_ADDRESS_WITH_TIME_1_BYTES.ToArray())); CollectionAssert.AreEqual(NETWORK_ADDRESS_WITH_TIME_1_BYTES.ToList(), actual.ToList()); }
public void TestWireEncodeTransaction() { var actual = NetworkEncoder.EncodeTransaction(TRANSACTION_1); CollectionAssert.AreEqual(TRANSACTION_1_BYTES.ToList(), actual.ToList()); }
public void TestWireEncodeAddressPayload() { var actual = NetworkEncoder.EncodeAddressPayload(ADDRESS_PAYLOAD_1); CollectionAssert.AreEqual(ADDRESS_PAYLOAD_1_BYTES.ToList(), actual.ToList()); }
private async Task <bool> ConnectAndHandshake(RemoteNode remoteNode, bool isIncoming) { // wire node WireNode(remoteNode); // connect await remoteNode.ConnectAsync(); if (remoteNode.IsConnected) { //TODO RemoteNode ignore; this.pendingPeers.TryRemove(remoteNode.RemoteEndPoint, out ignore); this.connectedPeers.TryAdd(remoteNode.RemoteEndPoint, remoteNode); // setup task to wait for verack var verAckTask = remoteNode.Receiver.WaitForMessage(x => x.Command == "verack", HANDSHAKE_TIMEOUT_MS); // setup task to wait for version var versionTask = remoteNode.Receiver.WaitForMessage(x => x.Command == "version", HANDSHAKE_TIMEOUT_MS); // start listening for messages after tasks have been setup remoteNode.Receiver.Listen(); // send our local version var nodeId = (((UInt64)random.Next()) << 32) + (UInt64)random.Next(); //TODO should be generated and verified on version message var currentBlockchainLocal = this.blockchainDaemon.CurrentBlockchain; var currentHeight = !currentBlockchainLocal.IsDefault ? (UInt32)currentBlockchainLocal.Height : 0; await remoteNode.Sender.SendVersion(Messaging.GetExternalIPEndPoint(), remoteNode.RemoteEndPoint, nodeId, 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 = NetworkEncoder.DecodeVersionPayload(versionMessage.Payload.ToArray().ToMemoryStream(), versionMessage.Payload.Length); var remoteAddressWithTime = new NetworkAddressWithTime ( Time: DateTime.UtcNow.ToUnixTime(), NetworkAddress: new NetworkAddress ( Services: versionPayload.LocalAddress.Services, IPv6Address: versionPayload.LocalAddress.IPv6Address, Port: versionPayload.LocalAddress.Port ) ); if (!isIncoming) { this.knownAddressCache.UpdateValue(remoteAddressWithTime.GetKey(), remoteAddressWithTime); } // acknowledge their version await remoteNode.Sender.SendVersionAcknowledge(); return(true); } else { return(false); } }
public void TestWireDecodeBlock() { var actual = NetworkEncoder.EncodeBlock(NetworkEncoder.DecodeBlock(BLOCK_1_BYTES.ToArray().ToMemoryStream())); CollectionAssert.AreEqual(BLOCK_1_BYTES.ToList(), actual.ToList()); }
public void TestWireEncodeBlock() { var actual = NetworkEncoder.EncodeBlock(BLOCK_1); CollectionAssert.AreEqual(BLOCK_1_BYTES.ToList(), actual.ToList()); }
public void TestWireDecodeAddressPayload() { var actual = NetworkEncoder.EncodeAddressPayload(NetworkEncoder.DecodeAddressPayload(ADDRESS_PAYLOAD_1_BYTES.ToArray().ToMemoryStream())); CollectionAssert.AreEqual(ADDRESS_PAYLOAD_1_BYTES.ToList(), actual.ToList()); }
public void TestWireDecodeTransaction() { var actual = NetworkEncoder.EncodeTransaction(NetworkEncoder.DecodeTransaction(TRANSACTION_1_BYTES.ToArray().ToMemoryStream())); CollectionAssert.AreEqual(TRANSACTION_1_BYTES.ToList(), actual.ToList()); }
public void TestWireDecodeInventoryPayload() { var actual = NetworkEncoder.EncodeInventoryPayload(NetworkEncoder.DecodeInventoryPayload(INVENTORY_PAYLOAD_1_BYTES.ToArray())); CollectionAssert.AreEqual(INVENTORY_PAYLOAD_1_BYTES.ToList(), actual.ToList()); }
public void TestWireDecodeInventoryVector() { var actual = NetworkEncoder.EncodeInventoryVector(NetworkEncoder.DecodeInventoryVector(INVENTORY_VECTOR_1_BYTES.ToArray())); CollectionAssert.AreEqual(INVENTORY_VECTOR_1_BYTES.ToList(), actual.ToList()); }
public void TestWireEncodeNetworkAddress() { var actual = NetworkEncoder.EncodeNetworkAddress(NETWORK_ADDRESS_1); CollectionAssert.AreEqual(NETWORK_ADDRESS_1_BYTES.ToList(), actual.ToList()); }
public void TestWireDecodeMessage() { var actual = NetworkEncoder.EncodeMessage(NetworkEncoder.DecodeMessage(MESSAGE_1_BYTES.ToArray())); CollectionAssert.AreEqual(MESSAGE_1_BYTES.ToList(), actual.ToList()); }
public void TestWireDecodeNetworkAddress() { var actual = NetworkEncoder.EncodeNetworkAddress(NetworkEncoder.DecodeNetworkAddress(NETWORK_ADDRESS_1_BYTES.ToArray().ToMemoryStream())); CollectionAssert.AreEqual(NETWORK_ADDRESS_1_BYTES.ToList(), actual.ToList()); }