Skip to content

Commit

Permalink
chore: node init auto fetches mainnet genesis, new config/app defaults (
Browse files Browse the repository at this point in the history
#7795)

* improve init process

* add logic in case download fails

* random chain id if fails

* add time limit

* assign mnemonic out of loop

* no longer set snapshot interval to 1500

* remove seed that doesn't exist anymore

* remove abci response and tx index overwrites

* add some time for upgrade in e2e

* increase p flag

* Revert "increase p flag"

This reverts commit bcd0cab.

* Revert "add some time for upgrade in e2e"

This reverts commit 7b00d6b.

* comment out the sleep and timeout

* address comments
  • Loading branch information
czarcas7ic authored Apr 11, 2024
1 parent 136c0e7 commit def581a
Showing 1 changed file with 128 additions and 37 deletions.
165 changes: 128 additions & 37 deletions cmd/osmosisd/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bufio"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -90,16 +92,16 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command {
serverCtx := server.GetServerContextFromCmd(cmd)
config := serverCtx.Config

// An easy way to run a lightweight seed node is to use tenderseed: github.com/binaryholdings/tenderseed
// Add Osmosis specific defaults to config.toml

// P2P
seeds := []string{
"[email protected]:2000", // Notional
"[email protected]:2000", // Notional
"[email protected]:2000", // Notional
"[email protected]:2000", // Notional
"[email protected]:26656", // [ block pane ]
"6bcdbcfd5d2c6ba58460f10dbcfde58278212833@osmosis.artifact-staking.io:26656", // Artifact Staking
"[email protected]:26656", // Pbcups
"77bb5fb9b6964d6e861e91c1d55cf82b67d838b5@bd-osmosis-seed-mainnet-us-01.bdnodes.net:26656", // Blockdaemon US
"3243426ab56b67f794fa60a79cc7f11bc7aa752d@bd-osmosis-seed-mainnet-eu-02.bdnodes.net:26656", // Blockdaemon EU
"ebc272824924ea1a27ea3183dd0b9ba713494f83@osmosis-mainnet-seed.autostake.com:26716", // AutoStake.com
Expand All @@ -108,26 +110,29 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command {
config.P2P.Seeds = strings.Join(seeds, ",")
config.P2P.MaxNumInboundPeers = 80
config.P2P.MaxNumOutboundPeers = 60
// config.P2P.FlushThrottleTimeout = 10 * time.Millisecond

// Mempool
config.Mempool.Size = 10000

// State Sync
config.StateSync.TrustPeriod = 112 * time.Hour

// The original default is 5s and is set in Cosmos SDK.
// We lower it to 2s for faster block times.
// Consensus
config.Consensus.TimeoutCommit = 2 * time.Second
// config.Consensus.PeerGossipSleepDuration = 10 * time.Millisecond

// Other
config.Moniker = args[0]
config.SetRoot(clientCtx.HomeDir)

chainID, _ := cmd.Flags().GetString(flags.FlagChainID)
if chainID == "" {
chainID = fmt.Sprintf("test-chain-%v", tmrand.Str(6))
}

// Get bip39 mnemonic
// Get bip39 mnemonic and initialize node validator files
var mnemonic string
var err error
recover, _ := cmd.Flags().GetBool(FlagRecover)
if recover {
inBuf := bufio.NewReader(cmd.InOrStdin())
mnemonic, err := input.GetString("Enter your bip39 mnemonic", inBuf)
mnemonic, err = input.GetString("Enter your bip39 mnemonic", inBuf)
if err != nil {
return err
}
Expand All @@ -136,53 +141,83 @@ func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command {
return errors.New("invalid mnemonic")
}
}

nodeID, _, err := genutil.InitializeNodeValidatorFilesFromMnemonic(config, mnemonic)
if err != nil {
return err
}

config.Moniker = args[0]

genFile := config.GenesisFile()
genFilePath := config.GenesisFile()
chainID, _ := cmd.Flags().GetString(flags.FlagChainID)
overwrite, _ := cmd.Flags().GetBool(FlagOverwrite)

if !overwrite && tmos.FileExists(genFile) {
return fmt.Errorf("genesis.json file already exists: %v", genFile)
}
appState, err := json.MarshalIndent(mbm.DefaultGenesis(cdc), "", " ")
if err != nil {
return errors.Wrap(err, "Failed to marshall default genesis state")
if !overwrite && tmos.FileExists(genFilePath) {
return fmt.Errorf("genesis.json file already exists: %v", genFilePath)
}

genDoc := &types.GenesisDoc{}
if _, err := os.Stat(genFile); err != nil {
if !os.IsNotExist(err) {
return err
}
} else {
genDoc, err = types.GenesisDocFromFile(genFile)
var toPrint printInfo
isMainnet := chainID == "" || chainID == "osmosis-1"
genesisFileDownloadFailed := false

if isMainnet {
// If the chainID is blank or osmosis-1, prep this as a mainnet node

// Attempt to download the genesis file from the Osmosis GitHub repository
// If fail, generate a new genesis file
err := downloadGenesis(config)
if err != nil {
return errors.Wrap(err, "Failed to read genesis doc from file")
// TODO: Maybe we should just fail in this case?
fmt.Println("Failed to download genesis file, using a random chain ID and genesis file for local testing")
genesisFileDownloadFailed = true
chainID = fmt.Sprintf("test-chain-%v", tmrand.Str(6))
} else {
// Set chainID to osmosis-1 in the case of a blank chainID
chainID = "osmosis-1"

// We dont print the app state for mainnet nodes because it's massive
fmt.Println("Not printing app state for mainnet node due to verbosity")
toPrint = newPrintInfo(config.Moniker, chainID, nodeID, "", nil)
}
}

genDoc.ChainID = chainID
genDoc.Validators = nil
genDoc.AppState = appState
if err = genutil.ExportGenesisFile(genDoc, genFile); err != nil {
return errors.Wrap(err, "Failed to export genesis file")
}
// If this is not a mainnet node, or the genesis file download failed, generate a new genesis file
if genesisFileDownloadFailed || !isMainnet {
// If the chainID is not blank or genesis file download failed, generate a new genesis file
var genDoc *types.GenesisDoc

toPrint := newPrintInfo(config.Moniker, chainID, nodeID, "", appState)
appState, err := json.MarshalIndent(mbm.DefaultGenesis(cdc), "", " ")
if err != nil {
return errors.Wrap(err, "Failed to marshall default genesis state")
}

tmcfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
if _, err := os.Stat(genFilePath); err != nil {
if !os.IsNotExist(err) {
return err
}
} else {
genDoc, err = types.GenesisDocFromFile(genFilePath)
if err != nil {
return errors.Wrap(err, "Failed to read genesis doc from file")
}
}

genDoc.ChainID = chainID
genDoc.Validators = nil
genDoc.AppState = appState
if err = genutil.ExportGenesisFile(genDoc, genFilePath); err != nil {
return errors.Wrap(err, "Failed to export genesis file")
}

toPrint = newPrintInfo(config.Moniker, chainID, nodeID, "", genDoc.AppState)
}

// Write both app.toml and config.toml to the app's config directory
tmcfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
err = writeConfigToFile(filepath.Join(config.RootDir, "config", "client.toml"), nil)
if err != nil {
return errors.Wrap(err, "Failed to write client.toml file")
}

// Create .env file if FlagSetEnv is true
createEnv, _ := cmd.Flags().GetBool(FlagSetEnv)
if createEnv {
err = CreateEnvFile(cmd)
Expand Down Expand Up @@ -239,3 +274,59 @@ func CreateEnvFile(cmd *cobra.Command) error {
}
return nil
}

// downloadGenesis downloads the genesis file from a predefined URL and writes it to the genesis file path specified in the config.
// It creates an HTTP client to send a GET request to the genesis file URL. If the request is successful, it reads the response body
// and writes it to the destination genesis file path. If any step in this process fails, it generates the default genesis.
//
// Parameters:
// - config: A pointer to a tmcfg.Config object that contains the configuration, including the genesis file path.
//
// Returns:
// - An error if the download or file writing fails, otherwise nil.
func downloadGenesis(config *tmcfg.Config) error {
// URL of the genesis file to download
genesisURL := "https://github.com/osmosis-labs/osmosis/raw/main/networks/osmosis-1/genesis.json?download"

// Determine the destination path for the genesis file
genFilePath := config.GenesisFile()

// Create a new HTTP client with a 30-second timeout
client := &http.Client{
Timeout: 30 * time.Second,
}

// Create a new GET request
req, err := http.NewRequest("GET", genesisURL, nil)
if err != nil {
return errors.Wrap(err, "failed to create HTTP request for genesis file")
}

// Send the request
fmt.Println("Downloading genesis file from", genesisURL)
fmt.Println("If the download is not successful in 30 seconds, we will gracefully continue and the default genesis file will be used")
resp, err := client.Do(req)
if err != nil {
return errors.Wrap(err, "failed to download genesis file")
}
defer resp.Body.Close()

// Check if the HTTP request was successful
if resp.StatusCode != http.StatusOK {
return errors.Errorf("failed to download genesis file: HTTP status %d", resp.StatusCode)
}

// Read the response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return errors.Wrap(err, "failed to read genesis file response body")
}

// Write the body to the destination genesis file
err = os.WriteFile(genFilePath, body, 0644)
if err != nil {
return errors.Wrap(err, "failed to write genesis file to destination")
}

return nil
}

0 comments on commit def581a

Please sign in to comment.