2019-03-28 12:36:23 +00:00
|
|
|
package models
|
|
|
|
|
2019-03-28 13:07:46 +00:00
|
|
|
import (
|
|
|
|
"context"
|
2022-11-08 23:51:13 +00:00
|
|
|
"strconv"
|
2019-03-28 13:07:46 +00:00
|
|
|
|
|
|
|
"github.com/edouardparis/lntop/app"
|
2019-04-15 07:28:44 +00:00
|
|
|
"github.com/edouardparis/lntop/logging"
|
|
|
|
"github.com/edouardparis/lntop/network"
|
2019-03-28 13:07:46 +00:00
|
|
|
"github.com/edouardparis/lntop/network/models"
|
2019-04-09 08:08:43 +00:00
|
|
|
"github.com/edouardparis/lntop/network/options"
|
2019-03-28 13:07:46 +00:00
|
|
|
)
|
2019-03-28 12:36:23 +00:00
|
|
|
|
|
|
|
type Models struct {
|
2019-04-15 07:28:44 +00:00
|
|
|
logger logging.Logger
|
|
|
|
network *network.Network
|
2019-03-29 11:38:09 +00:00
|
|
|
Info *Info
|
|
|
|
Channels *Channels
|
|
|
|
WalletBalance *WalletBalance
|
|
|
|
ChannelsBalance *ChannelsBalance
|
2019-05-14 16:13:59 +00:00
|
|
|
Transactions *Transactions
|
2021-05-09 21:37:01 +00:00
|
|
|
RoutingLog *RoutingLog
|
2022-11-08 23:51:13 +00:00
|
|
|
FwdingHist *FwdingHist
|
2019-03-28 12:36:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func New(app *app.App) *Models {
|
2022-11-08 23:51:13 +00:00
|
|
|
fwdingHist := FwdingHist{}
|
|
|
|
startTime := app.Config.Views.FwdingHist.Options.GetOption("START_TIME", "start_time")
|
|
|
|
maxNumEvents := app.Config.Views.FwdingHist.Options.GetOption("MAX_NUM_EVENTS", "max_num_events")
|
|
|
|
|
|
|
|
if startTime != "" {
|
|
|
|
fwdingHist.StartTime = startTime
|
|
|
|
}
|
|
|
|
|
|
|
|
if maxNumEvents != "" {
|
|
|
|
max, err := strconv.ParseUint(maxNumEvents, 10, 32)
|
|
|
|
if err != nil {
|
|
|
|
app.Logger.Info("Couldn't parse the maximum number of forwarding events.")
|
|
|
|
} else {
|
|
|
|
fwdingHist.MaxNumEvents = uint32(max)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-28 13:07:46 +00:00
|
|
|
return &Models{
|
2019-04-15 07:28:44 +00:00
|
|
|
logger: app.Logger.With(logging.String("logger", "models")),
|
|
|
|
network: app.Network,
|
2019-03-29 11:38:09 +00:00
|
|
|
Info: &Info{},
|
2019-04-03 12:11:49 +00:00
|
|
|
Channels: NewChannels(),
|
2019-03-29 11:38:09 +00:00
|
|
|
WalletBalance: &WalletBalance{},
|
|
|
|
ChannelsBalance: &ChannelsBalance{},
|
2019-05-14 16:13:59 +00:00
|
|
|
Transactions: &Transactions{},
|
2021-05-09 21:37:01 +00:00
|
|
|
RoutingLog: &RoutingLog{},
|
2022-11-08 23:51:13 +00:00
|
|
|
FwdingHist: &fwdingHist,
|
2019-03-28 13:07:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-29 11:38:09 +00:00
|
|
|
type Info struct {
|
|
|
|
*models.Info
|
|
|
|
}
|
|
|
|
|
2019-03-28 13:07:46 +00:00
|
|
|
func (m *Models) RefreshInfo(ctx context.Context) error {
|
2019-04-15 07:28:44 +00:00
|
|
|
info, err := m.network.Info(ctx)
|
2019-03-28 13:07:46 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
*m.Info = Info{info}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-11-08 23:51:13 +00:00
|
|
|
func (m *Models) RefreshForwardingHistory(ctx context.Context) error {
|
|
|
|
forwardingEvents, err := m.network.GetForwardingHistory(ctx, m.FwdingHist.StartTime, m.FwdingHist.MaxNumEvents)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
m.FwdingHist.Update(forwardingEvents)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-03-29 08:30:05 +00:00
|
|
|
func (m *Models) RefreshChannels(ctx context.Context) error {
|
2019-04-15 07:28:44 +00:00
|
|
|
channels, err := m.network.ListChannels(ctx, options.WithChannelPending)
|
2019-03-29 08:30:05 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-09-01 17:04:51 +00:00
|
|
|
index := map[string]*models.Channel{}
|
2019-04-03 12:11:49 +00:00
|
|
|
for i := range channels {
|
2022-09-01 17:04:51 +00:00
|
|
|
index[channels[i].ChannelPoint] = channels[i]
|
2022-09-23 08:16:45 +00:00
|
|
|
if channels[i].ID > 0 {
|
|
|
|
channels[i].Age = m.Info.BlockHeight - uint32(channels[i].ID>>40)
|
|
|
|
}
|
2019-04-03 12:11:49 +00:00
|
|
|
if !m.Channels.Contains(channels[i]) {
|
|
|
|
m.Channels.Add(channels[i])
|
|
|
|
}
|
2019-04-10 13:02:09 +00:00
|
|
|
channel := m.Channels.GetByChanPoint(channels[i].ChannelPoint)
|
2019-04-03 12:11:49 +00:00
|
|
|
if channel != nil &&
|
|
|
|
(channel.UpdatesCount < channels[i].UpdatesCount ||
|
2022-09-13 11:47:09 +00:00
|
|
|
channel.LastUpdate == nil || channel.LocalPolicy == nil || channel.RemotePolicy == nil) {
|
2019-04-15 07:28:44 +00:00
|
|
|
err := m.network.GetChannelInfo(ctx, channels[i])
|
2019-04-04 08:10:21 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-04-04 11:24:01 +00:00
|
|
|
if channels[i].Node == nil {
|
2019-04-15 07:28:44 +00:00
|
|
|
channels[i].Node, err = m.network.GetNode(ctx,
|
2022-09-07 17:30:21 +00:00
|
|
|
channels[i].RemotePubKey, false)
|
2019-04-04 11:24:01 +00:00
|
|
|
if err != nil {
|
2019-04-29 11:39:23 +00:00
|
|
|
m.logger.Debug("refreshChannels: cannot find Node",
|
2019-04-15 07:28:44 +00:00
|
|
|
logging.String("pubkey", channels[i].RemotePubKey))
|
2019-04-04 11:24:01 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-03 12:11:49 +00:00
|
|
|
}
|
2019-04-09 12:02:51 +00:00
|
|
|
|
|
|
|
m.Channels.Update(channels[i])
|
2019-04-03 12:11:49 +00:00
|
|
|
}
|
2022-09-01 17:04:51 +00:00
|
|
|
for _, c := range m.Channels.List() {
|
|
|
|
if _, ok := index[c.ChannelPoint]; !ok {
|
|
|
|
c.Status = models.ChannelClosed
|
|
|
|
}
|
|
|
|
}
|
2019-04-02 12:27:51 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-03-29 11:38:09 +00:00
|
|
|
type WalletBalance struct {
|
|
|
|
*models.WalletBalance
|
2019-03-28 12:36:23 +00:00
|
|
|
}
|
2019-03-29 08:30:05 +00:00
|
|
|
|
2019-03-29 11:38:09 +00:00
|
|
|
func (m *Models) RefreshWalletBalance(ctx context.Context) error {
|
2019-04-15 07:28:44 +00:00
|
|
|
balance, err := m.network.GetWalletBalance(ctx)
|
2019-03-29 11:38:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
*m.WalletBalance = WalletBalance{balance}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type ChannelsBalance struct {
|
|
|
|
*models.ChannelsBalance
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Models) RefreshChannelsBalance(ctx context.Context) error {
|
2019-04-15 07:28:44 +00:00
|
|
|
balance, err := m.network.GetChannelsBalance(ctx)
|
2019-03-29 11:38:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
*m.ChannelsBalance = ChannelsBalance{balance}
|
|
|
|
return nil
|
2019-03-29 08:30:05 +00:00
|
|
|
}
|
2021-05-09 21:37:01 +00:00
|
|
|
|
|
|
|
type RoutingLog struct {
|
|
|
|
Log []*models.RoutingEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
const MaxRoutingEvents = 512 // 8K monitor @ 8px per line = 540
|
|
|
|
|
|
|
|
func (m *Models) RefreshRouting(update interface{}) func(context.Context) error {
|
|
|
|
return (func(ctx context.Context) error {
|
|
|
|
hu, ok := update.(*models.RoutingEvent)
|
|
|
|
if ok {
|
|
|
|
found := false
|
|
|
|
for _, hlu := range m.RoutingLog.Log {
|
|
|
|
if hlu.Equals(hu) {
|
|
|
|
hlu.Update(hu)
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
if len(m.RoutingLog.Log) == MaxRoutingEvents {
|
|
|
|
m.RoutingLog.Log = m.RoutingLog.Log[1:]
|
|
|
|
}
|
|
|
|
m.RoutingLog.Log = append(m.RoutingLog.Log, hu)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
m.logger.Error("refreshRouting: invalid event data")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
2022-09-07 17:30:21 +00:00
|
|
|
|
2022-09-02 20:14:05 +00:00
|
|
|
func (m *Models) RefreshPolicies(update interface{}) func(context.Context) error {
|
|
|
|
return func(ctx context.Context) error {
|
|
|
|
for _, chanpoint := range update.(*models.ChannelEdgeUpdate).ChanPoints {
|
|
|
|
if m.Channels.Contains(&models.Channel{ChannelPoint: chanpoint}) {
|
|
|
|
m.logger.Debug("updating channel", logging.String("chanpoint", chanpoint))
|
|
|
|
channel := m.Channels.GetByChanPoint(chanpoint)
|
|
|
|
err := m.network.GetChannelInfo(ctx, channel)
|
|
|
|
if err != nil {
|
|
|
|
m.logger.Error("error updating channel info", logging.Error(err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-07 17:30:21 +00:00
|
|
|
func (m *Models) RefreshCurrentNode(ctx context.Context) (err error) {
|
|
|
|
cur := m.Channels.Current()
|
|
|
|
if cur != nil {
|
|
|
|
m.Channels.CurrentNode, err = m.network.GetNode(ctx, cur.RemotePubKey, true)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|