private static List <LnChannelConnectionPoints> GetChanHist(LndRpcClient lndClient, CoinpanicContext db, Channel c) { List <LnChannelConnectionPoints> chanHist; Int64 otherchanId = Convert.ToInt64(c.chan_id); var ch = db.LnChannelHistory.Where(h => h.ChanId == otherchanId); if (ch.Count() > 0) { // already known - check status chanHist = ch.OrderByDescending(h => h.Timestamp).AsNoTracking().ToList(); } else { LnNode remoteNode = GetOrCreateNode(lndClient, c.remote_pubkey, db); // new channel history LnChannelConnectionPoints newChanHist = new LnChannelConnectionPoints() { IsConnected = c.active, LocalBalance = Convert.ToInt64(c.local_balance), RemoteBalance = Convert.ToInt64(c.remote_balance), Timestamp = DateTime.UtcNow, RemoteNode = remoteNode, ChanId = Convert.ToInt64(c.chan_id), }; db.LnChannelHistory.Add(newChanHist); db.SaveChanges(); chanHist = new List <LnChannelConnectionPoints>() { newChanHist }; } return(chanHist); }
public ActionResult NodeChannels() { if (DateTime.Now - LastNodeChannelsUpdate > StatusCacheTimeout) { Guid taskid = Guid.NewGuid(); UpdateTask updateTask = new UpdateTask() { id = taskid, task = new Task(() => { try { bool useTestnet = GetUseTestnet(); LndRpcClient lndClient = GetLndClient(useTestnet); string pubkey = nodeURIViewModel.Node_Pubkey; if (pubkey == "") // If not already known { var info = lndClient.GetInfo(); pubkey = info.identity_pubkey; nodeURIViewModel.URI = info.uris.First(); nodeURIViewModel.Alias = info.alias; nodeURIViewModel.Node_Pubkey = info.identity_pubkey; } var channels = lndClient.GetChannels(); nodeChannelViewModel.channels = new List <LnChannelInfoModel>(); // Clear cache using (CoinpanicContext db = new CoinpanicContext()) { LnNode myNode = GetOrCreateNode(lndClient, nodeURIViewModel.Node_Pubkey, db); //Check each channel foreach (var c in channels.channels) { LnChannelInfoModel channelViewModel = new LnChannelInfoModel(); // Check if this is a new channel if (myNode.Channels.Where(ch => ch.ChannelId == c.chan_id).Count() < 1) { try { LnChannel thisChannel = GetOrCreateChannel(lndClient, db, c); if (thisChannel != null && !myNode.Channels.Contains(thisChannel)) { myNode.Channels.Add(thisChannel); db.SaveChanges(); } } catch (Exception e) { // TODO - manage errors reading channels LnChannel thisChannel = null; } } // Check if there is a history for the channel //List<LnChannelConnectionPoints> chanHist = GetChanHist(lndClient, db, c); DateTime cutoff = DateTime.UtcNow - TimeSpan.FromDays(30); Int64 otherchanid = Convert.ToInt64(c.chan_id); channelViewModel.History = db.LnChannelHistory .Where(ch => ch.ChanId == otherchanid) .Where(ch => ch.Timestamp > cutoff) .OrderByDescending(ch => ch.Timestamp) .Include("RemoteNode") .Take(30) .AsNoTracking() .ToList(); LnChannelConnectionPoints prevChanHist; if (channelViewModel.History.Count() > 0) { prevChanHist = channelViewModel.History.First(); } else { prevChanHist = new LnChannelConnectionPoints() { Timestamp = DateTime.UtcNow, }; } // check for changes if (prevChanHist.IsConnected != c.active || prevChanHist.LocalBalance != Convert.ToInt64(c.local_balance) || prevChanHist.RemoteBalance != Convert.ToInt64(c.remote_balance) || DateTime.UtcNow - prevChanHist.Timestamp > TimeSpan.FromHours(6)) { // update LnNode remoteNode = GetOrCreateNode(lndClient, c.remote_pubkey, db); LnChannelConnectionPoints newChanHist = new LnChannelConnectionPoints() { IsConnected = c.active, LocalBalance = Convert.ToInt64(c.local_balance), RemoteBalance = Convert.ToInt64(c.remote_balance), Timestamp = DateTime.UtcNow, RemoteNode = remoteNode, ChanId = Convert.ToInt64(c.chan_id), }; prevChanHist.RemoteNode = remoteNode; db.LnChannelHistory.Add(newChanHist); db.SaveChanges(); } if (c.remote_balance is null) { c.remote_balance = "0"; } if (c.local_balance is null) { c.local_balance = "0"; } channelViewModel.ChanInfo = c; channelViewModel.RemoteNode = prevChanHist.RemoteNode; nodeChannelViewModel.channels.Add(channelViewModel); } } // Updates to channelinfo nodeSummaryViewModel.NumChannels = channels.channels.Count; nodeSummaryViewModel.Capacity = Convert.ToDouble(channels.channels.Sum(c => Convert.ToInt64(c.capacity))) / 100000000.0; nodeSummaryViewModel.LocalCapacity = Convert.ToDouble(channels.channels.Sum(n => Convert.ToInt64(n.local_balance))) / 100000000.0; nodeSummaryViewModel.RemoteCapacity = Convert.ToDouble(channels.channels.Sum(n => Convert.ToInt64(n.remote_balance))) / 100000000.0; nodeSummaryViewModel.ActiveCapacity = Convert.ToDouble(channels.channels.Where(c => c.active).Sum(c => Convert.ToInt64(c.capacity))) / 100000000.0; nodeSummaryViewModel.ActiveLocalCapacity = Convert.ToDouble(channels.channels.Where(c => c.active).Sum(n => Convert.ToInt64(n.local_balance))) / 100000000.0; nodeSummaryViewModel.ActiveRemoteCapacity = Convert.ToDouble(channels.channels.Where(c => c.active).Sum(n => Convert.ToInt64(n.remote_balance))) / 100000000.0; UpdateTaskComplete(taskid); } catch (Exception e) { // Try again on next refresh LastNodeChannelsUpdate = DateTime.Now - StatusCacheTimeout; } }), }; updateTasks.TryAdd(taskid, updateTask); updateTask.task.Start(); LastNodeChannelsUpdate = DateTime.Now; } return(PartialView("NodeChannels", nodeChannelViewModel)); }