2023-09-09 23:45:47 +00:00
|
|
|
|
package app
|
|
|
|
|
|
|
|
|
|
import (
|
2023-11-27 02:51:46 +00:00
|
|
|
|
"bytes"
|
|
|
|
|
"context"
|
|
|
|
|
"encoding/base64"
|
|
|
|
|
"encoding/hex"
|
2023-09-09 23:45:47 +00:00
|
|
|
|
"fmt"
|
2023-11-27 02:51:46 +00:00
|
|
|
|
"math/big"
|
2023-09-09 23:45:47 +00:00
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
2024-01-15 04:32:28 +00:00
|
|
|
|
"time"
|
2023-09-09 23:45:47 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
|
|
|
"github.com/charmbracelet/lipgloss"
|
|
|
|
|
"github.com/libp2p/go-libp2p/core/crypto"
|
|
|
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
|
|
|
|
"github.com/multiformats/go-multiaddr"
|
|
|
|
|
mn "github.com/multiformats/go-multiaddr/net"
|
2023-09-27 09:05:39 +00:00
|
|
|
|
"github.com/pkg/errors"
|
2023-11-27 02:51:46 +00:00
|
|
|
|
"golang.org/x/term"
|
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
|
"google.golang.org/grpc/connectivity"
|
|
|
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
|
|
|
"source.quilibrium.com/quilibrium/monorepo/node/config"
|
2024-02-13 07:04:56 +00:00
|
|
|
|
"source.quilibrium.com/quilibrium/monorepo/node/execution/intrinsics/ceremony/application"
|
2024-01-03 07:31:42 +00:00
|
|
|
|
"source.quilibrium.com/quilibrium/monorepo/node/p2p"
|
2023-11-27 02:51:46 +00:00
|
|
|
|
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
|
|
|
|
|
"source.quilibrium.com/quilibrium/monorepo/node/tries"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
textColor = lipgloss.Color("#fff")
|
|
|
|
|
primaryColor = lipgloss.Color("#ff0070")
|
|
|
|
|
secondaryColor = lipgloss.Color("#ff5c00")
|
|
|
|
|
windowHeader = lipgloss.NewStyle().
|
|
|
|
|
Foreground(textColor).
|
|
|
|
|
Padding(0, 1)
|
|
|
|
|
unselectedListStyle = lipgloss.NewStyle().
|
|
|
|
|
Foreground(textColor).
|
|
|
|
|
Width(28).
|
|
|
|
|
Padding(0, 1)
|
|
|
|
|
navigatedListStyle = lipgloss.NewStyle().
|
|
|
|
|
Foreground(textColor).
|
|
|
|
|
Width(28).
|
|
|
|
|
Bold(true).
|
|
|
|
|
Padding(0, 1)
|
|
|
|
|
selectedListStyle = lipgloss.NewStyle().
|
|
|
|
|
Foreground(textColor).
|
|
|
|
|
Background(primaryColor).
|
|
|
|
|
Width(28).
|
|
|
|
|
Padding(0, 1)
|
|
|
|
|
statusBarStyle = lipgloss.NewStyle().
|
|
|
|
|
Foreground(textColor).
|
|
|
|
|
Background(primaryColor)
|
|
|
|
|
statusStyle = lipgloss.NewStyle().
|
|
|
|
|
Foreground(textColor).
|
|
|
|
|
Background(primaryColor).
|
|
|
|
|
Padding(0, 1)
|
|
|
|
|
statusItemStyle = lipgloss.NewStyle().
|
|
|
|
|
Foreground(textColor).
|
|
|
|
|
Background(secondaryColor).
|
|
|
|
|
Padding(0, 1)
|
|
|
|
|
docStyle = lipgloss.NewStyle().Padding(0)
|
|
|
|
|
border = lipgloss.Border{
|
|
|
|
|
Top: "─",
|
|
|
|
|
Bottom: "─",
|
|
|
|
|
Left: "│",
|
|
|
|
|
Right: "│",
|
|
|
|
|
TopLeft: "┌",
|
|
|
|
|
TopRight: "┐",
|
|
|
|
|
BottomLeft: "└",
|
|
|
|
|
BottomRight: "┘",
|
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type DBConsole struct {
|
2023-11-27 02:51:46 +00:00
|
|
|
|
nodeConfig *config.Config
|
2023-09-09 23:45:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
func newDBConsole(nodeConfig *config.Config) (*DBConsole, error) {
|
2023-09-09 23:45:47 +00:00
|
|
|
|
return &DBConsole{
|
2023-11-27 02:51:46 +00:00
|
|
|
|
nodeConfig,
|
2023-09-09 23:45:47 +00:00
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
type model struct {
|
2024-01-15 04:32:28 +00:00
|
|
|
|
filters []string
|
|
|
|
|
cursor int
|
|
|
|
|
selectedFilter string
|
|
|
|
|
conn *grpc.ClientConn
|
|
|
|
|
client protobufs.NodeServiceClient
|
|
|
|
|
peerId string
|
|
|
|
|
errorMsg string
|
|
|
|
|
frame *protobufs.ClockFrame
|
|
|
|
|
frames []*protobufs.ClockFrame
|
|
|
|
|
frameIndex int
|
|
|
|
|
grpcWarn bool
|
|
|
|
|
committed bool
|
|
|
|
|
lastChecked int64
|
|
|
|
|
owned *big.Int
|
|
|
|
|
unconfirmedOwned *big.Int
|
2023-11-27 02:51:46 +00:00
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
func (m model) Init() tea.Cmd {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
2024-01-15 04:32:28 +00:00
|
|
|
|
if m.conn.GetState() == connectivity.Ready {
|
|
|
|
|
if m.lastChecked < (time.Now().UnixMilli() - 10_000) {
|
|
|
|
|
m.lastChecked = time.Now().UnixMilli()
|
2024-01-29 21:11:40 +00:00
|
|
|
|
|
|
|
|
|
tokenBalance, err := FetchTokenBalance(m.client)
|
2024-01-15 04:32:28 +00:00
|
|
|
|
if err == nil {
|
2024-01-29 21:11:40 +00:00
|
|
|
|
m.owned = tokenBalance.Owned
|
|
|
|
|
m.unconfirmedOwned = tokenBalance.UnconfirmedOwned
|
2024-01-15 04:32:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
|
2024-01-15 04:32:28 +00:00
|
|
|
|
switch msg := msg.(type) {
|
2023-11-27 02:51:46 +00:00
|
|
|
|
case tea.KeyMsg:
|
|
|
|
|
switch msg.String() {
|
|
|
|
|
case "ctrl+c", "q":
|
|
|
|
|
return m, tea.Quit
|
|
|
|
|
case "up", "w":
|
|
|
|
|
if m.cursor > 0 {
|
|
|
|
|
m.cursor--
|
|
|
|
|
}
|
|
|
|
|
case "down", "s":
|
|
|
|
|
if m.cursor < len(m.filters)-1 {
|
|
|
|
|
m.cursor++
|
2023-09-09 23:45:47 +00:00
|
|
|
|
}
|
2023-11-27 02:51:46 +00:00
|
|
|
|
case "left", "a":
|
|
|
|
|
m.committed = false
|
|
|
|
|
m.errorMsg = ""
|
|
|
|
|
if m.frameIndex > 0 {
|
|
|
|
|
m.frameIndex--
|
|
|
|
|
if len(m.frames) != 0 && m.conn.GetState() == connectivity.Ready {
|
|
|
|
|
filter, _ := hex.DecodeString(m.selectedFilter)
|
|
|
|
|
selector, err := m.frames[m.frameIndex].GetSelector()
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err == nil && bytes.Equal(
|
|
|
|
|
frameInfo.ClockFrame.Output,
|
|
|
|
|
m.frames[m.frameIndex].Output,
|
|
|
|
|
) {
|
|
|
|
|
m.committed = true
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
} else {
|
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
Selector: selector.FillBytes(make([]byte, 32)),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = hex.EncodeToString(
|
2024-02-18 04:52:19 +00:00
|
|
|
|
selector.FillBytes(make([]byte, 32)),
|
2023-11-27 02:51:46 +00:00
|
|
|
|
) + ":" + err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
m.errorMsg = "Not currently connected to node, cannot query."
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
first := uint64(0)
|
|
|
|
|
if len(m.frames) != 0 {
|
|
|
|
|
first = m.frames[0].FrameNumber - 1
|
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
if first == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
max := uint64(17)
|
|
|
|
|
if len(m.frames) != 0 {
|
|
|
|
|
max = first
|
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
min := max - 16
|
|
|
|
|
filter, _ := hex.DecodeString(m.selectedFilter)
|
|
|
|
|
frames, err := m.client.GetFrames(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFramesRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FromFrameNumber: min,
|
|
|
|
|
ToFrameNumber: max + 1,
|
|
|
|
|
IncludeCandidates: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
2023-09-09 23:45:47 +00:00
|
|
|
|
if err != nil {
|
2023-11-27 02:51:46 +00:00
|
|
|
|
m.selectedFilter = ""
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
2023-09-09 23:45:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
if frames.TruncatedClockFrames != nil {
|
|
|
|
|
m.frames = frames.TruncatedClockFrames
|
|
|
|
|
m.frameIndex = len(m.frames) - 1
|
|
|
|
|
selector, err := m.frames[m.frameIndex].GetSelector()
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err == nil && bytes.Equal(
|
|
|
|
|
frameInfo.ClockFrame.Output,
|
|
|
|
|
m.frames[m.frameIndex].Output,
|
|
|
|
|
) {
|
|
|
|
|
m.committed = true
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
} else {
|
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
Selector: selector.FillBytes(make([]byte, 32)),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case "right", "d":
|
|
|
|
|
m.committed = false
|
|
|
|
|
m.errorMsg = ""
|
|
|
|
|
if m.frameIndex < len(m.frames)-1 {
|
|
|
|
|
m.frameIndex++
|
|
|
|
|
if len(m.frames) != 0 && m.conn.GetState() == connectivity.Ready {
|
|
|
|
|
filter, _ := hex.DecodeString(m.selectedFilter)
|
|
|
|
|
selector, err := m.frames[m.frameIndex].GetSelector()
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err == nil && bytes.Equal(
|
|
|
|
|
frameInfo.ClockFrame.Output,
|
|
|
|
|
m.frames[m.frameIndex].Output,
|
|
|
|
|
) {
|
|
|
|
|
m.committed = true
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
} else {
|
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
Selector: selector.FillBytes(make([]byte, 32)),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = hex.EncodeToString(
|
2024-02-18 04:52:19 +00:00
|
|
|
|
selector.FillBytes(make([]byte, 32)),
|
2023-11-27 02:51:46 +00:00
|
|
|
|
) + ":" + err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
m.errorMsg = "Not currently connected to node, cannot query."
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
min := uint64(1)
|
|
|
|
|
if len(m.frames) != 0 {
|
|
|
|
|
min = m.frames[len(m.frames)-1].FrameNumber + 1
|
2023-09-09 23:45:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
max := min + 16
|
|
|
|
|
filter, _ := hex.DecodeString(m.selectedFilter)
|
|
|
|
|
frames, err := m.client.GetFrames(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFramesRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FromFrameNumber: min,
|
|
|
|
|
ToFrameNumber: max,
|
|
|
|
|
IncludeCandidates: true,
|
|
|
|
|
},
|
2023-09-09 23:45:47 +00:00
|
|
|
|
)
|
2023-11-27 02:51:46 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
m.selectedFilter = ""
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
if frames.TruncatedClockFrames != nil {
|
|
|
|
|
m.frames = frames.TruncatedClockFrames
|
|
|
|
|
m.frameIndex = 0
|
|
|
|
|
selector, err := m.frames[m.frameIndex].GetSelector()
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
2023-09-27 09:05:39 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err == nil && bytes.Equal(
|
|
|
|
|
frameInfo.ClockFrame.Output,
|
|
|
|
|
m.frames[m.frameIndex].Output,
|
|
|
|
|
) {
|
|
|
|
|
m.committed = true
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
} else {
|
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
Selector: selector.FillBytes(make([]byte, 32)),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-27 09:05:39 +00:00
|
|
|
|
}
|
2023-11-27 02:51:46 +00:00
|
|
|
|
case "enter", " ":
|
|
|
|
|
m.errorMsg = ""
|
|
|
|
|
m.frame = nil
|
|
|
|
|
m.committed = false
|
|
|
|
|
if m.conn.GetState() == connectivity.Ready {
|
|
|
|
|
if m.selectedFilter != m.filters[m.cursor] {
|
|
|
|
|
m.selectedFilter = m.filters[m.cursor]
|
|
|
|
|
m.frames = []*protobufs.ClockFrame{}
|
|
|
|
|
}
|
2023-09-27 09:05:39 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
min := uint64(1)
|
|
|
|
|
if len(m.frames) != 0 {
|
|
|
|
|
min = m.frames[len(m.frames)-1].FrameNumber + 1
|
|
|
|
|
}
|
2023-09-27 09:05:39 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
max := min + 16
|
|
|
|
|
filter, _ := hex.DecodeString(m.selectedFilter)
|
|
|
|
|
frames, err := m.client.GetFrames(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFramesRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FromFrameNumber: min,
|
|
|
|
|
ToFrameNumber: max,
|
|
|
|
|
IncludeCandidates: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.selectedFilter = ""
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
2023-09-27 09:05:39 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
if frames.TruncatedClockFrames != nil {
|
|
|
|
|
m.frames = frames.TruncatedClockFrames
|
|
|
|
|
m.frameIndex = 0
|
|
|
|
|
selector, err := m.frames[m.frameIndex].GetSelector()
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err == nil && bytes.Equal(
|
|
|
|
|
frameInfo.ClockFrame.Output,
|
|
|
|
|
m.frames[m.frameIndex].Output,
|
|
|
|
|
) {
|
|
|
|
|
m.committed = true
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
} else {
|
|
|
|
|
frameInfo, err := m.client.GetFrameInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetFrameInfoRequest{
|
|
|
|
|
Filter: filter,
|
|
|
|
|
FrameNumber: m.frames[m.frameIndex].FrameNumber,
|
|
|
|
|
Selector: selector.FillBytes(make([]byte, 32)),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.errorMsg = err.Error()
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
m.frame = frameInfo.ClockFrame
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
m.errorMsg = "Not currently connected to node, cannot query."
|
2023-09-27 09:05:39 +00:00
|
|
|
|
}
|
2023-11-27 02:51:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m model) View() string {
|
|
|
|
|
physicalWidth, physicalHeight, _ := term.GetSize(int(os.Stdout.Fd()))
|
|
|
|
|
doc := strings.Builder{}
|
|
|
|
|
|
|
|
|
|
window := lipgloss.NewStyle().
|
|
|
|
|
Border(border, true).
|
|
|
|
|
BorderForeground(primaryColor).
|
|
|
|
|
Padding(0, 1)
|
|
|
|
|
|
|
|
|
|
list := []string{}
|
|
|
|
|
for i, item := range m.filters {
|
2024-01-03 07:31:42 +00:00
|
|
|
|
str := item[0:12] + ".." + item[len(item)-12:]
|
2023-11-27 02:51:46 +00:00
|
|
|
|
if m.selectedFilter == item {
|
|
|
|
|
list = append(list, selectedListStyle.Render(str))
|
|
|
|
|
} else if i == m.cursor {
|
|
|
|
|
list = append(list, navigatedListStyle.Render(str))
|
|
|
|
|
} else {
|
|
|
|
|
list = append(list, unselectedListStyle.Render(str))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
w := lipgloss.Width
|
|
|
|
|
|
|
|
|
|
statusKey := statusItemStyle.Render("STATUS")
|
|
|
|
|
info := statusStyle.Render("(Press Ctrl-C or Q to quit)")
|
|
|
|
|
onlineStatus := "gRPC Not Enabled, Please Configure"
|
|
|
|
|
if !m.grpcWarn {
|
|
|
|
|
switch m.conn.GetState() {
|
|
|
|
|
case connectivity.Connecting:
|
|
|
|
|
onlineStatus = "CONNECTING"
|
|
|
|
|
case connectivity.Idle:
|
|
|
|
|
onlineStatus = "IDLE"
|
|
|
|
|
case connectivity.Shutdown:
|
|
|
|
|
onlineStatus = "SHUTDOWN"
|
|
|
|
|
case connectivity.TransientFailure:
|
|
|
|
|
onlineStatus = "DISCONNECTED"
|
|
|
|
|
default:
|
|
|
|
|
onlineStatus = "CONNECTED"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-15 04:32:28 +00:00
|
|
|
|
ownedVal := statusItemStyle.Copy().
|
|
|
|
|
Render("Owned: " + m.owned.String())
|
|
|
|
|
if m.owned.Cmp(big.NewInt(-1)) == 0 {
|
|
|
|
|
ownedVal = statusItemStyle.Copy().
|
|
|
|
|
Render("")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unconfirmedOwnedVal := statusItemStyle.Copy().
|
|
|
|
|
Render("Unconfirmed: " + m.unconfirmedOwned.String())
|
|
|
|
|
if m.unconfirmedOwned.Cmp(big.NewInt(-1)) == 0 {
|
|
|
|
|
unconfirmedOwnedVal = statusItemStyle.Copy().
|
|
|
|
|
Render("")
|
|
|
|
|
}
|
2023-11-27 02:51:46 +00:00
|
|
|
|
peerIdVal := statusItemStyle.Render(m.peerId)
|
|
|
|
|
statusVal := statusBarStyle.Copy().
|
2024-01-15 04:32:28 +00:00
|
|
|
|
Width(physicalWidth-w(statusKey)-w(info)-w(peerIdVal)-w(ownedVal)-
|
|
|
|
|
w(unconfirmedOwnedVal)).
|
2023-11-27 02:51:46 +00:00
|
|
|
|
Padding(0, 1).
|
|
|
|
|
Render(onlineStatus)
|
|
|
|
|
|
|
|
|
|
bar := lipgloss.JoinHorizontal(lipgloss.Top,
|
|
|
|
|
statusKey,
|
|
|
|
|
statusVal,
|
|
|
|
|
info,
|
|
|
|
|
peerIdVal,
|
2024-01-15 04:32:28 +00:00
|
|
|
|
ownedVal,
|
|
|
|
|
unconfirmedOwnedVal,
|
2023-11-27 02:51:46 +00:00
|
|
|
|
)
|
2023-09-27 09:05:39 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
explorerContent := ""
|
|
|
|
|
|
|
|
|
|
if m.errorMsg != "" {
|
|
|
|
|
explorerContent = m.errorMsg
|
|
|
|
|
} else if m.frame != nil {
|
|
|
|
|
selector, err := m.frame.GetSelector()
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
committed := "Unconfirmed"
|
|
|
|
|
if m.committed {
|
|
|
|
|
committed = "Confirmed"
|
|
|
|
|
}
|
|
|
|
|
explorerContent = fmt.Sprintf(
|
|
|
|
|
"Frame %d (Selector: %x, %s):\n\tParent: %x\n\tVDF Proof: %x\n",
|
|
|
|
|
m.frame.FrameNumber,
|
2024-02-18 04:52:19 +00:00
|
|
|
|
selector.FillBytes(make([]byte, 32)),
|
2023-11-27 02:51:46 +00:00
|
|
|
|
committed,
|
|
|
|
|
m.frame.ParentSelector,
|
|
|
|
|
m.frame.Input[:516],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
for i := 0; i < len(m.frame.Input[516:])/74; i++ {
|
|
|
|
|
commit := m.frame.Input[516+(i*74) : 516+((i+1)*74)]
|
|
|
|
|
explorerContent += fmt.Sprintf(
|
|
|
|
|
"\tCommitment %+x\n",
|
|
|
|
|
commit,
|
|
|
|
|
)
|
|
|
|
|
explorerContent += fmt.Sprintf(
|
|
|
|
|
"\t\tType: %s\n",
|
|
|
|
|
m.frame.AggregateProofs[i].InclusionCommitments[0].TypeUrl,
|
|
|
|
|
)
|
|
|
|
|
switch m.frame.AggregateProofs[i].InclusionCommitments[0].TypeUrl {
|
|
|
|
|
case protobufs.IntrinsicExecutionOutputType:
|
|
|
|
|
explorerContent += "Application: Ceremony\n"
|
|
|
|
|
app, err := application.MaterializeApplicationFromFrame(m.frame)
|
2023-09-27 09:05:39 +00:00
|
|
|
|
if err != nil {
|
2023-11-27 02:51:46 +00:00
|
|
|
|
explorerContent += "Error: " + err.Error() + "\n"
|
|
|
|
|
continue
|
2023-09-27 09:05:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
total := new(big.Int)
|
|
|
|
|
if app.RewardTrie.Root == nil ||
|
|
|
|
|
(app.RewardTrie.Root.External == nil &&
|
|
|
|
|
app.RewardTrie.Root.Internal == nil) {
|
|
|
|
|
explorerContent += "Total Rewards: 0 QUIL\n"
|
|
|
|
|
continue
|
2023-09-27 09:05:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
limbs := []*tries.RewardInternalNode{}
|
|
|
|
|
if app.RewardTrie.Root.Internal != nil {
|
|
|
|
|
limbs = append(limbs, app.RewardTrie.Root.Internal)
|
|
|
|
|
} else {
|
|
|
|
|
total = total.Add(
|
|
|
|
|
total,
|
|
|
|
|
new(big.Int).SetUint64(app.RewardTrie.Root.External.Total),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for len(limbs) != 0 {
|
|
|
|
|
nextLimbs := []*tries.RewardInternalNode{}
|
|
|
|
|
for _, limb := range limbs {
|
|
|
|
|
for _, child := range limb.Child {
|
|
|
|
|
child := child
|
|
|
|
|
if child.Internal != nil {
|
|
|
|
|
nextLimbs = append(nextLimbs, child.Internal)
|
|
|
|
|
} else {
|
|
|
|
|
total = total.Add(
|
|
|
|
|
total,
|
|
|
|
|
new(big.Int).SetUint64(child.External.Total),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
limbs = nextLimbs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
explorerContent += "Total Rewards: " + total.String() + " QUIL\n"
|
|
|
|
|
|
|
|
|
|
state := app.LobbyState.String()
|
|
|
|
|
explorerContent += "Round State: " + state + "\n"
|
|
|
|
|
|
|
|
|
|
switch app.LobbyState {
|
|
|
|
|
case application.CEREMONY_APPLICATION_STATE_OPEN:
|
|
|
|
|
explorerContent += "Joins: \n"
|
|
|
|
|
|
|
|
|
|
for _, join := range app.LobbyJoins {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
|
|
|
|
join.PublicKeySignatureEd448.PublicKey.KeyValue,
|
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
explorerContent += "Preferred Next Round Participants: \n"
|
2023-09-27 09:05:39 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
for _, next := range app.NextRoundPreferredParticipants {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
|
|
|
|
next.KeyValue,
|
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
explorerContent += fmt.Sprintf(
|
|
|
|
|
"State Transition Counter: %d\n",
|
|
|
|
|
app.StateCount,
|
2023-09-27 09:05:39 +00:00
|
|
|
|
)
|
2023-11-27 02:51:46 +00:00
|
|
|
|
case application.CEREMONY_APPLICATION_STATE_IN_PROGRESS:
|
|
|
|
|
explorerContent += fmt.Sprintf("Sub-Round: %d\n", app.RoundCount)
|
|
|
|
|
explorerContent += "Participants: \n"
|
|
|
|
|
|
|
|
|
|
for _, active := range app.ActiveParticipants {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
2024-01-03 07:31:42 +00:00
|
|
|
|
active.PublicKeySignatureEd448.PublicKey.KeyValue,
|
2023-11-27 02:51:46 +00:00
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
explorerContent += "Latest Seen: \n"
|
|
|
|
|
|
|
|
|
|
for _, latest := range app.LatestSeenProverAttestations {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
|
|
|
|
latest.SeenProverKey.KeyValue,
|
|
|
|
|
) + " seen by " + base64.StdEncoding.EncodeToString(
|
|
|
|
|
latest.ProverSignature.PublicKey.KeyValue,
|
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
explorerContent += "Dropped: \n"
|
|
|
|
|
|
|
|
|
|
for _, dropped := range app.DroppedParticipantAttestations {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
|
|
|
|
dropped.DroppedProverKey.KeyValue,
|
|
|
|
|
) + " confirmed by " + base64.StdEncoding.EncodeToString(
|
|
|
|
|
dropped.ProverSignature.PublicKey.KeyValue,
|
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
explorerContent += "Preferred Next Round Participants: \n"
|
|
|
|
|
|
|
|
|
|
for _, next := range app.NextRoundPreferredParticipants {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
|
|
|
|
next.KeyValue,
|
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
case application.CEREMONY_APPLICATION_STATE_FINALIZING:
|
|
|
|
|
explorerContent += fmt.Sprintf(
|
|
|
|
|
"Confirmed Shares: %d\n",
|
|
|
|
|
len(app.TranscriptShares),
|
2023-09-27 09:05:39 +00:00
|
|
|
|
)
|
2023-11-27 02:51:46 +00:00
|
|
|
|
explorerContent += "Participants: \n"
|
2023-09-27 09:05:39 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
for _, active := range app.ActiveParticipants {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
2024-01-03 07:31:42 +00:00
|
|
|
|
active.PublicKeySignatureEd448.PublicKey.KeyValue,
|
2023-11-27 02:51:46 +00:00
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
explorerContent += "Latest Seen: \n"
|
|
|
|
|
|
|
|
|
|
for _, latest := range app.LatestSeenProverAttestations {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
|
|
|
|
latest.SeenProverKey.KeyValue,
|
|
|
|
|
) + " seen by " + base64.StdEncoding.EncodeToString(
|
|
|
|
|
latest.ProverSignature.PublicKey.KeyValue,
|
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
explorerContent += "Dropped: \n"
|
|
|
|
|
|
|
|
|
|
for _, dropped := range app.DroppedParticipantAttestations {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
|
|
|
|
dropped.DroppedProverKey.KeyValue,
|
|
|
|
|
) + " confirmed by " + base64.StdEncoding.EncodeToString(
|
|
|
|
|
dropped.ProverSignature.PublicKey.KeyValue,
|
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
2023-09-27 09:05:39 +00:00
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
explorerContent += "Preferred Next Round Participants: \n"
|
|
|
|
|
|
|
|
|
|
for _, next := range app.NextRoundPreferredParticipants {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
|
|
|
|
next.KeyValue,
|
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
case application.CEREMONY_APPLICATION_STATE_VALIDATING:
|
2024-01-03 07:31:42 +00:00
|
|
|
|
explorerContent += fmt.Sprintf(
|
|
|
|
|
"G1 Powers: %d\n", len(app.UpdatedTranscript.G1Powers),
|
|
|
|
|
)
|
2023-11-27 02:51:46 +00:00
|
|
|
|
explorerContent += "Preferred Next Round Participants: \n"
|
|
|
|
|
for _, next := range app.NextRoundPreferredParticipants {
|
|
|
|
|
explorerContent += "\t" + base64.StdEncoding.EncodeToString(
|
|
|
|
|
next.KeyValue,
|
|
|
|
|
) + "\n"
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-09 23:45:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-27 02:51:46 +00:00
|
|
|
|
} else {
|
|
|
|
|
explorerContent = logoVersion(physicalWidth - 34)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
doc.WriteString(
|
|
|
|
|
lipgloss.JoinVertical(
|
|
|
|
|
lipgloss.Left,
|
|
|
|
|
lipgloss.JoinHorizontal(
|
|
|
|
|
lipgloss.Top,
|
|
|
|
|
lipgloss.JoinVertical(
|
|
|
|
|
lipgloss.Left,
|
|
|
|
|
windowHeader.Render("Filters (Up/Down, Enter)"),
|
|
|
|
|
window.Width(30).Height(physicalHeight-4).Render(lipgloss.JoinVertical(lipgloss.Left, list...)),
|
|
|
|
|
),
|
|
|
|
|
lipgloss.JoinVertical(
|
|
|
|
|
lipgloss.Left,
|
|
|
|
|
windowHeader.Render("Explorer (Left/Right)"),
|
|
|
|
|
window.Width(physicalWidth-34).Height(physicalHeight-4).Render(explorerContent),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
statusBarStyle.Width(physicalWidth).Render(bar),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if physicalWidth > 0 {
|
|
|
|
|
docStyle = docStyle.MaxWidth(physicalWidth)
|
|
|
|
|
docStyle = docStyle.MaxHeight(physicalHeight)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return docStyle.Render(doc.String())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func consoleModel(
|
|
|
|
|
conn *grpc.ClientConn,
|
|
|
|
|
nodeConfig *config.Config,
|
|
|
|
|
grpcWarn bool,
|
|
|
|
|
) model {
|
|
|
|
|
peerPrivKey, err := hex.DecodeString(nodeConfig.P2P.PeerPrivKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(errors.Wrap(err, "error unmarshaling peerkey"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
privKey, err := crypto.UnmarshalEd448PrivateKey(peerPrivKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(errors.Wrap(err, "error unmarshaling peerkey"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub := privKey.GetPublic()
|
|
|
|
|
id, err := peer.IDFromPublicKey(pub)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(errors.Wrap(err, "error getting peer id"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return model{
|
|
|
|
|
filters: []string{
|
|
|
|
|
hex.EncodeToString([]byte{
|
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
|
}),
|
2024-01-03 07:31:42 +00:00
|
|
|
|
hex.EncodeToString(append(
|
|
|
|
|
p2p.GetBloomFilter(application.CEREMONY_ADDRESS, 256, 3),
|
|
|
|
|
p2p.GetBloomFilterIndices(application.CEREMONY_ADDRESS, 65536, 24)...,
|
|
|
|
|
)),
|
2023-11-27 02:51:46 +00:00
|
|
|
|
},
|
2024-01-15 04:32:28 +00:00
|
|
|
|
cursor: 0,
|
|
|
|
|
conn: conn,
|
|
|
|
|
client: protobufs.NewNodeServiceClient(conn),
|
|
|
|
|
owned: big.NewInt(-1),
|
|
|
|
|
unconfirmedOwned: big.NewInt(-1),
|
|
|
|
|
peerId: id.String(),
|
|
|
|
|
grpcWarn: grpcWarn,
|
2023-11-27 02:51:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-29 21:11:40 +00:00
|
|
|
|
var defaultGrpcAddress = "localhost:8337"
|
|
|
|
|
|
|
|
|
|
// Connect to the node via GRPC
|
|
|
|
|
func ConnectToNode(nodeConfig *config.Config) (*grpc.ClientConn, error) {
|
|
|
|
|
addr := defaultGrpcAddress
|
|
|
|
|
if nodeConfig.ListenGRPCMultiaddr != "" {
|
|
|
|
|
ma, err := multiaddr.NewMultiaddr(nodeConfig.ListenGRPCMultiaddr)
|
2023-11-27 02:51:46 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, addr, err = mn.DialArgs(ma)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-29 21:11:40 +00:00
|
|
|
|
return grpc.Dial(
|
2023-11-27 02:51:46 +00:00
|
|
|
|
addr,
|
|
|
|
|
grpc.WithTransportCredentials(
|
|
|
|
|
insecure.NewCredentials(),
|
|
|
|
|
),
|
|
|
|
|
grpc.WithDefaultCallOptions(
|
|
|
|
|
grpc.MaxCallSendMsgSize(600*1024*1024),
|
|
|
|
|
grpc.MaxCallRecvMsgSize(600*1024*1024),
|
|
|
|
|
),
|
|
|
|
|
)
|
2024-01-29 21:11:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type TokenBalance struct {
|
|
|
|
|
Owned *big.Int
|
|
|
|
|
UnconfirmedOwned *big.Int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FetchTokenBalance(client protobufs.NodeServiceClient) (TokenBalance, error) {
|
|
|
|
|
info, err := client.GetTokenInfo(
|
|
|
|
|
context.Background(),
|
|
|
|
|
&protobufs.GetTokenInfoRequest{},
|
|
|
|
|
)
|
2023-11-27 02:51:46 +00:00
|
|
|
|
if err != nil {
|
2024-01-29 21:11:40 +00:00
|
|
|
|
return TokenBalance{}, errors.Wrap(err, "error getting token info")
|
2023-11-27 02:51:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-29 21:11:40 +00:00
|
|
|
|
conversionFactor, _ := new(big.Int).SetString("1DCD65000", 16)
|
|
|
|
|
|
|
|
|
|
owned := new(big.Int).SetBytes(info.OwnedTokens)
|
|
|
|
|
owned.Div(owned, conversionFactor)
|
|
|
|
|
|
|
|
|
|
unconfirmedOwned := new(big.Int).SetBytes(info.UnconfirmedOwnedTokens)
|
|
|
|
|
unconfirmedOwned.Div(unconfirmedOwned, conversionFactor)
|
|
|
|
|
|
|
|
|
|
return TokenBalance{
|
|
|
|
|
Owned: owned,
|
|
|
|
|
UnconfirmedOwned: unconfirmedOwned,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Runs the DB console
|
|
|
|
|
func (c *DBConsole) Run() {
|
|
|
|
|
conn, err := ConnectToNode(c.nodeConfig)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
2023-11-27 02:51:46 +00:00
|
|
|
|
defer conn.Close()
|
2024-01-29 21:11:40 +00:00
|
|
|
|
|
|
|
|
|
grpcWarn := c.nodeConfig.ListenGRPCMultiaddr == ""
|
|
|
|
|
|
2023-11-27 02:51:46 +00:00
|
|
|
|
p := tea.NewProgram(consoleModel(conn, c.nodeConfig, grpcWarn))
|
|
|
|
|
if _, err := p.Run(); err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func logoVersion(width int) string {
|
|
|
|
|
var out string
|
|
|
|
|
|
|
|
|
|
if width >= 83 {
|
|
|
|
|
out = " %#########\n"
|
|
|
|
|
out += " #############################\n"
|
|
|
|
|
out += " ########################################&\n"
|
|
|
|
|
out += " ###############################################\n"
|
|
|
|
|
out += " &#####################% %######################\n"
|
|
|
|
|
out += " ################# #################\n"
|
|
|
|
|
out += " ############### ###############\n"
|
|
|
|
|
out += " ############# ##############\n"
|
|
|
|
|
out += " ############# ############&\n"
|
|
|
|
|
out += " ############ ############\n"
|
|
|
|
|
out += " ########### ########## &###########\n"
|
|
|
|
|
out += " ########### ############## ###########\n"
|
|
|
|
|
out += " ########### ############## ##########&\n"
|
|
|
|
|
out += " ########## ############## ##########\n"
|
|
|
|
|
out += "%########## ########## ##########\n"
|
|
|
|
|
out += "##########& ##########\n"
|
|
|
|
|
out += "########## &#########\n"
|
|
|
|
|
out += "##########& ####### ####### ##########\n"
|
|
|
|
|
out += " ########## &######################### ##########\n"
|
|
|
|
|
out += " ########## ##############% ############## &##########\n"
|
|
|
|
|
out += " %########## &############## ############### ##########\n"
|
|
|
|
|
out += " ########### ############### ##############% ###########\n"
|
|
|
|
|
out += " ###########& ########## ############### ########\n"
|
|
|
|
|
out += " ############ ##### ##############% ####\n"
|
|
|
|
|
out += " ############ ###############\n"
|
|
|
|
|
out += " ############## ##############%\n"
|
|
|
|
|
out += " ############### ###############\n"
|
|
|
|
|
out += " #################& ##############%\n"
|
|
|
|
|
out += " #########################&&&############# ###############\n"
|
|
|
|
|
out += " ########################################% ############\n"
|
|
|
|
|
out += " ####################################### ########\n"
|
|
|
|
|
out += " ############################# ##\n"
|
|
|
|
|
out += " \n"
|
2024-02-20 20:01:10 +00:00
|
|
|
|
out += " Quilibrium Node - v1.2.11 – Dawn\n"
|
2023-11-27 02:51:46 +00:00
|
|
|
|
out += " \n"
|
|
|
|
|
out += " DB Console\n"
|
|
|
|
|
} else {
|
2024-02-20 20:01:10 +00:00
|
|
|
|
out = "Quilibrium Node - v1.2.11 – Dawn - DB Console\n"
|
2023-09-09 23:45:47 +00:00
|
|
|
|
}
|
2023-11-27 02:51:46 +00:00
|
|
|
|
return out
|
2023-09-09 23:45:47 +00:00
|
|
|
|
}
|