예제 #1
0
        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);
            }
        }
예제 #2
0
 private API.Client CreateApi()
 {
     return(ApiFab.CreateReleaseApi(Network.GetById(Net).Ip));
 }
예제 #3
0
        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);
        }
예제 #4
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);
        }
예제 #5
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();
            }
        }