From f6ac0cd6f1f86c1949cfbd0c7c63a3db2cc32f9d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 15:40:05 +0000 Subject: [PATCH] feat: `download-genesis` command (backport #2791) (#2795) This is an automatic backport of pull request #2791 done by [Mergify](https://mergify.com). Cherry-pick of c34a93d79419a75e077103c3f1785c64f854641c has failed: ``` On branch mergify/bp/v1.x/pr-2791 Your branch is up to date with 'origin/v1.x'. You are currently cherry-picking commit c34a93d. (fix conflicts and run "git cherry-pick --continue") (use "git cherry-pick --skip" to skip this patch) (use "git cherry-pick --abort" to cancel the cherry-pick operation) Changes to be committed: new file: cmd/celestia-appd/cmd/download-genesis.go Unmerged paths: (use "git add ..." to mark resolution) both modified: cmd/celestia-appd/cmd/root.go ``` To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/github/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally ---
Mergify commands and options
More conditions and actions can be found in the [documentation](https://docs.mergify.com/). You can also trigger Mergify actions by commenting on this pull request: - `@Mergifyio refresh` will re-evaluate the rules - `@Mergifyio rebase` will rebase this PR on its base branch - `@Mergifyio update` will merge the base branch into this PR - `@Mergifyio backport ` will backport this PR on `` branch Additionally, on Mergify [dashboard](https://dashboard.mergify.com) you can: - look at your merge queues - generate the Mergify configuration with the config editor. Finally, you can contact us on https://mergify.com
--------- Co-authored-by: Rootul P --- cmd/celestia-appd/cmd/download-genesis.go | 128 ++++++++++++++++++++++ cmd/celestia-appd/cmd/root.go | 1 + 2 files changed, 129 insertions(+) create mode 100644 cmd/celestia-appd/cmd/download-genesis.go diff --git a/cmd/celestia-appd/cmd/download-genesis.go b/cmd/celestia-appd/cmd/download-genesis.go new file mode 100644 index 0000000000..ced81d352f --- /dev/null +++ b/cmd/celestia-appd/cmd/download-genesis.go @@ -0,0 +1,128 @@ +package cmd + +import ( + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "net/http" + "os" + + "github.com/cosmos/cosmos-sdk/server" + "github.com/spf13/cobra" +) + +var chainIDToSha256 = map[string]string{ + "celestia": "9727aac9bbfb021ce7fc695a92f901986421283a891b89e0af97bc9fad187793", + "mocha-4": "0846b99099271b240b638a94e17a6301423b5e4047f6558df543d6e91db7e575", + "arabica-10": "fad0a187669f7a2c11bb07f9dc27140d66d2448b7193e186312713856f28e3e1", +} + +func downloadGenesisCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "download-genesis [chain-id]", + Short: "Download genesis file from https://github.com/celestiaorg/networks", + Long: "Download genesis file from https://github.com/celestiaorg/networks.\n" + + "The first argument should be a known chain-id. Ex. celestia, mocha-4, or arabica-10.\n" + + "If no argument is provided, defaults to celestia.\n", + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + chainID := getChainIDOrDefault(args) + if !isKnownChainID(chainID) { + return fmt.Errorf("unknown chain-id: %s. Must be: celestia, mocha-4, or arabica-10", chainID) + } + outputFile := server.GetServerContextFromCmd(cmd).Config.GenesisFile() + fmt.Printf("Downloading genesis file for %s to %s\n", chainID, outputFile) + + url := fmt.Sprintf("https://raw.githubusercontent.com/celestiaorg/networks/master/%s/genesis.json", chainID) + if err := downloadFile(outputFile, url); err != nil { + return fmt.Errorf("error downloading / persisting the genesis file: %s", err) + } + fmt.Printf("Downloaded genesis file for %s to %s\n", chainID, outputFile) + + // Compute SHA-256 hash of the downloaded file + hash, err := computeSha256(outputFile) + if err != nil { + return fmt.Errorf("error computing sha256 hash: %s", err) + } + + // Compare computed hash against known hash + knownHash, ok := chainIDToSha256[chainID] + if !ok { + return fmt.Errorf("unknown chain-id: %s", chainID) + } + + if hash != knownHash { + return fmt.Errorf("sha256 hash mismatch: got %s, expected %s", hash, knownHash) + } + + fmt.Printf("SHA-256 hash verified for %s\n", chainID) + return nil + }, + } + + return cmd +} + +// getChainIDOrDefault returns the chainID from the command line arguments. If +// none is provided, defaults to celestia (mainnet). +func getChainIDOrDefault(args []string) string { + if len(args) == 1 { + return args[0] + } + return "celestia" +} + +// isKnownChainID returns true if the chainID is known. +func isKnownChainID(chainID string) bool { + knownChainIDs := []string{ + "arabica-10", // testnet + "mocha-4", // testnet + "celestia", // mainnet + } + return contains(knownChainIDs, chainID) +} + +// contains checks if a string is present in a slice. +func contains(slice []string, s string) bool { + for _, v := range slice { + if v == s { + return true + } + } + return false +} + +// downloadFile will download a URL to a local file. +func downloadFile(filepath string, url string) error { + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + out, err := os.Create(filepath) + if err != nil { + return err + } + defer out.Close() + + _, err = io.Copy(out, resp.Body) + return err +} + +// computeSha256 computes the SHA-256 hash of a file. +func computeSha256(filepath string) (string, error) { + f, err := os.Open(filepath) + if err != nil { + return "", err + } + defer f.Close() + + hasher := sha256.New() + if _, err := io.Copy(hasher, f); err != nil { + return "", err + } + + return hex.EncodeToString(hasher.Sum(nil)), nil +} diff --git a/cmd/celestia-appd/cmd/root.go b/cmd/celestia-appd/cmd/root.go index db1e19d458..511dfb22d6 100644 --- a/cmd/celestia-appd/cmd/root.go +++ b/cmd/celestia-appd/cmd/root.go @@ -128,6 +128,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig encoding.Config) { debugCmd, config.Cmd(), commands.CompactGoLevelDBCmd, + downloadGenesisCommand(), ) server.AddCommands(rootCmd, app.DefaultNodeHome, NewAppServer, createAppAndExport, addModuleInitFlags)