From 036071272f87086ed3fb44bc8e5ec20f36415b78 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Mon, 19 Apr 2021 09:30:55 +0200 Subject: [PATCH] node running --- cmd/ethermintd/gentx.go | 236 ++++++++++++++++++++++++++++++++++++++++ cmd/ethermintd/root.go | 2 +- ethereum/rpc/net_api.go | 8 +- init.sh | 58 +++++----- 4 files changed, 268 insertions(+), 36 deletions(-) create mode 100644 cmd/ethermintd/gentx.go diff --git a/cmd/ethermintd/gentx.go b/cmd/ethermintd/gentx.go new file mode 100644 index 00000000..db4c999e --- /dev/null +++ b/cmd/ethermintd/gentx.go @@ -0,0 +1,236 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + tmos "github.com/tendermint/tendermint/libs/os" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/server" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/version" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + "github.com/cosmos/cosmos-sdk/x/genutil" + "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/cosmos/cosmos-sdk/x/staking/client/cli" + + "github.com/cosmos/cosmos-sdk/crypto/keyring" +) + +// GenTxCmd builds the application's gentx command. +func GenTxCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfig, genBalIterator types.GenesisBalancesIterator, defaultNodeHome string) *cobra.Command { + ipDefault, _ := server.ExternalIP() + fsCreateValidator, defaultsDesc := cli.CreateValidatorMsgFlagSet(ipDefault) + + cmd := &cobra.Command{ + Use: "gentx [key_name]", + Short: "Generate a genesis tx carrying a self delegation", + Args: cobra.ExactArgs(1), + Long: fmt.Sprintf(`Generate a genesis transaction that creates a validator with a self-delegation, +that is signed by the key in the Keyring referenced by a given name. A node ID and Bech32 consensus +pubkey may optionally be provided. If they are omitted, they will be retrieved from the priv_validator.json +file. The following default parameters are included: + %s + +Example: +$ %s gentx my-key-name --home=/path/to/home/dir --keyring-backend=os --chain-id=test-chain-1 \ + --amount=1000000stake \ + --moniker="myvalidator" \ + --commission-max-change-rate=0.01 \ + --commission-max-rate=1.0 \ + --commission-rate=0.07 \ + --details="..." \ + --security-contact="..." \ + --website="..." +`, defaultsDesc, version.AppName, + ), + RunE: func(cmd *cobra.Command, args []string) error { + serverCtx := server.GetServerContextFromCmd(cmd) + clientCtx := client.GetClientContextFromCmd(cmd) + cdc := clientCtx.JSONMarshaler + + config := serverCtx.Config + config.SetRoot(clientCtx.HomeDir) + + nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(serverCtx.Config) + if err != nil { + return errors.Wrap(err, "failed to initialize node validator files") + } + + // read --nodeID, if empty take it from priv_validator.json + if nodeIDString, _ := cmd.Flags().GetString(cli.FlagNodeID); nodeIDString != "" { + nodeID = nodeIDString + } + + // read --pubkey, if empty take it from priv_validator.json + if valPubKeyString, _ := cmd.Flags().GetString(cli.FlagPubKey); valPubKeyString != "" { + valPubKey, err = sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeConsPub, valPubKeyString) + if err != nil { + return errors.Wrap(err, "failed to get consensus node public key") + } + } + + genDoc, err := tmtypes.GenesisDocFromFile(config.GenesisFile()) + if err != nil { + return errors.Wrapf(err, "failed to read genesis doc file %s", config.GenesisFile()) + } + + var genesisState map[string]json.RawMessage + if err = json.Unmarshal(genDoc.AppState, &genesisState); err != nil { + return errors.Wrap(err, "failed to unmarshal genesis state") + } + + if err = mbm.ValidateGenesis(cdc, txEncCfg, genesisState); err != nil { + return errors.Wrap(err, "failed to validate genesis state") + } + + inBuf := bufio.NewReader(cmd.InOrStdin()) + + name := args[0] + key, err := clientCtx.Keyring.Key(name) + if err != nil { + return errors.Wrapf(err, "failed to fetch '%s' from the keyring", name) + } + + moniker := config.Moniker + if m, _ := cmd.Flags().GetString(cli.FlagMoniker); m != "" { + moniker = m + } + + // set flags for creating a gentx + createValCfg, err := cli.PrepareConfigForTxCreateValidator(cmd.Flags(), moniker, nodeID, genDoc.ChainID, valPubKey) + if err != nil { + return errors.Wrap(err, "error creating configuration to create validator msg") + } + + amount, _ := cmd.Flags().GetString(cli.FlagAmount) + coins, err := sdk.ParseCoinsNormalized(amount) + if err != nil { + return errors.Wrap(err, "failed to parse coins") + } + + err = genutil.ValidateAccountInGenesis(genesisState, genBalIterator, key.GetAddress(), coins, cdc) + if err != nil { + return errors.Wrap(err, "failed to validate account in genesis") + } + + txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return errors.Wrap(err, "error creating tx builder") + } + + clientCtx = clientCtx.WithInput(inBuf).WithFromAddress(key.GetAddress()) + + // create a 'create-validator' message + txBldr, msg, err := cli.BuildCreateValidatorMsg(clientCtx, createValCfg, txFactory, true) + if err != nil { + return errors.Wrap(err, "failed to build create-validator message") + } + + if key.GetType() == keyring.TypeOffline || key.GetType() == keyring.TypeMulti { + cmd.PrintErrln("Offline key passed in. Use `tx sign` command to sign.") + return authclient.PrintUnsignedStdTx(txBldr, clientCtx, []sdk.Msg{msg}) + } + + // write the unsigned transaction to the buffer + w := bytes.NewBuffer([]byte{}) + clientCtx = clientCtx.WithOutput(w) + + if err = authclient.PrintUnsignedStdTx(txBldr, clientCtx, []sdk.Msg{msg}); err != nil { + return errors.Wrap(err, "failed to print unsigned std tx") + } + + // read the transaction + stdTx, err := readUnsignedGenTxFile(clientCtx, w) + if err != nil { + return errors.Wrap(err, "failed to read unsigned gen tx file") + } + + // sign the transaction and write it to the output file + txBuilder, err := clientCtx.TxConfig.WrapTxBuilder(stdTx) + if err != nil { + return fmt.Errorf("error creating tx builder: %w", err) + } + + err = authclient.SignTx(txFactory, clientCtx, name, txBuilder, true, true) + if err != nil { + return errors.Wrap(err, "failed to sign std tx") + } + + outputDocument, _ := cmd.Flags().GetString(flags.FlagOutputDocument) + if outputDocument == "" { + outputDocument, err = makeOutputFilepath(config.RootDir, nodeID) + if err != nil { + return errors.Wrap(err, "failed to create output file path") + } + } + + if err := writeSignedGenTx(clientCtx, outputDocument, stdTx); err != nil { + return errors.Wrap(err, "failed to write signed gen tx") + } + + cmd.PrintErrf("Genesis transaction written to %q\n", outputDocument) + return nil + }, + } + + cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") + cmd.Flags().String(flags.FlagOutputDocument, "", "Write the genesis transaction JSON document to the given file instead of the default location") + cmd.Flags().String(flags.FlagChainID, "", "The network chain ID") + cmd.Flags().AddFlagSet(fsCreateValidator) + + return cmd +} + +func makeOutputFilepath(rootDir, nodeID string) (string, error) { + writePath := filepath.Join(rootDir, "config", "gentx") + if err := tmos.EnsureDir(writePath, 0700); err != nil { + return "", err + } + + return filepath.Join(writePath, fmt.Sprintf("gentx-%v.json", nodeID)), nil +} + +func readUnsignedGenTxFile(clientCtx client.Context, r io.Reader) (sdk.Tx, error) { + bz, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + aTx, err := clientCtx.TxConfig.TxJSONDecoder()(bz) + if err != nil { + return nil, err + } + + return aTx, err +} + +func writeSignedGenTx(clientCtx client.Context, outputDocument string, tx sdk.Tx) error { + outputFile, err := os.OpenFile(outputDocument, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644) + if err != nil { + return err + } + defer outputFile.Close() + + json, err := clientCtx.TxConfig.TxJSONEncoder()(tx) + if err != nil { + return err + } + + _, err = fmt.Fprintf(outputFile, "%s\n", json) + + return err +} diff --git a/cmd/ethermintd/root.go b/cmd/ethermintd/root.go index 5bd33432..0b9a93eb 100644 --- a/cmd/ethermintd/root.go +++ b/cmd/ethermintd/root.go @@ -97,7 +97,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { ), genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), genutilcli.MigrateGenesisCmd(), - AddGenesisAccountCmd(app.DefaultNodeHome), + GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), genutilcli.ValidateGenesisCmd(app.ModuleBasics), AddGenesisAccountCmd(app.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), diff --git a/ethereum/rpc/net_api.go b/ethereum/rpc/net_api.go index cd911aa2..36ffe4be 100644 --- a/ethereum/rpc/net_api.go +++ b/ethereum/rpc/net_api.go @@ -3,12 +3,9 @@ package rpc import ( "fmt" - "github.com/spf13/viper" - ethermint "github.com/cosmos/ethermint/types" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" ) // PublicNetAPI is the eth_ prefixed set of APIs in the Web3 JSON-RPC spec. @@ -17,10 +14,9 @@ type PublicNetAPI struct { } // NewPublicNetAPI creates an instance of the public Net Web3 API. -func NewPublicNetAPI(_ client.Context) *PublicNetAPI { - chainID := viper.GetString(flags.FlagChainID) +func NewPublicNetAPI(clientCtx client.Context) *PublicNetAPI { // parse the chainID from a integer string - chainIDEpoch, err := ethermint.ParseChainID(chainID) + chainIDEpoch, err := ethermint.ParseChainID(clientCtx.ChainID) if err != nil { panic(err) } diff --git a/init.sh b/init.sh index aa8c202a..de8cfb01 100755 --- a/init.sh +++ b/init.sh @@ -4,7 +4,7 @@ CHAINID="ethermint-2" MONIKER="localtestnet" # remove existing daemon and client -rm -rf ~/.ethermint* +rm -rf ~/.ethermintd* make install @@ -15,50 +15,50 @@ ethermintd keys add $KEY --keyring-backend test --algo "eth_secp256k1" ethermintd init $MONIKER --chain-id $CHAINID # Change parameter token denominations to aphoton -cat $HOME/.ethermint/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="stake"' > $HOME/.ethermint/config/tmp_genesis.json && mv $HOME/.ethermint/config/tmp_genesis.json $HOME/.ethermint/config/genesis.json -cat $HOME/.ethermint/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="aphoton"' > $HOME/.ethermint/config/tmp_genesis.json && mv $HOME/.ethermint/config/tmp_genesis.json $HOME/.ethermint/config/genesis.json -cat $HOME/.ethermint/config/genesis.json | jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="aphoton"' > $HOME/.ethermint/config/tmp_genesis.json && mv $HOME/.ethermint/config/tmp_genesis.json $HOME/.ethermint/config/genesis.json -cat $HOME/.ethermint/config/genesis.json | jq '.app_state["mint"]["params"]["mint_denom"]="aphoton"' > $HOME/.ethermint/config/tmp_genesis.json && mv $HOME/.ethermint/config/tmp_genesis.json $HOME/.ethermint/config/genesis.json +cat $HOME/.ethermintd/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="aphoton"' > $HOME/.ethermintd/config/tmp_genesis.json && mv $HOME/.ethermintd/config/tmp_genesis.json $HOME/.ethermintd/config/genesis.json +cat $HOME/.ethermintd/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="aphoton"' > $HOME/.ethermintd/config/tmp_genesis.json && mv $HOME/.ethermintd/config/tmp_genesis.json $HOME/.ethermintd/config/genesis.json +cat $HOME/.ethermintd/config/genesis.json | jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="aphoton"' > $HOME/.ethermintd/config/tmp_genesis.json && mv $HOME/.ethermintd/config/tmp_genesis.json $HOME/.ethermintd/config/genesis.json +cat $HOME/.ethermintd/config/genesis.json | jq '.app_state["mint"]["params"]["mint_denom"]="aphoton"' > $HOME/.ethermintd/config/tmp_genesis.json && mv $HOME/.ethermintd/config/tmp_genesis.json $HOME/.ethermintd/config/genesis.json # increase block time (?) -cat $HOME/.ethermint/config/genesis.json | jq '.consensus_params["block"]["time_iota_ms"]="30000"' > $HOME/.ethermint/config/tmp_genesis.json && mv $HOME/.ethermint/config/tmp_genesis.json $HOME/.ethermint/config/genesis.json +cat $HOME/.ethermintd/config/genesis.json | jq '.consensus_params["block"]["time_iota_ms"]="30000"' > $HOME/.ethermintd/config/tmp_genesis.json && mv $HOME/.ethermintd/config/tmp_genesis.json $HOME/.ethermintd/config/genesis.json # disable produce empty block if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.ethermint/config/config.toml + sed -i '' 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.ethermintd/config/config.toml else - sed -i 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.ethermint/config/config.toml + sed -i 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.ethermintd/config/config.toml fi if [[ $1 == "pending" ]]; then if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.ethermint/config/config.toml - sed -i '' 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.ethermint/config/config.toml - sed -i '' 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.ethermint/config/config.toml - sed -i '' 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.ethermint/config/config.toml - sed -i '' 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.ethermint/config/config.toml - sed -i '' 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.ethermint/config/config.toml - sed -i '' 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.ethermint/config/config.toml - sed -i '' 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.ethermint/config/config.toml - sed -i '' 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.ethermint/config/config.toml + sed -i '' 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.ethermintd/config/config.toml + sed -i '' 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.ethermintd/config/config.toml + sed -i '' 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.ethermintd/config/config.toml + sed -i '' 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.ethermintd/config/config.toml + sed -i '' 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.ethermintd/config/config.toml + sed -i '' 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.ethermintd/config/config.toml + sed -i '' 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.ethermintd/config/config.toml + sed -i '' 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.ethermintd/config/config.toml + sed -i '' 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.ethermintd/config/config.toml else - sed -i 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.ethermint/config/config.toml - sed -i 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.ethermint/config/config.toml - sed -i 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.ethermint/config/config.toml - sed -i 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.ethermint/config/config.toml - sed -i 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.ethermint/config/config.toml - sed -i 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.ethermint/config/config.toml - sed -i 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.ethermint/config/config.toml - sed -i 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.ethermint/config/config.toml - sed -i 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.ethermint/config/config.toml + sed -i 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.ethermintd/config/config.toml + sed -i 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.ethermintd/config/config.toml + sed -i 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.ethermintd/config/config.toml + sed -i 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.ethermintd/config/config.toml + sed -i 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.ethermintd/config/config.toml + sed -i 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.ethermintd/config/config.toml + sed -i 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.ethermintd/config/config.toml + sed -i 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.ethermintd/config/config.toml + sed -i 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.ethermintd/config/config.toml fi fi # Allocate genesis accounts (cosmos formatted addresses) -ethermintd add-genesis-account $KEY 1000000000000000000000aphoton,1000000000000000000stake --keyring-backend test +ethermintd add-genesis-account $KEY 100000000000000000000000000aphoton --keyring-backend test # Sign genesis transaction -ethermintd gentx $KEY 1000000000000000000stake --amount=1000000000000000000000aphoton --keyring-backend test --chain-id $CHAINID +ethermintd gentx $KEY --amount=1000000000000000000000aphoton --keyring-backend test --chain-id $CHAINID # Collect genesis tx ethermintd collect-gentxs @@ -71,4 +71,4 @@ if [[ $1 == "pending" ]]; then fi # Start the node (remove the --pruning=nothing flag if historical queries are not needed) -ethermintd start --pruning=nothing --rpc.unsafe --rpc-api "web3, eth, personal, net" --keyring-backend test --trace --log_level info +ethermintd start --pruning=nothing --keyring-backend test --trace --log_level info