From 76be2f13004724c9b0dda79b9c02df59308c5ca2 Mon Sep 17 00:00:00 2001 From: "Masih H. Derkani" Date: Fri, 18 Oct 2024 18:08:18 +0100 Subject: [PATCH] Implement Lotus F3 CLI commands for general diagnostics Implement `lotus f3` CLI sub commands: * `manifest` to dump the current F3 manifest in either JSON or text. * `list-miners` to list the current F3 participants. * `status` to print summary status of F3. Part of #12607 --- CHANGELOG.md | 1 + cli/clicommands/cmd.go | 1 + cli/f3.go | 180 ++++++++++++++++++++++++++++++++++ documentation/en/cli-lotus.md | 56 +++++++++++ 4 files changed, 238 insertions(+) create mode 100644 cli/f3.go diff --git a/CHANGELOG.md b/CHANGELOG.md index d12f32df9fb..5354a196c2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - `lotus chain head` now supports a `--height` flag to print just the epoch number of the current chain head ([filecoin-project/lotus#12609](https://github.com/filecoin-project/lotus/pull/12609)) - `lotus-shed indexes inspect-indexes` now performs a comprehensive comparison of the event index data for each message by comparing the AMT root CID from the message receipt with the root of a reconstructed AMT. Previously `inspect-indexes` simply compared event counts, comparing AMT roots confirms all the event data is byte-perfect. ([filecoin-project/lotus#12570](https://github.com/filecoin-project/lotus/pull/12570)) - Expose APIs to list the miner IDs that are currently participating in F3 via node. ([filecoin-project/lotus#12608](https://github.com/filecoin-project/lotus/pull/12608)) +- Implement new `lotus f3` CLI commands to list F3 participants, dump manifest and check the F3 status. ([filecoin-project/lotus#12617](https://github.com/filecoin-project/lotus/pull/12617)) ## Bug Fixes - Fix a bug in the `lotus-shed indexes backfill-events` command that may result in either duplicate events being backfilled where there are existing events (such an operation *should* be idempotent) or events erroneously having duplicate `logIndex` values when queried via ETH APIs. ([filecoin-project/lotus#12567](https://github.com/filecoin-project/lotus/pull/12567)) diff --git a/cli/clicommands/cmd.go b/cli/clicommands/cmd.go index 791a11927d7..44709de45fb 100644 --- a/cli/clicommands/cmd.go +++ b/cli/clicommands/cmd.go @@ -23,6 +23,7 @@ var Commands = []*cli.Command{ lcli.WithCategory("developer", lcli.EvmCmd), lcli.WithCategory("network", lcli.NetCmd), lcli.WithCategory("network", lcli.SyncCmd), + lcli.WithCategory("network", lcli.F3Cmd), lcli.WithCategory("status", lcli.StatusCmd), lcli.PprofCmd, lcli.VersionCmd, diff --git a/cli/f3.go b/cli/f3.go new file mode 100644 index 00000000000..53c6d71721f --- /dev/null +++ b/cli/f3.go @@ -0,0 +1,180 @@ +package cli + +import ( + "encoding/json" + "fmt" + "io" + "strings" + "text/template" + + "github.com/urfave/cli/v2" + + "github.com/filecoin-project/go-f3/manifest" + + "github.com/filecoin-project/lotus/lib/tablewriter" +) + +var ( + F3Cmd = &cli.Command{ + Name: "f3", + Usage: "Manages Filecoin Fast Finality (F3) interactions", + Subcommands: []*cli.Command{ + { + Name: "list-miners", + Aliases: []string{"lp"}, + Usage: "Lists the miners that currently participate in F3 via this node.", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPIV1(cctx) + if err != nil { + return err + } + defer closer() + + miners, err := api.F3ListParticipants(cctx.Context) + if err != nil { + return fmt.Errorf("listing participants: %w", err) + } + if len(miners) == 0 { + _, err = fmt.Fprintln(cctx.App.Writer, "No miners.") + return err + } + const ( + idColumn = "ID" + fromColumn = "From" + ToColumn = "To" + ) + tw := tablewriter.New( + tablewriter.Col(idColumn), + tablewriter.Col(fromColumn), + tablewriter.Col(ToColumn), + ) + for _, participant := range miners { + tw.Write(map[string]interface{}{ + idColumn: participant.MinerID, + fromColumn: participant.FromInstance, + ToColumn: participant.FromInstance + participant.ValidityTerm, + }) + } + return tw.Flush(cctx.App.Writer) + }, + }, + { + Name: "manifest", + Usage: "Gets the current manifest used by F3.", + Flags: []cli.Flag{f3FlagOutput}, + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPIV1(cctx) + if err != nil { + return err + } + defer closer() + + manifest, err := api.F3GetManifest(cctx.Context) + if err != nil { + return fmt.Errorf("getting manifest: %w", err) + } + switch output := cctx.String(f3FlagOutput.Name); strings.ToLower(output) { + case "text": + return prettyPrintManifest(cctx.App.Writer, manifest) + case "json": + encoder := json.NewEncoder(cctx.App.Writer) + encoder.SetIndent("", " ") + return encoder.Encode(manifest) + default: + return fmt.Errorf("unknown output format: %s", output) + } + }, + }, + { + Name: "status", + Usage: "Checks the F3 status.", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPIV1(cctx) + if err != nil { + return err + } + defer closer() + + running, err := api.F3IsRunning(cctx.Context) + if err != nil { + return fmt.Errorf("getting running state: %w", err) + } + _, _ = fmt.Fprintf(cctx.App.Writer, "Running: %t\n", running) + if !running { + return nil + } + + progress, err := api.F3GetProgress(cctx.Context) + if err != nil { + return fmt.Errorf("getting progress: %w", err) + } + + _, _ = fmt.Fprintln(cctx.App.Writer, "Progress:") + _, _ = fmt.Fprintf(cctx.App.Writer, " Instance: %d\n", progress.ID) + _, _ = fmt.Fprintf(cctx.App.Writer, " Round: %d\n", progress.Round) + _, _ = fmt.Fprintf(cctx.App.Writer, " Phase: %s\n", progress.Phase) + + manifest, err := api.F3GetManifest(cctx.Context) + if err != nil { + return fmt.Errorf("getting manifest: %w", err) + } + return prettyPrintManifest(cctx.App.Writer, manifest) + }, + }, + }, + } + + // TODO: we should standardise format as a top level flag. For now, here is an f3 + // specific one. + // See: https://github.com/filecoin-project/lotus/issues/12616 + f3FlagOutput = &cli.StringFlag{ + Name: "output", + Usage: "The output format. Supported formats: text, json", + Value: "text", + Action: func(cctx *cli.Context, output string) error { + switch output { + case "text", "json": + return nil + default: + return fmt.Errorf("unknown output format: %s", output) + } + }, + } +) + +func prettyPrintManifest(out io.Writer, manifest *manifest.Manifest) error { + if manifest == nil { + _, err := fmt.Fprintln(out, "Manifest: None") + return err + } + + const manifestTemplate = `Manifest: + Protocol Version: {{.ProtocolVersion}} + Paused: {{.Pause}} + Initial Instance: {{.InitialInstance}} + Bootstrap Epoch: {{.BootstrapEpoch}} + Network Name: {{.NetworkName}} + Ignore EC Power: {{.IgnoreECPower}} + Committee Lookback: {{.CommitteeLookback}} + Catch Up Alignment: {{.CatchUpAlignment}} + + GPBFT Delta: {{.Gpbft.Delta}} + GPBFT Delta BackOff Exponent: {{.Gpbft.DeltaBackOffExponent}} + GPBFT Max Lookahead Rounds: {{.Gpbft.MaxLookaheadRounds}} + GPBFT Rebroadcast Backoff Base: {{.Gpbft.RebroadcastBackoffBase}} + GPBFT Rebroadcast Backoff Spread: {{.Gpbft.RebroadcastBackoffSpread}} + GPBFT Rebroadcast Backoff Max: {{.Gpbft.RebroadcastBackoffMax}} + + EC Period: {{.EC.Period}} + EC Finality: {{.EC.Finality}} + EC Delay Multiplier: {{.EC.DelayMultiplier}} + EC Head Lookback: {{.EC.HeadLookback}} + EC Finalize: {{.EC.Finalize}} + + Certificate Exchange Client Timeout: {{.CertificateExchange.ClientRequestTimeout}} + Certificate Exchange Server Timeout: {{.CertificateExchange.ServerRequestTimeout}} + Certificate Exchange Min Poll Interval: {{.CertificateExchange.MinimumPollInterval}} + Certificate Exchange Max Poll Interval: {{.CertificateExchange.MaximumPollInterval}} +` + return template.New("manifest").ExecuteTemplate(out, manifestTemplate, manifest) +} diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index 02950a2ba56..b907cede22a 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -34,6 +34,7 @@ COMMANDS: NETWORK: net Manage P2P Network sync Inspect or interact with the chain syncer + f3 Manages Filecoin Fast Finality (F3) interactions STATUS: status Check node status @@ -2719,6 +2720,61 @@ OPTIONS: --help, -h show help ``` +## lotus f3 +``` +NAME: + lotus f3 - Manages Filecoin Fast Finality (F3) interactions + +USAGE: + lotus f3 command [command options] [arguments...] + +COMMANDS: + list-miners, lp Lists the miners that currently participate in F3 via this node. + manifest Gets the current manifest used by F3. + status Checks the F3 status. + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help +``` + +### lotus f3 list-miners +``` +NAME: + lotus f3 list-miners - Lists the miners that currently participate in F3 via this node. + +USAGE: + lotus f3 list-miners [command options] [arguments...] + +OPTIONS: + --help, -h show help +``` + +### lotus f3 manifest +``` +NAME: + lotus f3 manifest - Gets the current manifest used by F3. + +USAGE: + lotus f3 manifest [command options] [arguments...] + +OPTIONS: + --output value The output format. Supported formats: text, json (default: "text") + --help, -h show help +``` + +### lotus f3 status +``` +NAME: + lotus f3 status - Checks the F3 status. + +USAGE: + lotus f3 status [command options] [arguments...] + +OPTIONS: + --help, -h show help +``` + ## lotus status ``` NAME: