Skip to content

Commit

Permalink
DVT-359 DVT-360 Monitor command should support scrolling through bloc…
Browse files Browse the repository at this point in the history
…ks (#22)

* feat: add block time colume with placeholder value

* fix: change value to raw block time

* fix: show correct block time

* feat: pageup and pagedown moves block cursor

* feat: use list instead of table

* fix: add table like view

* fix: column resize smulation

* rm codecovg

* fix: logs conditions

* fix: string replacement

* fix: remove selected block index and use builtin

* lint fix

* fix: loop through block fetch instead of batch call

* fix: pause update when in scroll mode

* review fixes

* fix: add verbosity

* fix: fix the selected row span

* exponential backoff

* fix: load blocks as reach end of list

* fix: lint
  • Loading branch information
gatsbyz authored Dec 15, 2022
1 parent 6012615 commit 1d0b717
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 113 deletions.
32 changes: 1 addition & 31 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,4 @@ jobs:
- name: Install shadow
run: go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
- name: Run shadow
run: shadow ./...
test:
if: (github.event.action != 'closed' || github.event.pull_request.merged == true)
runs-on: ubuntu-latest
name: Update coverage
steps:
- uses: actions/checkout@v3

- uses: actions/setup-go@v3
with:
go-version: 1.19.x

- uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/Library/Caches/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-go-

- name: Run Test
run: go test -v ./... -covermode=count -coverprofile=coverage.out

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.out
fail_ci_if_error: true # optional (default = false)
verbose: true # optional (default = false)
run: shadow ./...
158 changes: 98 additions & 60 deletions cmd/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,18 @@ import (
"github.com/ethereum/go-ethereum/ethclient"
ethrpc "github.com/ethereum/go-ethereum/rpc"

"github.com/cenkalti/backoff"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
"github.com/maticnetwork/polygon-cli/metrics"
"github.com/maticnetwork/polygon-cli/rpctypes"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

var inputBatchSize *uint64
var verbosity *int64

type (
monitorStatus struct {
Expand Down Expand Up @@ -137,14 +140,14 @@ var monitorCmd = &cobra.Command{

from := big.NewInt(0)

batchSize := defaultBatchSize
if *inputBatchSize > 0 {
batchSize = *inputBatchSize
}
// batchSize := *inputBatchSize
// if *inputBatchSize > 0 {
// batchSize = *inputBatchSize
// }

// if the max block is 0, meaning we haven't fetched any blocks, we're going to start with head - batchSize
if ms.MaxBlockRetrieved.Cmp(from) == 0 {
headBlockMinusBatchSize := new(big.Int).SetUint64(batchSize - 1)
headBlockMinusBatchSize := new(big.Int).SetUint64(50 - 1)
from.Sub(ms.HeadBlock, headBlockMinusBatchSize)
} else {
from = ms.MaxBlockRetrieved
Expand Down Expand Up @@ -174,7 +177,7 @@ var monitorCmd = &cobra.Command{
},
Args: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return fmt.Errorf("expected exactly one argument")
return fmt.Errorf("too many arguments")
}

// validate url argument
Expand All @@ -189,6 +192,8 @@ var monitorCmd = &cobra.Command{
return fmt.Errorf("batch-size can't be equal to zero")
}

setMonitorLogLevel(*verbosity)

return nil
},
}
Expand All @@ -206,7 +211,13 @@ func (ms *monitorStatus) getBlockRange(ctx context.Context, from, to *big.Int, c
Error: err,
})
}
err := c.BatchCallContext(ctx, blms)
b := backoff.NewExponentialBackOff()
b.MaxElapsedTime = 3 * time.Minute
retryable := func() error {
err := c.BatchCallContext(ctx, blms)
return err
}
err := backoff.Retry(retryable, b)
if err != nil {
return err
}
Expand All @@ -231,7 +242,8 @@ func (ms *monitorStatus) getBlockRange(ctx context.Context, from, to *big.Int, c
func init() {
rootCmd.AddCommand(monitorCmd)

inputBatchSize = monitorCmd.PersistentFlags().Uint64P("batch-size", "b", 25, "Number of requests per batch")
inputBatchSize = monitorCmd.PersistentFlags().Uint64P("batch-size", "b", defaultBatchSize, "Number of requests per batch")
verbosity = monitorCmd.PersistentFlags().Int64P("verbosity", "v", 200, "0 - Silent\n100 Fatals\n200 Errors\n300 Warnings\n400 INFO\n500 Debug\n600 Trace")
}

func renderMonitorUI(ms *monitorStatus) error {
Expand All @@ -242,24 +254,9 @@ func renderMonitorUI(ms *monitorStatus) error {

currentMode := monitorModeExplorer

blockTable := widgets.NewTable()
blockTable := widgets.NewList()

blockTable.TextStyle = ui.NewStyle(ui.ColorWhite)
blockTable.RowSeparator = true

columnWidths := make([]int, 6)

blockTable.ColumnResizer = func() {
defaultWidth := (blockTable.Inner.Dx() - (12 + 22 + 42 + 12 + 14)) / 1
columnWidths[0] = 12
columnWidths[1] = 22
columnWidths[2] = defaultWidth
columnWidths[3] = 42
columnWidths[4] = 12
columnWidths[5] = 14
}

blockTable.ColumnWidths = columnWidths

h0 := widgets.NewParagraph()
h0.Title = "Current"
Expand Down Expand Up @@ -343,16 +340,17 @@ func renderMonitorUI(ms *monitorStatus) error {
ui.NewCol(1.0/5, slg3),
ui.NewCol(1.0/5, slg4),
),
ui.NewRow(3.0/5, blockTable),
ui.NewRow(2.5/5, blockTable),
)

termWidth, termHeight := ui.TerminalDimensions()
grid.SetRect(0, 0, termWidth, termHeight)
blockGrid.SetRect(0, 0, termWidth, termHeight)

var selectedBlockIdx *int
var selectedBlock rpctypes.PolyBlock
var setBlock = false
var allBlocks metrics.SortableBlocks
var recentBlocks metrics.SortableBlocks

redraw := func(ms *monitorStatus) {
if currentMode == monitorModeHelp {
Expand All @@ -367,20 +365,22 @@ func renderMonitorUI(ms *monitorStatus) error {
return
}

//default
blocks := make([]rpctypes.PolyBlock, 0)
if blockTable.SelectedRow == 0 {
//default
blocks := make([]rpctypes.PolyBlock, 0)

ms.BlocksLock.RLock()
for _, b := range ms.Blocks {
blocks = append(blocks, b)
}
ms.BlocksLock.RUnlock()

ms.BlocksLock.RLock()
for _, b := range ms.Blocks {
blocks = append(blocks, b)
allBlocks = metrics.SortableBlocks(blocks)
sort.Sort(allBlocks)
}
ms.BlocksLock.RUnlock()

recentBlocks := metrics.SortableBlocks(blocks)
sort.Sort(recentBlocks)
// 25 needs to be a variable / parameter
if len(recentBlocks) > 25 {
recentBlocks = recentBlocks[len(recentBlocks)-25:]
if uint64(len(allBlocks)) > *inputBatchSize {
recentBlocks = allBlocks[uint64(len(allBlocks))-*inputBatchSize:]
}

h0.Text = fmt.Sprintf("Height: %s\nTime: %s", ms.HeadBlock.String(), time.Now().Format("02 Jan 06 15:04:05 MST"))
Expand All @@ -398,25 +398,16 @@ func renderMonitorUI(ms *monitorStatus) error {
sl4.Data = metrics.GetGasPerBlock(recentBlocks)

// assuming we haven't selected a particular row... we should get new blocks
if selectedBlockIdx == nil {
blockTable.Rows = metrics.GetSimpleBlockRecords(recentBlocks)
}
if len(columnWidths) != len(blockTable.Rows[0]) {
// i've messed up
panic("Mis matched between columns and specified widths")
}

for i := 0; i < len(blockTable.Rows); i = i + 1 {
blockTable.RowStyles[i] = ui.NewStyle(ui.ColorWhite)
}
if selectedBlockIdx != nil && *selectedBlockIdx > 0 && *selectedBlockIdx < len(blockTable.Rows) {

blockTable.RowStyles[*selectedBlockIdx] = ui.NewStyle(ui.ColorWhite, ui.ColorRed, ui.ModifierBold)
// the block table is reversed and has an extra row for the header
rows, title := metrics.GetSimpleBlockRecords(recentBlocks)
blockTable.Rows = rows
blockTable.Title = title

blockTable.TextStyle = ui.NewStyle(ui.ColorWhite)
blockTable.SelectedRowStyle = ui.NewStyle(ui.ColorWhite, ui.ColorRed, ui.ModifierBold)
if blockTable.SelectedRow > 0 && blockTable.SelectedRow <= len(blockTable.Rows) {
// only changed the selected block when the user presses the up down keys. Otherwise this will adjust when the table is updated automatically
if setBlock {
selectedBlock = recentBlocks[len(recentBlocks)-*selectedBlockIdx]
selectedBlock = recentBlocks[len(recentBlocks)-blockTable.SelectedRow]
setBlock = false
}

Expand All @@ -439,12 +430,12 @@ func renderMonitorUI(ms *monitorStatus) error {
case "q", "<C-c>":
return nil
case "<Escape>":
selectedBlockIdx = nil
blockTable.SelectedRow = 0
currentMode = monitorModeExplorer
redraw(ms)
case "<Enter>":
// TODO
if selectedBlockIdx != nil {
if blockTable.SelectedRow > 0 {
currentMode = monitorModeBlock
}
redraw(ms)
Expand All @@ -464,6 +455,27 @@ func renderMonitorUI(ms *monitorStatus) error {
redraw(ms)
break
}
if blockTable.SelectedRow == 0 {
currIdx = 1
blockTable.SelectedRow = currIdx
setBlock = true
redraw(ms)
break
}
currIdx = blockTable.SelectedRow

if e.ID == "<PageDown>" {
currIdx = currIdx + 1
setBlock = true
} else if e.ID == "<PageUp>" {
currIdx = currIdx - 1
setBlock = true
}
if currIdx >= 0 && uint64(currIdx) <= *inputBatchSize { // need a better way to understand how many rows are visible
blockTable.SelectedRow = currIdx
}

redraw(ms)
case "<Up>", "<Down>", "<Left>", "<Right>":
if currentMode == monitorModeBlock {
if e.ID == "<Down>" {
Expand All @@ -474,24 +486,32 @@ func renderMonitorUI(ms *monitorStatus) error {
redraw(ms)
break
}
if selectedBlockIdx == nil {
if blockTable.SelectedRow == 0 {
currIdx = 1
selectedBlockIdx = &currIdx
blockTable.SelectedRow = currIdx
setBlock = true
redraw(ms)
break
}
currIdx = *selectedBlockIdx
currIdx = blockTable.SelectedRow

if e.ID == "<Down>" {
if currIdx > int(*inputBatchSize)-1 {
if int(*inputBatchSize)+10 < len(allBlocks) {
*inputBatchSize = *inputBatchSize + 10
} else {
*inputBatchSize = uint64(len(allBlocks)) - 1
break
}
}
currIdx = currIdx + 1
setBlock = true
} else if e.ID == "<Up>" {
currIdx = currIdx - 1
setBlock = true
}
if currIdx > 0 && currIdx < 25 { // need a better way to understand how many rows are visble
selectedBlockIdx = &currIdx
if currIdx >= 0 && uint64(currIdx) <= *inputBatchSize { // need a better way to understand how many rows are visble
blockTable.SelectedRow = currIdx
}

redraw(ms)
Expand All @@ -508,3 +528,21 @@ func renderMonitorUI(ms *monitorStatus) error {
}
}
}

func setMonitorLogLevel(verbosity int64) {
if verbosity < 100 {
zerolog.SetGlobalLevel(zerolog.PanicLevel)
} else if verbosity < 200 {
zerolog.SetGlobalLevel(zerolog.FatalLevel)
} else if verbosity < 300 {
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
} else if verbosity < 400 {
zerolog.SetGlobalLevel(zerolog.WarnLevel)
} else if verbosity < 500 {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
} else if verbosity < 600 {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
} else {
zerolog.SetGlobalLevel(zerolog.TraceLevel)
}
}
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ require (
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9
)

require github.com/cenkalti/backoff v2.2.1+incompatible // indirect

require (
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect
Expand Down Expand Up @@ -102,7 +104,8 @@ require (
github.com/tklauser/numcpus v0.2.2 // indirect
github.com/vedhavyas/go-subkey v1.0.3 // indirect
golang.org/x/exp v0.0.0-20221114191408-850992195362
golang.org/x/sys v0.1.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/term v0.3.0
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/bwesterb/go-ristretto v1.2.0 h1:xxWOVbN5m8NNKiSDZXE1jtZvZnC6JSJ9cYFADiZcWtw=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
Expand Down Expand Up @@ -656,8 +658,12 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
Loading

0 comments on commit 1d0b717

Please sign in to comment.