This commit is contained in:
Federico Kunze
2021-04-18 19:23:26 +02:00
parent cb2ab3d95d
commit 6f7470c2e0
29 changed files with 650 additions and 1549 deletions
+26 -15
View File
@@ -6,12 +6,12 @@ import (
"errors"
"fmt"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
@@ -20,16 +20,16 @@ import (
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/ethermint/crypto/hd"
ethermint "github.com/cosmos/ethermint/types"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
chain "github.com/cosmos/ethermint/types"
)
const (
flagVestingStart = "vesting-start-time"
flagVestingEnd = "vesting-end-time"
flagVestingAmt = "vesting-amount"
flagKeyring = "pass"
)
// AddGenesisAccountCmd returns add-genesis-account cobra Command.
@@ -56,10 +56,12 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
addr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
inBuf := bufio.NewReader(cmd.InOrStdin())
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
// attempt to lookup address from Keyring if no address was provided
kr, err := keyring.New(
keyringBackend, err := cmd.Flags().GetString(flags.FlagKeyringBackend)
if err != nil {
return err
}
// attempt to lookup address from Keybase if no address was provided
kb, err := keyring.New(
sdk.KeyringServiceName(),
keyringBackend,
clientCtx.HomeDir,
@@ -70,9 +72,9 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
return err
}
info, err := kr.Key(args[0])
info, err := kb.Key(args[0])
if err != nil {
return fmt.Errorf("failed to get address from Keyring: %w", err)
return fmt.Errorf("failed to get address from Keybase: %w", err)
}
addr = info.GetAddress()
@@ -83,9 +85,18 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
return fmt.Errorf("failed to parse coins: %w", err)
}
vestingStart, _ := cmd.Flags().GetInt64(flagVestingStart)
vestingEnd, _ := cmd.Flags().GetInt64(flagVestingEnd)
vestingAmtStr, _ := cmd.Flags().GetString(flagVestingAmt)
vestingStart, err := cmd.Flags().GetInt64(flagVestingStart)
if err != nil {
return err
}
vestingEnd, err := cmd.Flags().GetInt64(flagVestingEnd)
if err != nil {
return err
}
vestingAmtStr, err := cmd.Flags().GetString(flagVestingAmt)
if err != nil {
return err
}
vestingAmt, err := sdk.ParseCoinsNormalized(vestingAmtStr)
if err != nil {
@@ -117,7 +128,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
return errors.New("invalid vesting parameters; must supply start and end time or end time")
}
} else {
genAccount = &ethermint.EthAccount{
genAccount = &chain.EthAccount{
BaseAccount: baseAccount,
CodeHash: ethcrypto.Keccak256(nil),
}
@@ -185,7 +196,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
}
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
cmd.Flags().String(flags.FlagKeyringBackend, keyring.BackendFile, "Select keyring's backend (os|file|kwallet|pass|test)")
cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts")
cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
+69 -36
View File
@@ -1,13 +1,21 @@
package main
import (
"errors"
"context"
"io"
"math/big"
"os"
"path/filepath"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp/params"
"github.com/cosmos/cosmos-sdk/snapshots"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/crisis"
"github.com/spf13/cast"
"github.com/spf13/cobra"
tmcli "github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
@@ -19,8 +27,6 @@ import (
"github.com/cosmos/cosmos-sdk/client/rpc"
sdkserver "github.com/cosmos/cosmos-sdk/server"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/simapp/params"
"github.com/cosmos/cosmos-sdk/snapshots"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
@@ -28,13 +34,10 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/types"
vestingcli "github.com/cosmos/cosmos-sdk/x/auth/vesting/client/cli"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/crisis"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
"github.com/cosmos/ethermint/app"
ethermintclient "github.com/cosmos/ethermint/client"
ethermintclientKey "github.com/cosmos/ethermint/client/keys"
"github.com/cosmos/ethermint/server"
)
// NewRootCmd creates a new root command for simd. It is called once in the
@@ -48,18 +51,18 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
WithLegacyAmino(encodingConfig.Amino).
WithInput(os.Stdin).
WithAccountRetriever(types.AccountRetriever{}).
WithBroadcastMode(flags.BroadcastSync).
WithBroadcastMode(flags.BroadcastBlock).
WithHomeDir(app.DefaultNodeHome)
rootCmd := &cobra.Command{
Use: "ethermintd",
Short: "ethermint app daemon",
Short: "Ethermint Daemon",
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil {
return err
}
return server.InterceptConfigsPreRunHandler(cmd)
return InterceptConfigsPreRunHandler(cmd)
},
}
@@ -68,18 +71,33 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
return rootCmd, encodingConfig
}
// Execute executes the root command.
func Execute(rootCmd *cobra.Command) error {
// Create and set a client.Context on the command's Context. During the pre-run
// of the root command, a default initialized client.Context is provided to
// seed child command execution with values such as AccountRetriver, Keyring,
// and a Tendermint RPC. This requires the use of a pointer reference when
// getting and setting the client.Context. Ideally, we utilize
// https://github.com/spf13/cobra/pull/1118.
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &client.Context{})
ctx = context.WithValue(ctx, sdkserver.ServerContextKey, sdkserver.NewDefaultContext())
executor := tmcli.PrepareBaseCmd(rootCmd, "", app.DefaultNodeHome)
return executor.ExecuteContext(ctx)
}
func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
authclient.Codec = encodingConfig.Marshaler
sdk.PowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
rootCmd.AddCommand(
ethermintclient.GenerateChainID(
ethermintclient.ValidateChainID(
genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
),
ethermintclient.ValidateChainID(
genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
),
genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
genutilcli.MigrateGenesisCmd(),
genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
AddGenesisAccountCmd(app.DefaultNodeHome),
genutilcli.ValidateGenesisCmd(app.ModuleBasics),
AddGenesisAccountCmd(app.DefaultNodeHome),
tmcli.NewCompletionCmd(rootCmd, true),
@@ -87,16 +105,37 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
debug.Cmd(),
)
a := appCreator{encCfg: encodingConfig}
server.AddCommands(rootCmd, app.DefaultNodeHome, a.newApp, a.appExport, addModuleInitFlags)
tendermintCmd := &cobra.Command{
Use: "tendermint",
Short: "Tendermint subcommands",
}
tendermintCmd.AddCommand(
sdkserver.ShowNodeIDCmd(),
sdkserver.ShowValidatorCmd(),
sdkserver.ShowAddressCmd(),
sdkserver.VersionCmd(),
)
rootCmd.AddCommand(
StartCmd(newApp, app.DefaultNodeHome),
sdkserver.UnsafeResetAllCmd(),
flags.LineBreak,
tendermintCmd,
sdkserver.ExportCmd(createAppAndExport, app.DefaultNodeHome),
flags.LineBreak,
version.NewVersionCommand(),
)
// add keybase, auxiliary RPC, query, and tx child commands
rootCmd.AddCommand(
rpc.StatusCommand(),
queryCommand(),
txCommand(),
ethermintclientKey.Commands(app.DefaultNodeHome),
ethermintclient.KeyCommands(app.DefaultNodeHome),
)
rootCmd = addTxFlags(rootCmd)
}
func addModuleInitFlags(startCmd *cobra.Command) {
@@ -155,12 +194,7 @@ func txCommand() *cobra.Command {
return cmd
}
type appCreator struct {
encCfg params.EncodingConfig
}
// newApp create a new SDK application binary
func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
var cache sdk.MultiStorePersistentCache
if cast.ToBool(appOpts.Get(sdkserver.FlagInterBlockCache)) {
@@ -187,11 +221,11 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a
panic(err)
}
return app.NewEthermintApp(
ethermintApp := app.NewEthermintApp(
logger, db, traceStore, true, skipUpgradeHeights,
cast.ToString(appOpts.Get(flags.FlagHome)),
cast.ToUint(appOpts.Get(sdkserver.FlagInvCheckPeriod)),
a.encCfg,
app.MakeEncodingConfig(), // Ideally, we would reuse the one created by NewRootCmd.
appOpts,
baseapp.SetPruning(pruningOpts),
baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(sdkserver.FlagMinGasPrices))),
@@ -205,28 +239,27 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a
baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(sdkserver.FlagStateSyncSnapshotInterval))),
baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(sdkserver.FlagStateSyncSnapshotKeepRecent))),
)
return ethermintApp
}
// appExport creates a new Ethermint app (optionally at a given height)
// createAppAndExport creates a new Ethermint app (optionally at a given height)
// and exports state.
func (a appCreator) appExport(
func createAppAndExport(
logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string,
appOpts servertypes.AppOptions) (servertypes.ExportedApp, error) {
appOpts servertypes.AppOptions,
) (servertypes.ExportedApp, error) {
encCfg := app.MakeEncodingConfig() // Ideally, we would reuse the one created by NewRootCmd.
encCfg.Marshaler = codec.NewProtoCodec(encCfg.InterfaceRegistry)
var ethermintApp *app.EthermintApp
homePath, ok := appOpts.Get(flags.FlagHome).(string)
if !ok || homePath == "" {
return servertypes.ExportedApp{}, errors.New("application home not set")
}
if height != -1 {
ethermintApp = app.NewEthermintApp(logger, db, traceStore, false, map[int64]bool{}, homePath, 0, a.encCfg, appOpts)
ethermintApp = app.NewEthermintApp(logger, db, traceStore, false, map[int64]bool{}, "", uint(1), encCfg, appOpts)
if err := ethermintApp.LoadHeight(height); err != nil {
return servertypes.ExportedApp{}, err
}
} else {
ethermintApp = app.NewEthermintApp(logger, db, traceStore, true, map[int64]bool{}, homePath, 0, a.encCfg, appOpts)
ethermintApp = app.NewEthermintApp(logger, db, traceStore, true, map[int64]bool{}, "", uint(1), encCfg, appOpts)
}
return ethermintApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs)
+1 -19
View File
@@ -168,24 +168,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
cfg := ctx.Config
home := cfg.RootDir
envName := "chain-" + ctx.Viper.GetString(flags.FlagChainID)
if env := os.Getenv("APP_ENV"); len(env) > 0 {
envName = env
}
if statsdEnabled {
hostname, _ := os.Hostname()
metrics.Init(statsdAddress, statsdPrefix, &metrics.StatterConfig{
EnvName: envName,
HostName: hostname,
StuckFunctionTimeout: duration(statsdStuckFunc, 5*time.Minute),
MockingEnabled: false,
})
closer.Bind(func() {
metrics.Close()
})
}
traceWriterFile := ctx.Viper.GetString(flagTraceStore)
db, err := openDB(home)
if err != nil {
@@ -243,7 +225,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
var grpcSrv *grpc.Server
if config.GRPC.Enable {
grpcSrv, err = servergrpc.StartGRPCServer(app, config.GRPC.Address)
grpcSrv, err = servergrpc.StartGRPCServer(clientCtx, app, config.GRPC.Address)
if err != nil {
log.WithError(err).Errorln("failed to boot GRPC server")
}
+132
View File
@@ -0,0 +1,132 @@
package main
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/server"
tmcfg "github.com/tendermint/tendermint/config"
tmcli "github.com/tendermint/tendermint/libs/cli"
tmflags "github.com/tendermint/tendermint/libs/cli/flags"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/ethermint/cmd/ethermintd/config"
)
// InterceptConfigsPreRunHandler performs a pre-run function for the root daemon
// application command. It will create a Viper literal and a default server
// Context. The server Tendermint configuration will either be read and parsed
// or created and saved to disk, where the server Context is updated to reflect
// the Tendermint configuration. The Viper literal is used to read and parse
// the application configuration. Command handlers can fetch the server Context
// to get the Tendermint configuration or to get access to Viper.
func InterceptConfigsPreRunHandler(cmd *cobra.Command) error {
rootViper := viper.New()
rootViper.BindPFlags(cmd.Flags())
rootViper.BindPFlags(cmd.PersistentFlags())
serverCtx := server.NewDefaultContext()
config, err := interceptConfigs(serverCtx, rootViper)
if err != nil {
return err
}
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, tmcfg.DefaultLogLevel)
if err != nil {
return err
}
if rootViper.GetBool(tmcli.TraceFlag) {
logger = log.NewTracingLogger(logger)
}
serverCtx.Config = config
serverCtx.Logger = logger.With("module", "main")
// TODO: parse package-level log levels correctly (replace tmlib)
//
// if len(config.LogLevel) == 0 {
// if ll := rootViper.GetString("log-level"); len(ll) > 0 {
// config.LogLevel = ll
// } else {
// config.LogLevel = "info"
// }
// }
//
// logger := logging.NewWrappedSuplog("info", false)
//
// if rootViper.GetBool(tmcli.TraceFlag) {
// logger = tmlog.NewTracingLogger(logger)
// }
//
// serverCtx.Config = config
// serverCtx.Logger = logger.With("module", "main")
return server.SetCmdServerContext(cmd, serverCtx)
}
// interceptConfigs parses and updates a Tendermint configuration file or
// creates a new one and saves it. It also parses and saves the application
// configuration file. The Tendermint configuration file is parsed given a root
// Viper object, whereas the application is parsed with the private package-aware
// viperCfg object.
func interceptConfigs(ctx *server.Context, rootViper *viper.Viper) (*tmcfg.Config, error) {
rootDir := rootViper.GetString(flags.FlagHome)
configPath := filepath.Join(rootDir, "config")
configFile := filepath.Join(configPath, "config.toml")
conf := tmcfg.DefaultConfig()
if _, err := os.Stat(configFile); os.IsNotExist(err) {
tmcfg.EnsureRoot(rootDir)
if err = conf.ValidateBasic(); err != nil {
return nil, fmt.Errorf("error in config file: %v", err)
}
conf.RPC.PprofListenAddress = "localhost:6060"
conf.P2P.RecvRate = 5120000
conf.P2P.SendRate = 5120000
conf.Consensus.TimeoutCommit = 5 * time.Second
tmcfg.WriteConfigFile(configFile, conf)
} else {
rootViper.SetConfigType("toml")
rootViper.SetConfigName("config")
rootViper.AddConfigPath(configPath)
if err := rootViper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("failed to read in app.toml: %w", err)
}
if err := rootViper.Unmarshal(conf); err != nil {
return nil, err
}
}
conf.SetRoot(rootDir)
appConfigFilePath := filepath.Join(configPath, "app.toml")
if _, err := os.Stat(appConfigFilePath); os.IsNotExist(err) {
appConf, err := config.ParseConfig(ctx.Viper)
if err != nil {
return nil, fmt.Errorf("failed to parse app.toml: %w", err)
}
config.WriteConfigFile(appConfigFilePath, appConf)
}
ctx.Viper.SetConfigType("toml")
ctx.Viper.SetConfigName("app")
ctx.Viper.AddConfigPath(configPath)
if err := ctx.Viper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("failed to read in app.toml: %w", err)
}
return conf, nil
}