コード例 #1
0
        private async Task Peer_OnVersion(BitcoinPeer s, bitcoin_lib.P2P.Version v)
        {
            var va = new VerAck();
            await s.WriteMessage(va);

            Console.WriteLine($"Client connected {v.UserAgent}");
        }
コード例 #2
0
        public ReadOnlySpan <byte> ReadFromPayload(ReadOnlySpan <byte> data)
        {
            var next = data.ReadAndSlice(out IPAddress oIp)
                       .ReadAndSlice(out UInt16 oPort)
                       .ReadAndSlice(out Int64 oLastSeen)
                       .ReadAndSlice(out bitcoin_lib.P2P.Version oVersion);

            Ip          = new IPEndPoint(oIp, oPort);
            LastSeen    = new DateTime(oLastSeen);
            LastVersion = oVersion;

            return(next);
        }
コード例 #3
0
        public async Task <bitcoin_lib.P2P.Version> GetNodeDetails()
        {
            var ret = new bitcoin_lib.P2P.Version("");
            var ipb = IP.ToByteArray();
            var rv  = await db.HashGetAsync($"hs:nodes:detail:{IP.ToString()}", "version");

            if (rv.HasValue)
            {
#if NETCOREAPP2_1
                ret.ReadFromPayload(((byte[])rv).AsSpan());
#else
                ret.ReadFromPayload(rv, 0);
#endif
            }

            return(ret);
        }
コード例 #4
0
        public NodeScraper()
        {
            ThreadPool.SetMinThreads(MaxPoll, 20);
            GeoIp = new MaxMind.GeoIP2.DatabaseReader("GeoLite2-City.mmdb");
            Redis = ConnectionMultiplexer.Connect("localhost");

            Ver = new bitcoin_lib.P2P.Version($"https://nodes.hashstream.net/");
            var nd = new byte[9];

            new Random().NextBytes(nd);
            Ver.Nonce         = BitConverter.ToUInt64(nd, 0);
            Ver.RecvServices  = 0;
            Ver.StartHeight   = 0;
            Ver.TransIp       = Ver.RecvIp = IPAddress.None;
            Ver.TransPort     = Ver.RecvPort = 0;
            Ver.TransServices = Ver.RecvServices = (UInt64)Services.Unknown;
        }
コード例 #5
0
        public BitcoinNodePeer(BitcoinPeer p)
        {
            Peer                = p;
            Peer.OnAddr        += Peer_OnAddr;
            Peer.OnAlert       += Peer_OnAlert;
            Peer.OnFeeFilter   += Peer_OnFeeFilter;
            Peer.OnFilterAdd   += Peer_OnFilterAdd;
            Peer.OnFilterClear += Peer_OnFilterClear;
            Peer.OnFilterLoad  += Peer_OnFilterLoad;
            Peer.OnGetAddr     += Peer_OnGetAddr;
            Peer.OnGetBlocks   += Peer_OnGetBlocks;
            Peer.OnGetData     += Peer_OnGetData;
            Peer.OnGetHeaders  += Peer_OnGetHeaders;
            Peer.OnHeaders     += Peer_OnHeaders;
            Peer.OnInv         += Peer_OnInv;
            Peer.OnMemPool     += Peer_OnMemPool;
            Peer.OnNotFound    += Peer_OnNotFound;
            Peer.OnPing        += Peer_OnPing;
            Peer.OnPong        += Peer_OnPong;
            Peer.OnReject      += Peer_OnReject;
            Peer.OnSendHeaders += Peer_OnSendHeaders;
            Peer.OnVerAck      += Peer_OnVerAck;
            Peer.OnVersion     += Peer_OnVersion;

            Peer.Start();

            //Send version
            Ver = new bitcoin_lib.P2P.Version($"/hashstream:0.0.1-alpha/");
            var nd = new byte[9];

            new Random().NextBytes(nd);
            Ver.Nonce         = BitConverter.ToUInt64(nd, 0);
            Ver.RecvIp        = ((IPEndPoint)Peer.RemoteEndpoint).Address;
            Ver.RecvPort      = (UInt16)((IPEndPoint)Peer.RemoteEndpoint).Port;
            Ver.RecvServices  = 0;
            Ver.StartHeight   = 0;
            Ver.Timestamp     = (UInt64)DateTimeOffset.Now.ToUnixTimeSeconds();
            Ver.TransIp       = IPAddress.None;
            Ver.TransPort     = 0;
            Ver.TransServices = (UInt64)Services.NODE_NETWORK;

            Peer.WriteMessage(Ver);
        }
コード例 #6
0
        public async Task <bool> SetNodeDetails(bitcoin_lib.P2P.Version v)
        {
            var ipb = IP.ToByteArray();

            await SetAsGoodNode();

            if (await db.HashSetAsync($"hs:nodes:detail:{IP.ToString()}", "version", v.ToArray()))
            {
                await db.HashSetAsync($"hs:nodes:detail:{IP.ToString()}", "first_seen", DateTime.Now.Ticks);

                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));
                }

                return(true);
            }
            return(false);
        }
コード例 #7
0
        public Node(ConnectionMultiplexer redis, Action <IPEndPoint> nq, DatabaseReader geo, IPEndPoint ip)
        {
            IP = ip;

            Ver = new bitcoin_lib.P2P.Version($"https://nodes.hashstream.net/");
            var nd = new byte[9];

            new Random().NextBytes(nd);
            Ver.Nonce         = BitConverter.ToUInt64(nd, 0);
            Ver.RecvServices  = 0;
            Ver.StartHeight   = 0;
            Ver.TransIp       = Ver.RecvIp = IPAddress.None;
            Ver.TransPort     = Ver.RecvPort = 0;
            Ver.TransServices = Ver.RecvServices = (UInt64)Services.NODE_NONE;
            Ver.Relay         = false; //no need for them to send new tx / blocks since we only want to map the network

            QueueNewNode = nq;
            this.db      = redis.GetDatabase();
            this.GeoIp   = geo;
        }
コード例 #8
0
        public async Task SendVersion()
        {
            //Send version
            var v  = new bitcoin_lib.P2P.Version(Peer.ChainParams.UserAgent);
            var nd = new byte[9];

            new Random().NextBytes(nd);

            v.HighestVersion = Peer.ChainParams.Version;
            v.Services       = Peer.ChainParams.Services;
            v.Nonce          = BitConverter.ToUInt64(nd, 0);
            v.RecvIp         = ((IPEndPoint)Peer.RemoteEndpoint).Address;
            v.RecvPort       = (UInt16)((IPEndPoint)Peer.RemoteEndpoint).Port;
            v.RecvServices   = 0;
            v.StartHeight    = 0;
            v.Timestamp      = (UInt64)DateTimeOffset.Now.ToUnixTimeSeconds();
            v.TransIp        = IPAddress.None;
            v.TransPort      = 0;
            v.TransServices  = Peer.ChainParams.Services;
            v.Relay          = true;

            await WriteMessage(v);
        }
コード例 #9
0
ファイル: BitcoinPeer.cs プロジェクト: xbluckly/bitcoin-lib
        private async Task ReadStream()
        {
            while (!Closing)
            {
                try
                {
                    //try to read a header
                    var hdata = new byte[24];
                    await Stream.ReadAsyncExact(hdata, 0, hdata.Length);

                    var h = new MessageHeader();
                    h.ReadFromPayload(hdata, 0);
                    if (h != null)
                    {
                        //read the payload
                        var pl = new byte[h.PayloadSize];
                        await Stream.ReadAsyncExact(pl, 0, pl.Length);

                        bool checksumOk = false;

                        //verify hash
                        using (var sha = SHA256.Create())
                        {
                            var h1 = sha.ComputeHash(pl);
                            var h2 = sha.ComputeHash(h1);

                            checksumOk = h2[0] == h.Checksum[0] && h2[1] == h.Checksum[1] && h2[2] == h.Checksum[2] && h2[3] == h.Checksum[3];
                        }

                        if (checksumOk)
                        {
                            switch (h.Command)
                            {
                            case "addr\0\0\0\0\0\0\0\0":
                            {
                                if (OnAddr != null)
                                {
                                    var a = new Addr();
                                    a.ReadFromPayload(pl, 0);

                                    await OnAddr?.Invoke(this, a);
                                }
                                break;
                            }

                            case "alert\0\0\0\0\0\0\0":
                            {
                                if (OnAlert != null)
                                {
                                    var a = new Alert();
                                    a.ReadFromPayload(pl, 0);

                                    await OnAlert?.Invoke(this, a);
                                }
                                break;
                            }

                            case "feefilter\0\0\0":
                            {
                                if (OnFeeFilter != null)
                                {
                                    var f = new FeeFilter();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFeeFilter?.Invoke(this, f);
                                }
                                break;
                            }

                            case "filteradd\0\0\0":
                            {
                                if (OnFilterAdd != null)
                                {
                                    var f = new FilterAdd();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFilterAdd?.Invoke(this, f);
                                }
                                break;
                            }

                            case "filterclear\0":
                            {
                                if (OnFilterClear != null)
                                {
                                    var f = new FilterClear();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFilterClear?.Invoke(this, f);
                                }
                                break;
                            }

                            case "filterload\0\0":
                            {
                                if (OnFilterLoad != null)
                                {
                                    var f = new FilterLoad();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFilterLoad?.Invoke(this, f);
                                }
                                break;
                            }

                            case "getaddr\0\0\0\0\0":
                            {
                                if (OnGetAddr != null)
                                {
                                    var ga = new GetAddr();
                                    ga.ReadFromPayload(pl, 0);

                                    await OnGetAddr?.Invoke(this, ga);
                                }
                                break;
                            }

                            case "getblocks\0\0\0":
                            {
                                if (OnGetBlocks != null)
                                {
                                    var gb = new GetBlocks();
                                    gb.ReadFromPayload(pl, 0);

                                    await OnGetBlocks?.Invoke(this, gb);
                                }
                                break;
                            }

                            case "getdata\0\0\0\0\0":
                            {
                                if (OnGetData != null)
                                {
                                    var gd = new GetData();
                                    gd.ReadFromPayload(pl, 0);

                                    await OnGetData?.Invoke(this, gd);
                                }
                                break;
                            }

                            case "getheaders\0\0":
                            {
                                if (OnGetHeaders != null)
                                {
                                    var gh = new GetHeaders();
                                    gh.ReadFromPayload(pl, 0);

                                    await OnGetHeaders?.Invoke(this, gh);
                                }
                                break;
                            }

                            case "headers\0\0\0\0\0":
                            {
                                if (OnHeaders != null)
                                {
                                    var hd = new Headers();
                                    hd.ReadFromPayload(pl, 0);

                                    await OnHeaders?.Invoke(this, hd);
                                }
                                break;
                            }

                            case "inv\0\0\0\0\0\0\0\0\0":
                            {
                                if (OnInv != null)
                                {
                                    var iv = new Inv();
                                    iv.ReadFromPayload(pl, 0);

                                    await OnInv?.Invoke(this, iv);
                                }
                                break;
                            }

                            case "mempool\0\0\0\0\0":
                            {
                                if (OnMemPool != null)
                                {
                                    var mp = new MemPool();
                                    mp.ReadFromPayload(pl, 0);

                                    await OnMemPool?.Invoke(this, mp);
                                }
                                break;
                            }

                            case "notfound\0\0\0\0":
                            {
                                if (OnNotFound != null)
                                {
                                    var nf = new NotFound();
                                    nf.ReadFromPayload(pl, 0);

                                    await OnNotFound?.Invoke(this, nf);
                                }
                                break;
                            }

                            case "ping\0\0\0\0\0\0\0\0":
                            {
                                if (OnPing != null)
                                {
                                    var ping = new Ping();
                                    ping.ReadFromPayload(pl, 0);

                                    await OnPing?.Invoke(this, ping);
                                }
                                break;
                            }

                            case "pong\0\0\0\0\0\0\0\0":
                            {
                                if (OnPong != null)
                                {
                                    var pong = new Pong();
                                    pong.ReadFromPayload(pl, 0);

                                    await OnPong?.Invoke(this, pong);
                                }
                                break;
                            }

                            case "reject\0\0\0\0\0\0":
                            {
                                if (OnReject != null)
                                {
                                    var re = new Reject();
                                    re.ReadFromPayload(pl, 0);

                                    await OnReject?.Invoke(this, re);
                                }
                                break;
                            }

                            case "sendheaders\0":
                            {
                                if (OnSendHeaders != null)
                                {
                                    var sh = new SendHeaders();
                                    sh.ReadFromPayload(pl, 0);

                                    await OnSendHeaders?.Invoke(this, sh);
                                }
                                break;
                            }

                            case "verack\0\0\0\0\0\0":
                            {
                                if (OnVerAck != null)
                                {
                                    var va = new VerAck();
                                    va.ReadFromPayload(pl, 0);

                                    await OnVerAck.Invoke(this, va);
                                }
                                break;
                            }

                            case "version\0\0\0\0\0":
                            {
                                if (OnVersion != null)
                                {
                                    var v = new bitcoin_lib.P2P.Version("");
                                    v.ReadFromPayload(pl, 0);

                                    await OnVersion?.Invoke(this, v);
                                }
                                break;
                            }

                            default:
                            {
                                //Console.WriteLine($"Got cmd: {h.Command}");
                                break;
                            }
                            }
                        }
                        else
                        {
                            Closing = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Closing = true;
                }
            }
        }