示例#1
0
        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;
            }
            }
        }
示例#2
0
        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);
            }
        }