From eebd2efcbf76b71838e3387d69d14e0884d33e60 Mon Sep 17 00:00:00 2001 From: Travis Person Date: Sat, 5 Sep 2020 00:40:57 +0000 Subject: [PATCH] lotus-shed: add math command --- cmd/lotus-shed/main.go | 1 + cmd/lotus-shed/math.go | 103 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 cmd/lotus-shed/math.go diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 5438a31ef6d..fb931decfc1 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -31,6 +31,7 @@ func main() { miscCmd, mpoolCmd, genesisVerifyCmd, + mathCmd, } app := &cli.App{ diff --git a/cmd/lotus-shed/math.go b/cmd/lotus-shed/math.go new file mode 100644 index 00000000000..434559f09a0 --- /dev/null +++ b/cmd/lotus-shed/math.go @@ -0,0 +1,103 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "os" + "strings" + + "github.com/urfave/cli/v2" + + "github.com/filecoin-project/lotus/chain/types" +) + +var mathCmd = &cli.Command{ + Name: "math", + Usage: "utility commands around doing math on a list of numbers", + Subcommands: []*cli.Command{ + mathSumCmd, + }, +} + +func readLargeNumbers(i io.Reader) ([]types.BigInt, error) { + list := []types.BigInt{} + reader := bufio.NewReader(i) + + exit := false + for { + if exit { + break + } + + line, err := reader.ReadString('\n') + if err != nil && err != io.EOF { + break + } + if err == io.EOF { + exit = true + } + + line = strings.Trim(line, "\n") + + if len(line) == 0 { + continue + } + + value, err := types.BigFromString(line) + if err != nil { + return []types.BigInt{}, fmt.Errorf("failed to parse line: %s", line) + } + + list = append(list, value) + } + + return list, nil +} + +var mathSumCmd = &cli.Command{ + Name: "sum", + Usage: "Sum numbers", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "avg", + Value: false, + Usage: "Print the average instead of the sum", + }, + &cli.StringFlag{ + Name: "format", + Value: "raw", + Usage: "format the number in a more readable way [fil,bytes2,bytes10]", + }, + }, + Action: func(cctx *cli.Context) error { + list, err := readLargeNumbers(os.Stdin) + if err != nil { + return err + } + + val := types.NewInt(0) + for _, value := range list { + val = types.BigAdd(val, value) + } + + if cctx.Bool("avg") { + val = types.BigDiv(val, types.NewInt(uint64(len(list)))) + } + + switch cctx.String("format") { + case "byte2": + fmt.Printf("%s\n", types.SizeStr(val)) + case "byte10": + fmt.Printf("%s\n", types.DeciStr(val)) + case "fil": + fmt.Printf("%s\n", types.FIL(val)) + case "raw": + fmt.Printf("%s\n", val) + default: + return fmt.Errorf("Unknown format") + } + + return nil + }, +}