diff --git a/app/ante/eth.go b/app/ante/eth.go index 7e487347..df34020c 100644 --- a/app/ante/eth.go +++ b/app/ante/eth.go @@ -11,7 +11,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authante "github.com/cosmos/cosmos-sdk/x/auth/ante" - sidechain "github.com/cosmos/ethermint/types" + ethermint "github.com/cosmos/ethermint/types" evmtypes "github.com/cosmos/ethermint/x/evm/types" "github.com/ethereum/go-ethereum/common" @@ -185,7 +185,7 @@ func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s } // parse the chainID from a string to a base-10 integer - chainIDEpoch, err := sidechain.ParseChainID(ctx.ChainID()) + chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID()) if err != nil { fmt.Println("chain id parsing failed") diff --git a/app/ante/utils_test.go b/app/ante/utils_test.go index 945f4689..d134fbaf 100644 --- a/app/ante/utils_test.go +++ b/app/ante/utils_test.go @@ -16,7 +16,7 @@ import ( "github.com/cosmos/ethermint/app" ante "github.com/cosmos/ethermint/app/ante" "github.com/cosmos/ethermint/crypto/ethsecp256k1" - sidechain "github.com/cosmos/ethermint/types" + ethermint "github.com/cosmos/ethermint/types" evmtypes "github.com/cosmos/ethermint/x/evm/types" ethcrypto "github.com/ethereum/go-ethereum/crypto" @@ -59,11 +59,11 @@ func newTestMsg(addrs ...sdk.AccAddress) *sdk.TestMsg { } func newTestCoins() sdk.Coins { - return sdk.NewCoins(sidechain.NewPhotonCoinInt64(500000000)) + return sdk.NewCoins(ethermint.NewPhotonCoinInt64(500000000)) } func newTestStdFee() auth.StdFee { - return auth.NewStdFee(220000, sdk.NewCoins(sidechain.NewPhotonCoinInt64(150))) + return auth.NewStdFee(220000, sdk.NewCoins(ethermint.NewPhotonCoinInt64(150))) } // GenerateAddress generates an Ethereum address. @@ -98,7 +98,7 @@ func newTestSDKTx( } func newTestEthTx(ctx sdk.Context, msg *evmtypes.MsgEthereumTx, priv tmcrypto.PrivKey) (sdk.Tx, error) { - chainIDEpoch, err := sidechain.ParseChainID(ctx.ChainID()) + chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID()) if err != nil { return nil, err } diff --git a/app/ethermint.go b/app/app.go similarity index 99% rename from app/ethermint.go rename to app/app.go index 112dc353..71d11f45 100644 --- a/app/ethermint.go +++ b/app/app.go @@ -322,8 +322,9 @@ func NewEthermintApp( AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). - AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)). - app.GovKeeper = govkeeper.NewKeeper( + AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)) + + app.GovKeeper = govkeeper.NewKeeper( appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, &stakingKeeper, govRouter, ) diff --git a/app/ethermint_test.go b/app/app_test.go similarity index 100% rename from app/ethermint_test.go rename to app/app_test.go diff --git a/client/testnet.go b/client/testnet.go index 23d75b4d..1fcbef01 100644 --- a/client/testnet.go +++ b/client/testnet.go @@ -112,7 +112,7 @@ Note, strict routability for addresses is turned off in the config file.`, 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)") cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.EthSecp256k1Type), "Key signing algorithm to generate keys for") - cmd.Flags().String(flagCoinDenom, chaintypes.InjectiveCoin, "Coin denomination used for staking, governance, mint, crisis and evm parameters") + cmd.Flags().String(flagCoinDenom, chaintypes.AttoPhoton, "Coin denomination used for staking, governance, mint, crisis and evm parameters") return cmd } diff --git a/cmd/ethermintd/genaccounts.go b/cmd/ethermintd/genaccounts.go index b470ef9a..a5663ba8 100644 --- a/cmd/ethermintd/genaccounts.go +++ b/cmd/ethermintd/genaccounts.go @@ -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 = ðermint.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") diff --git a/cmd/ethermintd/root.go b/cmd/ethermintd/root.go index 41069900..5bd33432 100644 --- a/cmd/ethermintd/root.go +++ b/cmd/ethermintd/root.go @@ -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) diff --git a/cmd/ethermintd/start.go b/cmd/ethermintd/start.go index f373cf1a..d38bff02 100644 --- a/cmd/ethermintd/start.go +++ b/cmd/ethermintd/start.go @@ -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") } diff --git a/cmd/ethermintd/util.go b/cmd/ethermintd/util.go new file mode 100644 index 00000000..dfec959e --- /dev/null +++ b/cmd/ethermintd/util.go @@ -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 +} diff --git a/ethereum/rpc/web3_api.go b/ethereum/rpc/web3_api.go index edff98fd..89bbb888 100644 --- a/ethereum/rpc/web3_api.go +++ b/ethereum/rpc/web3_api.go @@ -17,7 +17,7 @@ func NewPublicWeb3API() *PublicWeb3API { // ClientVersion returns the client version in the Web3 user agent format. func (a *PublicWeb3API) ClientVersion() string { - return version.ClientVersion() + return version.Version() } // Sha3 returns the keccak-256 hash of the passed-in input. diff --git a/go.mod b/go.mod index 167788d7..58d6dfdc 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.15 require ( github.com/aristanetworks/goarista v0.0.0-20201012165903-2cb20defcd66 // indirect - github.com/armon/go-metrics v0.3.6 github.com/aws/aws-sdk-go v1.38.21 // indirect + github.com/bitly/go-simplejson v0.5.0 // indirect github.com/btcsuite/btcd v0.21.0-beta github.com/btcsuite/btcutil v1.0.2 github.com/bugsnag/bugsnag-go v2.1.0+incompatible // indirect @@ -14,6 +14,7 @@ require ( github.com/cosmos/cosmos-sdk v0.42.4 github.com/cosmos/go-bip39 v1.0.0 github.com/deckarep/golang-set v1.7.1 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/ethereum/go-ethereum v1.9.25 github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect @@ -23,13 +24,15 @@ require ( github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.4.2 github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/improbable-eng/grpc-web v0.14.0 github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/mattn/go-colorable v0.1.8 // indirect github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20200123000308-a60dcd172b4c github.com/pkg/errors v0.9.1 github.com/prometheus/tsdb v0.10.0 // indirect + github.com/rakyll/statik v0.1.7 github.com/regen-network/cosmos-proto v0.3.1 - github.com/rs/zerolog v1.20.0 + github.com/rs/cors v1.7.0 github.com/spf13/cast v1.3.1 github.com/spf13/cobra v1.1.1 github.com/spf13/viper v1.7.1 @@ -38,13 +41,15 @@ require ( github.com/tendermint/tendermint v0.34.10 github.com/tendermint/tm-db v0.6.4 github.com/tyler-smith/go-bip39 v1.0.2 - github.com/xlab/suplog v1.3.0 // indirect + github.com/xlab/closer v0.0.0-20190328110542-03326addb7c2 + github.com/xlab/suplog v1.3.0 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 golang.org/x/sys v0.0.0-20210415045647-66c3f260301c // indirect google.golang.org/genproto v0.0.0-20210405174219-a39eb2f71cb9 google.golang.org/grpc v1.37.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + nhooyr.io/websocket v1.8.7 // indirect ) replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.4 diff --git a/go.sum b/go.sum index 7516c710..c807cdba 100644 --- a/go.sum +++ b/go.sum @@ -92,7 +92,10 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= @@ -177,6 +180,8 @@ github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vs github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgraph-io/badger/v2 v2.2007.1/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= @@ -242,6 +247,10 @@ github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -254,10 +263,24 @@ github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= @@ -334,6 +357,7 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= @@ -395,6 +419,8 @@ github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmK github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/improbable-eng/grpc-web v0.14.0 h1:GdoK+cXABdB+1keuqsV1drSFO2XLYIxqt/4Rj8SWGBk= +github.com/improbable-eng/grpc-web v0.14.0/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= @@ -411,6 +437,7 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= @@ -421,6 +448,7 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -441,6 +469,8 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6 github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA= github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= @@ -450,12 +480,15 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -500,12 +533,15 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= @@ -743,7 +779,6 @@ github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoM github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4= github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX6mjJTgbLHTwi17VDVg= github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ= -github.com/tendermint/tendermint v0.34.9 h1:9P2MXDEPOcPW0NBcHQ/HDSfvczZm+q5nUUw7AZ6f1Vc= github.com/tendermint/tendermint v0.34.9/go.mod h1:kl4Z1JwGx1I+u1SXIzMDy7Z3T8LiMeCAOnzNn6AIMT4= github.com/tendermint/tendermint v0.34.10 h1:wBOc/It8sh/pVH9np2V5fBvRmIyFN/bUrGPx+eAHexs= github.com/tendermint/tendermint v0.34.10/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0= @@ -761,7 +796,11 @@ github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:s github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk= @@ -952,7 +991,6 @@ golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 h1:EZ2mChiOa8udjfp6rRmswTbtZN/QzUQp4ptM4rnjHvc= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210415045647-66c3f260301c h1:6L+uOeS3OQt/f4eFHXZcTxeZrGCuz+CLElgEBjbcTA4= golang.org/x/sys v0.0.0-20210415045647-66c3f260301c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1060,8 +1098,8 @@ google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1 h1:cmUfbeGKnz9+2DD/UYsMQXeqbHZqZDs4eQwW0sFOpBY= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1128,6 +1166,8 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/server/config/config.go b/server/config/config.go deleted file mode 100644 index 29294fb0..00000000 --- a/server/config/config.go +++ /dev/null @@ -1,70 +0,0 @@ -package config - -import ( - "github.com/spf13/viper" - - "github.com/cosmos/cosmos-sdk/server/config" -) - -const ( - // DefaultJSONRPCAddress is the default address the JSON-RPC server binds to. - DefaultJSONRPCAddress = "tcp://0.0.0.0:8545" - // DefaultEthereumWebsocketAddress is the default address the Ethereum websocket server binds to. - DefaultEthereumWebsocketAddress = "tcp://0.0.0.0:8546" -) - -// Config defines the server's top level configuration -type Config struct { - *config.Config - - JSONRPC JSONRPCConfig `mapstructure:"json-rpc"` - EthereumWebsocket WebsocketConfig `mapstructure:"ethereum-websocket"` -} - -// JSONRPCConfig defines the Ethereum API listener configuration. -type JSONRPCConfig struct { - // Enable defines if the JSON-RPC server should be enabled. - Enable bool `mapstructure:"enable"` - // Address defines the JSON-RPC server address to listen on - Address string `mapstructure:"address"` -} - -// WebsocketConfig defines the Ethereum API listener configuration. -type WebsocketConfig struct { - // Enable defines if the Ethereum websocker server should be enabled. - Enable bool `mapstructure:"enable"` - - // Address defines the Websocket server address to listen on - Address string `mapstructure:"address"` -} - -// DefaultConfig returns server's default configuration. -func DefaultConfig() *Config { - return &Config{ - Config: config.DefaultConfig(), - JSONRPC: JSONRPCConfig{ - Enable: true, - Address: DefaultJSONRPCAddress, - }, - EthereumWebsocket: WebsocketConfig{ - Enable: true, - Address: DefaultEthereumWebsocketAddress, - }, - } -} - -// GetConfig returns a fully parsed Config object. -func GetConfig(v *viper.Viper) Config { - sdkConfig := config.GetConfig(v) - return Config{ - Config: &sdkConfig, - JSONRPC: JSONRPCConfig{ - Enable: v.GetBool("json-rpc.enable"), - Address: v.GetString("json-rpc.address"), - }, - EthereumWebsocket: WebsocketConfig{ - Enable: v.GetBool("ethereum-websocket.enable"), - Address: v.GetString("ethereum-websocket.address"), - }, - } -} diff --git a/server/config/toml.go b/server/config/toml.go deleted file mode 100644 index f2a73d81..00000000 --- a/server/config/toml.go +++ /dev/null @@ -1,225 +0,0 @@ -package config - -import ( - "bytes" - "text/template" - - "github.com/spf13/viper" - tmos "github.com/tendermint/tendermint/libs/os" -) - -const defaultConfigTemplate = `# This is a TOML config file. -# For more information, see https://github.com/toml-lang/toml - -############################################################################### -### Base Configuration ### -############################################################################### - -# The minimum gas prices a validator is willing to accept for processing a -# transaction. A transaction's fees must meet the minimum of any denomination -# specified in this config (e.g. 0.25token1;0.0001token2). -minimum-gas-prices = "{{ .BaseConfig.MinGasPrices }}" - -# default: the last 100 states are kept in addition to every 500th state; pruning at 10 block intervals -# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node) -# everything: all saved states will be deleted, storing only the current state; pruning at 10 block intervals -# custom: allow pruning options to be manually specified through 'pruning-keep-recent', 'pruning-keep-every', and 'pruning-interval' -pruning = "{{ .BaseConfig.Pruning }}" - -# These are applied if and only if the pruning strategy is custom. -pruning-keep-recent = "{{ .BaseConfig.PruningKeepRecent }}" -pruning-keep-every = "{{ .BaseConfig.PruningKeepEvery }}" -pruning-interval = "{{ .BaseConfig.PruningInterval }}" - -# HaltHeight contains a non-zero block height at which a node will gracefully -# halt and shutdown that can be used to assist upgrades and testing. -# -# Note: Commitment of state will be attempted on the corresponding block. -halt-height = {{ .BaseConfig.HaltHeight }} - -# HaltTime contains a non-zero minimum block time (in Unix seconds) at which -# a node will gracefully halt and shutdown that can be used to assist upgrades -# and testing. -# -# Note: Commitment of state will be attempted on the corresponding block. -halt-time = {{ .BaseConfig.HaltTime }} - -# MinRetainBlocks defines the minimum block height offset from the current -# block being committed, such that all blocks past this offset are pruned -# from Tendermint. It is used as part of the process of determining the -# ResponseCommit.RetainHeight value during ABCI Commit. A value of 0 indicates -# that no blocks should be pruned. -# -# This configuration value is only responsible for pruning Tendermint blocks. -# It has no bearing on application state pruning which is determined by the -# "pruning-*" configurations. -# -# Note: Tendermint block pruning is dependant on this parameter in conunction -# with the unbonding (safety threshold) period, state pruning and state sync -# snapshot parameters to determine the correct minimum value of -# ResponseCommit.RetainHeight. -min-retain-blocks = {{ .BaseConfig.MinRetainBlocks }} - -# InterBlockCache enables inter-block caching. -inter-block-cache = {{ .BaseConfig.InterBlockCache }} - -# IndexEvents defines the set of events in the form {eventType}.{attributeKey}, -# which informs Tendermint what to index. If empty, all events will be indexed. -# -# Example: -# ["message.sender", "message.recipient"] -index-events = {{ .BaseConfig.IndexEvents }} - -############################################################################### -### Telemetry Configuration ### -############################################################################### - -[telemetry] - -# Prefixed with keys to separate services. -service-name = "{{ .Telemetry.ServiceName }}" - -# Enabled enables the application telemetry functionality. When enabled, -# an in-memory sink is also enabled by default. Operators may also enabled -# other sinks such as Prometheus. -enabled = {{ .Telemetry.Enabled }} - -# Enable prefixing gauge values with hostname. -enable-hostname = {{ .Telemetry.EnableHostname }} - -# Enable adding hostname to labels. -enable-hostname-label = {{ .Telemetry.EnableHostnameLabel }} - -# Enable adding service to labels. -enable-service-label = {{ .Telemetry.EnableServiceLabel }} - -# PrometheusRetentionTime, when positive, enables a Prometheus metrics sink. -prometheus-retention-time = {{ .Telemetry.PrometheusRetentionTime }} - -# GlobalLabels defines a global set of name/value label tuples applied to all -# metrics emitted using the wrapper functions defined in telemetry package. -# -# Example: -# [["chain_id", "cosmoshub-1"]] -global-labels = [{{ range $k, $v := .Telemetry.GlobalLabels }} - ["{{index $v 0 }}", "{{ index $v 1}}"],{{ end }} -] - -############################################################################### -### API Configuration ### -############################################################################### - -[api] - -# Enable defines if the API server should be enabled. -enable = {{ .API.Enable }} - -# Swagger defines if swagger documentation should automatically be registered. -swagger = {{ .API.Swagger }} - -# Address defines the API server to listen on. -address = "{{ .API.Address }}" - -# MaxOpenConnections defines the number of maximum open connections. -max-open-connections = {{ .API.MaxOpenConnections }} - -# RPCReadTimeout defines the Tendermint RPC read timeout (in seconds). -rpc-read-timeout = {{ .API.RPCReadTimeout }} - -# RPCWriteTimeout defines the Tendermint RPC write timeout (in seconds). -rpc-write-timeout = {{ .API.RPCWriteTimeout }} - -# RPCMaxBodyBytes defines the Tendermint maximum response body (in bytes). -rpc-max-body-bytes = {{ .API.RPCMaxBodyBytes }} - -# EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk). -enabled-unsafe-cors = {{ .API.EnableUnsafeCORS }} - -############################################################################### -### gRPC Configuration ### -############################################################################### - -[grpc] - -# Enable defines if the gRPC server should be enabled. -enable = {{ .GRPC.Enable }} - -# Address defines the gRPC server address to bind to. -address = "{{ .GRPC.Address }}" - -############################################################################### -### State Sync Configuration ### -############################################################################### - -# State sync snapshots allow other nodes to rapidly join the network without replaying historical -# blocks, instead downloading and applying a snapshot of the application state at a given height. -[state-sync] - -# snapshot-interval specifies the block interval at which local state sync snapshots are -# taken (0 to disable). Must be a multiple of pruning-keep-every. -snapshot-interval = {{ .StateSync.SnapshotInterval }} - -# snapshot-keep-recent specifies the number of recent snapshots to keep and serve (0 to keep all). -snapshot-keep-recent = {{ .StateSync.SnapshotKeepRecent }} - -############################################################################### -### JSON-RPC Configuration ### -############################################################################### - -# JSON-RPC enables a JSON-RPC server that allows Ethereum clients to connect to an Ethermint node. -# For the full list of supported endpoints see https://docs.ethermint.zone/basics/json_rpc.html -[json-rpc] - -# Enable defines if the JSON-RPC server should be enabled. -enable = {{ .JSONRPC.Enable }} - -# Address defines the JSON-RPC server address to bind to. -address = "{{ .JSONRPC.Address }}" - - -############################################################################### -### Ethereum Websocket Configuration ### -############################################################################### - -# Ethereum Websocket enables a PubSub server that allows Ethereum clients to subscribe to specific endpoints. -[ethereum-websocket] - -# Enable defines if the Ethereum Websocket server should be enabled. -enable = {{ .EthereumWebsocket.Enable }} - -# Address defines the Ethereum Websocket server address to bind to. -address = "{{ .EthereumWebsocket.Address }}" -` - -var configTemplate *template.Template - -func init() { - var err error - - tmpl := template.New("appConfigFileTemplate") - - if configTemplate, err = tmpl.Parse(defaultConfigTemplate); err != nil { - panic(err) - } -} - -// ParseConfig retrieves the default environment configuration for the -// application. -func ParseConfig(v *viper.Viper) (*Config, error) { - conf := DefaultConfig() - err := v.Unmarshal(conf) - - return conf, err -} - -// WriteConfigFile renders config using the template and writes it to -// configFilePath. -func WriteConfigFile(configFilePath string, config *Config) { - var buffer bytes.Buffer - - if err := configTemplate.Execute(&buffer, config); err != nil { - panic(err) - } - - tmos.MustWriteFile(configFilePath, buffer.Bytes(), 0644) -} diff --git a/server/flags.go b/server/flags.go deleted file mode 100644 index b17691bf..00000000 --- a/server/flags.go +++ /dev/null @@ -1,29 +0,0 @@ -package server - -// Tendermint full-node start flags -const ( - flagWithTendermint = "with-tendermint" - flagAddress = "address" - flagTransport = "transport" - flagTraceStore = "trace-store" - flagCPUProfile = "cpu-profile" -) - -// GRPC-related flags. -const ( - flagGRPCEnable = "grpc.enable" - flagGRPCAddress = "grpc.address" -) - -// RPCAPI-related flags. -const ( - flagRPCAPI = "rpc-api" -) - -// Ethereum-related flags. -const ( - flagJSONRPCEnable = "json-rpc.enable" - flagJSONRPCAddress = "json-rpc.address" - flagEthereumWebsocketEnable = "ethereum-websocket.enable" - flagEthereumWebsocketAddress = "ethereum-websocket.address" -) diff --git a/server/services/jsonrpc/service.go b/server/services/jsonrpc/service.go deleted file mode 100644 index 2790dd2a..00000000 --- a/server/services/jsonrpc/service.go +++ /dev/null @@ -1,90 +0,0 @@ -package jsonrpc - -import ( - "context" - "fmt" - "net" - "net/http" - "net/url" - "time" - - "github.com/cosmos/ethermint/server/config" - "github.com/ethereum/go-ethereum/rpc" -) - -type Service struct { - rpcServer *rpc.Server - apis []rpc.API - http *http.Server -} - -// NewService creates a new JSON-RPC server instance over http with public Ethereum APIs -func NewService(apis []rpc.API) *Service { - s := &Service{ - rpcServer: rpc.NewServer(), - apis: apis, - http: &http.Server{}, - } - s.http.Handler = s.rpcServer - - return s -} - -// Name returns the JSON-RPC service name -func (Service) Name() string { - return "JSON-RPC" -} - -// RegisterRoutes registers the JSON-RPC server to the application. It fails if any of the -// API names fail to register. -func (s *Service) RegisterRoutes() error { - for _, api := range s.apis { - if err := s.rpcServer.RegisterName(api.Namespace, api.Service); err != nil { - return err - } - } - - return nil -} - -// Start starts the JSON-RPC server on the address defined on the configuration. -func (s *Service) Start(cfg config.Config) error { - u, err := url.Parse(cfg.JSONRPC.Address) - if err != nil { - return err - } - - listener, err := net.Listen("tcp", u.Host) - if err != nil { - return err - } - - errCh := make(chan error) - go func() { - err = s.http.Serve(listener) - if err != nil { - errCh <- fmt.Errorf("failed to serve: %w", err) - } - }() - - select { - case err := <-errCh: - return err - case <-time.After(5 * time.Second): // assume server started successfully - return nil - } -} - -// Stop stops the JSON-RPC service by no longer reading new requests, waits for -// stopPendingRequestTimeout to allow pending requests to finish, then closes all codecs which will -// cancel pending requests and subscriptions. -func (s *Service) Stop() error { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - err := s.http.Shutdown(ctx) - if err != nil { - return err - } - return nil -} diff --git a/server/services/websocket/service.go b/server/services/websocket/service.go deleted file mode 100644 index 4737d1dc..00000000 --- a/server/services/websocket/service.go +++ /dev/null @@ -1,57 +0,0 @@ -package websocket - -import ( - "net/http" - "net/url" - "time" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/gorilla/mux" - - "github.com/cosmos/ethermint/rpc/websockets" - "github.com/cosmos/ethermint/server/config" -) - -type Service struct { - websocketServer *websockets.Server -} - -// NewService creates a new gRPC server instance with a defined listener address. -func NewService(clientCtx client.Context) *Service { - return &Service{ - websocketServer: websockets.NewServer(clientCtx), - } -} - -// Name returns the JSON-RPC service name -func (Service) Name() string { - return "Ethereum Websocket" -} - -// Start runs the websocket server -func (s Service) Start(cfg config.Config) error { - s.websocketServer.Address = cfg.JSONRPC.Address - - u, err := url.Parse(cfg.EthereumWebsocket.Address) - if err != nil { - return err - } - - ws := mux.NewRouter() - ws.Handle("/", s.websocketServer) - - errCh := make(chan error) - go func() { - err := http.ListenAndServe(":"+u.Port(), ws) - if err != nil { - errCh <- err - } - }() - - select { - case err := <-errCh: - return err - case <-time.After(5 * time.Second): // assume server started successfully - return nil - } -} diff --git a/server/start.go b/server/start.go deleted file mode 100644 index f3b1d482..00000000 --- a/server/start.go +++ /dev/null @@ -1,331 +0,0 @@ -package server - -// DONTCOVER - -import ( - "fmt" - "os" - "runtime/pprof" - "strings" - "time" - - "github.com/tendermint/tendermint/rpc/client/local" - - "github.com/spf13/cobra" - "google.golang.org/grpc" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdkserver "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/server/api" - sdkconfig "github.com/cosmos/cosmos-sdk/server/config" - servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" - servertypes "github.com/cosmos/cosmos-sdk/server/types" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - "github.com/tendermint/tendermint/abci/server" - tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" - tmos "github.com/tendermint/tendermint/libs/os" - "github.com/tendermint/tendermint/node" - "github.com/tendermint/tendermint/p2p" - pvm "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/proxy" - - "github.com/cosmos/ethermint/rpc" - "github.com/cosmos/ethermint/server/config" - "github.com/cosmos/ethermint/server/services/jsonrpc" - "github.com/cosmos/ethermint/server/services/websocket" -) - -// StartCmd runs the service passed in, either stand-alone or in-process with -// Tendermint. -func StartCmd(appCreator servertypes.AppCreator, defaultNodeHome string) *cobra.Command { - cmd := &cobra.Command{ - Use: "start", - Short: "Run the full node", - Long: `Run the full node application with Tendermint in or out of process. By -default, the application will run with Tendermint in process. - -Pruning options can be provided via the '--pruning' flag or alternatively with '--pruning-keep-recent', -'pruning-keep-every', and 'pruning-interval' together. - -For '--pruning' the options are as follows: - -default: the last 100 states are kept in addition to every 500th state; pruning at 10 block intervals -nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node) -everything: all saved states will be deleted, storing only the current state; pruning at 10 block intervals -custom: allow pruning options to be manually specified through 'pruning-keep-recent', 'pruning-keep-every', and 'pruning-interval' - -Node halting configurations exist in the form of two flags: '--halt-height' and '--halt-time'. During -the ABCI Commit phase, the node will check if the current block height is greater than or equal to -the halt-height or if the current block time is greater than or equal to the halt-time. If so, the -node will attempt to gracefully shutdown and the block will not be committed. In addition, the node -will not be able to commit subsequent blocks. - -For profiling and benchmarking purposes, CPU profiling can be enabled via the '--cpu-profile' flag -which accepts a path for the resulting pprof file. -`, - PreRunE: func(cmd *cobra.Command, _ []string) error { - serverCtx := sdkserver.GetServerContextFromCmd(cmd) - - // Bind flags to the Context's Viper so the app construction can set - // options accordingly. - if err := serverCtx.Viper.BindPFlags(cmd.Flags()); err != nil { - return err - } - - _, err := sdkserver.GetPruningOptionsFromFlags(serverCtx.Viper) - return err - }, - RunE: func(cmd *cobra.Command, _ []string) error { - serverCtx := sdkserver.GetServerContextFromCmd(cmd) - clientCtx := client.GetClientContextFromCmd(cmd) - - withTM, _ := cmd.Flags().GetBool(flagWithTendermint) - if !withTM { - serverCtx.Logger.Info("starting ABCI without Tendermint") - return startStandAlone(serverCtx, appCreator) - } - - serverCtx.Logger.Info("starting ABCI with Tendermint") - - // amino is needed here for backwards compatibility of REST routes - err := startInProcess(serverCtx, clientCtx, appCreator) - return err - }, - } - - cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") - cmd.Flags().Bool(flagWithTendermint, true, "Run abci app embedded in-process with tendermint") - cmd.Flags().String(flagAddress, "tcp://0.0.0.0:26658", "Listen address") - cmd.Flags().String(flagTransport, "socket", "Transport protocol: socket, grpc") - cmd.Flags().String(flagTraceStore, "", "Enable KVStore tracing to an output file") - cmd.Flags().String(sdkserver.FlagMinGasPrices, "", "Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)") - cmd.Flags().IntSlice(sdkserver.FlagUnsafeSkipUpgrades, []int{}, "Skip a set of upgrade heights to continue the old binary") - cmd.Flags().Uint64(sdkserver.FlagHaltHeight, 0, "Block height at which to gracefully halt the chain and shutdown the node") - cmd.Flags().Uint64(sdkserver.FlagHaltTime, 0, "Minimum block time (in Unix seconds) at which to gracefully halt the chain and shutdown the node") - cmd.Flags().Bool(sdkserver.FlagInterBlockCache, true, "Enable inter-block caching") - cmd.Flags().String(flagCPUProfile, "", "Enable CPU profiling and write to the provided file") - cmd.Flags().Bool(sdkserver.FlagTrace, false, "Provide full stack traces for errors in ABCI Log") - cmd.Flags().String(sdkserver.FlagPruning, storetypes.PruningOptionDefault, "Pruning strategy (default|nothing|everything|custom)") - cmd.Flags().Uint64(sdkserver.FlagPruningKeepRecent, 0, "Number of recent heights to keep on disk (ignored if pruning is not 'custom')") - cmd.Flags().Uint64(sdkserver.FlagPruningKeepEvery, 0, "Offset heights to keep on disk after 'keep-every' (ignored if pruning is not 'custom')") - cmd.Flags().Uint64(sdkserver.FlagPruningInterval, 0, "Height interval at which pruned heights are removed from disk (ignored if pruning is not 'custom')") - cmd.Flags().Uint(sdkserver.FlagInvCheckPeriod, 0, "Assert registered invariants every N blocks") - cmd.Flags().Uint64(sdkserver.FlagMinRetainBlocks, 0, "Minimum block height offset during ABCI commit to prune Tendermint blocks") - - cmd.Flags().Bool(flagGRPCEnable, true, "Define if the gRPC server should be enabled") - cmd.Flags().String(flagGRPCAddress, sdkconfig.DefaultGRPCAddress, "the gRPC server address to listen on") - - cmd.Flags().Bool(flagJSONRPCEnable, true, "Define if the Ethereum JSON-RPC server should be enabled") - cmd.Flags().String(flagJSONRPCAddress, config.DefaultJSONRPCAddress, "the JSON-RPC server address to listen on") - - cmd.Flags().Bool(flagEthereumWebsocketEnable, true, "Define if the Ethereum Websocket server should be enabled") - cmd.Flags().String(flagEthereumWebsocketAddress, config.DefaultEthereumWebsocketAddress, "the Ethereum websocket server address to listen on") - - cmd.Flags().Uint64(sdkserver.FlagStateSyncSnapshotInterval, 0, "State sync snapshot interval") - cmd.Flags().Uint32(sdkserver.FlagStateSyncSnapshotKeepRecent, 2, "State sync snapshot to keep") - - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)") - - cmd.Flags().String(flagRPCAPI, "", fmt.Sprintf("Comma separated list of RPC API modules to enable: %s, %s, %s, %s", rpc.Web3Namespace, rpc.EthNamespace, rpc.PersonalNamespace, rpc.NetNamespace)) - - // add support for all Tendermint-specific command line options - tcmd.AddNodeFlags(cmd) - return cmd -} - -func startStandAlone(ctx *sdkserver.Context, appCreator servertypes.AppCreator) error { - addr := ctx.Viper.GetString(flagAddress) - transport := ctx.Viper.GetString(flagTransport) - home := ctx.Viper.GetString(flags.FlagHome) - - db, err := openDB(home) - if err != nil { - return err - } - - traceWriterFile := ctx.Viper.GetString(flagTraceStore) - traceWriter, err := openTraceWriter(traceWriterFile) - if err != nil { - return err - } - - app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper) - - svr, err := server.NewServer(addr, transport, app) - if err != nil { - return fmt.Errorf("error creating listener: %v", err) - } - - svr.SetLogger(ctx.Logger.With("module", "abci-server")) - - err = svr.Start() - if err != nil { - tmos.Exit(err.Error()) - } - - sdkserver.TrapSignal(func() { - if err = svr.Stop(); err != nil { - tmos.Exit(err.Error()) - } - }) - - // run forever (the node will not be returned) - select {} -} - -// legacyAminoCdc is used for the legacy REST API -func startInProcess(ctx *sdkserver.Context, clientCtx client.Context, appCreator servertypes.AppCreator) error { - cfg := ctx.Config - home := cfg.RootDir - var cpuProfileCleanup func() - - if cpuProfile := ctx.Viper.GetString(flagCPUProfile); cpuProfile != "" { - f, err := os.Create(cpuProfile) - if err != nil { - return err - } - - ctx.Logger.Info("starting CPU profiler", "profile", cpuProfile) - if err := pprof.StartCPUProfile(f); err != nil { - return err - } - - cpuProfileCleanup = func() { - ctx.Logger.Info("stopping CPU profiler", "profile", cpuProfile) - pprof.StopCPUProfile() - f.Close() - } - } - - traceWriterFile := ctx.Viper.GetString(flagTraceStore) - db, err := openDB(home) - if err != nil { - return err - } - - traceWriter, err := openTraceWriter(traceWriterFile) - if err != nil { - return err - } - - app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper) - - nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile()) - if err != nil { - return err - } - - genDocProvider := node.DefaultGenesisDocProviderFunc(cfg) - tmNode, err := node.NewNode( - cfg, - pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()), - nodeKey, - proxy.NewLocalClientCreator(app), - genDocProvider, - node.DefaultDBProvider, - node.DefaultMetricsProvider(cfg.Instrumentation), - ctx.Logger.With("module", "node"), - ) - if err != nil { - return err - } - ctx.Logger.Debug("Initialization: tmNode created") - - if err := tmNode.Start(); err != nil { - return err - } - ctx.Logger.Debug("Initialization: tmNode started") - - // Add the tx service to the gRPC router. - app.RegisterTxService(clientCtx) - - var apiSrv *api.Server - - config := config.GetConfig(ctx.Viper) - - genDoc, err := genDocProvider() - if err != nil { - return err - } - - clientCtx = clientCtx. - WithHomeDir(home). - WithChainID(genDoc.ChainID). - WithClient(local.New(tmNode)) - - if config.API.Enable { - apiSrv = api.New(clientCtx, ctx.Logger.With("module", "api-server")) - app.RegisterAPIRoutes(apiSrv, config.API) - errCh := make(chan error) - - go func() { - if err := apiSrv.Start(*config.Config); err != nil { - errCh <- err - } - }() - - select { - case err := <-errCh: - return err - case <-time.After(5 * time.Second): // assume server started successfully - } - } - - var grpcSrv *grpc.Server - if config.GRPC.Enable { - grpcSrv, err = servergrpc.StartGRPCServer(clientCtx, app, config.GRPC.Address) - if err != nil { - return err - } - } - - rpcapi := ctx.Viper.GetString(flagRPCAPI) - rpcapi = strings.ReplaceAll(rpcapi, " ", "") - rpcapiArr := strings.Split(rpcapi, ",") - - jsonRPCSrv := jsonrpc.NewService(rpc.GetAPIs(clientCtx, rpcapiArr)) - if config.JSONRPC.Enable { - if err := jsonRPCSrv.RegisterRoutes(); err != nil { - return err - } - - err = jsonRPCSrv.Start(config) - if err != nil { - return err - } - } - - if config.EthereumWebsocket.Enable { - websocketSrv := websocket.NewService(clientCtx) - err = websocketSrv.Start(config) - if err != nil { - return err - } - } - - defer func() { - if tmNode.IsRunning() { - _ = tmNode.Stop() - } - - if cpuProfileCleanup != nil { - cpuProfileCleanup() - } - - if apiSrv != nil { - _ = apiSrv.Close() - } - - if grpcSrv != nil { - grpcSrv.Stop() - } - - _ = jsonRPCSrv.Stop() - - ctx.Logger.Info("exiting...") - }() - - // Wait for SIGINT or SIGTERM signal - return sdkserver.WaitForQuitSignals() -} diff --git a/server/util.go b/server/util.go deleted file mode 100644 index ea650eb9..00000000 --- a/server/util.go +++ /dev/null @@ -1,199 +0,0 @@ -package server - -import ( - "fmt" - "io" - "os" - "path" - "path/filepath" - "strings" - "time" - - "github.com/rs/zerolog" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - tmcfg "github.com/tendermint/tendermint/config" - dbm "github.com/tendermint/tm-db" - - "github.com/cosmos/cosmos-sdk/client/flags" - sdkserver "github.com/cosmos/cosmos-sdk/server" - servertypes "github.com/cosmos/cosmos-sdk/server/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/version" - - "github.com/cosmos/ethermint/server/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 { - serverCtx := sdkserver.NewDefaultContext() - - // Get the executable name and configure the viper instance so that environmental - // variables are checked based off that name. The underscore character is used - // as a separator - executableName, err := os.Executable() - if err != nil { - return err - } - - basename := path.Base(executableName) - - // Configure the viper instance - if err := serverCtx.Viper.BindPFlags(cmd.Flags()); err != nil { - return err - } - if err := serverCtx.Viper.BindPFlags(cmd.PersistentFlags()); err != nil { - return err - } - serverCtx.Viper.SetEnvPrefix(basename) - serverCtx.Viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) - serverCtx.Viper.AutomaticEnv() - - // intercept configuration files, using both Viper instances separately - config, err := interceptConfigs(serverCtx.Viper) - if err != nil { - return err - } - - // return value is a tendermint configuration object - serverCtx.Config = config - - var logWriter io.Writer - if strings.ToLower(serverCtx.Viper.GetString(flags.FlagLogFormat)) == tmcfg.LogFormatPlain { - logWriter = zerolog.ConsoleWriter{Out: os.Stderr} - } else { - logWriter = os.Stderr - } - - logLvlStr := serverCtx.Viper.GetString(flags.FlagLogLevel) - logLvl, err := zerolog.ParseLevel(logLvlStr) - if err != nil { - return fmt.Errorf("failed to parse log level (%s): %w", logLvlStr, err) - } - - serverCtx.Logger = sdkserver.ZeroLogWrapper{ - Logger: zerolog.New(logWriter).Level(logLvl).With().Timestamp().Logger(), - } - - return sdkserver.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(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() - - switch _, err := os.Stat(configFile); { - case 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) - - case err != nil: - return nil, err - - default: - 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) - } - } - - // Read into the configuration whatever data the viper instance has for it - // This may come from the configuration file above but also any of the other sources - // viper uses - 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(rootViper) - if err != nil { - return nil, fmt.Errorf("failed to parse app.toml: %w", err) - } - - config.WriteConfigFile(appConfigFilePath, appConf) - } - - rootViper.SetConfigType("toml") - rootViper.SetConfigName("app") - rootViper.AddConfigPath(configPath) - if err := rootViper.ReadInConfig(); err != nil { - return nil, fmt.Errorf("failed to read in app.toml: %w", err) - } - - return conf, nil -} - -// AddCommands adds the server commands -func AddCommands( - rootCmd *cobra.Command, defaultNodeHome string, - appCreator servertypes.AppCreator, appExport servertypes.AppExporter, addStartFlags servertypes.ModuleInitFlags, -) { - tendermintCmd := &cobra.Command{ - Use: "tendermint", - Short: "Tendermint subcommands", - } - - tendermintCmd.AddCommand( - sdkserver.ShowNodeIDCmd(), - sdkserver.ShowValidatorCmd(), - sdkserver.ShowAddressCmd(), - sdkserver.VersionCmd(), - ) - - startCmd := StartCmd(appCreator, defaultNodeHome) - addStartFlags(startCmd) - - rootCmd.AddCommand( - startCmd, - sdkserver.UnsafeResetAllCmd(), - flags.LineBreak, - tendermintCmd, - sdkserver.ExportCmd(appExport, defaultNodeHome), - flags.LineBreak, - version.NewVersionCommand(), - ) -} - -func openDB(rootDir string) (dbm.DB, error) { - dataDir := filepath.Join(rootDir, "data") - return sdk.NewLevelDB("application", dataDir) -} - -func openTraceWriter(traceWriterFile string) (w io.Writer, err error) { - if traceWriterFile == "" { - return - } - return os.OpenFile( - traceWriterFile, - os.O_WRONLY|os.O_APPEND|os.O_CREATE, - 0666, - ) -} diff --git a/tests/rpc_test.go b/tests/rpc_test.go index 4f475bcc..09a69ec6 100644 --- a/tests/rpc_test.go +++ b/tests/rpc_test.go @@ -1,12 +1,14 @@ // This is a test utility for Ethermint's Web3 JSON-RPC services. // -// To run these tests please first ensure you have the ethermintd running +// To run these tests please first ensure you have the injectived running +// and have started the RPC service with `injectived rest-server`. // -// You can configure the desired HOST and MODE as well in integration-test-all.sh +// You can configure the desired HOST and MODE as well package tests import ( "bytes" + "encoding/hex" "encoding/json" "fmt" "math/big" @@ -17,12 +19,11 @@ import ( "github.com/stretchr/testify/require" + rpctypes "github.com/cosmos/ethermint/ethereum/rpc/types" + evmtypes "github.com/cosmos/ethermint/x/evm/types" ethcmn "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" - - rpctypes "github.com/cosmos/ethermint/rpc/types" - ethermint "github.com/cosmos/ethermint/types" ) const ( @@ -31,9 +32,10 @@ const ( ) var ( - MODE = os.Getenv("MODE") - from = []byte{} + MODE = os.Getenv("MODE") + zeroString = "0x0" + from = []byte{} ) func TestMain(m *testing.M) { @@ -42,8 +44,12 @@ func TestMain(m *testing.M) { return } + if HOST == "" { + HOST = "http://localhost:8545" + } + var err error - from, err = GetAddress() + from, err = getAddress() if err != nil { fmt.Printf("failed to get account: %s\n", err) os.Exit(1) @@ -54,48 +60,115 @@ func TestMain(m *testing.M) { os.Exit(code) } -func TestEth_GetTransactionCount(t *testing.T) { - // TODO: this test passes on when run on its own, but fails when run with the other tests - if testing.Short() { - t.Skip("skipping TestEth_GetTransactionCount") +func getAddress() ([]byte, error) { + rpcRes, err := callWithError("eth_accounts", []string{}) + if err != nil { + return nil, err } - prev := GetNonce(t, "latest") - SendTestTransaction(t, from) - time.Sleep(20 * time.Second) - post := GetNonce(t, "latest") - require.Equal(t, prev, post-1) + var res []hexutil.Bytes + err = json.Unmarshal(rpcRes.Result, &res) + if err != nil { + return nil, err + } + + return res[0], nil +} + +func createRequest(method string, params interface{}) Request { + return Request{ + Version: "2.0", + Method: method, + Params: params, + ID: 1, + } +} + +func call(t *testing.T, method string, params interface{}) *Response { + req, err := json.Marshal(createRequest(method, params)) + require.NoError(t, err) + + var rpcRes *Response + time.Sleep(1 * time.Second) + /* #nosec */ + res, err := http.Post(HOST, "application/json", bytes.NewBuffer(req)) + require.NoError(t, err) + + decoder := json.NewDecoder(res.Body) + rpcRes = new(Response) + err = decoder.Decode(&rpcRes) + require.NoError(t, err) + + err = res.Body.Close() + require.NoError(t, err) + require.Nil(t, rpcRes.Error) + + return rpcRes +} + +func callWithError(method string, params interface{}) (*Response, error) { + req, err := json.Marshal(createRequest(method, params)) + if err != nil { + return nil, err + } + + var rpcRes *Response + time.Sleep(1 * time.Second) + /* #nosec */ + res, err := http.Post(HOST, "application/json", bytes.NewBuffer(req)) + if err != nil { + return nil, err + } + + decoder := json.NewDecoder(res.Body) + rpcRes = new(Response) + err = decoder.Decode(&rpcRes) + if err != nil { + return nil, err + } + + err = res.Body.Close() + if err != nil { + return nil, err + } + + if rpcRes.Error != nil { + return nil, fmt.Errorf(rpcRes.Error.Message) + } + + return rpcRes, nil +} + +// turns a 0x prefixed hex string to a big.Int +func hexToBigInt(t *testing.T, in string) *big.Int { + s := in[2:] + b, err := hex.DecodeString(s) + require.NoError(t, err) + return big.NewInt(0).SetBytes(b) +} + +func TestBlockBloom(t *testing.T) { + hash := deployTestContractWithFunction(t) + receipt := waitForReceipt(t, hash) + + number := receipt["blockNumber"].(string) + param := []interface{}{number, false} + rpcRes := call(t, "eth_getBlockByNumber", param) + + block := make(map[string]interface{}) + err := json.Unmarshal(rpcRes.Result, &block) + require.NoError(t, err) + + lb := hexToBigInt(t, block["logsBloom"].(string)) + require.NotEqual(t, big.NewInt(0), lb) + require.Equal(t, hash.String(), block["transactions"].([]interface{})[0]) } func TestEth_GetLogs_NoLogs(t *testing.T) { param := make([]map[string][]string, 1) param[0] = make(map[string][]string) param[0]["topics"] = []string{} - rpcRes := Call(t, "eth_getLogs", param) - require.NotNil(t, rpcRes) - require.Nil(t, rpcRes.Error) - - var logs []*ethtypes.Log - err := json.Unmarshal(rpcRes.Result, &logs) - require.NoError(t, err) - require.Empty(t, logs) // begin, end are -1, crit.Addresses, crit.Topics are empty array, so no log should be returned(run this test before anyone else so that log will be empty) -} - -func TestBlockBloom(t *testing.T) { - hash := DeployTestContractWithFunction(t, from) - receipt := WaitForReceipt(t, hash) - - number := receipt["blockNumber"].(string) - param := []interface{}{number, false} - rpcRes := Call(t, "eth_getBlockByNumber", param) - - block := make(map[string]interface{}) - err := json.Unmarshal(rpcRes.Result, &block) - require.NoError(t, err) - - lb := HexToBigInt(t, block["logsBloom"].(string)) - require.NotEqual(t, big.NewInt(0), lb) - require.Equal(t, hash.String(), block["transactions"].([]interface{})[0]) + call(t, "eth_getLogs", param) } func TestEth_GetLogs_Topics_AB(t *testing.T) { @@ -104,7 +177,7 @@ func TestEth_GetLogs_Topics_AB(t *testing.T) { t.Skip("skipping TestEth_GetLogs_Topics_AB") } - rpcRes := Call(t, "eth_blockNumber", []string{}) + rpcRes := call(t, "eth_blockNumber", []string{}) var res hexutil.Uint64 err := res.UnmarshalJSON(rpcRes.Result) @@ -115,10 +188,10 @@ func TestEth_GetLogs_Topics_AB(t *testing.T) { param[0]["topics"] = []string{helloTopic, worldTopic} param[0]["fromBlock"] = res.String() - hash := DeployTestContractWithFunction(t, from) - WaitForReceipt(t, hash) + hash := deployTestContractWithFunction(t) + waitForReceipt(t, hash) - rpcRes = Call(t, "eth_getLogs", param) + rpcRes = call(t, "eth_getLogs", param) var logs []*ethtypes.Log err = json.Unmarshal(rpcRes.Result, &logs) @@ -127,16 +200,28 @@ func TestEth_GetLogs_Topics_AB(t *testing.T) { require.Equal(t, 1, len(logs)) } +func TestEth_GetTransactionCount(t *testing.T) { + // TODO: this test passes on when run on its own, but fails when run with the other tests + if testing.Short() { + t.Skip("skipping TestEth_GetTransactionCount") + } + + prev := getNonce(t) + sendTestTransaction(t) + post := getNonce(t) + require.Equal(t, prev, post-1) +} + func TestEth_GetTransactionLogs(t *testing.T) { // TODO: this test passes on when run on its own, but fails when run with the other tests if testing.Short() { t.Skip("skipping TestEth_GetTransactionLogs") } - hash, _ := DeployTestContract(t, from) + hash, _ := deployTestContract(t) param := []string{hash.String()} - rpcRes := Call(t, "eth_getTransactionLogs", param) + rpcRes := call(t, "eth_getTransactionLogs", param) logs := new([]*ethtypes.Log) err := json.Unmarshal(rpcRes.Result, logs) @@ -145,9 +230,9 @@ func TestEth_GetTransactionLogs(t *testing.T) { } func TestEth_protocolVersion(t *testing.T) { - expectedRes := hexutil.Uint(ethermint.ProtocolVersion) + expectedRes := hexutil.Uint(evmtypes.ProtocolVersion) - rpcRes := Call(t, "eth_protocolVersion", []string{}) + rpcRes := call(t, "eth_protocolVersion", []string{}) var res hexutil.Uint err := res.UnmarshalJSON(rpcRes.Result) @@ -158,7 +243,7 @@ func TestEth_protocolVersion(t *testing.T) { } func TestEth_chainId(t *testing.T) { - rpcRes := Call(t, "eth_chainId", []string{}) + rpcRes := call(t, "eth_chainId", []string{}) var res hexutil.Uint err := res.UnmarshalJSON(rpcRes.Result) @@ -167,7 +252,7 @@ func TestEth_chainId(t *testing.T) { } func TestEth_blockNumber(t *testing.T) { - rpcRes := Call(t, "eth_blockNumber", []string{}) + rpcRes := call(t, "eth_blockNumber", []string{}) var res hexutil.Uint64 err := res.UnmarshalJSON(rpcRes.Result) @@ -178,7 +263,7 @@ func TestEth_blockNumber(t *testing.T) { func TestEth_coinbase(t *testing.T) { zeroAddress := hexutil.Bytes(ethcmn.Address{}.Bytes()) - rpcRes := Call(t, "eth_coinbase", []string{}) + rpcRes := call(t, "eth_coinbase", []string{}) var res hexutil.Bytes err := res.UnmarshalJSON(rpcRes.Result) @@ -189,7 +274,7 @@ func TestEth_coinbase(t *testing.T) { } func TestEth_GetBalance(t *testing.T) { - rpcRes := Call(t, "eth_getBalance", []string{addrA, zeroString}) + rpcRes := call(t, "eth_getBalance", []string{addrA, zeroString}) var res hexutil.Big err := res.UnmarshalJSON(rpcRes.Result) @@ -205,8 +290,7 @@ func TestEth_GetBalance(t *testing.T) { func TestEth_GetStorageAt(t *testing.T) { expectedRes := hexutil.Bytes{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - testKey := 1 // using 0 as key here will create an ethereum empty hash which is considered as invalid hash - rpcRes := Call(t, "eth_getStorageAt", []string{addrA, fmt.Sprint(testKey), "0x3"}) + rpcRes := call(t, "eth_getStorageAt", []string{addrA, fmt.Sprint(addrAStoreKey), zeroString}) var storage hexutil.Bytes err := storage.UnmarshalJSON(rpcRes.Result) @@ -221,9 +305,8 @@ func TestEth_GetProof(t *testing.T) { params := make([]interface{}, 3) params[0] = addrA params[1] = []string{fmt.Sprint(addrAStoreKey)} - params[2] = "0x3" // queries at height <= 2 are not supported - - rpcRes := Call(t, "eth_getProof", params) + params[2] = "latest" + rpcRes := call(t, "eth_getProof", params) require.NotNil(t, rpcRes) var accRes rpctypes.AccountResult @@ -237,7 +320,7 @@ func TestEth_GetProof(t *testing.T) { func TestEth_GetCode(t *testing.T) { expectedRes := hexutil.Bytes{} - rpcRes := Call(t, "eth_getCode", []string{addrA, zeroString}) + rpcRes := call(t, "eth_getCode", []string{addrA, zeroString}) var code hexutil.Bytes err := code.UnmarshalJSON(rpcRes.Result) @@ -257,16 +340,13 @@ func TestEth_SendTransaction_Transfer(t *testing.T) { param[0]["gasLimit"] = "0x5208" param[0]["gasPrice"] = "0x55ae82600" - rpcRes := Call(t, "personal_unlockAccount", []interface{}{param[0]["from"], ""}) - require.Nil(t, rpcRes.Error) - - rpcRes = Call(t, "eth_sendTransaction", param) + rpcRes := call(t, "eth_sendTransaction", param) var hash hexutil.Bytes err := json.Unmarshal(rpcRes.Result, &hash) require.NoError(t, err) - receipt := WaitForReceipt(t, hash) + receipt := waitForReceipt(t, hash) require.NotNil(t, receipt) require.Equal(t, "0x1", receipt["status"].(string)) } @@ -277,10 +357,7 @@ func TestEth_SendTransaction_ContractDeploy(t *testing.T) { param[0]["from"] = "0x" + fmt.Sprintf("%x", from) param[0]["data"] = "0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029" - rpcRes := Call(t, "personal_unlockAccount", []interface{}{param[0]["from"], ""}) - require.Nil(t, rpcRes.Error) - - rpcRes = Call(t, "eth_sendTransaction", param) + rpcRes := call(t, "eth_sendTransaction", param) var hash hexutil.Bytes err := json.Unmarshal(rpcRes.Result, &hash) @@ -291,7 +368,7 @@ func TestEth_NewFilter(t *testing.T) { param := make([]map[string][]string, 1) param[0] = make(map[string][]string) param[0]["topics"] = []string{"0x0000000000000000000000000000000000000000000000000000000012341234"} - rpcRes := Call(t, "eth_newFilter", param) + rpcRes := call(t, "eth_newFilter", param) var ID string err := json.Unmarshal(rpcRes.Result, &ID) @@ -299,7 +376,7 @@ func TestEth_NewFilter(t *testing.T) { } func TestEth_NewBlockFilter(t *testing.T) { - rpcRes := Call(t, "eth_newBlockFilter", []string{}) + rpcRes := call(t, "eth_newBlockFilter", []string{}) var ID string err := json.Unmarshal(rpcRes.Result, &ID) @@ -307,7 +384,7 @@ func TestEth_NewBlockFilter(t *testing.T) { } func TestEth_GetFilterChanges_BlockFilter(t *testing.T) { - rpcRes := Call(t, "eth_newBlockFilter", []string{}) + rpcRes := call(t, "eth_newBlockFilter", []string{}) var ID string err := json.Unmarshal(rpcRes.Result, &ID) @@ -315,7 +392,7 @@ func TestEth_GetFilterChanges_BlockFilter(t *testing.T) { time.Sleep(5 * time.Second) - changesRes := Call(t, "eth_getFilterChanges", []string{ID}) + changesRes := call(t, "eth_getFilterChanges", []string{ID}) var hashes []ethcmn.Hash err = json.Unmarshal(changesRes.Result, &hashes) require.NoError(t, err) @@ -326,13 +403,13 @@ func TestEth_GetFilterChanges_NoLogs(t *testing.T) { param := make([]map[string][]string, 1) param[0] = make(map[string][]string) param[0]["topics"] = []string{} - rpcRes := Call(t, "eth_newFilter", param) + rpcRes := call(t, "eth_newFilter", param) var ID string err := json.Unmarshal(rpcRes.Result, &ID) require.NoError(t, err) - changesRes := Call(t, "eth_getFilterChanges", []string{ID}) + changesRes := call(t, "eth_getFilterChanges", []string{ID}) var logs []*ethtypes.Log err = json.Unmarshal(changesRes.Result, &logs) @@ -340,7 +417,7 @@ func TestEth_GetFilterChanges_NoLogs(t *testing.T) { } func TestEth_GetFilterChanges_WrongID(t *testing.T) { - req, err := json.Marshal(CreateRequest("eth_getFilterChanges", []string{"0x1122334400000077"})) + req, err := json.Marshal(createRequest("eth_getFilterChanges", []string{"0x1122334400000077"})) require.NoError(t, err) var rpcRes *Response @@ -359,13 +436,28 @@ func TestEth_GetFilterChanges_WrongID(t *testing.T) { require.NotNil(t, "invalid filter ID", rpcRes.Error.Message) } +// sendTestTransaction sends a dummy transaction +func sendTestTransaction(t *testing.T) hexutil.Bytes { + param := make([]map[string]string, 1) + param[0] = make(map[string]string) + param[0]["from"] = "0x" + fmt.Sprintf("%x", from) + param[0]["to"] = "0x1122334455667788990011223344556677889900" + param[0]["value"] = "0x1" + rpcRes := call(t, "eth_sendTransaction", param) + + var hash hexutil.Bytes + err := json.Unmarshal(rpcRes.Result, &hash) + require.NoError(t, err) + return hash +} + func TestEth_GetTransactionReceipt(t *testing.T) { - hash := SendTestTransaction(t, from) + hash := sendTestTransaction(t) time.Sleep(time.Second * 5) param := []string{hash.String()} - rpcRes := Call(t, "eth_getTransactionReceipt", param) + rpcRes := call(t, "eth_getTransactionReceipt", param) require.Nil(t, rpcRes.Error) receipt := make(map[string]interface{}) @@ -376,16 +468,34 @@ func TestEth_GetTransactionReceipt(t *testing.T) { require.Equal(t, []interface{}{}, receipt["logs"].([]interface{})) } -func TestEth_GetTransactionReceipt_ContractDeployment(t *testing.T) { - rpcRes := Call(t, "personal_unlockAccount", []interface{}{hexutil.Bytes(from), ""}) - require.Nil(t, rpcRes.Error) +// deployTestContract deploys a contract that emits an event in the constructor +func deployTestContract(t *testing.T) (hexutil.Bytes, map[string]interface{}) { + param := make([]map[string]string, 1) + param[0] = make(map[string]string) + param[0]["from"] = "0x" + fmt.Sprintf("%x", from) + param[0]["data"] = "0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029" + param[0]["gas"] = "0x200000" - hash, _ := DeployTestContract(t, from) + rpcRes := call(t, "eth_sendTransaction", param) + + var hash hexutil.Bytes + err := json.Unmarshal(rpcRes.Result, &hash) + require.NoError(t, err) + + receipt := waitForReceipt(t, hash) + require.NotNil(t, receipt, "transaction failed") + require.Equal(t, "0x1", receipt["status"].(string)) + + return hash, receipt +} + +func TestEth_GetTransactionReceipt_ContractDeployment(t *testing.T) { + hash, _ := deployTestContract(t) time.Sleep(time.Second * 5) param := []string{hash.String()} - rpcRes = Call(t, "eth_getTransactionReceipt", param) + rpcRes := call(t, "eth_getTransactionReceipt", param) receipt := make(map[string]interface{}) err := json.Unmarshal(rpcRes.Result, &receipt) @@ -397,8 +507,32 @@ func TestEth_GetTransactionReceipt_ContractDeployment(t *testing.T) { } +func getTransactionReceipt(t *testing.T, hash hexutil.Bytes) map[string]interface{} { + param := []string{hash.String()} + rpcRes := call(t, "eth_getTransactionReceipt", param) + + receipt := make(map[string]interface{}) + err := json.Unmarshal(rpcRes.Result, &receipt) + require.NoError(t, err) + + return receipt +} + +func waitForReceipt(t *testing.T, hash hexutil.Bytes) map[string]interface{} { + for i := 0; i < 12; i++ { + receipt := getTransactionReceipt(t, hash) + if receipt != nil { + return receipt + } + + time.Sleep(time.Second) + } + + return nil +} + func TestEth_GetFilterChanges_NoTopics(t *testing.T) { - rpcRes := Call(t, "eth_blockNumber", []string{}) + rpcRes := call(t, "eth_blockNumber", []string{}) var res hexutil.Uint64 err := res.UnmarshalJSON(rpcRes.Result) @@ -410,18 +544,22 @@ func TestEth_GetFilterChanges_NoTopics(t *testing.T) { param[0]["fromBlock"] = res.String() // instantiate new filter - rpcRes = Call(t, "eth_newFilter", param) + rpcRes = call(t, "eth_newFilter", param) require.Nil(t, rpcRes.Error) var ID string err = json.Unmarshal(rpcRes.Result, &ID) require.NoError(t, err) // deploy contract, emitting some event - DeployTestContract(t, from) + deployTestContract(t) // get filter changes - changesRes := Call(t, "eth_getFilterChanges", []string{ID}) - require.Equal(t, 2, len(changesRes.Result)) + changesRes := call(t, "eth_getFilterChanges", []string{ID}) + + var logs []*ethtypes.Log + err = json.Unmarshal(changesRes.Result, &logs) + require.NoError(t, err) + require.Equal(t, 1, len(logs)) } func TestEth_GetFilterChanges_Addresses(t *testing.T) { @@ -440,11 +578,51 @@ var helloTopic = "0x775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73 // world parameter in Hello event var worldTopic = "0x0000000000000000000000000000000000000000000000000000000000000011" +func deployTestContractWithFunction(t *testing.T) hexutil.Bytes { + // pragma solidity ^0.5.1; + + // contract Test { + // event Hello(uint256 indexed world); + // event TestEvent(uint256 indexed a, uint256 indexed b); + + // uint256 myStorage; + + // constructor() public { + // emit Hello(17); + // } + + // function test(uint256 a, uint256 b) public { + // myStorage = a; + // emit TestEvent(a, b); + // } + // } + + bytecode := "0x608060405234801561001057600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a260d08061004d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063eb8ac92114602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506062565b005b8160008190555080827ff3ca124a697ba07e8c5e80bebcfcc48991fc16a63170e8a9206e30508960d00360405160405180910390a3505056fea265627a7a723158201d94d2187aaf3a6790527b615fcc40970febf0385fa6d72a2344848ebd0df3e964736f6c63430005110032" + + param := make([]map[string]string, 1) + param[0] = make(map[string]string) + param[0]["from"] = "0x" + fmt.Sprintf("%x", from) + param[0]["data"] = bytecode + param[0]["gas"] = "0x200000" + + rpcRes := call(t, "eth_sendTransaction", param) + + var hash hexutil.Bytes + err := json.Unmarshal(rpcRes.Result, &hash) + require.NoError(t, err) + + receipt := waitForReceipt(t, hash) + require.NotNil(t, receipt, "transaction failed") + require.Equal(t, "0x1", receipt["status"].(string)) + + return hash +} + // Tests topics case where there are topics in first two positions func TestEth_GetFilterChanges_Topics_AB(t *testing.T) { time.Sleep(time.Second) - rpcRes := Call(t, "eth_blockNumber", []string{}) + rpcRes := call(t, "eth_blockNumber", []string{}) var res hexutil.Uint64 err := res.UnmarshalJSON(rpcRes.Result) @@ -456,20 +634,25 @@ func TestEth_GetFilterChanges_Topics_AB(t *testing.T) { param[0]["fromBlock"] = res.String() // instantiate new filter - rpcRes = Call(t, "eth_newFilter", param) + rpcRes = call(t, "eth_newFilter", param) var ID string err = json.Unmarshal(rpcRes.Result, &ID) require.NoError(t, err, string(rpcRes.Result)) - DeployTestContractWithFunction(t, from) + deployTestContractWithFunction(t) // get filter changes - changesRes := Call(t, "eth_getFilterChanges", []string{ID}) - require.Equal(t, 2, len(changesRes.Result)) + changesRes := call(t, "eth_getFilterChanges", []string{ID}) + + var logs []*ethtypes.Log + err = json.Unmarshal(changesRes.Result, &logs) + require.NoError(t, err) + + require.Equal(t, 1, len(logs)) } func TestEth_GetFilterChanges_Topics_XB(t *testing.T) { - rpcRes := Call(t, "eth_blockNumber", []string{}) + rpcRes := call(t, "eth_blockNumber", []string{}) var res hexutil.Uint64 err := res.UnmarshalJSON(rpcRes.Result) @@ -481,16 +664,21 @@ func TestEth_GetFilterChanges_Topics_XB(t *testing.T) { param[0]["fromBlock"] = res.String() // instantiate new filter - rpcRes = Call(t, "eth_newFilter", param) + rpcRes = call(t, "eth_newFilter", param) var ID string err = json.Unmarshal(rpcRes.Result, &ID) require.NoError(t, err) - DeployTestContractWithFunction(t, from) + deployTestContractWithFunction(t) // get filter changes - changesRes := Call(t, "eth_getFilterChanges", []string{ID}) - require.Equal(t, 2, len(changesRes.Result)) + changesRes := call(t, "eth_getFilterChanges", []string{ID}) + + var logs []*ethtypes.Log + err = json.Unmarshal(changesRes.Result, &logs) + require.NoError(t, err) + + require.Equal(t, 1, len(logs)) } func TestEth_GetFilterChanges_Topics_XXC(t *testing.T) { @@ -499,20 +687,20 @@ func TestEth_GetFilterChanges_Topics_XXC(t *testing.T) { } func TestEth_PendingTransactionFilter(t *testing.T) { - rpcRes := Call(t, "eth_newPendingTransactionFilter", []string{}) + rpcRes := call(t, "eth_newPendingTransactionFilter", []string{}) var ID string err := json.Unmarshal(rpcRes.Result, &ID) require.NoError(t, err) for i := 0; i < 5; i++ { - DeployTestContractWithFunction(t, from) + deployTestContractWithFunction(t) } time.Sleep(10 * time.Second) // get filter changes - changesRes := Call(t, "eth_getFilterChanges", []string{ID}) + changesRes := call(t, "eth_getFilterChanges", []string{ID}) require.NotNil(t, changesRes) var txs []*hexutil.Bytes @@ -522,18 +710,23 @@ func TestEth_PendingTransactionFilter(t *testing.T) { require.True(t, len(txs) >= 2, "could not get any txs", "changesRes.Result", string(changesRes.Result)) } -func TestEth_EstimateGas(t *testing.T) { +func getNonce(t *testing.T) hexutil.Uint64 { + param := []interface{}{hexutil.Bytes(from), "latest"} + rpcRes := call(t, "eth_getTransactionCount", param) + var nonce hexutil.Uint64 + err := json.Unmarshal(rpcRes.Result, &nonce) + require.NoError(t, err) + return nonce +} + +func TestEth_EstimateGas(t *testing.T) { param := make([]map[string]string, 1) param[0] = make(map[string]string) param[0]["from"] = "0x" + fmt.Sprintf("%x", from) param[0]["to"] = "0x1122334455667788990011223344556677889900" param[0]["value"] = "0x1" - - rpcRes := Call(t, "personal_unlockAccount", []interface{}{param[0]["from"], ""}) - require.NotNil(t, rpcRes) - - rpcRes = Call(t, "eth_estimateGas", param) + rpcRes := call(t, "eth_estimateGas", param) require.NotNil(t, rpcRes) require.NotEmpty(t, rpcRes.Result) @@ -541,28 +734,18 @@ func TestEth_EstimateGas(t *testing.T) { err := json.Unmarshal(rpcRes.Result, &gas) require.NoError(t, err, string(rpcRes.Result)) - require.Equal(t, "0xfab9", gas) + require.Equal(t, "0xf552", gas) } func TestEth_EstimateGas_ContractDeployment(t *testing.T) { bytecode := "0x608060405234801561001057600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a260d08061004d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063eb8ac92114602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506062565b005b8160008190555080827ff3ca124a697ba07e8c5e80bebcfcc48991fc16a63170e8a9206e30508960d00360405160405180910390a3505056fea265627a7a723158201d94d2187aaf3a6790527b615fcc40970febf0385fa6d72a2344848ebd0df3e964736f6c63430005110032" - //deploy contract befor call estimateGas, make account nonce changed - hash, _ := DeployTestContract(t, from) - time.Sleep(5 * time.Second) - paramdeploy := []string{hash.String()} - rpcRes := Call(t, "eth_getTransactionReceipt", paramdeploy) - require.Nil(t, rpcRes.Error) - param := make([]map[string]string, 1) param[0] = make(map[string]string) param[0]["from"] = "0x" + fmt.Sprintf("%x", from) param[0]["data"] = bytecode - rpcRes := Call(t, "personal_unlockAccount", []interface{}{param[0]["from"], ""}) - require.NotNil(t, rpcRes) - - rpcRes = Call(t, "eth_estimateGas", param) + rpcRes := call(t, "eth_estimateGas", param) require.NotNil(t, rpcRes) require.NotEmpty(t, rpcRes.Result) @@ -570,12 +753,53 @@ func TestEth_EstimateGas_ContractDeployment(t *testing.T) { err := json.Unmarshal(rpcRes.Result, &gas) require.NoError(t, err, string(rpcRes.Result)) - require.Equal(t, "0x1ab8d", gas.String()) + require.Equal(t, "0x1c2c4", gas.String()) +} + +func TestEth_ExportAccount_WithStorage(t *testing.T) { + hash := deployTestContractWithFunction(t) + receipt := waitForReceipt(t, hash) + addr := receipt["contractAddress"].(string) + + // call function to set storage + calldata := "0xeb8ac92100000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000000" + + param := make([]map[string]string, 1) + param[0] = make(map[string]string) + param[0]["from"] = "0x" + fmt.Sprintf("%x", from) + param[0]["to"] = addr + param[0]["data"] = calldata + rpcRes := call(t, "eth_sendTransaction", param) + + var txhash hexutil.Bytes + err := json.Unmarshal(rpcRes.Result, &txhash) + require.NoError(t, err) + waitForReceipt(t, txhash) + + // get exported account + eap := []string{} + eap = append(eap, addr) + eap = append(eap, "latest") + rpcRes = call(t, "eth_exportAccount", eap) + + var res string + err = json.Unmarshal(rpcRes.Result, &res) + require.NoError(t, err) + + var account evmtypes.GenesisAccount + err = json.Unmarshal([]byte(res), &account) + require.NoError(t, err) + + // deployed bytecode + bytecode := "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063eb8ac92114602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506062565b005b8160008190555080827ff3ca124a697ba07e8c5e80bebcfcc48991fc16a63170e8a9206e30508960d00360405160405180910390a3505056fea265627a7a723158201d94d2187aaf3a6790527b615fcc40970febf0385fa6d72a2344848ebd0df3e964736f6c63430005110032" + require.Equal(t, addr, account.Address) + require.Equal(t, bytecode, account.Code) + require.NotEqual(t, evmtypes.Storage(nil), account.Storage) } func TestEth_GetBlockByNumber(t *testing.T) { param := []interface{}{"0x1", false} - rpcRes := Call(t, "eth_getBlockByNumber", param) + rpcRes := call(t, "eth_getBlockByNumber", param) block := make(map[string]interface{}) err := json.Unmarshal(rpcRes.Result, &block) diff --git a/tests/tests-pending/rpc_pending_test.go b/tests/tests-pending/rpc_pending_test.go index 711b19f9..22502fc0 100644 --- a/tests/tests-pending/rpc_pending_test.go +++ b/tests/tests-pending/rpc_pending_test.go @@ -16,7 +16,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" - rpctypes "github.com/cosmos/ethermint/rpc/types" + rpctypes "github.com/cosmos/ethermint/ethereum/rpc/types" util "github.com/cosmos/ethermint/tests" ) @@ -30,25 +30,6 @@ var ( from = []byte{} ) -type Request struct { - Version string `json:"jsonrpc"` - Method string `json:"method"` - Params interface{} `json:"params"` - ID int `json:"id"` -} - -type RPCError struct { - Code int `json:"code"` - Message string `json:"message"` - Data interface{} `json:"data,omitempty"` -} - -type Response struct { - Error *RPCError `json:"error"` - ID int `json:"id"` - Result json.RawMessage `json:"result,omitempty"` -} - func TestMain(m *testing.M) { if MODE != "pending" { _, _ = fmt.Fprintln(os.Stdout, "Skipping pending RPC test") diff --git a/x/evm/client/cli/query.go b/x/evm/client/cli/query.go index a3e197df..dadc6f48 100644 --- a/x/evm/client/cli/query.go +++ b/x/evm/client/cli/query.go @@ -1,19 +1,12 @@ package cli import ( - "math/big" - "strings" - rpctypes "github.com/cosmos/ethermint/ethereum/rpc/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/InjectiveLabs/sdk-go/ethereum/rpc" - "github.com/InjectiveLabs/sdk-go/wrappers" "github.com/cosmos/ethermint/x/evm/types" ) @@ -30,8 +23,6 @@ func GetQueryCmd() *cobra.Command { cmd.AddCommand( GetStorageCmd(), GetCodeCmd(), - GetErc20Balance(), - GetAccount(), ) return cmd } @@ -112,88 +103,3 @@ func GetCodeCmd() *cobra.Command { flags.AddQueryFlagsToCmd(cmd) return cmd } - -// GetErc20Balance queries the erc20 balance of an address -func GetErc20Balance() *cobra.Command { - cmd := &cobra.Command{ - Use: "erc20balance [contract] [address]", - Short: "Gets erc20 balance of an account", - Long: "Gets erc20 balance of an account.", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := client.GetClientContextFromCmd(cmd) - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - - contract := args[0] - address := args[1] - - erc20ABI, err := abi.JSON(strings.NewReader(wrappers.ERC20ABI)) - if err != nil { - return err - } - input, err := erc20ABI.Pack("balanceOf", common.HexToAddress(address)) - if err != nil { - return err - } - - req := &types.QueryStaticCallRequest{ - Address: contract, - Input: input, - } - - res, err := queryClient.StaticCall(rpc.ContextWithHeight(clientCtx.Height), req) - if err != nil { - return err - } - ret := big.NewInt(0) - err = erc20ABI.UnpackIntoInterface(&ret, "balanceOf", res.Data) - if err != nil { - return err - } - - return clientCtx.PrintString(ret.String()) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - return cmd -} - -// GetAccount queries the account by address -func GetAccount() *cobra.Command { - cmd := &cobra.Command{ - Use: "account [address]", - Short: "Get an account by address", - Long: "Get an account by address", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := client.GetClientContextFromCmd(cmd) - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - address := args[0] - - req := &types.QueryAccountRequest{ - Address: address, - } - - res, err := queryClient.Account(rpc.ContextWithHeight(clientCtx.Height), req) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - return cmd -} diff --git a/x/evm/keeper/abci.go b/x/evm/keeper/abci.go index d4641bb2..054e52df 100644 --- a/x/evm/keeper/abci.go +++ b/x/evm/keeper/abci.go @@ -3,8 +3,6 @@ package keeper import ( "math/big" - "github.com/cosmos/ethermint/metrics" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -37,10 +35,6 @@ func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { // the store. The EVM end block logic doesn't update the validator set, thus it returns // an empty slice. func (k Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - // Gas costs are handled within msg handler so costs should be ignored ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) diff --git a/x/evm/keeper/grpc_query.go b/x/evm/keeper/grpc_query.go index 33aea3d9..4ac21856 100644 --- a/x/evm/keeper/grpc_query.go +++ b/x/evm/keeper/grpc_query.go @@ -12,7 +12,6 @@ import ( ethcmn "github.com/ethereum/go-ethereum/common" - "github.com/cosmos/ethermint/metrics" ethermint "github.com/cosmos/ethermint/types" "github.com/cosmos/ethermint/x/evm/types" ) @@ -21,17 +20,11 @@ var _ types.QueryServer = Keeper{} // Account implements the Query/Account gRPC method func (k Keeper) Account(c context.Context, req *types.QueryAccountRequest) (*types.QueryAccountResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } if types.IsZeroAddress(req.Address) { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.InvalidArgument, types.ErrZeroAddress.Error(), @@ -42,7 +35,6 @@ func (k Keeper) Account(c context.Context, req *types.QueryAccountRequest) (*typ so := k.GetOrNewStateObject(ctx, ethcmn.HexToAddress(req.Address)) balance, err := ethermint.MarshalBigInt(so.Balance()) if err != nil { - metrics.ReportFuncError(k.svcTags) return nil, err } @@ -54,17 +46,12 @@ func (k Keeper) Account(c context.Context, req *types.QueryAccountRequest) (*typ } func (k Keeper) CosmosAccount(c context.Context, req *types.QueryCosmosAccountRequest) (*types.QueryCosmosAccountResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } if types.IsZeroAddress(req.Address) { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.InvalidArgument, types.ErrZeroAddress.Error(), @@ -92,17 +79,11 @@ func (k Keeper) CosmosAccount(c context.Context, req *types.QueryCosmosAccountRe // Balance implements the Query/Balance gRPC method func (k Keeper) Balance(c context.Context, req *types.QueryBalanceRequest) (*types.QueryBalanceResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } if types.IsZeroAddress(req.Address) { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.InvalidArgument, types.ErrZeroAddress.Error(), @@ -114,7 +95,6 @@ func (k Keeper) Balance(c context.Context, req *types.QueryBalanceRequest) (*typ balanceInt := k.GetBalance(ctx, ethcmn.HexToAddress(req.Address)) balance, err := ethermint.MarshalBigInt(balanceInt) if err != nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.Internal, "failed to marshal big.Int to string", @@ -128,17 +108,12 @@ func (k Keeper) Balance(c context.Context, req *types.QueryBalanceRequest) (*typ // Storage implements the Query/Storage gRPC method func (k Keeper) Storage(c context.Context, req *types.QueryStorageRequest) (*types.QueryStorageResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } if types.IsZeroAddress(req.Address) { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.InvalidArgument, types.ErrZeroAddress.Error(), @@ -159,17 +134,11 @@ func (k Keeper) Storage(c context.Context, req *types.QueryStorageRequest) (*typ // Code implements the Query/Code gRPC method func (k Keeper) Code(c context.Context, req *types.QueryCodeRequest) (*types.QueryCodeResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } if types.IsZeroAddress(req.Address) { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.InvalidArgument, types.ErrZeroAddress.Error(), @@ -188,17 +157,11 @@ func (k Keeper) Code(c context.Context, req *types.QueryCodeRequest) (*types.Que // TxLogs implements the Query/TxLogs gRPC method func (k Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types.QueryTxLogsResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } if types.IsEmptyHash(req.Hash) { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.InvalidArgument, types.ErrEmptyHash.Error(), @@ -210,7 +173,6 @@ func (k Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types hash := ethcmn.HexToHash(req.Hash) logs, err := k.GetLogs(ctx, hash) if err != nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.Internal, err.Error(), @@ -224,17 +186,12 @@ func (k Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types // TxReceipt implements the Query/TxReceipt gRPC method func (k Keeper) TxReceipt(c context.Context, req *types.QueryTxReceiptRequest) (*types.QueryTxReceiptResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } if types.IsEmptyHash(req.Hash) { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.InvalidArgument, types.ErrEmptyHash.Error(), @@ -246,7 +203,6 @@ func (k Keeper) TxReceipt(c context.Context, req *types.QueryTxReceiptRequest) ( hash := ethcmn.HexToHash(req.Hash) receipt, found := k.GetTxReceiptFromHash(ctx, hash) if !found { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.NotFound, types.ErrTxReceiptNotFound.Error(), ) @@ -259,12 +215,7 @@ func (k Keeper) TxReceipt(c context.Context, req *types.QueryTxReceiptRequest) ( // TxReceiptsByBlockHeight implements the Query/TxReceiptsByBlockHeight gRPC method func (k Keeper) TxReceiptsByBlockHeight(c context.Context, req *types.QueryTxReceiptsByBlockHeightRequest) (*types.QueryTxReceiptsByBlockHeightResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } @@ -278,17 +229,12 @@ func (k Keeper) TxReceiptsByBlockHeight(c context.Context, req *types.QueryTxRec // TxReceiptsByBlockHash implements the Query/TxReceiptsByBlockHash gRPC method func (k Keeper) TxReceiptsByBlockHash(c context.Context, req *types.QueryTxReceiptsByBlockHashRequest) (*types.QueryTxReceiptsByBlockHashResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } if types.IsEmptyHash(req.Hash) { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.InvalidArgument, types.ErrEmptyHash.Error(), @@ -307,17 +253,12 @@ func (k Keeper) TxReceiptsByBlockHash(c context.Context, req *types.QueryTxRecei // BlockLogs implements the Query/BlockLogs gRPC method func (k Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) (*types.QueryBlockLogsResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } if types.IsEmptyHash(req.Hash) { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.InvalidArgument, types.ErrEmptyHash.Error(), @@ -335,12 +276,8 @@ func (k Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) ( // BlockBloom implements the Query/BlockBloom gRPC method func (k Keeper) BlockBloom(c context.Context, req *types.QueryBlockBloomRequest) (*types.QueryBlockBloomResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } @@ -353,7 +290,6 @@ func (k Keeper) BlockBloom(c context.Context, req *types.QueryBlockBloomRequest) bloom, found := k.GetBlockBloom(ctx, height) if !found { - metrics.ReportFuncError(k.svcTags) return nil, status.Error( codes.NotFound, types.ErrBloomNotFound.Error(), ) @@ -366,12 +302,8 @@ func (k Keeper) BlockBloom(c context.Context, req *types.QueryBlockBloomRequest) // Params implements the Query/Params gRPC method func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() if req == nil { - metrics.ReportFuncError(k.svcTags) return nil, status.Error(codes.InvalidArgument, "empty request") } diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 2f401b0c..2bed9209 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -10,7 +10,6 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/ethermint/metrics" "github.com/cosmos/ethermint/x/evm/types" ) @@ -41,8 +40,6 @@ type Keeper struct { // LogsCache keeps mapping of contract address -> eth logs emitted // during EVM execution in the current block. LogsCache map[common.Address][]*ethtypes.Log - - svcTags metrics.Tags } // NewKeeper generates new evm module keeper @@ -57,10 +54,6 @@ func NewKeeper( // NOTE: we pass in the parameter space to the CommitStateDB in order to use custom denominations for the EVM operations return &Keeper{ - svcTags: metrics.Tags{ - "svc": "evm_k", - }, - cdc: cdc, accountKeeper: ak, bankKeeper: bankKeeper, @@ -84,10 +77,6 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetBlockBloom gets bloombits from block height func (k Keeper) GetBlockBloom(ctx sdk.Context, height int64) (ethtypes.Bloom, bool) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) key := types.BloomKey(height) @@ -102,10 +91,6 @@ func (k Keeper) GetBlockBloom(ctx sdk.Context, height int64) (ethtypes.Bloom, bo // SetBlockBloom sets the mapping from block height to bloom bits func (k Keeper) SetBlockBloom(ctx sdk.Context, height int64, bloom ethtypes.Bloom) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) key := types.BloomKey(height) @@ -114,10 +99,6 @@ func (k Keeper) SetBlockBloom(ctx sdk.Context, height int64, bloom ethtypes.Bloo // GetBlockHash gets block height from block consensus hash func (k Keeper) GetBlockHashFromHeight(ctx sdk.Context, height int64) ([]byte, bool) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyBlockHeightHash(uint64(height))) if len(bz) == 0 { @@ -129,10 +110,6 @@ func (k Keeper) GetBlockHashFromHeight(ctx sdk.Context, height int64) ([]byte, b // SetBlockHash sets the mapping from block consensus hash to block height func (k Keeper) SetBlockHash(ctx sdk.Context, hash []byte, height int64) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) bz := sdk.Uint64ToBigEndian(uint64(height)) store.Set(types.KeyBlockHash(common.BytesToHash(hash)), bz) @@ -140,10 +117,6 @@ func (k Keeper) SetBlockHash(ctx sdk.Context, hash []byte, height int64) { // GetBlockHash gets block height from block consensus hash func (k Keeper) GetBlockHeightByHash(ctx sdk.Context, hash common.Hash) (int64, bool) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyBlockHash(hash)) if len(bz) == 0 { @@ -156,20 +129,12 @@ func (k Keeper) GetBlockHeightByHash(ctx sdk.Context, hash common.Hash) (int64, // SetBlockHash sets the mapping from block consensus hash to block height func (k Keeper) SetBlockHeightToHash(ctx sdk.Context, hash []byte, height int64) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) store.Set(types.KeyBlockHeightHash(uint64(height)), hash) } // SetTxReceiptToHash sets the mapping from tx hash to tx receipt func (k Keeper) SetTxReceiptToHash(ctx sdk.Context, hash common.Hash, receipt *types.TxReceipt) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) data := k.cdc.MustMarshalBinaryBare(receipt) @@ -190,10 +155,6 @@ func (k Keeper) SetHeightHash(ctx sdk.Context, height uint64, hash common.Hash) // GetTxReceiptFromHash gets tx receipt by tx hash. func (k Keeper) GetTxReceiptFromHash(ctx sdk.Context, hash common.Hash) (*types.TxReceipt, bool) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) data := store.Get(types.KeyHashTxReceipt(hash)) if data == nil || len(data) == 0 { @@ -208,10 +169,6 @@ func (k Keeper) GetTxReceiptFromHash(ctx sdk.Context, hash common.Hash) (*types. // AddTxHashToBlock stores tx hash in the list of tx for the block. func (k Keeper) AddTxHashToBlock(ctx sdk.Context, blockHeight int64, txHash common.Hash) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - key := types.KeyBlockHeightTxs(uint64(blockHeight)) list := types.BytesList{} @@ -230,10 +187,6 @@ func (k Keeper) AddTxHashToBlock(ctx sdk.Context, blockHeight int64, txHash comm // GetTxsFromBlock returns list of tx hash in the block by height. func (k Keeper) GetTxsFromBlock(ctx sdk.Context, blockHeight int64) []common.Hash { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - key := types.KeyBlockHeightTxs(uint64(blockHeight)) store := ctx.KVStore(k.storeKey) @@ -255,10 +208,6 @@ func (k Keeper) GetTxsFromBlock(ctx sdk.Context, blockHeight int64) []common.Has // GetTxReceiptsByBlockHeight gets tx receipts by block height. func (k Keeper) GetTxReceiptsByBlockHeight(ctx sdk.Context, blockHeight int64) []*types.TxReceipt { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - txs := k.GetTxsFromBlock(ctx, blockHeight) if len(txs) == 0 { return nil @@ -285,10 +234,6 @@ func (k Keeper) GetTxReceiptsByBlockHeight(ctx sdk.Context, blockHeight int64) [ // GetTxReceiptsByBlockHash gets tx receipts by block hash. func (k Keeper) GetTxReceiptsByBlockHash(ctx sdk.Context, hash common.Hash) []*types.TxReceipt { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - blockHeight, ok := k.GetBlockHeightByHash(ctx, hash) if !ok { return nil @@ -299,10 +244,6 @@ func (k Keeper) GetTxReceiptsByBlockHash(ctx sdk.Context, hash common.Hash) []*t // GetAllTxLogs return all the transaction logs from the store. func (k Keeper) GetAllTxLogs(ctx sdk.Context) []types.TransactionLogs { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, types.KeyPrefixLogs) defer iterator.Close() @@ -320,10 +261,6 @@ func (k Keeper) GetAllTxLogs(ctx sdk.Context) []types.TransactionLogs { // GetAccountStorage return state storage associated with an account func (k Keeper) GetAccountStorage(ctx sdk.Context, address common.Address) (types.Storage, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - storage := types.Storage{} err := k.ForEachStorage(ctx, address, func(key, value common.Hash) bool { @@ -339,10 +276,6 @@ func (k Keeper) GetAccountStorage(ctx sdk.Context, address common.Address) (type // GetChainConfig gets block height from block consensus hash func (k Keeper) GetChainConfig(ctx sdk.Context) (types.ChainConfig, bool) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyPrefixChainConfig) if len(bz) == 0 { @@ -356,10 +289,6 @@ func (k Keeper) GetChainConfig(ctx sdk.Context) (types.ChainConfig, bool) { // SetChainConfig sets the mapping from block consensus hash to block height func (k Keeper) SetChainConfig(ctx sdk.Context, config types.ChainConfig) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinaryBare(&config) store.Set(types.KeyPrefixChainConfig, bz) diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index e177f2ac..2fa0bfe9 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -12,7 +12,6 @@ import ( ethcmn "github.com/ethereum/go-ethereum/common" tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/ethermint/metrics" ethermint "github.com/cosmos/ethermint/types" "github.com/cosmos/ethermint/x/evm/types" ) @@ -20,16 +19,11 @@ import ( var _ types.MsgServer = &Keeper{} func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*types.MsgEthereumTxResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - ctx := sdk.UnwrapSDKContext(goCtx) // parse the chainID from a string to a base-10 integer chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID()) if err != nil { - metrics.ReportFuncError(k.svcTags) return nil, err } @@ -44,7 +38,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t "homestead_err": homesteadErr.Error(), }).Warningln("failed to verify signatures with EIP155 and Homestead signers") - metrics.ReportFuncError(k.svcTags) return nil, errors.New("no valid signatures") } } @@ -84,7 +77,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t config, found := k.GetChainConfig(ctx) if !found { - metrics.ReportFuncError(k.svcTags) return nil, types.ErrChainConfigNotFound } @@ -93,7 +85,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t if err.Error() == "execution reverted" && executionResult != nil { // keep the execution result for revert reason executionResult.Response.Reverted = true - metrics.ReportFuncError(k.svcTags) if !st.Simulate { blockHash, _ := k.GetBlockHashFromHeight(ctx, ctx.BlockHeight()) @@ -117,7 +108,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t return executionResult.Response, nil } - metrics.ReportFuncError(k.svcTags) return nil, err } @@ -180,7 +170,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t ) } - metrics.ReportFuncError(k.svcTags) return executionResult.Response, nil } @@ -232,15 +221,10 @@ func (k *Keeper) InternalEthereumTx( sender common.Address, tx *types.TxData, ) (*types.MsgEthereumTxResponse, error) { - metrics.ReportFuncCall(k.svcTags) - doneFn := metrics.ReportFuncTiming(k.svcTags) - defer doneFn() - ctx := sdk.UnwrapSDKContext(goCtx) // parse the chainID from a string to a base-10 integer chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID()) if err != nil { - metrics.ReportFuncError(k.svcTags) return nil, err } @@ -281,7 +265,6 @@ func (k *Keeper) InternalEthereumTx( config, found := k.GetChainConfig(ctx) if !found { - metrics.ReportFuncError(k.svcTags) return nil, types.ErrChainConfigNotFound } @@ -290,7 +273,6 @@ func (k *Keeper) InternalEthereumTx( if err.Error() == "execution reverted" && executionResult != nil { // keep the execution result for revert reason executionResult.Response.Reverted = true - metrics.ReportFuncError(k.svcTags) if !st.Simulate { blockHash, _ := k.GetBlockHashFromHeight(ctx, ctx.BlockHeight()) @@ -314,7 +296,6 @@ func (k *Keeper) InternalEthereumTx( return executionResult.Response, err } - metrics.ReportFuncError(k.svcTags) return nil, err } diff --git a/x/evm/types/genesis_test.go b/x/evm/types/genesis_test.go index f158a1be..0e04827e 100644 --- a/x/evm/types/genesis_test.go +++ b/x/evm/types/genesis_test.go @@ -5,7 +5,6 @@ import ( "github.com/stretchr/testify/suite" - sdk "github.com/cosmos/cosmos-sdk/types" ethcmn "github.com/ethereum/go-ethereum/common" "github.com/cosmos/ethermint/crypto/ethsecp256k1" @@ -43,7 +42,6 @@ func (suite *GenesisTestSuite) TestValidateGenesisAccount() { "valid genesis account", GenesisAccount{ Address: suite.address, - Balance: sdk.OneInt(), Code: suite.code, Storage: Storage{ NewState(suite.hash, suite.hash), @@ -55,23 +53,6 @@ func (suite *GenesisTestSuite) TestValidateGenesisAccount() { "empty account address bytes", GenesisAccount{ Address: ethcmn.Address{}.String(), - Balance: sdk.OneInt(), - }, - false, - }, - { - "empty account balance", - GenesisAccount{ - Address: suite.address, - Balance: sdk.Int{}, - }, - false, - }, - { - "negative account balance", - GenesisAccount{ - Address: suite.address, - Balance: sdk.NewInt(-1), }, false, }, @@ -79,7 +60,6 @@ func (suite *GenesisTestSuite) TestValidateGenesisAccount() { "empty code bytes", GenesisAccount{ Address: suite.address, - Balance: sdk.OneInt(), Code: "", }, false, @@ -115,8 +95,8 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { Accounts: []GenesisAccount{ { Address: suite.address, - Balance: sdk.OneInt(), - Code: suite.code, + + Code: suite.code, Storage: Storage{ {Key: suite.hash.String()}, }, @@ -167,16 +147,16 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { Accounts: []GenesisAccount{ { Address: suite.address, - Balance: sdk.OneInt(), - Code: suite.code, + + Code: suite.code, Storage: Storage{ NewState(suite.hash, suite.hash), }, }, { Address: suite.address, - Balance: sdk.OneInt(), - Code: suite.code, + + Code: suite.code, Storage: Storage{ NewState(suite.hash, suite.hash), }, @@ -191,8 +171,8 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { Accounts: []GenesisAccount{ { Address: suite.address, - Balance: sdk.OneInt(), - Code: suite.code, + + Code: suite.code, Storage: Storage{ {Key: suite.hash.String()}, }, @@ -241,8 +221,8 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { Accounts: []GenesisAccount{ { Address: suite.address, - Balance: sdk.OneInt(), - Code: suite.code, + + Code: suite.code, Storage: Storage{ {Key: suite.hash.String()}, }, diff --git a/x/evm/types/state_transition.go b/x/evm/types/state_transition.go index cf9bebf8..26660189 100644 --- a/x/evm/types/state_transition.go +++ b/x/evm/types/state_transition.go @@ -3,7 +3,6 @@ package types import ( "math/big" "os" - "sync" "github.com/pkg/errors" log "github.com/xlab/suplog" @@ -16,7 +15,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/ethermint/metrics" ) // StateTransition defines data to transitionDB in evm @@ -35,17 +33,6 @@ type StateTransition struct { Sender common.Address Simulate bool // i.e CheckTx execution Debug bool // enable EVM debugging - - once sync.Once - svcTags metrics.Tags -} - -func (st *StateTransition) initOnce() { - st.once.Do(func() { - st.svcTags = metrics.Tags{ - "svc": "evm_state", - } - }) } // GasInfo returns the gas limit, gas consumed and gas refunded from the EVM transition @@ -96,14 +83,12 @@ func (st *StateTransition) newEVM( config ChainConfig, extraEIPs []int64, ) *vm.EVM { - st.initOnce() - // Create context for evm blockCtx := vm.BlockContext{ CanTransfer: core.CanTransfer, Transfer: core.Transfer, GetHash: GetHashFn(ctx, csdb), - Coinbase: common.Address{}, // there's no benefitiary since we're not mining + Coinbase: common.Address{}, // there's no beneficiary since we're not mining BlockNumber: big.NewInt(ctx.BlockHeight()), Time: big.NewInt(ctx.BlockHeader().Time.Unix()), Difficulty: big.NewInt(0), // unused. Only required in PoW context @@ -139,17 +124,10 @@ func (st *StateTransition) newEVM( // returning the evm execution result. // NOTE: State transition checks are run during AnteHandler execution. func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (resp *ExecutionResult, err error) { - st.initOnce() - - metrics.ReportFuncCall(st.svcTags) - doneFn := metrics.ReportFuncTiming(st.svcTags) - defer doneFn() - contractCreation := st.Recipient == nil cost, err := core.IntrinsicGas(st.Payload, contractCreation, true, false) if err != nil { - metrics.ReportFuncError(st.svcTags) err = sdkerrors.Wrap(err, "invalid intrinsic gas for transaction") return nil, err } @@ -185,7 +163,6 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re gasPrice := ctx.MinGasPrices().AmountOf(params.EvmDenom) //gasPrice := sdk.ZeroDec() if gasPrice.IsNil() { - metrics.ReportFuncError(st.svcTags) return nil, errors.New("min gas price cannot be nil") } @@ -263,8 +240,6 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re if err != nil { // Consume gas before returning - metrics.EVMRevertedTx(st.svcTags) - metrics.EVMGasConsumed(resp.GasInfo.GasConsumed) ctx.GasMeter().ConsumeGas(resp.GasInfo.GasConsumed, "evm execution consumption") return resp, err } @@ -283,7 +258,6 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re if st.TxHash != nil && !st.Simulate { logs, err = csdb.GetLogs(*st.TxHash) if err != nil { - metrics.ReportFuncError(st.svcTags) err = errors.Wrap(err, "failed to get logs") return nil, err } @@ -296,7 +270,6 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re // Finalise state if not a simulated transaction // TODO: change to depend on config if err := csdb.Finalise(true); err != nil { - metrics.ReportFuncError(st.svcTags) return nil, err } } @@ -317,7 +290,7 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re // Consume gas from evm execution // Out of gas check does not need to be done here since it is done within the EVM execution - metrics.EVMGasConsumed(resp.GasInfo.GasConsumed) + // TODO: @albert, @maxim, decide if can take this out, since InternalEthereumTx may want to continue execution afterwards // which will use gas. _ = currentGasMeter @@ -331,8 +304,6 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re // Opcodes that attempt to perform such modifications will result in exceptions // instead of performing the modifications. func (st *StateTransition) StaticCall(ctx sdk.Context, config ChainConfig) ([]byte, error) { - st.initOnce() - // This gas limit the the transaction gas limit with intrinsic gas subtracted gasLimit := st.GasLimit - ctx.GasMeter().GasConsumed() csdb := st.Csdb.WithContext(ctx) diff --git a/x/evm/types/state_transition_test.go b/x/evm/types/state_transition_test.go index bd7aac25..32f3d2ec 100644 --- a/x/evm/types/state_transition_test.go +++ b/x/evm/types/state_transition_test.go @@ -126,7 +126,7 @@ func (suite *StateDBTestSuite) TestTransitionDb() { "nil gas price", func() { invalidGas := sdk.DecCoins{ - {Denom: ethermint.InjectiveCoin}, + {Denom: ethermint.PhotonCoin}, } suite.ctx = suite.ctx.WithMinGasPrices(invalidGas) },