github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/internal/cli/debug_block.go (about)

     1  package cli
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/ethereum/go-ethereum/internal/cli/flagset"
    10  	"github.com/ethereum/go-ethereum/internal/cli/server/proto"
    11  )
    12  
    13  // DebugBlockCommand is the command to group the peers commands
    14  type DebugBlockCommand struct {
    15  	*Meta2
    16  
    17  	output string
    18  }
    19  
    20  func (p *DebugBlockCommand) MarkDown() string {
    21  	items := []string{
    22  		"# Debug trace",
    23  		"The ```bor debug block <number>``` command will create an archive containing traces of a bor block.",
    24  		p.Flags().MarkDown(),
    25  	}
    26  
    27  	return strings.Join(items, "\n\n")
    28  }
    29  
    30  // Help implements the cli.Command interface
    31  func (c *DebugBlockCommand) Help() string {
    32  	return `Usage: bor debug block <number>
    33  
    34    This command is used get traces of a bor block`
    35  }
    36  
    37  func (c *DebugBlockCommand) Flags() *flagset.Flagset {
    38  	flags := c.NewFlagSet("trace")
    39  
    40  	flags.StringFlag(&flagset.StringFlag{
    41  		Name:  "output",
    42  		Value: &c.output,
    43  		Usage: "Output directory",
    44  	})
    45  
    46  	return flags
    47  }
    48  
    49  // Synopsis implements the cli.Command interface
    50  func (c *DebugBlockCommand) Synopsis() string {
    51  	return "Get trace of a bor block"
    52  }
    53  
    54  // Run implements the cli.Command interface
    55  func (c *DebugBlockCommand) Run(args []string) int {
    56  	flags := c.Flags()
    57  
    58  	var number *int64 = nil
    59  
    60  	// parse the block number (if available)
    61  	if len(args)%2 != 0 {
    62  		num, err := strconv.ParseInt(args[0], 10, 64)
    63  		if err == nil {
    64  			number = &num
    65  		}
    66  
    67  		args = args[1:]
    68  	}
    69  	// parse output directory
    70  	if err := flags.Parse(args); err != nil {
    71  		c.UI.Error(err.Error())
    72  		return 1
    73  	}
    74  
    75  	borClt, err := c.BorConn()
    76  	if err != nil {
    77  		c.UI.Error(err.Error())
    78  		return 1
    79  	}
    80  
    81  	dEnv := &debugEnv{
    82  		output: c.output,
    83  		prefix: "bor-block-trace-",
    84  	}
    85  	if err := dEnv.init(); err != nil {
    86  		c.UI.Error(err.Error())
    87  		return 1
    88  	}
    89  
    90  	c.UI.Output("Starting block tracer...")
    91  	c.UI.Output("")
    92  
    93  	// create a debug block request
    94  	var debugRequest *proto.DebugBlockRequest = &proto.DebugBlockRequest{}
    95  	if number != nil {
    96  		debugRequest.Number = *number
    97  	} else {
    98  		debugRequest.Number = -1
    99  	}
   100  
   101  	// send the request
   102  	// receives a grpc stream of debug block response
   103  	stream, err := borClt.DebugBlock(context.Background(), debugRequest)
   104  	if err != nil {
   105  		c.UI.Error(err.Error())
   106  		return 1
   107  	}
   108  
   109  	if err := dEnv.writeFromStream("block.json", stream); err != nil {
   110  		c.UI.Error(err.Error())
   111  		return 1
   112  	}
   113  
   114  	if err := dEnv.finish(); err != nil {
   115  		c.UI.Error(err.Error())
   116  		return 1
   117  	}
   118  
   119  	if c.output != "" {
   120  		c.UI.Output(fmt.Sprintf("Created debug directory: %s", dEnv.dst))
   121  	} else {
   122  		c.UI.Output(fmt.Sprintf("Created block trace archive: %s", dEnv.tarName()))
   123  	}
   124  
   125  	return 0
   126  }