From fbaa9466b0cee72b40e56cd4ce437f342e593784 Mon Sep 17 00:00:00 2001 From: Austin Abell Date: Fri, 12 Jul 2019 13:13:15 -0400 Subject: [PATCH] Update Ethermint app/ Daemon to run functional TM node (#70) * Updates eithermint app to new Cosmos SDK version and sets up base tendermint node commands * Updated vague comment --- app/ethermint.go | 288 ++++++++++++++++++++++++++++----------------- app/test_utils.go | 2 +- cmd/emintd/main.go | 48 ++++---- go.mod | 2 +- go.sum | 3 + 5 files changed, 209 insertions(+), 134 deletions(-) diff --git a/app/ethermint.go b/app/ethermint.go index 39b50086..851194f5 100644 --- a/app/ethermint.go +++ b/app/ethermint.go @@ -1,22 +1,25 @@ package app import ( + "encoding/json" "os" - "github.com/cosmos/ethermint/x/evm" - bam "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/crisis" distr "github.com/cosmos/cosmos-sdk/x/distribution" + distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client" "github.com/cosmos/cosmos-sdk/x/genaccounts" "github.com/cosmos/cosmos-sdk/x/genutil" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/mint" "github.com/cosmos/cosmos-sdk/x/params" + paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/supply" @@ -24,17 +27,14 @@ import ( "github.com/cosmos/ethermint/crypto" evmtypes "github.com/cosmos/ethermint/x/evm/types" - "github.com/pkg/errors" - abci "github.com/tendermint/tendermint/abci/types" - tmcmn "github.com/tendermint/tendermint/libs/common" dbm "github.com/tendermint/tendermint/libs/db" tmlog "github.com/tendermint/tendermint/libs/log" + tmtypes "github.com/tendermint/tendermint/types" ) const appName = "Ethermint" -// application multi-store keys var ( // default home directories for the application CLI DefaultCLIHome = os.ExpandEnv("$HOME/.emintcli") @@ -42,33 +42,32 @@ var ( // DefaultNodeHome sets the folder where the applcation data and configuration will be stored DefaultNodeHome = os.ExpandEnv("$HOME/.emintd") - // ModuleBasics is in charge of setting up basic module elements + // The module BasicManager is in charge of setting up basic, + // non-dependant module elements, such as codec registration + // and genesis verification. ModuleBasics = module.NewBasicManager( genaccounts.AppModuleBasic{}, genutil.AppModuleBasic{}, auth.AppModuleBasic{}, bank.AppModuleBasic{}, - params.AppModuleBasic{}, - evm.AppModuleBasic{}, staking.AppModuleBasic{}, + mint.AppModuleBasic{}, distr.AppModuleBasic{}, + gov.NewAppModuleBasic(paramsclient.ProposalHandler, distrclient.ProposalHandler), + params.AppModuleBasic{}, + crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, + supply.AppModuleBasic{}, ) - - storeKeyAccount = sdk.NewKVStoreKey("acc") - storeKeyStorage = sdk.NewKVStoreKey("contract_storage") - storeKeyMain = sdk.NewKVStoreKey("main") - storeKeyStake = sdk.NewKVStoreKey("stake") - storeKeySlashing = sdk.NewKVStoreKey("slashing") - storeKeyGov = sdk.NewKVStoreKey("gov") - storeKeySupply = sdk.NewKVStoreKey("supply") - storeKeyParams = sdk.NewKVStoreKey("params") - storeKeyTransParams = sdk.NewTransientStoreKey("transient_params") ) // MakeCodec generates the necessary codecs for Amino func MakeCodec() *codec.Codec { var cdc = codec.New() + + // TODO: Move this codec to module (Issue #12 https://github.com/ChainSafe/ethermint/issues/12) + crypto.RegisterCodec(cdc) + ModuleBasics.RegisterCodec(cdc) sdk.RegisterCodec(cdc) codec.RegisterCrypto(cdc) @@ -80,26 +79,40 @@ func MakeCodec() *codec.Codec { // Tendermint consensus. type EthermintApp struct { *bam.BaseApp - cdc *codec.Codec - accountKey *sdk.KVStoreKey - storageKey *sdk.KVStoreKey - mainKey *sdk.KVStoreKey - stakeKey *sdk.KVStoreKey - slashingKey *sdk.KVStoreKey - govKey *sdk.KVStoreKey - supplyKey *sdk.KVStoreKey - paramsKey *sdk.KVStoreKey - tParamsKey *sdk.TransientStoreKey + invCheckPeriod uint + // keys to access the substores + keyMain *sdk.KVStoreKey + keyAccount *sdk.KVStoreKey + keySupply *sdk.KVStoreKey + keyStaking *sdk.KVStoreKey + tkeyStaking *sdk.TransientStoreKey + keySlashing *sdk.KVStoreKey + keyMint *sdk.KVStoreKey + keyDistr *sdk.KVStoreKey + tkeyDistr *sdk.TransientStoreKey + keyGov *sdk.KVStoreKey + keyParams *sdk.KVStoreKey + tkeyParams *sdk.TransientStoreKey + // TODO: Add evm module key + + // keepers accountKeeper auth.AccountKeeper - supplyKeeper supply.Keeper bankKeeper bank.Keeper - stakeKeeper staking.Keeper + supplyKeeper supply.Keeper + stakingKeeper staking.Keeper slashingKeeper slashing.Keeper + mintKeeper mint.Keeper + distrKeeper distr.Keeper govKeeper gov.Keeper + crisisKeeper crisis.Keeper paramsKeeper params.Keeper + // TODO: Include evm Keeper + + // the module manager + mm *module.Manager } // NewEthermintApp returns a reference to a new initialized Ethermint @@ -108,28 +121,42 @@ type EthermintApp struct { // TODO: Ethermint needs to support being bootstrapped as an application running // in a sovereign zone and as an application running with a shared security model. // For now, it will support only running as a sovereign application. -func NewEthermintApp(logger tmlog.Logger, db dbm.DB, baseAppOpts ...func(*bam.BaseApp)) *EthermintApp { - cdc := CreateCodec() +func NewEthermintApp(logger tmlog.Logger, db dbm.DB, loadLatest bool, + invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp)) *EthermintApp { + cdc := MakeCodec() - baseApp := bam.NewBaseApp(appName, logger, db, evmtypes.TxDecoder(cdc), baseAppOpts...) - app := &EthermintApp{ - BaseApp: baseApp, - cdc: cdc, - accountKey: storeKeyAccount, - storageKey: storeKeyStorage, - mainKey: storeKeyMain, - stakeKey: storeKeyStake, - slashingKey: storeKeySlashing, - govKey: storeKeyGov, - supplyKey: storeKeySupply, - paramsKey: storeKeyParams, - tParamsKey: storeKeyTransParams, + baseApp := bam.NewBaseApp(appName, logger, db, evmtypes.TxDecoder(cdc), baseAppOptions...) + baseApp.SetAppVersion(version.Version) + + var app = &EthermintApp{ + BaseApp: baseApp, + cdc: cdc, + invCheckPeriod: invCheckPeriod, + keyMain: sdk.NewKVStoreKey(bam.MainStoreKey), + keyAccount: sdk.NewKVStoreKey(auth.StoreKey), + keyStaking: sdk.NewKVStoreKey(staking.StoreKey), + keySupply: sdk.NewKVStoreKey(supply.StoreKey), + tkeyStaking: sdk.NewTransientStoreKey(staking.TStoreKey), + keyMint: sdk.NewKVStoreKey(mint.StoreKey), + keyDistr: sdk.NewKVStoreKey(distr.StoreKey), + tkeyDistr: sdk.NewTransientStoreKey(distr.TStoreKey), + keySlashing: sdk.NewKVStoreKey(slashing.StoreKey), + keyGov: sdk.NewKVStoreKey(gov.StoreKey), + keyParams: sdk.NewKVStoreKey(params.StoreKey), + tkeyParams: sdk.NewTransientStoreKey(params.TStoreKey), + // TODO: Initialize evm module key } - // Set params keeper and subspaces - app.paramsKeeper = params.NewKeeper(app.cdc, app.paramsKey, app.tParamsKey, params.DefaultCodespace) + // init params keeper and subspaces + app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams, params.DefaultCodespace) authSubspace := app.paramsKeeper.Subspace(auth.DefaultParamspace) bankSubspace := app.paramsKeeper.Subspace(bank.DefaultParamspace) + stakingSubspace := app.paramsKeeper.Subspace(staking.DefaultParamspace) + mintSubspace := app.paramsKeeper.Subspace(mint.DefaultParamspace) + distrSubspace := app.paramsKeeper.Subspace(distr.DefaultParamspace) + slashingSubspace := app.paramsKeeper.Subspace(slashing.DefaultParamspace) + govSubspace := app.paramsKeeper.Subspace(gov.DefaultParamspace) + crisisSubspace := app.paramsKeeper.Subspace(crisis.DefaultParamspace) // account permissions maccPerms := map[string][]string{ @@ -141,88 +168,127 @@ func NewEthermintApp(logger tmlog.Logger, db dbm.DB, baseAppOpts ...func(*bam.Ba gov.ModuleName: []string{supply.Burner}, } - // Add keepers - app.accountKeeper = auth.NewAccountKeeper(app.cdc, app.accountKey, authSubspace, auth.ProtoBaseAccount) + // add keepers + app.accountKeeper = auth.NewAccountKeeper(app.cdc, app.keyAccount, authSubspace, auth.ProtoBaseAccount) app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper, bankSubspace, bank.DefaultCodespace) - app.supplyKeeper = supply.NewKeeper(cdc, app.supplyKey, app.accountKeeper, app.bankKeeper, supply.DefaultCodespace, maccPerms) + app.supplyKeeper = supply.NewKeeper(app.cdc, app.keySupply, app.accountKeeper, app.bankKeeper, supply.DefaultCodespace, maccPerms) + stakingKeeper := staking.NewKeeper(app.cdc, app.keyStaking, app.tkeyStaking, + app.supplyKeeper, stakingSubspace, staking.DefaultCodespace) + app.mintKeeper = mint.NewKeeper(app.cdc, app.keyMint, mintSubspace, &stakingKeeper, app.supplyKeeper, auth.FeeCollectorName) + app.distrKeeper = distr.NewKeeper(app.cdc, app.keyDistr, distrSubspace, &stakingKeeper, + app.supplyKeeper, distr.DefaultCodespace, auth.FeeCollectorName) + app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, &stakingKeeper, + slashingSubspace, slashing.DefaultCodespace) + app.crisisKeeper = crisis.NewKeeper(crisisSubspace, invCheckPeriod, app.supplyKeeper, auth.FeeCollectorName) + // TODO: Instantiate evm Keeper - // register message handlers - app.Router(). - // TODO: add remaining routes - AddRoute("stake", staking.NewHandler(app.stakeKeeper)). - AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)). - AddRoute("gov", gov.NewHandler(app.govKeeper)) + // register the proposal types + govRouter := gov.NewRouter() + govRouter.AddRoute(gov.RouterKey, gov.ProposalHandler). + AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)). + AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper)) + app.govKeeper = gov.NewKeeper(app.cdc, app.keyGov, app.paramsKeeper, govSubspace, + app.supplyKeeper, &stakingKeeper, gov.DefaultCodespace, govRouter) - // initialize the underlying ABCI BaseApp - app.SetInitChainer(app.initChainer) - app.SetBeginBlocker(app.BeginBlocker) - app.SetEndBlocker(app.EndBlocker) - app.SetAnteHandler(NewAnteHandler(app.accountKeeper, app.supplyKeeper)) + // register the staking hooks + // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks + app.stakingKeeper = *stakingKeeper.SetHooks( + staking.NewMultiStakingHooks(app.distrKeeper.Hooks(), app.slashingKeeper.Hooks())) - app.MountStores( - app.mainKey, app.accountKey, app.stakeKey, app.slashingKey, - app.govKey, app.supplyKey, app.paramsKey, app.storageKey, + app.mm = module.NewManager( + genaccounts.NewAppModule(app.accountKeeper), + genutil.NewAppModule(app.accountKeeper, app.stakingKeeper, app.BaseApp.DeliverTx), + auth.NewAppModule(app.accountKeeper), + bank.NewAppModule(app.bankKeeper, app.accountKeeper), + crisis.NewAppModule(app.crisisKeeper), + supply.NewAppModule(app.supplyKeeper, app.accountKeeper), + distr.NewAppModule(app.distrKeeper, app.supplyKeeper), + gov.NewAppModule(app.govKeeper, app.supplyKeeper), + mint.NewAppModule(app.mintKeeper), + slashing.NewAppModule(app.slashingKeeper, app.stakingKeeper), + staking.NewAppModule(app.stakingKeeper, app.distrKeeper, app.accountKeeper, app.supplyKeeper), ) - app.MountStore(app.tParamsKey, sdk.StoreTypeTransient) - if err := app.LoadLatestVersion(app.accountKey); err != nil { - tmcmn.Exit(err.Error()) + // During begin block slashing happens after distr.BeginBlocker so that + // there is nothing left over in the validator fee pool, so as to keep the + // CanWithdrawInvariant invariant. + app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName) + + app.mm.SetOrderEndBlockers(gov.ModuleName, staking.ModuleName) + + // genutils must occur after staking so that pools are properly + // initialized with tokens from genesis accounts. + app.mm.SetOrderInitGenesis(genaccounts.ModuleName, supply.ModuleName, distr.ModuleName, + staking.ModuleName, auth.ModuleName, bank.ModuleName, slashing.ModuleName, + gov.ModuleName, mint.ModuleName, crisis.ModuleName, genutil.ModuleName) + + app.mm.RegisterInvariants(&app.crisisKeeper) + app.mm.RegisterRoutes(app.Router(), app.QueryRouter()) + + // initialize stores + app.MountStores(app.keyMain, app.keyAccount, app.keySupply, app.keyStaking, + app.keyMint, app.keyDistr, app.keySlashing, app.keyGov, app.keyParams, + app.tkeyParams, app.tkeyStaking, app.tkeyDistr) + + // initialize BaseApp + app.SetInitChainer(app.InitChainer) + app.SetBeginBlocker(app.BeginBlocker) + app.SetAnteHandler(auth.NewAnteHandler(app.accountKeeper, app.supplyKeeper, auth.DefaultSigVerificationGasConsumer)) + app.SetEndBlocker(app.EndBlocker) + + if loadLatest { + err := app.LoadLatestVersion(app.keyMain) + if err != nil { + panic(err) + } } - - app.BaseApp.Seal() return app + } -// BeginBlocker signals the beginning of a block. It performs application -// updates on the start of every block. -func (app *EthermintApp) BeginBlocker( - _ sdk.Context, _ abci.RequestBeginBlock, -) abci.ResponseBeginBlock { +// The genesis state of the blockchain is represented here as a map of raw json +// messages key'd by a identifier string. +type GenesisState map[string]json.RawMessage - return abci.ResponseBeginBlock{} +// application updates every begin block +func (app *EthermintApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + return app.mm.BeginBlock(ctx, req) } -// EndBlocker signals the end of a block. It performs application updates on -// the end of every block. -func (app *EthermintApp) EndBlocker( - _ sdk.Context, _ abci.RequestEndBlock, -) abci.ResponseEndBlock { - - return abci.ResponseEndBlock{} +// application updates every end block +func (app *EthermintApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + return app.mm.EndBlock(ctx, req) } -// initChainer initializes the application blockchain with validators and other -// state data from TendermintCore. -func (app *EthermintApp) initChainer( - _ sdk.Context, req abci.RequestInitChain, -) abci.ResponseInitChain { +// application update at chain initialization +func (app *EthermintApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + var genesisState GenesisState + app.cdc.MustUnmarshalJSON(req.AppStateBytes, &genesisState) + return app.mm.InitGenesis(ctx, genesisState) +} - var genesisState evm.GenesisState - stateJSON := req.AppStateBytes +// load a particular height +func (app *EthermintApp) LoadHeight(height int64) error { + return app.LoadVersion(height, app.keyMain) +} - err := app.cdc.UnmarshalJSON(stateJSON, &genesisState) +// ExportAppStateAndValidators exports the state of the application for a genesis +// file. +func (app *EthermintApp) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []string, +) (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) { + + // Creates context with current height and checks txs for ctx to be usable by start of next block + ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()}) + + // Export genesis to be used by SDK modules + genState := app.mm.ExportGenesis(ctx) + appState, err = codec.MarshalJSONIndent(app.cdc, genState) if err != nil { - panic(errors.Wrap(err, "failed to parse application genesis state")) + return nil, nil, err } - // TODO: load the genesis accounts + // Write validators to staking module to be used by TM node + validators = staking.WriteValidators(ctx, app.stakingKeeper) - return abci.ResponseInitChain{} -} - -// CreateCodec creates a new amino wire codec and registers all the necessary -// concrete types and interfaces needed for the application. -func CreateCodec() *codec.Codec { - cdc := codec.New() - - // TODO: Add remaining codec registrations: - // bank, staking, distribution, slashing, and gov - - crypto.RegisterCodec(cdc) - evmtypes.RegisterCodec(cdc) - auth.RegisterCodec(cdc) - sdk.RegisterCodec(cdc) - codec.RegisterCrypto(cdc) - - return cdc + return appState, validators, nil } diff --git a/app/test_utils.go b/app/test_utils.go index bca38227..31eb4a8d 100644 --- a/app/test_utils.go +++ b/app/test_utils.go @@ -47,7 +47,7 @@ func newTestSetup() testSetup { // nolint:errcheck ms.LoadLatestVersion() - cdc := CreateCodec() + cdc := MakeCodec() cdc.RegisterConcrete(&sdk.TestMsg{}, "test/TestMsg", nil) // Set params keeper and subspaces diff --git a/cmd/emintd/main.go b/cmd/emintd/main.go index 7b25ca01..acb9ad31 100644 --- a/cmd/emintd/main.go +++ b/cmd/emintd/main.go @@ -1,6 +1,9 @@ package main import ( + "encoding/json" + "io" + "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/x/genaccounts" genaccscli "github.com/cosmos/cosmos-sdk/x/genaccounts/client/cli" @@ -12,6 +15,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" emintapp "github.com/cosmos/ethermint/app" + + abci "github.com/tendermint/tendermint/abci/types" + dbm "github.com/tendermint/tendermint/libs/db" + tmlog "github.com/tendermint/tendermint/libs/log" + tmtypes "github.com/tendermint/tendermint/types" ) func main() { @@ -43,8 +51,8 @@ func main() { genaccscli.AddGenesisAccountCmd(ctx, cdc, emintapp.DefaultNodeHome, emintapp.DefaultCLIHome), ) - // TODO: Add export app state and TM validators commands - // server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators) + // Tendermint node base commands + server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators) // prepare and add flags executor := cli.PrepareBaseCmd(rootCmd, "EM", emintapp.DefaultNodeHome) @@ -54,26 +62,24 @@ func main() { } } -// func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application { -// return emintapp.NewEthermintApp(logger, db) -// } +func newApp(logger tmlog.Logger, db dbm.DB, traceStore io.Writer) abci.Application { + return emintapp.NewEthermintApp(logger, db, true, 0) +} -// func exportAppStateAndTMValidators( -// logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailWhiteList []string, -// ) (json.RawMessage, []tmtypes.GenesisValidator, error) { +func exportAppStateAndTMValidators( + logger tmlog.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailWhiteList []string, +) (json.RawMessage, []tmtypes.GenesisValidator, error) { -// // if height != -1 { -// // emintApp := emintapp.NewEthermintApp(logger, db) -// // err := emintApp.LoadHeight(height) -// // if err != nil { -// // return nil, nil, err -// // } -// // return emintApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) -// // } + if height != -1 { + emintApp := emintapp.NewEthermintApp(logger, db, true, 0) + err := emintApp.LoadHeight(height) + if err != nil { + return nil, nil, err + } + return emintApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) + } -// // emintApp := emintapp.NewEthermintApp(logger, db) + emintApp := emintapp.NewEthermintApp(logger, db, true, 0) -// // return emintApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) -// // TODO: Unstub method -// return json.RawMessage{}, []tmtypes.GenesisValidator{}, nil -// } + return emintApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) +} diff --git a/go.mod b/go.mod index 7f2369a2..554a1f52 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/aristanetworks/goarista v0.0.0-20181101003910-5bb443fba8e0 // indirect github.com/btcsuite/btcd v0.0.0-20190629003639-c26ffa870fd8 // indirect github.com/cespare/cp v1.1.1 // indirect - github.com/cosmos/cosmos-sdk v0.28.2-0.20190709220430-3f519832a7a5 + github.com/cosmos/cosmos-sdk v0.28.2-0.20190711105643-280734d0e37f github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d // indirect github.com/deckarep/golang-set v1.7.1 // indirect github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 // indirect diff --git a/go.sum b/go.sum index dcbc034f..3171f7f7 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,9 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cosmos/cosmos-sdk v0.28.2-0.20190709220430-3f519832a7a5 h1:gakqjbZrqlUB1/rx8r/s86SVcRatOafVDfJF99yBcng= github.com/cosmos/cosmos-sdk v0.28.2-0.20190709220430-3f519832a7a5/go.mod h1:qzvnGkt2+ynMpjmf9/dws/94/qM87awRbuyvF7r2R8Q= +github.com/cosmos/cosmos-sdk v0.28.2-0.20190711105643-280734d0e37f h1:jmVM19bsHZRVVe8rugzfILuL3VPgCj5b6941I20Naw0= +github.com/cosmos/cosmos-sdk v0.28.2-0.20190711105643-280734d0e37f/go.mod h1:qzvnGkt2+ynMpjmf9/dws/94/qM87awRbuyvF7r2R8Q= +github.com/cosmos/cosmos-sdk v0.35.0 h1:EPeie1aKHwnXtTzKggvabG7aAPN+DDmju2xquvjFwao= github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8 h1:Iwin12wRQtyZhH6FV3ykFcdGNlYEzoeR0jN8Vn+JWsI= github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU=