private async Task Peer_OnMessage(BitcoinPeer s, IStreamable msg) { switch (msg) { case Addr a: { foreach (var ip in a.Ips) { var ep = new IPEndPoint(ip.Ip.MapToIPv6(), ip.Port); var epb = ep.ToByteArray(); if (!await db.SetContainsAsync("hs:nodes:good-nodes", epb) && !await db.SetContainsAsync("hs:nodes:bad-nodes", epb)) { QueueNewNode(ep); } } break; } case Ping a: { var pong = new Pong(); pong.Nonce = a.Nonce; await s.WriteMessage(pong); break; } case bitcoin_lib.P2P.Version a: { GotVersion = true; //send verack and log await SetNodeDetails(a); var va = new VerAck(); await s.WriteMessage(va); var ga = new GetAddr(); await s.WriteMessage(ga); break; } } }
public async Task UpdateNodeInfo(Node n) { //Console.WriteLine($"Update node info: {n.IP}"); try { //try to connect to the node to get version info and to get its peers var ns = new Socket(SocketType.Stream, ProtocolType.Tcp); await ns.ConnectAsync(n.IP); var p = new BitcoinPeer(ns); //Console.WriteLine($"Connected to {n.IP}"); var ss = new SemaphoreSlim(0, 1); var db = Redis.GetDatabase(); p.OnVersion += async(s, v) => { //send verack and log var ip = new IPEndPoint(((IPEndPoint)s.RemoteEndpoint).Address.MapToIPv6(), ((IPEndPoint)s.RemoteEndpoint).Port); var ipb = ip.ToByteArray(); await db.HashSetAsync($"hs:nodes:detail:{ip.ToString()}", "version", v.ToArray()); if (await db.SortedSetAddAsync("hs:nodes:all-nodes", ipb, DateTime.Now.Ticks)) { //Console.WriteLine($"Got new node: {ip}"); await db.SetRemoveAsync("hs:nodes:new-nodes", ipb); var gloc = GeoIp.City(ip.Address); if (gloc.Location.HasCoordinates) { await db.GeoAddAsync("hs:nodes:geo", new GeoEntry(gloc.Location.Longitude.Value, gloc.Location.Latitude.Value, ipb)); } } var va = new VerAck(); await s.WriteMessage(va); var ga = new GetAddr(); await s.WriteMessage(ga); }; p.OnAddr += async(s, a) => { //Console.WriteLine($"Got {a.IpCount.Value} ips"); foreach (var ip in a.Ips) { var ep = new IPEndPoint(ip.Ip.MapToIPv6(), ip.Port); var epb = ep.ToByteArray(); if (await db.SetAddAsync("hs:nodes:new-nodes", epb)) { //Console.WriteLine($"Got new node: {ep}"); } } s.Stop(); ss.Release(); //Console.WriteLine($"Disconnected from {n.IP}"); }; p.Start(); Ver.Timestamp = (UInt64)DateTimeOffset.Now.ToUnixTimeSeconds(); await p.WriteMessage(Ver); await ss.WaitAsync(TimeSpan.FromSeconds(5)); } catch (Exception ex) { //Console.WriteLine(ex); } }