From c8fad86d94e8329b91eacd6945e49d99acb69ff8 Mon Sep 17 00:00:00 2001 From: Edouard Paris Date: Tue, 9 Apr 2019 10:08:43 +0200 Subject: [PATCH] network: pending channels --- network/backend/lnd/proto.go | 68 ++++++++++++++++++++++++++++++++---- network/models/channel.go | 1 + network/options/channels.go | 4 +-- ui/controller.go | 36 ++++++++++++++----- ui/models/models.go | 3 +- ui/views/channels.go | 14 ++++---- 6 files changed, 101 insertions(+), 25 deletions(-) diff --git a/network/backend/lnd/proto.go b/network/backend/lnd/proto.go index 0f5b2ed..e00d27f 100644 --- a/network/backend/lnd/proto.go +++ b/network/backend/lnd/proto.go @@ -109,17 +109,40 @@ func htlcProtoToHTLC(h *lnrpc.HTLC) *models.HTLC { } func pendingChannelsProtoToChannels(r *lnrpc.PendingChannelsResponse) []*models.Channel { - resp := r.GetPendingOpenChannels() - channels := make([]*models.Channel, len(resp)) - for i := range resp { - channels[i] = openingProtoToChannel(resp[i]) + respPending := r.GetPendingOpenChannels() + pending := make([]*models.Channel, len(respPending)) + for i := range respPending { + pending[i] = openingChannelProtoToChannel(respPending[i]) } - return channels + respClosing := r.GetPendingClosingChannels() + closing := make([]*models.Channel, len(respClosing)) + for i := range respClosing { + closing[i] = closingChannelProtoToChannel(respClosing[i]) + } + + channels := append(pending, closing...) + + respForceClosing := r.GetPendingForceClosingChannels() + forceClosing := make([]*models.Channel, len(respForceClosing)) + for i := range respForceClosing { + forceClosing[i] = forceClosingChannelProtoToChannel(respForceClosing[i]) + } + + channels = append(channels, forceClosing...) + + respWaitingClose := r.GetWaitingCloseChannels() + waitingClose := make([]*models.Channel, len(respWaitingClose)) + for i := range respWaitingClose { + waitingClose[i] = waitingCloseChannelProtoToChannel(respWaitingClose[i]) + } + + return append(channels, waitingClose...) } -func openingProtoToChannel(c *lnrpc.PendingChannelsResponse_PendingOpenChannel) *models.Channel { +func openingChannelProtoToChannel(c *lnrpc.PendingChannelsResponse_PendingOpenChannel) *models.Channel { return &models.Channel{ + Status: models.ChannelOpening, RemotePubKey: c.Channel.RemoteNodePub, Capacity: c.Channel.Capacity, LocalBalance: c.Channel.LocalBalance, @@ -132,6 +155,39 @@ func openingProtoToChannel(c *lnrpc.PendingChannelsResponse_PendingOpenChannel) } } +func closingChannelProtoToChannel(c *lnrpc.PendingChannelsResponse_ClosedChannel) *models.Channel { + return &models.Channel{ + Status: models.ChannelClosing, + RemotePubKey: c.Channel.RemoteNodePub, + Capacity: c.Channel.Capacity, + LocalBalance: c.Channel.LocalBalance, + RemoteBalance: c.Channel.RemoteBalance, + ChannelPoint: c.Channel.ChannelPoint, + } +} + +func forceClosingChannelProtoToChannel(c *lnrpc.PendingChannelsResponse_ForceClosedChannel) *models.Channel { + return &models.Channel{ + Status: models.ChannelClosing, + RemotePubKey: c.Channel.RemoteNodePub, + Capacity: c.Channel.Capacity, + LocalBalance: c.Channel.LocalBalance, + RemoteBalance: c.Channel.RemoteBalance, + ChannelPoint: c.Channel.ChannelPoint, + } +} + +func waitingCloseChannelProtoToChannel(c *lnrpc.PendingChannelsResponse_WaitingCloseChannel) *models.Channel { + return &models.Channel{ + Status: models.ChannelWaitingClose, + RemotePubKey: c.Channel.RemoteNodePub, + Capacity: c.Channel.Capacity, + LocalBalance: c.Channel.LocalBalance, + RemoteBalance: c.Channel.RemoteBalance, + ChannelPoint: c.Channel.ChannelPoint, + } +} + func payreqProtoToPayReq(h *lnrpc.PayReq, payreq string) *models.PayReq { if h == nil { return nil diff --git a/network/models/channel.go b/network/models/channel.go index 8bf537d..3531b1b 100644 --- a/network/models/channel.go +++ b/network/models/channel.go @@ -12,6 +12,7 @@ const ( ChannelOpening ChannelClosing ChannelForceClosing + ChannelWaitingClose ) type ChannelsBalance struct { diff --git a/network/options/channels.go b/network/options/channels.go index d9bde35..a8b7659 100644 --- a/network/options/channels.go +++ b/network/options/channels.go @@ -10,9 +10,7 @@ type ChannelOptions struct { Pending bool } -func WithChannelPending() Channel { - return func(c *ChannelOptions) { c.Pending = true } -} +func WithChannelPending(c *ChannelOptions) { c.Pending = true } func WithChannelPublic(v bool) Channel { return func(c *ChannelOptions) { c.Public = v } diff --git a/ui/controller.go b/ui/controller.go index 1860c63..36d5b26 100644 --- a/ui/controller.go +++ b/ui/controller.go @@ -70,25 +70,43 @@ func (c *controller) SetModels(ctx context.Context) error { func (c *controller) Listen(ctx context.Context, g *gocui.Gui, sub chan *events.Event) { c.logger.Debug("Listening...") + refresh := func(fn ...func(context.Context) error) { + for i := range fn { + err := fn[i](ctx) + if err != nil { + c.logger.Error("failed", logging.Error(err)) + } + } + } + for event := range sub { - var err error + c.logger.Debug("event received", logging.String("type", event.Type)) switch event.Type { case events.BlockReceived: - err = c.models.RefreshInfo(ctx) + refresh(c.models.RefreshInfo) case events.ChannelPending: - err = c.models.RefreshInfo(ctx) + refresh( + c.models.RefreshInfo, + c.models.RefreshChannelsBalance, + c.models.RefreshChannels, + ) case events.ChannelActive: - err = c.models.RefreshInfo(ctx) + refresh( + c.models.RefreshInfo, + c.models.RefreshChannelsBalance, + c.models.RefreshChannels, + ) case events.ChannelInactive: - err = c.models.RefreshInfo(ctx) + refresh( + c.models.RefreshInfo, + c.models.RefreshChannelsBalance, + c.models.RefreshChannels, + ) case events.PeerUpdated: - err = c.models.RefreshInfo(ctx) + refresh(c.models.RefreshInfo) default: c.logger.Info("event received", logging.String("type", event.Type)) } - if err != nil { - c.logger.Error("failed", logging.String("event", event.Type)) - } } } diff --git a/ui/models/models.go b/ui/models/models.go index 1a04fb7..fa77ef0 100644 --- a/ui/models/models.go +++ b/ui/models/models.go @@ -5,6 +5,7 @@ import ( "github.com/edouardparis/lntop/app" "github.com/edouardparis/lntop/network/models" + "github.com/edouardparis/lntop/network/options" ) type Models struct { @@ -41,7 +42,7 @@ func (m *Models) RefreshInfo(ctx context.Context) error { } func (m *Models) RefreshChannels(ctx context.Context) error { - channels, err := m.App.Network.ListChannels(ctx) + channels, err := m.App.Network.ListChannels(ctx, options.WithChannelPending) if err != nil { return err } diff --git a/ui/views/channels.go b/ui/views/channels.go index 920ef92..5347ecb 100644 --- a/ui/views/channels.go +++ b/ui/views/channels.go @@ -80,7 +80,7 @@ func (c *Channels) Set(g *gocui.Gui, x0, y0, x1, y1 int) error { func displayChannelsColumns(v *gocui.View) { v.Clear() - fmt.Fprintln(v, fmt.Sprintf("%-9s %-20s %-21s %12s %12s %5s %-15s %s", + fmt.Fprintln(v, fmt.Sprintf("%-13s %-20s %-21s %12s %12s %5s %-15s %s", "STATUS", "ALIAS", "GAUGE", @@ -130,15 +130,17 @@ func lastUpdate(c *netmodels.Channel) string { func status(c *netmodels.Channel) string { switch c.Status { case netmodels.ChannelActive: - return color.Green(fmt.Sprintf("%-9s", "active")) + return color.Green(fmt.Sprintf("%-13s", "active")) case netmodels.ChannelInactive: - return color.Red(fmt.Sprintf("%-9s", "inactive")) + return color.Red(fmt.Sprintf("%-13s", "inactive")) case netmodels.ChannelOpening: - return color.Yellow(fmt.Sprintf("%-9s", "opening")) + return color.Yellow(fmt.Sprintf("%-13s", "opening")) case netmodels.ChannelClosing: - return color.Yellow(fmt.Sprintf("%-9s", "closing")) + return color.Yellow(fmt.Sprintf("%-13s", "closing")) case netmodels.ChannelForceClosing: - return color.Yellow(fmt.Sprintf("%-9s", "closing -f")) + return color.Yellow(fmt.Sprintf("%-13s", "force closing")) + case netmodels.ChannelWaitingClose: + return color.Yellow(fmt.Sprintf("%-13s", "waiting close")) } return "" }