diff --git a/CHANGELOG.md b/CHANGELOG.md index 2948ce1b..ec0b098d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,11 @@ Ref: https://keepachangelog.com/en/1.0.0/ # Changelog -## [v0.1.0] - 2020-08-23 +## Unreleased + +### Improvements + +* (app) [\#471](https://github.com/ChainSafe/ethermint/pull/471) Add `x/upgrade` module for managing software updates. ## [v0.1.0] - 2020-08-23 diff --git a/app/ethermint.go b/app/ethermint.go index 0aecdb74..1a371655 100644 --- a/app/ethermint.go +++ b/app/ethermint.go @@ -23,6 +23,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/supply" + "github.com/cosmos/cosmos-sdk/x/upgrade" + upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" "github.com/cosmos/ethermint/app/ante" ethermintcodec "github.com/cosmos/ethermint/codec" @@ -63,12 +65,13 @@ var ( mint.AppModuleBasic{}, distr.AppModuleBasic{}, gov.NewAppModuleBasic( - paramsclient.ProposalHandler, distr.ProposalHandler, + paramsclient.ProposalHandler, distr.ProposalHandler, upgradeclient.ProposalHandler, ), params.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, evidence.AppModuleBasic{}, + upgrade.AppModuleBasic{}, evm.AppModuleBasic{}, faucet.AppModuleBasic{}, ) @@ -118,6 +121,7 @@ type EthermintApp struct { DistrKeeper distr.Keeper GovKeeper gov.Keeper CrisisKeeper crisis.Keeper + UpgradeKeeper upgrade.Keeper ParamsKeeper params.Keeper EvidenceKeeper evidence.Keeper EvmKeeper evm.Keeper @@ -130,15 +134,15 @@ type EthermintApp struct { sm *module.SimulationManager } -// NewEthermintApp returns a reference to a new initialized Ethermint -// application. -// -// 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. +// NewEthermintApp returns a reference to a new initialized Ethermint application. func NewEthermintApp( - logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, - invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp), + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + loadLatest bool, + skipUpgradeHeights map[int64]bool, + invCheckPeriod uint, + baseAppOptions ...func(*bam.BaseApp), ) *EthermintApp { cdc := ethermintcodec.MakeCodec(ModuleBasics) @@ -151,8 +155,8 @@ func NewEthermintApp( keys := sdk.NewKVStoreKeys( bam.MainStoreKey, auth.StoreKey, staking.StoreKey, supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey, - gov.StoreKey, params.StoreKey, evidence.StoreKey, evm.StoreKey, - faucet.StoreKey, + gov.StoreKey, params.StoreKey, upgrade.StoreKey, evidence.StoreKey, + evm.StoreKey, faucet.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(params.TStoreKey) @@ -205,6 +209,7 @@ func NewEthermintApp( app.CrisisKeeper = crisis.NewKeeper( app.subspaces[crisis.ModuleName], invCheckPeriod, app.SupplyKeeper, auth.FeeCollectorName, ) + app.UpgradeKeeper = upgrade.NewKeeper(skipUpgradeHeights, keys[upgrade.StoreKey], app.cdc) app.EvmKeeper = evm.NewKeeper( app.cdc, keys[evm.StoreKey], app.AccountKeeper, ) @@ -225,7 +230,9 @@ func NewEthermintApp( govRouter := gov.NewRouter() govRouter.AddRoute(gov.RouterKey, gov.ProposalHandler). AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). - AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)) + AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). + AddRoute(upgrade.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)) + app.GovKeeper = gov.NewKeeper( cdc, keys[gov.StoreKey], app.subspaces[gov.ModuleName], app.SupplyKeeper, &stakingKeeper, govRouter, diff --git a/app/ethermint_test.go b/app/ethermint_test.go index a0cc4775..6a3cdd26 100644 --- a/app/ethermint_test.go +++ b/app/ethermint_test.go @@ -15,7 +15,7 @@ import ( func TestEthermintAppExport(t *testing.T) { db := dbm.NewMemDB() - app := NewEthermintApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0) + app := NewEthermintApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, 0) genesisState := ModuleBasics.DefaultGenesis() stateBytes, err := codec.MarshalJSONIndent(app.cdc, genesisState) @@ -31,7 +31,7 @@ func TestEthermintAppExport(t *testing.T) { app.Commit() // Making a new app object with the db, so that initchain hasn't been called - app2 := NewEthermintApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0) + app2 := NewEthermintApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, 0) _, _, err = app2.ExportAppStateAndValidators(false, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } diff --git a/app/simulation_test.go b/app/simulation_test.go index a144a853..a5b3d1be 100644 --- a/app/simulation_test.go +++ b/app/simulation_test.go @@ -63,7 +63,7 @@ func TestFullAppSimulation(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewEthermintApp(logger, db, nil, true, simapp.FlagPeriodValue, fauxMerkleModeOpt) + app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, simapp.FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, appName, app.Name()) // run randomized simulation @@ -95,7 +95,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewEthermintApp(logger, db, nil, true, simapp.FlagPeriodValue, fauxMerkleModeOpt) + app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, simapp.FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, appName, app.Name()) // Run randomized simulation @@ -130,7 +130,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewEthermintApp(log.NewNopLogger(), newDB, nil, true, simapp.FlagPeriodValue, fauxMerkleModeOpt) + newApp := NewEthermintApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, simapp.FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, appName, newApp.Name()) var genesisState map[string]json.RawMessage @@ -183,7 +183,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewEthermintApp(logger, db, nil, true, simapp.FlagPeriodValue, fauxMerkleModeOpt) + app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, simapp.FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, appName, app.Name()) // Run randomized simulation @@ -223,7 +223,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewEthermintApp(log.NewNopLogger(), newDB, nil, true, simapp.FlagPeriodValue, fauxMerkleModeOpt) + newApp := NewEthermintApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, simapp.FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, appName, newApp.Name()) newApp.InitChain(abci.RequestInitChain{ @@ -265,7 +265,7 @@ func TestAppStateDeterminism(t *testing.T) { db := dbm.NewMemDB() - app := NewEthermintApp(logger, db, nil, true, simapp.FlagPeriodValue, interBlockCacheOpt()) + app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, simapp.FlagPeriodValue, interBlockCacheOpt()) fmt.Printf( "running non-determinism simulation; seed %d: attempt: %d/%d\n", diff --git a/app/test_helpers.go b/app/test_helpers.go index 7a9bbe07..b23f9445 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -11,7 +11,7 @@ import ( // Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp. func Setup(isCheckTx bool) *EthermintApp { db := dbm.NewMemDB() - app := NewEthermintApp(log.NewNopLogger(), db, nil, true, 0) + app := NewEthermintApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0) if !isCheckTx { // init chain must be called to stop deliverState from being nil diff --git a/cmd/ethermintd/main.go b/cmd/ethermintd/main.go index f3b0aec7..aaf58237 100644 --- a/cmd/ethermintd/main.go +++ b/cmd/ethermintd/main.go @@ -94,24 +94,31 @@ func main() { } func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application { - return app.NewEthermintApp(logger, db, traceStore, true, 0, - baseapp.SetPruning(storetypes.NewPruningOptionsFromString(viper.GetString("pruning")))) + return app.NewEthermintApp( + logger, + db, + traceStore, + true, + map[int64]bool{}, + 0, + baseapp.SetPruning(storetypes.NewPruningOptionsFromString(viper.GetString("pruning"))), + baseapp.SetMinGasPrices(viper.GetString(server.FlagMinGasPrices)), + baseapp.SetHaltHeight(uint64(viper.GetInt(server.FlagHaltHeight))), + ) } func exportAppStateAndTMValidators( logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailWhiteList []string, ) (json.RawMessage, []tmtypes.GenesisValidator, error) { + ethermintApp := app.NewEthermintApp(logger, db, traceStore, true, map[int64]bool{}, 0) + if height != -1 { - emintApp := app.NewEthermintApp(logger, db, traceStore, true, 0) - err := emintApp.LoadHeight(height) + err := ethermintApp.LoadHeight(height) if err != nil { return nil, nil, err } - return emintApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) } - emintApp := app.NewEthermintApp(logger, db, traceStore, true, 0) - - return emintApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) + return ethermintApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) }