diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index f2c75f5f5a..2e3640519f 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -17,6 +17,7 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" "cosmossdk.io/core/header" + "cosmossdk.io/core/server" corestore "cosmossdk.io/core/store" errorsmod "cosmossdk.io/errors" "cosmossdk.io/log" @@ -89,6 +90,7 @@ type BaseApp struct { verifyVoteExt sdk.VerifyVoteExtensionHandler // ABCI VerifyVoteExtension handler prepareCheckStater sdk.PrepareCheckStater // logic to run during commit using the checkState precommiter sdk.Precommiter // logic to run during commit using the deliverState + versionModifier server.VersionModifier // interface to get and set the app version addrPeerFilter sdk.PeerFilter // filter peers by address and port idPeerFilter sdk.PeerFilter // filter peers by node ID @@ -249,18 +251,11 @@ func (app *BaseApp) Name() string { // AppVersion returns the application's protocol version. func (app *BaseApp) AppVersion(ctx context.Context) (uint64, error) { - if app.paramStore == nil { - return 0, errors.New("app.paramStore is nil") + if app.versionModifier == nil { + return 0, errors.New("app.versionModifier is nil") } - cp, err := app.paramStore.Get(ctx) - if err != nil { - return 0, fmt.Errorf("failed to get consensus params: %w", err) - } - if cp.Version == nil { - return 0, nil - } - return cp.Version.App, nil + return app.versionModifier.AppVersion(ctx) } // Version returns the application's version string. diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index ecaf6894b4..22b046cf8a 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -81,6 +81,7 @@ func NewBaseAppSuite(t *testing.T, opts ...func(*baseapp.BaseApp)) *BaseAppSuite app.SetParamStore(paramStore{db: dbm.NewMemDB()}) app.SetTxDecoder(txConfig.TxDecoder()) app.SetTxEncoder(txConfig.TxEncoder()) + app.SetVersionModifier(newMockedVersionModifier(0)) // mount stores and seal require.Nil(t, app.LoadLatestVersion()) diff --git a/baseapp/options.go b/baseapp/options.go index 431f64b709..05962ec06c 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -7,6 +7,7 @@ import ( "io" "math" + "cosmossdk.io/core/server" corestore "cosmossdk.io/core/store" "cosmossdk.io/store/metrics" pruningtypes "cosmossdk.io/store/pruning/types" @@ -146,22 +147,11 @@ func (app *BaseApp) SetVersion(v string) { // SetAppVersion sets the application's version this is used as part of the // header in blocks and is returned to the consensus engine in EndBlock. func (app *BaseApp) SetAppVersion(ctx context.Context, v uint64) error { - if app.paramStore == nil { - return errors.New("param store must be set to set app version") + if app.versionModifier == nil { + return errors.New("version modifier must be set to set app version") } - cp, err := app.paramStore.Get(ctx) - if err != nil { - return fmt.Errorf("failed to get consensus params: %w", err) - } - if cp.Version == nil { - return errors.New("version is not set in param store") - } - cp.Version.App = v - if err := app.paramStore.Set(ctx, cp); err != nil { - return err - } - return nil + return app.versionModifier.SetAppVersion(ctx, v) } func (app *BaseApp) SetDB(db corestore.KVStoreWithBatch) { @@ -323,6 +313,15 @@ func (app *BaseApp) SetTxEncoder(txEncoder sdk.TxEncoder) { app.txEncoder = txEncoder } +// SetVersionModifier sets the version modifier for the BaseApp that allows to set the app version. +func (app *BaseApp) SetVersionModifier(versionModifier server.VersionModifier) { + if app.sealed { + panic("SetVersionModifier() on sealed BaseApp") + } + + app.versionModifier = versionModifier +} + // SetQueryMultiStore set a alternative MultiStore implementation to support grpc query service. // // Ref: https://github.com/cosmos/cosmos-sdk/issues/13317 diff --git a/baseapp/utils_test.go b/baseapp/utils_test.go index 9a47fde242..5715d57d13 100644 --- a/baseapp/utils_test.go +++ b/baseapp/utils_test.go @@ -20,6 +20,7 @@ import ( runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1" appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" "cosmossdk.io/core/address" + "cosmossdk.io/core/server" "cosmossdk.io/depinject" "cosmossdk.io/depinject/appconfig" errorsmod "cosmossdk.io/errors" @@ -375,3 +376,20 @@ func wonkyMsg(t *testing.T, cfg client.TxConfig, tx signing.Tx) signing.Tx { require.NoError(t, err) return builder.GetTx() } + +func newMockedVersionModifier(startingVersion uint64) server.VersionModifier { + return &mockedVersionModifier{version: startingVersion} +} + +type mockedVersionModifier struct { + version uint64 +} + +func (m *mockedVersionModifier) SetAppVersion(ctx context.Context, u uint64) error { + m.version = u + return nil +} + +func (m *mockedVersionModifier) AppVersion(ctx context.Context) (uint64, error) { + return m.version, nil +} diff --git a/runtime/module.go b/runtime/module.go index 2b2a9bb1b9..95595fc209 100644 --- a/runtime/module.go +++ b/runtime/module.go @@ -15,7 +15,6 @@ import ( "cosmossdk.io/core/appmodule" "cosmossdk.io/core/comet" "cosmossdk.io/core/registry" - "cosmossdk.io/core/server" "cosmossdk.io/core/store" "cosmossdk.io/depinject" "cosmossdk.io/depinject/appconfig" @@ -103,7 +102,6 @@ func init() { ProvideEnvironment, ProvideTransientStoreService, ProvideModuleManager, - ProvideAppVersionModifier, ProvideCometService, ), appconfig.Invoke(SetupAppBuilder), @@ -293,10 +291,6 @@ func ProvideTransientStoreService( return transientStoreService{key: storeKey} } -func ProvideAppVersionModifier(app *AppBuilder) server.VersionModifier { - return app.app -} - func ProvideCometService() comet.Service { return NewContextAwareCometInfoService() } diff --git a/simapp/CHANGELOG.md b/simapp/CHANGELOG.md index 5e6dae65ec..678870d8b7 100644 --- a/simapp/CHANGELOG.md +++ b/simapp/CHANGELOG.md @@ -46,6 +46,8 @@ Always refer to the [UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/mai * [#20490](https://github.com/cosmos/cosmos-sdk/pull/20490) Refactor simulations to make use of `testutil/sims` instead of `runsims`. * [#19726](https://github.com/cosmos/cosmos-sdk/pull/19726) Update APIs to match CometBFT v1. * [#21466](https://github.com/cosmos/cosmos-sdk/pull/21466) Allow chains to plug in their own public key types in `base.Account` +* [#21508](https://github.com/cosmos/cosmos-sdk/pull/21508) Abstract the way we update the version of the app state in `app.go` using the interface `VersionModifier`. + ## v0.47 to v0.50 diff --git a/simapp/app.go b/simapp/app.go index 2cc114103f..6cb7a326cf 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -294,6 +294,9 @@ func NewSimApp( app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, runtime.NewEnvironment(runtime.NewKVStoreService(keys[consensustypes.StoreKey]), logger.With(log.ModuleKey, "x/consensus")), govModuleAddr) bApp.SetParamStore(app.ConsensusParamsKeeper.ParamsStore) + // set the version modifier + bApp.SetVersionModifier(consensus.ProvideAppVersionModifier(app.ConsensusParamsKeeper)) + // add keepers accountsKeeper, err := accounts.NewKeeper( appCodec, diff --git a/simapp/v2/go.mod b/simapp/v2/go.mod index 310cf9938d..d890ce0280 100644 --- a/simapp/v2/go.mod +++ b/simapp/v2/go.mod @@ -10,7 +10,7 @@ require ( cosmossdk.io/depinject v1.0.0 cosmossdk.io/log v1.4.1 cosmossdk.io/math v1.3.0 - cosmossdk.io/runtime/v2 v2.0.0-20240905114452-a57b25418a59 // main + cosmossdk.io/runtime/v2 v2.0.0-20240906155629-dce0365c234b // main cosmossdk.io/server/v2 v2.0.0-20240829074658-81a225e6a29b // main cosmossdk.io/server/v2/cometbft v0.0.0-00010101000000-000000000000 cosmossdk.io/store/v2 v2.0.0-20240906090851-36d9b25e8981 // main diff --git a/simapp/v2/go.sum b/simapp/v2/go.sum index ace10a1275..9f30c4a3dc 100644 --- a/simapp/v2/go.sum +++ b/simapp/v2/go.sum @@ -210,8 +210,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/runtime/v2 v2.0.0-20240905114452-a57b25418a59 h1:9p9X7mTme7w0dznm6Zqr5APd7qhakJZx7CqGJyAYtYE= -cosmossdk.io/runtime/v2 v2.0.0-20240905114452-a57b25418a59/go.mod h1:yrRIRz4pLdpntieuC6DrCx+7AZGcy6zVI1kOEYzZTmo= +cosmossdk.io/runtime/v2 v2.0.0-20240906155629-dce0365c234b h1:jxpSMaMYYbkD7Ydt6YgbBev4txSyeSQhJJyMQ9ZNZrs= +cosmossdk.io/runtime/v2 v2.0.0-20240906155629-dce0365c234b/go.mod h1:dS/uElxFZjZUgwEjjRh8qE84OoavL8Yd6gEdUOGtkjQ= cosmossdk.io/schema v0.2.0 h1:UH5CR1DqUq8yP+5Np8PbvG4YX0zAUsTN2Qk6yThmfMk= cosmossdk.io/schema v0.2.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= cosmossdk.io/server/v2 v2.0.0-20240829074658-81a225e6a29b h1:FFixNVq2SbtRlYvr1fB/WikfYTRrA0o/35ImIhhZzrE= diff --git a/x/consensus/depinject.go b/x/consensus/depinject.go index 127144d91a..f5e71717c7 100644 --- a/x/consensus/depinject.go +++ b/x/consensus/depinject.go @@ -1,9 +1,12 @@ package consensus import ( + "context" + modulev1 "cosmossdk.io/api/cosmos/consensus/module/v1" "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" + "cosmossdk.io/core/server" "cosmossdk.io/depinject" "cosmossdk.io/depinject/appconfig" "cosmossdk.io/x/consensus/keeper" @@ -23,6 +26,7 @@ func init() { appconfig.RegisterModule( &modulev1.Module{}, appconfig.Provide(ProvideModule), + appconfig.Provide(ProvideAppVersionModifier), ) } @@ -64,6 +68,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { m := NewAppModule(in.Cdc, k) baseappOpt := func(app *baseapp.BaseApp) { app.SetParamStore(k.ParamsStore) + app.SetVersionModifier(versionModifier{Keeper: k}) } return ModuleOutputs{ @@ -72,3 +77,37 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { BaseAppOption: baseappOpt, } } + +type versionModifier struct { + Keeper keeper.Keeper +} + +func (v versionModifier) SetAppVersion(ctx context.Context, version uint64) error { + params, err := v.Keeper.Params(ctx, nil) + if err != nil { + return err + } + + updatedParams := params.Params + updatedParams.Version.App = version + + err = v.Keeper.ParamsStore.Set(ctx, *updatedParams) + if err != nil { + return err + } + + return nil +} + +func (v versionModifier) AppVersion(ctx context.Context) (uint64, error) { + params, err := v.Keeper.Params(ctx, nil) + if err != nil { + return 0, err + } + + return params.Params.Version.GetApp(), nil +} + +func ProvideAppVersionModifier(k keeper.Keeper) server.VersionModifier { + return versionModifier{Keeper: k} +} diff --git a/x/upgrade/keeper/abci_test.go b/x/upgrade/keeper/abci_test.go index 5ae0fd23ff..200594436f 100644 --- a/x/upgrade/keeper/abci_test.go +++ b/x/upgrade/keeper/abci_test.go @@ -12,6 +12,7 @@ import ( "cosmossdk.io/core/appmodule" "cosmossdk.io/core/header" + "cosmossdk.io/core/server" coretesting "cosmossdk.io/core/testing" "cosmossdk.io/log" storetypes "cosmossdk.io/store/types" @@ -132,6 +133,7 @@ func setupTest(t *testing.T, height int64, skip map[int64]bool) *TestSuite { s.env = runtime.NewEnvironment(storeService, coretesting.NewNopLogger(), runtime.EnvWithMsgRouterService(s.baseApp.MsgServiceRouter()), runtime.EnvWithQueryRouterService(s.baseApp.GRPCQueryRouter())) s.baseApp.SetParamStore(¶mStore{params: cmtproto.ConsensusParams{Version: &cmtproto.VersionParams{App: 1}}}) + s.baseApp.SetVersionModifier(newMockedVersionModifier(1)) authority, err := addresscodec.NewBech32Codec("cosmos").BytesToString(authtypes.NewModuleAddress(govModuleName)) require.NoError(t, err) @@ -144,6 +146,23 @@ func setupTest(t *testing.T, height int64, skip map[int64]bool) *TestSuite { return &s } +func newMockedVersionModifier(startingVersion uint64) server.VersionModifier { + return &mockedVersionModifier{version: startingVersion} +} + +type mockedVersionModifier struct { + version uint64 +} + +func (m *mockedVersionModifier) SetAppVersion(ctx context.Context, u uint64) error { + m.version = u + return nil +} + +func (m *mockedVersionModifier) AppVersion(ctx context.Context) (uint64, error) { + return m.version, nil +} + func TestRequireFutureBlock(t *testing.T) { s := setupTest(t, 10, map[int64]bool{}) err := s.keeper.ScheduleUpgrade(s.ctx, types.Plan{Name: "test", Height: s.ctx.HeaderInfo().Height - 1}) diff --git a/x/upgrade/keeper/keeper_test.go b/x/upgrade/keeper/keeper_test.go index 0aabb13500..d211c8fedc 100644 --- a/x/upgrade/keeper/keeper_test.go +++ b/x/upgrade/keeper/keeper_test.go @@ -60,6 +60,8 @@ func (s *KeeperTestSuite) SetupTest() { s.encCfg.TxConfig.TxDecoder(), ) s.baseApp.SetParamStore(¶mStore{params: cmttypes.DefaultConsensusParams().ToProto()}) + s.baseApp.SetVersionModifier(newMockedVersionModifier(0)) + appVersion, err := s.baseApp.AppVersion(context.Background()) s.Require().NoError(err) s.Require().Equal(uint64(0), appVersion)