|
1 | 1 | package cmd |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "fmt" |
| 5 | + "path/filepath" |
| 6 | + |
4 | 7 | "github.com/spf13/cobra" |
5 | 8 |
|
6 | 9 | "github.com/onflow/flow-go/cmd" |
| 10 | + "github.com/onflow/flow-go/cmd/bootstrap/run" |
7 | 11 | "github.com/onflow/flow-go/cmd/util/cmd/common" |
| 12 | + hotstuff "github.com/onflow/flow-go/consensus/hotstuff/model" |
8 | 13 | model "github.com/onflow/flow-go/model/bootstrap" |
| 14 | + "github.com/onflow/flow-go/model/flow" |
| 15 | + cluster2 "github.com/onflow/flow-go/state/cluster" |
9 | 16 | "github.com/onflow/flow-go/state/protocol/prg" |
10 | 17 | ) |
11 | 18 |
|
@@ -132,8 +139,49 @@ func clusterAssignment(cmd *cobra.Command, args []string) { |
132 | 139 | Assignments: assignments, |
133 | 140 | Clusters: clusters, |
134 | 141 | } |
135 | | - err = common.WriteJSON(model.PathIntermediaryBootstrappingData, flagOutdir, output) |
| 142 | + err = common.WriteJSON(model.PathClusteringData, flagOutdir, output) |
136 | 143 | if err != nil { |
137 | 144 | log.Fatal().Err(err).Msg("failed to write json") |
138 | 145 | } |
| 146 | + log.Info().Msgf("wrote file %s/%s", flagOutdir, model.PathClusteringData) |
| 147 | + log.Info().Msg("") |
| 148 | + |
| 149 | + log.Info().Msg("constructing and writing cluster block votes for internal nodes") |
| 150 | + constructClusterRootVotes( |
| 151 | + output, |
| 152 | + model.FilterByRole(internalNodes, flow.RoleCollection), |
| 153 | + ) |
| 154 | + log.Info().Msg("") |
| 155 | +} |
| 156 | + |
| 157 | +// constructClusterRootVotes generates and writes vote files for internal collector nodes with private keys available. |
| 158 | +func constructClusterRootVotes(data IntermediaryClusteringData, internalCollectors []model.NodeInfo) { |
| 159 | + for i := range data.Clusters { |
| 160 | + clusterRootBlock, err := cluster2.CanonicalRootBlock(data.EpochCounter, data.Assignments[i]) |
| 161 | + if err != nil { |
| 162 | + log.Fatal().Err(err).Msg("could not construct cluster root block") |
| 163 | + } |
| 164 | + block := hotstuff.GenesisBlockFromFlow(clusterRootBlock.ToHeader()) |
| 165 | + // collate private NodeInfos for internal nodes in this cluster |
| 166 | + signers := make([]model.NodeInfo, 0) |
| 167 | + for _, nodeID := range data.Assignments[i] { |
| 168 | + for _, node := range internalCollectors { |
| 169 | + if node.NodeID == nodeID { |
| 170 | + signers = append(signers, node) |
| 171 | + } |
| 172 | + } |
| 173 | + } |
| 174 | + votes, err := run.CreateClusterRootBlockVotes(signers, block) |
| 175 | + if err != nil { |
| 176 | + log.Fatal().Err(err).Msg("could not create cluster root block votes") |
| 177 | + } |
| 178 | + for _, vote := range votes { |
| 179 | + path := filepath.Join(model.DirnameRootBlockVotes, fmt.Sprintf(model.FilenameRootClusterBlockVote, vote.SignerID)) |
| 180 | + err = common.WriteJSON(path, flagOutdir, vote) |
| 181 | + if err != nil { |
| 182 | + log.Fatal().Err(err).Msg("failed to write json") |
| 183 | + } |
| 184 | + log.Info().Msgf("wrote file %s/%s", flagOutdir, path) |
| 185 | + } |
| 186 | + } |
139 | 187 | } |
0 commit comments