Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: improve x/upgrade app wiring (part of upgrade audit) #14216

Merged
merged 38 commits into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
95e848d
refactor: set genesis module order in app config
julienrbrt Dec 7, 2022
7d53ceb
set custom migration order via app config
julienrbrt Dec 7, 2022
1b566fb
updates
julienrbrt Dec 7, 2022
2006601
updates
julienrbrt Dec 7, 2022
527f082
updates
julienrbrt Dec 8, 2022
e2ec990
updates
julienrbrt Dec 8, 2022
f393e1c
updates
julienrbrt Dec 8, 2022
b3a4c23
add replace directive in tests
julienrbrt Dec 8, 2022
e8f19ab
improve description
julienrbrt Dec 8, 2022
351c942
split in follow-up
julienrbrt Dec 8, 2022
7130073
Merge branch 'main' into julien/appv2
julienrbrt Dec 8, 2022
4b944f8
refactor: improve `x/upgrade` app config
julienrbrt Dec 8, 2022
5d48a37
updates
julienrbrt Dec 8, 2022
fde91f6
updates
julienrbrt Dec 8, 2022
77d27e1
remove todos
julienrbrt Dec 8, 2022
2b440c1
Merge branch 'julien/appv2' into julien/upgrade
julienrbrt Dec 8, 2022
55eab41
updates
julienrbrt Dec 8, 2022
e20e901
Merge branch 'main' into julien/upgrade
julienrbrt Dec 8, 2022
666a54d
updates
julienrbrt Dec 8, 2022
4725bc8
updates
julienrbrt Dec 9, 2022
c0c19ae
don't use fmt in app.go
julienrbrt Dec 11, 2022
99519a9
Merge branch 'main' into julien/upgrade
julienrbrt Dec 11, 2022
7eb9573
updates
julienrbrt Dec 11, 2022
328b92f
updates
julienrbrt Dec 12, 2022
6e5eb26
improve comment
julienrbrt Dec 12, 2022
d1a9328
update logger error
julienrbrt Dec 12, 2022
aca5f70
fix e2e
julienrbrt Dec 12, 2022
f5e92aa
Merge branch 'main' into julien/upgrade
julienrbrt Dec 12, 2022
c99bfe6
Merge branch 'main' into julien/upgrade
julienrbrt Dec 13, 2022
4e34404
updates
julienrbrt Dec 13, 2022
6474125
Merge branch 'main' into julien/upgrade
julienrbrt Dec 13, 2022
8639ce1
set legacy router at correct place
julienrbrt Dec 13, 2022
a445d92
updates
julienrbrt Dec 13, 2022
3518a40
Merge branch 'main' into julien/upgrade
julienrbrt Dec 13, 2022
ec9121e
remove global
julienrbrt Dec 13, 2022
5fe8266
Merge branch 'main' into julien/upgrade
julienrbrt Dec 13, 2022
2eabd59
improve comment
julienrbrt Dec 14, 2022
d3705e1
Merge branch 'main' into julien/upgrade
julienrbrt Dec 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sonar.projectKey=cosmos-sdk-core
sonar.organization=cosmos

sonar.projectName=Cosmos SDK Core
sonar.projectName=Cosmos SDK - Core
sonar.project.monorepo.enabled=true

sonar.sources=.
Expand Down
18 changes: 16 additions & 2 deletions runtime/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type App struct {
baseAppOptions []BaseAppOption
msgServiceRouter *baseapp.MsgServiceRouter
appConfig *appv1alpha1.Config
// initChainer is the init chainer function defined by the app config.
// this is only required if the chain wants to add special InitChainer logic.
initChainer sdk.InitChainer
}

// RegisterModules registers the provided modules with the module manager and
Expand Down Expand Up @@ -82,7 +85,9 @@ func (a *App) Load(loadLatest bool) error {

if len(a.config.InitGenesis) != 0 {
a.ModuleManager.SetOrderInitGenesis(a.config.InitGenesis...)
a.SetInitChainer(a.InitChainer)
if a.initChainer == nil {
a.SetInitChainer(a.InitChainer)
}
}

if len(a.config.ExportGenesis) != 0 {
Expand Down Expand Up @@ -165,10 +170,12 @@ func (a *App) RegisterTendermintService(clientCtx client.Context) {
)
}

// RegisterNodeService registers the node gRPC service on the app gRPC router.
func (a *App) RegisterNodeService(clientCtx client.Context) {
nodeservice.RegisterNodeService(clientCtx, a.GRPCQueryRouter())
}

// Configurator returns the app's configurator.
func (a *App) Configurator() module.Configurator {
return a.configurator
}
Expand All @@ -183,11 +190,18 @@ func (a *App) DefaultGenesis() map[string]json.RawMessage {
return a.basicManager.DefaultGenesis(a.cdc)
}

// GetStoreKeys returns all the keys stored store keys.
// GetStoreKeys returns all the stored store keys.
func (a *App) GetStoreKeys() []storetypes.StoreKey {
return a.storeKeys
}

// SetInitChainer sets the init chainer function
// It wraps `BaseApp.SetInitChainer` to allow setting a custom init chainer from an app.
func (a *App) SetInitChainer(initChainer sdk.InitChainer) {
a.initChainer = initChainer
a.BaseApp.SetInitChainer(initChainer)
}

// UnsafeFindStoreKey fetches a registered StoreKey from the App in linear time.
//
// NOTE: This should only be used in testing.
Expand Down
13 changes: 6 additions & 7 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package simapp

import (
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
Expand Down Expand Up @@ -184,7 +183,7 @@ type SimApp struct {
DistrKeeper distrkeeper.Keeper
GovKeeper govkeeper.Keeper
CrisisKeeper *crisiskeeper.Keeper
UpgradeKeeper upgradekeeper.Keeper
UpgradeKeeper *upgradekeeper.Keeper
ParamsKeeper paramskeeper.Keeper
AuthzKeeper authzkeeper.Keeper
EvidenceKeeper evidencekeeper.Keeper
Expand Down Expand Up @@ -265,7 +264,7 @@ func NewSimApp(

// load state streaming if enabled
if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, logger, keys); err != nil {
fmt.Printf("failed to load state streaming: %s", err)
logger.Error("failed to load state streaming", "err", err)
os.Exit(1)
}

Expand Down Expand Up @@ -360,15 +359,15 @@ func NewSimApp(
app.StakingKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

// Set legacy router for backwards compatibility with gov v1beta1
govKeeper.SetLegacyRouter(govRouter)

app.GovKeeper = *govKeeper.SetHooks(
govtypes.NewMultiGovHooks(
// register the governance hooks
),
)

// Set legacy router for backwards compatibility with gov v1beta1
govKeeper.SetLegacyRouter(govRouter)

app.NFTKeeper = nftkeeper.NewKeeper(keys[nftkeeper.StoreKey], appCodec, app.AccountKeeper, app.BankKeeper)

// create evidence keeper with router
Expand Down Expand Up @@ -514,7 +513,7 @@ func NewSimApp(

if loadLatest {
if err := app.LoadLatestVersion(); err != nil {
fmt.Println(err.Error())
logger.Error("error on loading last version", "err", err)
os.Exit(1)
}
}
Expand Down
2 changes: 1 addition & 1 deletion simapp/app_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ var (
KvStoreKey: "acc",
},
},
// InitGenesis: genesisModuleOrder,
InitGenesis: genesisModuleOrder,
// When ExportGenesis is not specified, the export genesis module order
// is equal to the init genesis order
// ExportGenesis: genesisModuleOrder,
Expand Down
31 changes: 12 additions & 19 deletions simapp/app_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ package simapp

import (
_ "embed"
"fmt"
"io"
"os"
"path/filepath"

abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"

Expand All @@ -27,7 +25,6 @@ import (
"github.com/cosmos/cosmos-sdk/store/streaming"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata_pulsar"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
Expand Down Expand Up @@ -136,7 +133,7 @@ type SimApp struct {
DistrKeeper distrkeeper.Keeper
GovKeeper *govkeeper.Keeper
CrisisKeeper *crisiskeeper.Keeper
UpgradeKeeper upgradekeeper.Keeper
UpgradeKeeper *upgradekeeper.Keeper
ParamsKeeper paramskeeper.Keeper
AuthzKeeper authzkeeper.Keeper
EvidenceKeeper evidencekeeper.Keeper
Expand Down Expand Up @@ -250,18 +247,12 @@ func NewSimApp(

// load state streaming if enabled
if _, _, err := streaming.LoadStreamingServices(app.App.BaseApp, appOpts, app.appCodec, logger, app.kvStoreKeys()); err != nil {
fmt.Printf("failed to load state streaming: %s", err)
logger.Error("failed to load state streaming", "err", err)
os.Exit(1)
}

/**** Module Options ****/

// Set upgrade module options
app.UpgradeKeeper.SetVersionSetter(app.BaseApp)

app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...)
app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...)

app.ModuleManager.RegisterInvariants(app.CrisisKeeper)

// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
Expand All @@ -281,8 +272,16 @@ func NewSimApp(

app.sm.RegisterStoreDecoders()

// initialize BaseApp
app.SetInitChainer(app.InitChainer)
// A custom InitChainer can be set if extra pre-init-genesis logic is required.
// By default, when using app wiring enabled module, this is not required.
// For instance, the upgrade module will set automatically the module version map in its init genesis thanks to app wiring.
// However, when registering a module manually (i.e. that does not support app wiring), the module version map
// must be set manually as follow. The upgrade module will de-duplicate the module version map.
//
// app.SetInitChainer(func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
// app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
// return app.App.InitChainer(ctx, req)
// })

if err := app.Load(loadLatest); err != nil {
panic(err)
Expand All @@ -294,12 +293,6 @@ func NewSimApp(
// Name returns the name of the App
func (app *SimApp) Name() string { return app.BaseApp.Name() }

// InitChainer application update at chain initialization
func (app *SimApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
return app.App.InitChainer(ctx, req)
}

// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
Expand Down
1 change: 0 additions & 1 deletion simapp/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ func AppStateRandomizedFn(
accs []simtypes.Account, genesisTimestamp time.Time, appParams simtypes.AppParams,
) (json.RawMessage, []simtypes.Account) {
numAccs := int64(len(accs))
// TODO - in case runtime.RegisterModules(...) is used, the genesis state of the module won't be reflected here
genesisState := ModuleBasics.DefaultGenesis(cdc)

// generate a random amount of initial stake coins and a random initial
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/upgrade/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

func NewIntegrationTestSuite(cfg network.Config, keeper keeper.Keeper, ctx sdk.Context) *IntegrationTestSuite {
func NewIntegrationTestSuite(cfg network.Config, keeper *keeper.Keeper, ctx sdk.Context) *IntegrationTestSuite {
return &IntegrationTestSuite{
cfg: cfg,
upgradeKeeper: keeper,
Expand All @@ -24,7 +24,7 @@ func NewIntegrationTestSuite(cfg network.Config, keeper keeper.Keeper, ctx sdk.C
type IntegrationTestSuite struct {
suite.Suite

upgradeKeeper keeper.Keeper
upgradeKeeper *keeper.Keeper
cfg network.Config
network *network.Network
ctx sdk.Context
Expand Down
2 changes: 1 addition & 1 deletion x/upgrade/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
// The purpose is to ensure the binary is switched EXACTLY at the desired block, and to allow
// a migration to be executed if needed upon this switch (migration defined in the new binary)
// skipUpgradeHeightArray is a set of block heights for which the upgrade must be skipped
func BeginBlocker(k keeper.Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) {
func BeginBlocker(k *keeper.Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)

plan, found := k.GetUpgradePlan(ctx)
Expand Down
8 changes: 4 additions & 4 deletions x/upgrade/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type TestSuite struct {
suite.Suite

module module.BeginBlockAppModule
keeper keeper.Keeper
keeper *keeper.Keeper
handler govtypesv1beta1.Handler
ctx sdk.Context
baseApp *baseapp.BaseApp
Expand Down Expand Up @@ -510,18 +510,18 @@ func TestDowngradeVerification(t *testing.T) {
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)

testCases := map[string]struct {
preRun func(keeper.Keeper, sdk.Context, string)
preRun func(*keeper.Keeper, sdk.Context, string)
expectPanic bool
}{
"valid binary": {
preRun: func(k keeper.Keeper, ctx sdk.Context, name string) {
preRun: func(k *keeper.Keeper, ctx sdk.Context, name string) {
k.SetUpgradeHandler(planName, func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) {
return vm, nil
})
},
},
"downgrade with an active plan": {
preRun: func(k keeper.Keeper, ctx sdk.Context, name string) {
preRun: func(k *keeper.Keeper, ctx sdk.Context, name string) {
handler := upgrade.NewSoftwareUpgradeProposalHandler(k)
err := handler(ctx, &types.SoftwareUpgradeProposal{Title: "test", Plan: types.Plan{Name: "another" + planName, Height: ctx.BlockHeight() + 1}})
require.NoError(t, err, name)
Expand Down
6 changes: 3 additions & 3 deletions x/upgrade/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
// to abort a previously voted upgrade.
//
//nolint:staticcheck // we are intentionally using a deprecated proposal here.
func NewSoftwareUpgradeProposalHandler(k keeper.Keeper) govtypes.Handler {
func NewSoftwareUpgradeProposalHandler(k *keeper.Keeper) govtypes.Handler {
return func(ctx sdk.Context, content govtypes.Content) error {
switch c := content.(type) {
case *types.SoftwareUpgradeProposal:
Expand All @@ -29,12 +29,12 @@ func NewSoftwareUpgradeProposalHandler(k keeper.Keeper) govtypes.Handler {
}

//nolint:staticcheck // we are intentionally using a deprecated proposal here.
func handleSoftwareUpgradeProposal(ctx sdk.Context, k keeper.Keeper, p *types.SoftwareUpgradeProposal) error {
func handleSoftwareUpgradeProposal(ctx sdk.Context, k *keeper.Keeper, p *types.SoftwareUpgradeProposal) error {
return k.ScheduleUpgrade(ctx, p.Plan)
}

//nolint:staticcheck // we are intentionally using a deprecated proposal here.
func handleCancelSoftwareUpgradeProposal(ctx sdk.Context, k keeper.Keeper, _ *types.CancelSoftwareUpgradeProposal) error {
func handleCancelSoftwareUpgradeProposal(ctx sdk.Context, k *keeper.Keeper, _ *types.CancelSoftwareUpgradeProposal) error {
k.ClearUpgradePlan(ctx)
return nil
}
2 changes: 1 addition & 1 deletion x/upgrade/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
type UpgradeTestSuite struct {
suite.Suite

upgradeKeeper keeper.Keeper
upgradeKeeper *keeper.Keeper
ctx sdk.Context
queryClient types.QueryClient
encCfg moduletestutil.TestEncodingConfig
Expand Down
17 changes: 15 additions & 2 deletions x/upgrade/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type Keeper struct {
versionSetter xp.ProtocolVersionSetter // implements setting the protocol version field on BaseApp
downgradeVerified bool // tells if we've already sanity checked that this binary version isn't being used against an old state.
authority string // the address capable of executing and cancelling an upgrade. Usually the gov module account
initVersionMap module.VersionMap // the module version map at init genesis
}

// NewKeeper constructs an upgrade Keeper which requires the following arguments:
Expand All @@ -43,8 +44,8 @@ type Keeper struct {
// cdc - the app-wide binary codec
// homePath - root directory of the application's config
// vs - the interface implemented by baseapp which allows setting baseapp's protocol version field
func NewKeeper(skipUpgradeHeights map[int64]bool, storeKey storetypes.StoreKey, cdc codec.BinaryCodec, homePath string, vs xp.ProtocolVersionSetter, authority string) Keeper {
return Keeper{
func NewKeeper(skipUpgradeHeights map[int64]bool, storeKey storetypes.StoreKey, cdc codec.BinaryCodec, homePath string, vs xp.ProtocolVersionSetter, authority string) *Keeper {
return &Keeper{
homePath: homePath,
skipUpgradeHeights: skipUpgradeHeights,
storeKey: storeKey,
Expand All @@ -65,6 +66,18 @@ func (k *Keeper) GetVersionSetter() xp.ProtocolVersionSetter {
return k.versionSetter
}

// SetInitVersionMap sets the initial version map.
// This is only used in app wiring and should not be used in any other context.
func (k *Keeper) SetInitVersionMap(vm module.VersionMap) {
k.initVersionMap = vm
}

// GetInitVersionMap gets the initial version map
// This is only used in upgrade InitGenesis and should not be used in any other context.
func (k *Keeper) GetInitVersionMap() module.VersionMap {
return k.initVersionMap
}

// SetUpgradeHandler sets an UpgradeHandler for the upgrade specified by name. This handler will be called when the upgrade
// with this name is applied. In order for an upgrade with the given name to proceed, a handler for this upgrade
// must be set even if it is a no-op function.
Expand Down
2 changes: 1 addition & 1 deletion x/upgrade/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type KeeperTestSuite struct {

key *storetypes.KVStoreKey
baseApp *baseapp.BaseApp
upgradeKeeper keeper.Keeper
upgradeKeeper *keeper.Keeper
homeDir string
ctx sdk.Context
msgSrvr types.MsgServer
Expand Down
4 changes: 2 additions & 2 deletions x/upgrade/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import (

// Migrator is a struct for handling in-place store migrations.
type Migrator struct {
keeper Keeper
keeper *Keeper
}

// NewMigrator returns a new Migrator.
func NewMigrator(keeper Keeper) Migrator {
func NewMigrator(keeper *Keeper) Migrator {
return Migrator{keeper: keeper}
}

Expand Down
4 changes: 2 additions & 2 deletions x/upgrade/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import (
)

type msgServer struct {
Keeper
*Keeper
}

// NewMsgServerImpl returns an implementation of the upgrade MsgServer interface
// for the provided Keeper.
func NewMsgServerImpl(k Keeper) types.MsgServer {
func NewMsgServerImpl(k *Keeper) types.MsgServer {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is a reference needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return &msgServer{
Keeper: k,
}
Expand Down
Loading