2020-08-04 18:52:32 +00:00
package client
2020-07-31 21:42:04 +00:00
// DONTCOVER
import (
"bufio"
"encoding/json"
2021-04-17 10:00:07 +00:00
"errors"
2020-07-31 21:42:04 +00:00
"fmt"
"net"
"os"
"path/filepath"
2021-04-18 15:54:18 +00:00
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
2021-06-29 17:02:21 +00:00
"github.com/ethereum/go-ethereum/common"
2021-04-18 15:54:18 +00:00
2020-07-31 21:42:04 +00:00
"github.com/spf13/cobra"
2021-04-17 10:00:07 +00:00
2020-07-31 21:42:04 +00:00
tmconfig "github.com/tendermint/tendermint/config"
tmos "github.com/tendermint/tendermint/libs/os"
tmrand "github.com/tendermint/tendermint/libs/rand"
2021-04-17 10:00:07 +00:00
"github.com/tendermint/tendermint/types"
2020-07-31 21:42:04 +00:00
tmtime "github.com/tendermint/tendermint/types/time"
2021-04-17 10:00:07 +00:00
"github.com/cosmos/cosmos-sdk/client"
2020-07-31 21:42:04 +00:00
"github.com/cosmos/cosmos-sdk/client/flags"
2021-04-17 10:00:07 +00:00
"github.com/cosmos/cosmos-sdk/client/tx"
2021-06-29 17:02:21 +00:00
"github.com/cosmos/cosmos-sdk/crypto/keyring"
2020-07-31 21:42:04 +00:00
"github.com/cosmos/cosmos-sdk/server"
2021-06-29 17:02:21 +00:00
srvconfig "github.com/cosmos/cosmos-sdk/server/config"
2020-07-31 21:42:04 +00:00
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
2021-04-17 10:00:07 +00:00
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
2020-07-31 21:42:04 +00:00
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
2021-04-17 10:00:07 +00:00
mintypes "github.com/cosmos/cosmos-sdk/x/mint/types"
2020-07-31 21:42:04 +00:00
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
2021-06-22 10:49:18 +00:00
"github.com/tharsis/ethermint/crypto/hd"
2021-07-28 09:47:29 +00:00
"github.com/tharsis/ethermint/server/config"
2021-06-29 17:02:21 +00:00
ethermint "github.com/tharsis/ethermint/types"
2021-06-22 10:49:18 +00:00
evmtypes "github.com/tharsis/ethermint/x/evm/types"
2020-07-31 21:42:04 +00:00
)
var (
2021-04-17 10:00:07 +00:00
flagNodeDirPrefix = "node-dir-prefix"
flagNumValidators = "v"
flagOutputDir = "output-dir"
flagNodeDaemonHome = "node-daemon-home"
flagCoinDenom = "coin-denom"
flagIPAddrs = "ip-addresses"
2020-07-31 21:42:04 +00:00
)
const nodeDirPerm = 0755
2020-08-04 18:52:32 +00:00
// TestnetCmd initializes all files for tendermint testnet and application
2021-04-17 10:00:07 +00:00
func TestnetCmd (
mbm module . BasicManager , genBalancesIterator banktypes . GenesisBalancesIterator ,
2020-07-31 21:42:04 +00:00
) * cobra . Command {
cmd := & cobra . Command {
Use : "testnet" ,
Short : "Initialize files for a Ethermint testnet" ,
Long : ` testnet will create "v" number of directories and populate each with
necessary files ( private validator , genesis , config , etc . ) .
Note , strict routability for addresses is turned off in the config file . ` ,
2021-04-18 16:39:15 +00:00
Example : "ethermintd testnet --v 4 --keyring-backend test --output-dir ./output --ip-addresses 192.168.10.2" ,
2020-07-31 21:42:04 +00:00
RunE : func ( cmd * cobra . Command , _ [ ] string ) error {
2021-04-17 10:00:07 +00:00
clientCtx := client . GetClientContextFromCmd ( cmd )
serverCtx := server . GetServerContextFromCmd ( cmd )
config := serverCtx . Config
2020-07-31 21:42:04 +00:00
outputDir , _ := cmd . Flags ( ) . GetString ( flagOutputDir )
keyringBackend , _ := cmd . Flags ( ) . GetString ( flags . FlagKeyringBackend )
chainID , _ := cmd . Flags ( ) . GetString ( flags . FlagChainID )
minGasPrices , _ := cmd . Flags ( ) . GetString ( server . FlagMinGasPrices )
nodeDirPrefix , _ := cmd . Flags ( ) . GetString ( flagNodeDirPrefix )
nodeDaemonHome , _ := cmd . Flags ( ) . GetString ( flagNodeDaemonHome )
2020-09-25 23:00:49 +00:00
ipAddresses , _ := cmd . Flags ( ) . GetStringSlice ( flagIPAddrs )
2020-07-31 21:42:04 +00:00
numValidators , _ := cmd . Flags ( ) . GetInt ( flagNumValidators )
2021-04-17 10:00:07 +00:00
algo , _ := cmd . Flags ( ) . GetString ( flags . FlagKeyAlgorithm )
2020-09-08 14:39:48 +00:00
coinDenom , _ := cmd . Flags ( ) . GetString ( flagCoinDenom )
2021-04-17 10:00:07 +00:00
if len ( ipAddresses ) == 0 {
return errors . New ( "IP address list cannot be empty" )
}
2020-07-31 21:42:04 +00:00
return InitTestnet (
2021-04-17 10:00:07 +00:00
clientCtx , cmd , config , mbm , genBalancesIterator , outputDir , chainID , coinDenom , minGasPrices ,
nodeDirPrefix , nodeDaemonHome , keyringBackend , algo , ipAddresses , numValidators ,
2020-07-31 21:42:04 +00:00
)
} ,
}
cmd . Flags ( ) . Int ( flagNumValidators , 4 , "Number of validators to initialize the testnet with" )
2021-04-17 10:00:07 +00:00
cmd . Flags ( ) . StringP ( flagOutputDir , "o" , "./mytestnet" , "Directory to store initialization data for the testnet" )
2020-07-31 21:42:04 +00:00
cmd . Flags ( ) . String ( flagNodeDirPrefix , "node" , "Prefix the directory name for each node with (node results in node0, node1, ...)" )
2021-04-18 16:39:15 +00:00
cmd . Flags ( ) . String ( flagNodeDaemonHome , "ethermintd" , "Home directory of the node's daemon configuration" )
2021-04-17 10:00:07 +00:00
cmd . Flags ( ) . StringSlice ( flagIPAddrs , [ ] string { "192.168.0.1" } , "List of IP addresses to use (i.e. `192.168.0.1,172.168.0.1` results in persistent peers list ID0@192.168.0.1:46656, ID1@172.168.0.1)" )
2020-07-31 21:42:04 +00:00
cmd . Flags ( ) . String ( flags . FlagChainID , "" , "genesis file chain-id, if left blank will be randomly created" )
2021-04-18 15:54:18 +00:00
cmd . Flags ( ) . String ( server . FlagMinGasPrices , "" , "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01inj,0.001stake)" )
2020-07-31 21:42:04 +00:00
cmd . Flags ( ) . String ( flags . FlagKeyringBackend , flags . DefaultKeyringBackend , "Select keyring's backend (os|file|test)" )
2021-04-17 10:00:07 +00:00
cmd . Flags ( ) . String ( flags . FlagKeyAlgorithm , string ( hd . EthSecp256k1Type ) , "Key signing algorithm to generate keys for" )
2021-06-29 17:02:21 +00:00
cmd . Flags ( ) . String ( flagCoinDenom , ethermint . AttoPhoton , "Coin denomination used for staking, governance, mint, crisis and evm parameters" )
2020-07-31 21:42:04 +00:00
return cmd
}
// InitTestnet initializes the testnet configuration
func InitTestnet (
2021-04-17 10:00:07 +00:00
clientCtx client . Context ,
2020-08-12 14:25:57 +00:00
cmd * cobra . Command ,
2021-04-17 10:00:07 +00:00
nodeConfig * tmconfig . Config ,
2020-08-12 14:25:57 +00:00
mbm module . BasicManager ,
2021-04-17 10:00:07 +00:00
genBalIterator banktypes . GenesisBalancesIterator ,
2020-08-12 14:25:57 +00:00
outputDir ,
chainID ,
2020-09-08 14:39:48 +00:00
coinDenom ,
2020-08-12 14:25:57 +00:00
minGasPrices ,
nodeDirPrefix ,
nodeDaemonHome ,
keyringBackend ,
2021-04-17 10:00:07 +00:00
algoStr string ,
ipAddresses [ ] string ,
2020-08-12 14:25:57 +00:00
numValidators int ,
2020-07-31 21:42:04 +00:00
) error {
if chainID == "" {
2021-08-17 14:11:26 +00:00
chainID = fmt . Sprintf ( "ethermint_%d-1" , tmrand . Int63n ( 9999999999999 ) + 1 )
2020-09-24 17:50:47 +00:00
}
2021-06-29 17:02:21 +00:00
if ! ethermint . IsValidChainID ( chainID ) {
2020-09-24 17:50:47 +00:00
return fmt . Errorf ( "invalid chain-id: %s" , chainID )
2020-07-31 21:42:04 +00:00
}
2020-09-08 14:39:48 +00:00
if err := sdk . ValidateDenom ( coinDenom ) ; err != nil {
return err
}
2020-09-25 23:00:49 +00:00
if len ( ipAddresses ) != 0 {
numValidators = len ( ipAddresses )
}
2020-07-31 21:42:04 +00:00
nodeIDs := make ( [ ] string , numValidators )
2021-04-17 10:00:07 +00:00
valPubKeys := make ( [ ] cryptotypes . PubKey , numValidators )
2020-07-31 21:42:04 +00:00
2021-04-18 15:54:18 +00:00
appConfig := config . DefaultConfig ( )
2021-04-17 10:00:07 +00:00
appConfig . MinGasPrices = minGasPrices
appConfig . API . Enable = true
appConfig . Telemetry . Enabled = true
appConfig . Telemetry . PrometheusRetentionTime = 60
appConfig . Telemetry . EnableHostnameLabel = false
appConfig . Telemetry . GlobalLabels = [ ] [ ] string { { "chain_id" , chainID } }
2020-07-31 21:42:04 +00:00
var (
2021-04-17 10:00:07 +00:00
genAccounts [ ] authtypes . GenesisAccount
genBalances [ ] banktypes . Balance
2020-07-31 21:42:04 +00:00
genFiles [ ] string
)
inBuf := bufio . NewReader ( cmd . InOrStdin ( ) )
// generate private keys, node IDs, and initial transactions
for i := 0 ; i < numValidators ; i ++ {
nodeDirName := fmt . Sprintf ( "%s%d" , nodeDirPrefix , i )
nodeDir := filepath . Join ( outputDir , nodeDirName , nodeDaemonHome )
gentxsDir := filepath . Join ( outputDir , "gentxs" )
2021-04-17 10:00:07 +00:00
nodeConfig . SetRoot ( nodeDir )
nodeConfig . RPC . ListenAddress = "tcp://0.0.0.0:26657"
2020-07-31 21:42:04 +00:00
if err := os . MkdirAll ( filepath . Join ( nodeDir , "config" ) , nodeDirPerm ) ; err != nil {
_ = os . RemoveAll ( outputDir )
return err
}
2021-04-17 10:00:07 +00:00
nodeConfig . Moniker = nodeDirName
2020-07-31 21:42:04 +00:00
2021-04-17 10:00:07 +00:00
var (
ip string
err error
)
2020-07-31 21:42:04 +00:00
2021-04-17 10:00:07 +00:00
if len ( ipAddresses ) == 1 {
ip , err = getIP ( i , ipAddresses [ 0 ] )
2020-09-25 23:00:49 +00:00
if err != nil {
_ = os . RemoveAll ( outputDir )
return err
}
} else {
ip = ipAddresses [ i ]
2020-07-31 21:42:04 +00:00
}
2021-04-17 10:00:07 +00:00
nodeIDs [ i ] , valPubKeys [ i ] , err = genutil . InitializeNodeValidatorFiles ( nodeConfig )
2020-07-31 21:42:04 +00:00
if err != nil {
_ = os . RemoveAll ( outputDir )
return err
}
memo := fmt . Sprintf ( "%s@%s:26656" , nodeIDs [ i ] , ip )
2021-04-17 10:00:07 +00:00
genFiles = append ( genFiles , nodeConfig . GenesisFile ( ) )
2020-07-31 21:42:04 +00:00
2021-04-17 10:00:07 +00:00
kb , err := keyring . New (
2020-07-31 21:42:04 +00:00
sdk . KeyringServiceName ( ) ,
keyringBackend ,
2021-04-17 10:00:07 +00:00
nodeDir ,
2020-07-31 21:42:04 +00:00
inBuf ,
2021-04-17 10:00:07 +00:00
hd . EthSecp256k1Option ( ) ,
2020-07-31 21:42:04 +00:00
)
if err != nil {
return err
}
2021-04-17 10:00:07 +00:00
keyringAlgos , _ := kb . SupportedAlgorithms ( )
algo , err := keyring . NewSigningAlgoFromString ( algoStr , keyringAlgos )
if err != nil {
return err
}
2020-07-31 21:42:04 +00:00
2021-04-17 10:00:07 +00:00
addr , secret , err := server . GenerateSaveCoinKey ( kb , nodeDirName , true , algo )
2020-07-31 21:42:04 +00:00
if err != nil {
_ = os . RemoveAll ( outputDir )
return err
}
info := map [ string ] string { "secret" : secret }
cliPrint , err := json . Marshal ( info )
if err != nil {
return err
}
// save private key seed words
2021-04-17 10:00:07 +00:00
if err := writeFile ( fmt . Sprintf ( "%v.json" , "key_seed" ) , nodeDir , cliPrint ) ; err != nil {
2020-07-31 21:42:04 +00:00
return err
}
2021-06-29 17:02:21 +00:00
accStakingTokens := sdk . TokensFromConsensusPower ( 5000 , ethermint . PowerReduction )
2020-07-31 21:42:04 +00:00
coins := sdk . NewCoins (
2020-09-08 14:39:48 +00:00
sdk . NewCoin ( coinDenom , accStakingTokens ) ,
2020-07-31 21:42:04 +00:00
)
2021-04-17 10:00:07 +00:00
genBalances = append ( genBalances , banktypes . Balance { Address : addr . String ( ) , Coins : coins } )
2021-06-29 17:02:21 +00:00
genAccounts = append ( genAccounts , & ethermint . EthAccount {
2021-04-17 10:00:07 +00:00
BaseAccount : authtypes . NewBaseAccount ( addr , nil , 0 , 0 ) ,
2021-06-29 17:02:21 +00:00
CodeHash : common . BytesToHash ( evmtypes . EmptyCodeHash ) . Hex ( ) ,
2020-07-31 21:42:04 +00:00
} )
2021-06-29 17:02:21 +00:00
valTokens := sdk . TokensFromConsensusPower ( 100 , ethermint . PowerReduction )
2021-04-17 10:00:07 +00:00
createValMsg , err := stakingtypes . NewMsgCreateValidator (
2020-07-31 21:42:04 +00:00
sdk . ValAddress ( addr ) ,
valPubKeys [ i ] ,
2020-09-08 14:39:48 +00:00
sdk . NewCoin ( coinDenom , valTokens ) ,
2020-07-31 21:42:04 +00:00
stakingtypes . NewDescription ( nodeDirName , "" , "" , "" , "" ) ,
stakingtypes . NewCommissionRates ( sdk . OneDec ( ) , sdk . OneDec ( ) , sdk . OneDec ( ) ) ,
sdk . OneInt ( ) ,
)
if err != nil {
return err
}
2021-04-17 10:00:07 +00:00
txBuilder := clientCtx . TxConfig . NewTxBuilder ( )
if err := txBuilder . SetMsgs ( createValMsg ) ; err != nil {
return err
}
txBuilder . SetMemo ( memo )
txFactory := tx . Factory { }
txFactory = txFactory .
WithChainID ( chainID ) .
WithMemo ( memo ) .
WithKeybase ( kb ) .
WithTxConfig ( clientCtx . TxConfig )
if err := tx . Sign ( txFactory , nodeDirName , txBuilder , false ) ; err != nil {
return err
}
txBz , err := clientCtx . TxConfig . TxJSONEncoder ( ) ( txBuilder . GetTx ( ) )
2020-07-31 21:42:04 +00:00
if err != nil {
return err
}
2021-04-17 10:00:07 +00:00
if err := writeFile ( fmt . Sprintf ( "%v.json" , nodeDirName ) , gentxsDir , txBz ) ; err != nil {
2020-07-31 21:42:04 +00:00
return err
}
2021-06-29 17:02:21 +00:00
srvconfig . WriteConfigFile ( filepath . Join ( nodeDir , "config/app.toml" ) , appConfig )
2020-07-31 21:42:04 +00:00
}
2021-04-17 10:00:07 +00:00
if err := initGenFiles ( clientCtx , mbm , chainID , coinDenom , genAccounts , genBalances , genFiles , numValidators ) ; err != nil {
2020-07-31 21:42:04 +00:00
return err
}
err := collectGenFiles (
2021-04-17 10:00:07 +00:00
clientCtx , nodeConfig , chainID , nodeIDs , valPubKeys , numValidators ,
outputDir , nodeDirPrefix , nodeDaemonHome , genBalIterator ,
2020-07-31 21:42:04 +00:00
)
if err != nil {
return err
}
cmd . PrintErrf ( "Successfully initialized %d node directories\n" , numValidators )
return nil
}
func initGenFiles (
2021-04-17 10:00:07 +00:00
clientCtx client . Context ,
mbm module . BasicManager ,
chainID ,
coinDenom string ,
genAccounts [ ] authtypes . GenesisAccount ,
genBalances [ ] banktypes . Balance ,
genFiles [ ] string ,
numValidators int ,
2020-07-31 21:42:04 +00:00
) error {
2021-08-26 15:45:45 +00:00
appGenState := mbm . DefaultGenesis ( clientCtx . Codec )
2020-07-31 21:42:04 +00:00
// set the accounts in the genesis state
var authGenState authtypes . GenesisState
2021-08-26 15:45:45 +00:00
clientCtx . Codec . MustUnmarshalJSON ( appGenState [ authtypes . ModuleName ] , & authGenState )
2021-04-17 10:00:07 +00:00
accounts , err := authtypes . PackAccounts ( genAccounts )
if err != nil {
return err
}
authGenState . Accounts = accounts
2021-08-26 15:45:45 +00:00
appGenState [ authtypes . ModuleName ] = clientCtx . Codec . MustMarshalJSON ( & authGenState )
2020-07-31 21:42:04 +00:00
2021-04-17 10:00:07 +00:00
// set the balances in the genesis state
var bankGenState banktypes . GenesisState
2021-08-26 15:45:45 +00:00
clientCtx . Codec . MustUnmarshalJSON ( appGenState [ banktypes . ModuleName ] , & bankGenState )
2021-04-17 10:00:07 +00:00
bankGenState . Balances = genBalances
2021-08-26 15:45:45 +00:00
appGenState [ banktypes . ModuleName ] = clientCtx . Codec . MustMarshalJSON ( & bankGenState )
2020-07-31 21:42:04 +00:00
var stakingGenState stakingtypes . GenesisState
2021-08-26 15:45:45 +00:00
clientCtx . Codec . MustUnmarshalJSON ( appGenState [ stakingtypes . ModuleName ] , & stakingGenState )
2020-07-31 21:42:04 +00:00
2020-09-08 14:39:48 +00:00
stakingGenState . Params . BondDenom = coinDenom
2021-08-26 15:45:45 +00:00
appGenState [ stakingtypes . ModuleName ] = clientCtx . Codec . MustMarshalJSON ( & stakingGenState )
2020-07-31 21:42:04 +00:00
var govGenState govtypes . GenesisState
2021-08-26 15:45:45 +00:00
clientCtx . Codec . MustUnmarshalJSON ( appGenState [ govtypes . ModuleName ] , & govGenState )
2020-07-31 21:42:04 +00:00
2020-09-08 14:39:48 +00:00
govGenState . DepositParams . MinDeposit [ 0 ] . Denom = coinDenom
2021-08-26 15:45:45 +00:00
appGenState [ govtypes . ModuleName ] = clientCtx . Codec . MustMarshalJSON ( & govGenState )
2020-07-31 21:42:04 +00:00
2021-04-17 10:00:07 +00:00
var mintGenState mintypes . GenesisState
2021-08-26 15:45:45 +00:00
clientCtx . Codec . MustUnmarshalJSON ( appGenState [ mintypes . ModuleName ] , & mintGenState )
2020-07-31 21:42:04 +00:00
2020-09-08 14:39:48 +00:00
mintGenState . Params . MintDenom = coinDenom
2021-08-26 15:45:45 +00:00
appGenState [ mintypes . ModuleName ] = clientCtx . Codec . MustMarshalJSON ( & mintGenState )
2020-07-31 21:42:04 +00:00
2021-04-17 10:00:07 +00:00
var crisisGenState crisistypes . GenesisState
2021-08-26 15:45:45 +00:00
clientCtx . Codec . MustUnmarshalJSON ( appGenState [ crisistypes . ModuleName ] , & crisisGenState )
2020-07-31 21:42:04 +00:00
2020-09-08 14:39:48 +00:00
crisisGenState . ConstantFee . Denom = coinDenom
2021-08-26 15:45:45 +00:00
appGenState [ crisistypes . ModuleName ] = clientCtx . Codec . MustMarshalJSON ( & crisisGenState )
2020-07-31 21:42:04 +00:00
2020-09-08 14:39:48 +00:00
var evmGenState evmtypes . GenesisState
2021-08-26 15:45:45 +00:00
clientCtx . Codec . MustUnmarshalJSON ( appGenState [ evmtypes . ModuleName ] , & evmGenState )
2020-09-08 14:39:48 +00:00
evmGenState . Params . EvmDenom = coinDenom
2021-08-26 15:45:45 +00:00
appGenState [ evmtypes . ModuleName ] = clientCtx . Codec . MustMarshalJSON ( & evmGenState )
2020-09-08 14:39:48 +00:00
2021-04-17 10:00:07 +00:00
appGenStateJSON , err := json . MarshalIndent ( appGenState , "" , " " )
2020-07-31 21:42:04 +00:00
if err != nil {
return err
}
2021-04-17 10:00:07 +00:00
genDoc := types . GenesisDoc {
2020-07-31 21:42:04 +00:00
ChainID : chainID ,
AppState : appGenStateJSON ,
Validators : nil ,
}
// generate empty genesis files for each validator and save
for i := 0 ; i < numValidators ; i ++ {
if err := genDoc . SaveAs ( genFiles [ i ] ) ; err != nil {
return err
}
}
return nil
}
func collectGenFiles (
2021-04-17 10:00:07 +00:00
clientCtx client . Context , nodeConfig * tmconfig . Config , chainID string ,
nodeIDs [ ] string , valPubKeys [ ] cryptotypes . PubKey , numValidators int ,
outputDir , nodeDirPrefix , nodeDaemonHome string , genBalIterator banktypes . GenesisBalancesIterator ,
2020-07-31 21:42:04 +00:00
) error {
var appState json . RawMessage
genTime := tmtime . Now ( )
for i := 0 ; i < numValidators ; i ++ {
nodeDirName := fmt . Sprintf ( "%s%d" , nodeDirPrefix , i )
nodeDir := filepath . Join ( outputDir , nodeDirName , nodeDaemonHome )
gentxsDir := filepath . Join ( outputDir , "gentxs" )
2021-04-17 10:00:07 +00:00
nodeConfig . Moniker = nodeDirName
2020-07-31 21:42:04 +00:00
2021-04-17 10:00:07 +00:00
nodeConfig . SetRoot ( nodeDir )
2020-07-31 21:42:04 +00:00
nodeID , valPubKey := nodeIDs [ i ] , valPubKeys [ i ]
2021-04-17 10:00:07 +00:00
initCfg := genutiltypes . NewInitConfig ( chainID , gentxsDir , nodeID , valPubKey )
2020-07-31 21:42:04 +00:00
2021-04-17 10:00:07 +00:00
genDoc , err := types . GenesisDocFromFile ( nodeConfig . GenesisFile ( ) )
2020-07-31 21:42:04 +00:00
if err != nil {
return err
}
2021-08-26 15:45:45 +00:00
nodeAppState , err := genutil . GenAppStateFromConfig ( clientCtx . Codec , clientCtx . TxConfig , nodeConfig , initCfg , * genDoc , genBalIterator )
2020-07-31 21:42:04 +00:00
if err != nil {
return err
}
if appState == nil {
// set the canonical application state (they should not differ)
appState = nodeAppState
}
2021-04-17 10:00:07 +00:00
genFile := nodeConfig . GenesisFile ( )
2020-07-31 21:42:04 +00:00
// overwrite each validator's genesis file to have a canonical genesis time
if err := genutil . ExportGenesisFileWithTime ( genFile , chainID , nil , appState , genTime ) ; err != nil {
return err
}
}
return nil
}
func getIP ( i int , startingIPAddr string ) ( ip string , err error ) {
if len ( startingIPAddr ) == 0 {
ip , err = server . ExternalIP ( )
if err != nil {
return "" , err
}
return ip , nil
}
return calculateIP ( startingIPAddr , i )
}
func calculateIP ( ip string , i int ) ( string , error ) {
ipv4 := net . ParseIP ( ip ) . To4 ( )
if ipv4 == nil {
return "" , fmt . Errorf ( "%v: non ipv4 address" , ip )
}
for j := 0 ; j < i ; j ++ {
ipv4 [ 3 ] ++
}
return ipv4 . String ( ) , nil
}
func writeFile ( name string , dir string , contents [ ] byte ) error {
writePath := filepath . Join ( dir )
file := filepath . Join ( writePath , name )
err := tmos . EnsureDir ( writePath , 0755 )
if err != nil {
return err
}
err = tmos . WriteFile ( file , contents , 0644 )
if err != nil {
return err
}
return nil
}