github.com/shrimpyuk/bor@v0.2.15-0.20220224151350-fb4ec6020bae/internal/cli/chain_watch.go (about)

     1  package cli
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"os/signal"
     8  	"syscall"
     9  
    10  	"github.com/ethereum/go-ethereum/core"
    11  	"github.com/ethereum/go-ethereum/internal/cli/flagset"
    12  	"github.com/ethereum/go-ethereum/internal/cli/server/proto"
    13  )
    14  
    15  // ChainWatchCommand is the command to group the peers commands
    16  type ChainWatchCommand struct {
    17  	*Meta2
    18  }
    19  
    20  // Help implements the cli.Command interface
    21  func (c *ChainWatchCommand) Help() string {
    22  	return `Usage: bor chain watch
    23  
    24    This command is used to view the chainHead, reorg and fork events in real-time`
    25  }
    26  
    27  func (c *ChainWatchCommand) Flags() *flagset.Flagset {
    28  	flags := c.NewFlagSet("chain watch")
    29  
    30  	return flags
    31  }
    32  
    33  // Synopsis implements the cli.Command interface
    34  func (c *ChainWatchCommand) Synopsis() string {
    35  	return "Watch the chainHead, reorg and fork events in real-time"
    36  }
    37  
    38  // Run implements the cli.Command interface
    39  func (c *ChainWatchCommand) Run(args []string) int {
    40  	flags := c.Flags()
    41  	if err := flags.Parse(args); err != nil {
    42  		c.UI.Error(err.Error())
    43  		return 1
    44  	}
    45  
    46  	borClt, err := c.BorConn()
    47  	if err != nil {
    48  		c.UI.Error(err.Error())
    49  		return 1
    50  	}
    51  
    52  	sub, err := borClt.ChainWatch(context.Background(), &proto.ChainWatchRequest{})
    53  	if err != nil {
    54  		c.UI.Error(err.Error())
    55  		return 1
    56  	}
    57  
    58  	signalCh := make(chan os.Signal, 1)
    59  	signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
    60  
    61  	go func() {
    62  		<-signalCh
    63  		sub.CloseSend()
    64  	}()
    65  
    66  	for {
    67  		msg, err := sub.Recv()
    68  		if err != nil {
    69  			// if err == EOF if finished on the other side
    70  			c.UI.Output(err.Error())
    71  			break
    72  		}
    73  		c.UI.Output(formatHeadEvent(msg))
    74  	}
    75  
    76  	return 0
    77  }
    78  
    79  func formatHeadEvent(msg *proto.ChainWatchResponse) string {
    80  	var out string
    81  	if msg.Type == core.Chain2HeadCanonicalEvent {
    82  		out = fmt.Sprintf("Block Added : %v", msg.Newchain)
    83  	} else if msg.Type == core.Chain2HeadForkEvent {
    84  		out = fmt.Sprintf("New Fork Block : %v", msg.Newchain)
    85  	} else if msg.Type == core.Chain2HeadReorgEvent {
    86  		out = fmt.Sprintf("Reorg Detected \nAdded : %v \nRemoved : %v", msg.Newchain, msg.Oldchain)
    87  	}
    88  	return out
    89  }