public async Task InvokeAsync(HttpContext context) { var token = context.Request.Path.ToString(); if (!context.Request.IsHttps && token.EndsWith("/getLastBlock", StringComparison.InvariantCultureIgnoreCase)) { var net = Network.GetById(token.Split('/')[1]); if (net == null) { context.Response.Redirect("/"); return; } using (var client = ApiFab.CreateReleaseApi(net.Ip)) { var pools = client.PoolListGet(0, 1); context.Response.StatusCode = 200; await context.Response.WriteAsync(pools.Pools[0].PoolNumber.ToString()); } } else { await _next.Invoke(context); } }
private API.Client CreateApi() { return(ApiFab.CreateReleaseApi(Network.GetById(Net).Ip)); }
private void OnCacheTimer(object state) { var tpState = (IndexServiceState)state; try { if (tpState.Net.Api.EndsWith("/Api")) { using (var client = ApiFab.CreateNodeApi(tpState.Net.Ip)) { // Service available if (tpState.Net.Updating) { tpState.Net.Updating = false; } // Request blocks if ((!tpState.PoolsOut.Any() && !tpState.PoolsIn.Any())) { var result = client.PoolListGet(0, SizeOut); tpState.PoolsOut = result.Pools.Select(p => new PoolInfo(p)).ToList(); } else { var result = client.PoolListGet(0, 20); lock (tpState.PoolsLock) { var firstPoolNum = tpState.PoolsIn.Any() ? tpState.PoolsIn[0].Number : tpState.PoolsOut[0].Number; var nPools = result.Pools.TakeWhile(p => (p.PoolNumber > firstPoolNum) || (p.PoolNumber < firstPoolNum - 1000)).Select(p => new PoolInfo(p)).ToList(); tpState.PoolsIn = nPools.Concat(tpState.PoolsIn).ToList(); } } // Request stats if (tpState.StatRequestCounter == 0) { var stats = client.StatsGet(); if (stats != null && stats.Stats.Count >= 4) { var statsSorted = stats.Stats.OrderBy(s => s.PeriodDuration).ToList(); var statData = new StatData(); for (var i = 0; i < 4; i++) { statData.Pdata[i] = new PeriodData(statsSorted[i]); } tpState.StatData = statData; } } } } else if (tpState.Net.Api.EndsWith("/TestApi")) { using (var client = ApiFab.CreateTestApi(tpState.Net.Ip)) { // Service available if (tpState.Net.Updating) { tpState.Net.Updating = false; } // Request blocks if ((!tpState.PoolsOut.Any() && !tpState.PoolsIn.Any())) { var result = client.PoolListGet(0, SizeOut); tpState.PoolsOut = result.Pools.Where(p => p.PoolNumber > 0).Select(p => new PoolInfo(p)).ToList(); } else { var result = client.PoolListGet(0, 20); lock (tpState.PoolsLock) { var firstPoolNum = tpState.PoolsIn.Any() ? tpState.PoolsIn[0].Number : tpState.PoolsOut[0].Number; var nPools = result.Pools.Where(p => p.PoolNumber > 0).TakeWhile(p => (p.PoolNumber > firstPoolNum) || (p.PoolNumber < firstPoolNum - 1000)).Select(p => new PoolInfo(p)).ToList(); tpState.PoolsIn = nPools.Concat(tpState.PoolsIn).ToList(); } } // Request stats if (tpState.StatRequestCounter == 0) { var stats = client.StatsGet(); if (stats != null && stats.Stats.Count >= 4) { var statsSorted = stats.Stats.OrderBy(s => s.PeriodDuration).ToList(); var statData = new StatData(); for (var i = 0; i < 4; i++) { statData.Pdata[i] = new PeriodData(statsSorted[i]); } tpState.StatData = statData; } } } } else if (tpState.Net.Api.EndsWith("/ReleaseApi")) { using (var client = ApiFab.CreateReleaseApi(tpState.Net.Ip)) { // Service available if (tpState.Net.Updating) { tpState.Net.Updating = false; } // Request blocks if ((!tpState.PoolsOut.Any() && !tpState.PoolsIn.Any())) { var result = client.PoolListGet(0, SizeOut); tpState.PoolsOut = result.Pools.Where(p => p.PoolNumber > 0).Select(p => new PoolInfo(p)).ToList(); } else { var result = client.PoolListGet(0, 20); var firstPoolNum = tpState.PoolsIn.Any() ? tpState.PoolsIn[0].Number : tpState.PoolsOut[0].Number; var newPools = result.Pools .Where(p => p.PoolNumber > 0) .TakeWhile(p => p.PoolNumber > firstPoolNum || p.PoolNumber < firstPoolNum - 1000) .Select(p => new PoolInfo(p)).ToList(); lock (tpState.PoolsLock) tpState.PoolsIn = newPools.Concat(tpState.PoolsIn).ToList(); } // Request stats if (tpState.StatRequestCounter == 0) { var stats = client.StatsGet(); if (stats != null && stats.Stats.Count >= 4) { var statsSorted = stats.Stats.OrderBy(s => s.PeriodDuration).ToList(); var statData = new StatData(); for (var i = 0; i < 4; i++) { statData.Pdata[i] = new PeriodData(statsSorted[i]); } tpState.StatData = statData; } } } } if (tpState.StatRequestCounter < Settings.UpdStatsPeriodSec * 1000 / Period) { tpState.StatRequestCounter++; } else { tpState.StatRequestCounter = 0; } } catch (Thrift.Transport.TTransportException e) { tpState.Net.Updating = true; _logger.LogError(e, ""); } catch (Exception e) { _logger.LogError(e, ""); } tpState.TimerForCache.Change(Period, 0); }
private void OnCacheTimer(object state) { var tpState = (IndexServiceState)state; try { using (var client = ApiFab.CreateReleaseApi(tpState.Net.Ip)) { // Service available if (tpState.Net.Updating) { tpState.Net.Updating = false; } // Request blocks if (!tpState.PoolsOut.Any() && !tpState.PoolsIn.Any()) { var result = client.PoolListGet(0, SizeOut); tpState.PoolsOut = result.Pools.Where(p => p.PoolNumber > 0).Select(p => new BlockInfo(p)).ToList(); } else { // Get last 20 blocks from API var result = client.PoolListGet(0, 20); // Get last block number (first from the top) var firstPoolNum = tpState.PoolsIn.Any() ? tpState.PoolsIn[0].Number : tpState.PoolsOut[0].Number; // Network reset detection var newNetWorkPools = result.Pools .Count(p => p.PoolNumber > 0 && p.PoolNumber < firstPoolNum - 200); // Reset cache, if network reset if (newNetWorkPools > 0) { lock (tpState.PoolsLock) { tpState.PoolsOut = new List <BlockInfo>(); tpState.PoolsIn = new List <BlockInfo>(); } firstPoolNum = 0; // Delete Transactions per second statistics data TpsService.Reset(tpState.Net.Id); } // Prepare list of new blocks var newPools = result.Pools .Where(p => p.PoolNumber > 0) .TakeWhile(p => p.PoolNumber > firstPoolNum).ToList(); // Get Txs of new blocks var newTx = new List <TransactionInfo>(); foreach (var pool in newPools) { var poolTr = client.PoolTransactionsGet(pool.Hash, 0, BlockTxLimit); var newPoolTx = poolTr.Transactions.Select((t, i) => new TransactionInfo(i, t.Id, t.Trxn) { Color = (int)(pool.PoolNumber % 10) }).ToList(); newTx = newPoolTx.Concat(newTx).ToList(); } // Append new blocks and txs to the input cache lock (tpState.PoolsLock) { tpState.PoolsIn = newPools.Select(p => new BlockInfo(p)).Concat(tpState.PoolsIn).ToList(); tpState.TxIn = newTx.Concat(tpState.TxIn).ToList(); } } // Request stats if (tpState.StatRequestCounter == 0) { var stats = client.StatsGet(); if (stats != null && stats.Stats.Count >= 4) { var statsSorted = stats.Stats.OrderBy(s => s.PeriodDuration).ToList(); var statData = new StatData(); for (var i = 0; i < 4; i++) { statData.Pdata[i] = new PeriodData(statsSorted[i]); } //statData.CorrectTotalValue(); tpState.StatData = statData; } } } // Increment statistics time counter (or reset if it's time) if (tpState.StatRequestCounter < Settings.UpdStatsPeriodSec * 1000 / Period) { tpState.StatRequestCounter++; } else { tpState.StatRequestCounter = 0; } } catch (Thrift.Transport.TTransportException e) { // Set up network updating flag in case of no connection to the node tpState.Net.Updating = true; _logger.LogError(e, ""); } catch (Exception e) { // Log other errors _logger.LogError(e, ""); } // Set up next timer tick tpState.TimerForCache.Change(Period, 0); }
// Updates the list of nodes, from signal server private async Task UpdateNetworkNodes(Network network) { // Create a connection to the signal server API using (var client = ApiFab.CreateSignalApi(network.SignalIp, network.SignalPort)) { // Get the list of nodes from API var result = client.GetActiveNodes(); // Convert nodes to nodeInfos var nodes = result.Nodes.Select(n => new NodeInfo(n)).ToList(); // Try to get country and geo-location for all nodes try { // Connect to DB using (var db = CsmonDbContext.Create()) { // Get nodes, stored in db var dbNodes = db.Nodes.Where(n => n.Network == network.Id).ToList(); // Add new nodes into db and update existing foreach (var node in nodes) { var dbNode = dbNodes.FirstOrDefault(n => n.PublicKey.Equals(node.PublicKey)); if (dbNode == null) { db.Nodes.Add(new Node(node, network.Id)); } else if (!node.EqualsDbNode(dbNode)) { db.Nodes.Update(node.UpdateDbNode(dbNode)); } } db.SaveChanges(); // Get Non-Active nodes from db foreach (var node in dbNodes.Where(n => !nodes.Any(d => d.PublicKey.Equals(n.PublicKey)))) { nodes.Add(new NodeInfo(node)); } // Find geo data for nodes foreach (var ip in nodes.Select(n => n.Ip).Distinct()) { // Try to find node in db by ip address var location = db.Locations.FirstOrDefault(l => l.Ip.Equals(ip)); // If not found, try to get info by ip using ipapi.co web service if (location == null) { try { var uri = new Uri("https://ipapi.co/" + $"{ip}/json/"); var nodeStr = await GetAsync(uri); nodeStr = nodeStr.Replace("\"latitude\": null,", ""); nodeStr = nodeStr.Replace("\"longitude\": null,", ""); location = JsonConvert.DeserializeObject <Location>(nodeStr); location.Ip = ip; if (location.Org.Length > 64) { location.Org = location.Org.Substring(0, 64); } // Store data in db db.Locations.Add(location); db.SaveChanges(); } catch (Exception e) { _logger.LogError(e, ""); continue; } } // Set location data to nodes foreach (var nodeInfo in nodes.Where(n => n.Ip.Equals(ip))) { nodeInfo.SetLocation(location); } } } } catch (Exception e) { _logger.LogError(e, ""); } // Collect additional info about nodes from the network try { using (var cnt = ApiFab.CreateReleaseApi(network.Ip)) { var page = 0; while (true) { var writers = cnt.WritersGet(page++); if (!writers.Writers.Any()) { break; } foreach (var writer in writers.Writers) { var key = Base58Encoding.Encode(writer.Address); var node = nodes.FirstOrDefault(n => n.PublicKey == key); if (node == null) { continue; } node.TotalFee = ConvUtils.FormatAmount(writer.FeeCollected); node.TimesWriter = writer.TimesWriter; } } } } catch (Exception e) { _logger.LogError(e, ""); } // Hide Ip addresses before output foreach (var nodeInfo in nodes) { nodeInfo.HideIp(); } // Put the ordered list into the storage _states[network.Id].Nodes = nodes.OrderByDescending(n => n.Active).ThenBy(n => n.Ip).ToList(); } }