Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple leader selection utility #7160

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions cmd/util/cmd/leaders/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package leaders

import (
"encoding/json"
"os"

"github.com/rs/zerolog/log"
"github.com/spf13/cobra"

"github.com/onflow/flow-go/cmd"
"github.com/onflow/flow-go/consensus/hotstuff/committees/leader"
"github.com/onflow/flow-go/model/flow"
"github.com/onflow/flow-go/state/protocol/inmem"
)

var (
flagStartView uint64
flagEndView uint64
)
var Cmd = &cobra.Command{
Use: "leaders",
Short: "Get leader selection for a view range.",
Long: `Get leader selection for a view range in the current epoch for a provided snapshot.
Expects a valid protocol state snapshot JSON to be piped into STDIN. Writes a JSON list of leaders for the given view range to STDOUT.`,
Run: run,
}

func init() {

Cmd.Flags().Uint64Var(&flagStartView, "start-view", 0, "the inclusive first view to get leader selection for")
Cmd.Flags().Uint64Var(&flagEndView, "end-view", 0, "the inclusive last view to get leader selection for")
cmd.MarkFlagRequired(Cmd, "start-view")
cmd.MarkFlagRequired(Cmd, "end-view")
}

func run(*cobra.Command, []string) {

var snapshot inmem.EncodableSnapshot
err := json.NewDecoder(os.Stdin).Decode(&snapshot)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the usage? something like

cat snapshot.json | util ...

would it make sense to accept a path to the snapshot file as an argument instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is the usage. We were starting from some jq queries so the shortest path was something with the same input scheme. I don't mind adding the file IO in the command -- that is probably more consistent with the rest of the util commands.

if err != nil {
log.Fatal().Err(err).Msg("Failed to read snapshot from stdin")
}

snap := inmem.SnapshotFromEncodable(snapshot)
epoch, err := snap.Epochs().Current()
if err != nil {
log.Fatal().Err(err).Msg("Failed to read current epoch")
}

// Should match https://github.com/onflow/flow-go/blob/48b6db32d4491903aa0ffa541377c8f239da3bcc/consensus/hotstuff/committees/consensus_committee.go#L74-L78
selection, err := leader.SelectionForConsensus(
epoch.InitialIdentities(),
epoch.RandomSource(),
epoch.FirstView(),
epoch.FinalView(),
)
if err != nil {
log.Fatal().Err(err).Msg("Failed to read current leader selection")
}

type LeaderForView struct {
View uint64
LeaderID flow.Identifier
}

leaders := make([]LeaderForView, 0, flagEndView-flagStartView+1)
for view := flagStartView; view <= flagEndView; view++ {
leaderID, err := selection.LeaderForView(view)
if err != nil {
log.Fatal().Err(err).Msg("Failed to read leader for view")
}
leaders = append(leaders, LeaderForView{View: view, LeaderID: leaderID})
}

err = json.NewEncoder(os.Stdout).Encode(leaders)
if err != nil {
log.Fatal().Err(err).Msg("Failed to encode leaders")
}
}
2 changes: 2 additions & 0 deletions cmd/util/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
find_inconsistent_result "github.com/onflow/flow-go/cmd/util/cmd/find-inconsistent-result"
find_trie_root "github.com/onflow/flow-go/cmd/util/cmd/find-trie-root"
generate_authorization_fixes "github.com/onflow/flow-go/cmd/util/cmd/generate-authorization-fixes"
"github.com/onflow/flow-go/cmd/util/cmd/leaders"
read_badger "github.com/onflow/flow-go/cmd/util/cmd/read-badger/cmd"
read_execution_state "github.com/onflow/flow-go/cmd/util/cmd/read-execution-state"
read_hotstuff "github.com/onflow/flow-go/cmd/util/cmd/read-hotstuff/cmd"
Expand Down Expand Up @@ -106,6 +107,7 @@ func addCommands() {
rootCmd.AddCommand(read_badger.RootCmd)
rootCmd.AddCommand(read_protocol_state.RootCmd)
rootCmd.AddCommand(ledger_json_exporter.Cmd)
rootCmd.AddCommand(leaders.Cmd)
rootCmd.AddCommand(epochs.RootCmd)
rootCmd.AddCommand(edbs.RootCmd)
rootCmd.AddCommand(index_er.RootCmd)
Expand Down
Loading