go-ethereum/internal/cli/chain_watch.go
2022-05-26 11:55:44 -07:00

105 lines
2.3 KiB
Go

package cli
import (
"context"
"fmt"
"os"
"os/signal"
"strings"
"syscall"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/internal/cli/flagset"
"github.com/ethereum/go-ethereum/internal/cli/server/proto"
)
// ChainWatchCommand is the command to group the peers commands
type ChainWatchCommand struct {
*Meta2
}
// MarkDown implements cli.MarkDown interface
func (c *ChainWatchCommand) MarkDown() string {
items := []string{
"# Chain watch",
"The ```chain watch``` command is used to view the chainHead, reorg and fork events in real-time.",
}
return strings.Join(items, "\n\n")
}
// Help implements the cli.Command interface
func (c *ChainWatchCommand) Help() string {
return `Usage: bor chain watch
This command is used to view the chainHead, reorg and fork events in real-time`
}
func (c *ChainWatchCommand) Flags() *flagset.Flagset {
flags := c.NewFlagSet("chain watch")
return flags
}
// Synopsis implements the cli.Command interface
func (c *ChainWatchCommand) Synopsis() string {
return "Watch the chainHead, reorg and fork events in real-time"
}
// Run implements the cli.Command interface
func (c *ChainWatchCommand) Run(args []string) int {
flags := c.Flags()
if err := flags.Parse(args); err != nil {
c.UI.Error(err.Error())
return 1
}
borClt, err := c.BorConn()
if err != nil {
c.UI.Error(err.Error())
return 1
}
sub, err := borClt.ChainWatch(context.Background(), &proto.ChainWatchRequest{})
if err != nil {
c.UI.Error(err.Error())
return 1
}
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
go func() {
<-signalCh
if err := sub.CloseSend(); err != nil {
c.UI.Error(err.Error())
}
}()
for {
msg, err := sub.Recv()
if err != nil {
// if err == EOF if finished on the other side
c.UI.Output(err.Error())
break
}
c.UI.Output(formatHeadEvent(msg))
}
return 0
}
func formatHeadEvent(msg *proto.ChainWatchResponse) string {
var out string
if msg.Type == core.Chain2HeadCanonicalEvent {
out = fmt.Sprintf("Block Added : %v", msg.Newchain)
} else if msg.Type == core.Chain2HeadForkEvent {
out = fmt.Sprintf("New Fork Block : %v", msg.Newchain)
} else if msg.Type == core.Chain2HeadReorgEvent {
out = fmt.Sprintf("Reorg Detected \nAdded : %v \nRemoved : %v", msg.Newchain, msg.Oldchain)
}
return out
}