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