github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/test/loadtime/cmd/report/main.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/csv"
     5  	"flag"
     6  	"fmt"
     7  	"log"
     8  	"os"
     9  	"strconv"
    10  	"strings"
    11  
    12  	dbm "github.com/badrootd/nibiru-db"
    13  	"github.com/badrootd/nibiru-cometbft/store"
    14  	"github.com/badrootd/nibiru-cometbft/test/loadtime/report"
    15  )
    16  
    17  var (
    18  	db     = flag.String("database-type", "goleveldb", "the type of database holding the blockstore")
    19  	dir    = flag.String("data-dir", "", "path to the directory containing the CometBFT databases")
    20  	csvOut = flag.String("csv", "", "dump the extracted latencies as raw csv for use in additional tooling")
    21  )
    22  
    23  func main() {
    24  	flag.Parse()
    25  	if *db == "" {
    26  		log.Fatalf("must specify a database-type")
    27  	}
    28  	if *dir == "" {
    29  		log.Fatalf("must specify a data-dir")
    30  	}
    31  	d := strings.TrimPrefix(*dir, "~/")
    32  	if d != *dir {
    33  		h, err := os.UserHomeDir()
    34  		if err != nil {
    35  			panic(err)
    36  		}
    37  		d = h + "/" + d
    38  	}
    39  	_, err := os.Stat(d)
    40  	if err != nil {
    41  		panic(err)
    42  	}
    43  	dbType := dbm.BackendType(*db)
    44  	db, err := dbm.NewDB("blockstore", dbType, d)
    45  	if err != nil {
    46  		panic(err)
    47  	}
    48  	s := store.NewBlockStore(db)
    49  	defer s.Close()
    50  	rs, err := report.GenerateFromBlockStore(s)
    51  	if err != nil {
    52  		panic(err)
    53  	}
    54  	if *csvOut != "" {
    55  		cf, err := os.Create(*csvOut)
    56  		if err != nil {
    57  			panic(err)
    58  		}
    59  		w := csv.NewWriter(cf)
    60  		err = w.WriteAll(toCSVRecords(rs.List()))
    61  		if err != nil {
    62  			panic(err)
    63  		}
    64  		return
    65  	}
    66  	for _, r := range rs.List() {
    67  		fmt.Printf(""+
    68  			"Experiment ID: %s\n\n"+
    69  			"\tConnections: %d\n"+
    70  			"\tRate: %d\n"+
    71  			"\tSize: %d\n\n"+
    72  			"\tTotal Valid Tx: %d\n"+
    73  			"\tTotal Negative Latencies: %d\n"+
    74  			"\tMinimum Latency: %s\n"+
    75  			"\tMaximum Latency: %s\n"+
    76  			"\tAverage Latency: %s\n"+
    77  			"\tStandard Deviation: %s\n\n", r.ID, r.Connections, r.Rate, r.Size, len(r.All), r.NegativeCount, r.Min, r.Max, r.Avg, r.StdDev) //nolint: lll
    78  
    79  	}
    80  	fmt.Printf("Total Invalid Tx: %d\n", rs.ErrorCount())
    81  }
    82  
    83  func toCSVRecords(rs []report.Report) [][]string {
    84  	total := 0
    85  	for _, v := range rs {
    86  		total += len(v.All)
    87  	}
    88  	res := make([][]string, total+1)
    89  
    90  	res[0] = []string{"experiment_id", "block_time", "duration_ns", "tx_hash", "connections", "rate", "size"}
    91  	offset := 1
    92  	for _, r := range rs {
    93  		idStr := r.ID.String()
    94  		connStr := strconv.FormatInt(int64(r.Connections), 10)
    95  		rateStr := strconv.FormatInt(int64(r.Rate), 10)
    96  		sizeStr := strconv.FormatInt(int64(r.Size), 10)
    97  		for i, v := range r.All {
    98  			res[offset+i] = []string{idStr, strconv.FormatInt(v.BlockTime.UnixNano(), 10), strconv.FormatInt(int64(v.Duration), 10), fmt.Sprintf("%X", v.Hash), connStr, rateStr, sizeStr}
    99  		}
   100  		offset += len(r.All)
   101  	}
   102  	return res
   103  }