Skip to content

Commit

Permalink
Add player info migration and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
xavierlepretre committed Feb 12, 2024
1 parent 19c3413 commit ae255f6
Show file tree
Hide file tree
Showing 10 changed files with 536 additions and 36 deletions.
80 changes: 45 additions & 35 deletions app/app.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package app

import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"

"github.com/b9lab/checkers/app/upgrades/v1tov1_1"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
Expand All @@ -16,6 +18,7 @@ import (
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/simapp"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
Expand Down Expand Up @@ -94,10 +97,6 @@ import (
"github.com/ignite-hq/cli/ignite/pkg/cosmoscmd"
"github.com/ignite-hq/cli/ignite/pkg/openapiconsole"

monitoringp "github.com/tendermint/spn/x/monitoringp"
monitoringpkeeper "github.com/tendermint/spn/x/monitoringp/keeper"
monitoringptypes "github.com/tendermint/spn/x/monitoringp/types"

"github.com/b9lab/checkers/docs"

checkersmodule "github.com/b9lab/checkers/x/checkers"
Expand Down Expand Up @@ -156,7 +155,6 @@ var (
evidence.AppModuleBasic{},
transfer.AppModuleBasic{},
vesting.AppModuleBasic{},
monitoringp.AppModuleBasic{},
checkersmodule.AppModuleBasic{},
// this line is used by starport scaffolding # stargate/app/moduleBasic
)
Expand Down Expand Up @@ -224,12 +222,10 @@ type App struct {
EvidenceKeeper evidencekeeper.Keeper
TransferKeeper ibctransferkeeper.Keeper
FeeGrantKeeper feegrantkeeper.Keeper
MonitoringKeeper monitoringpkeeper.Keeper

// make scoped keepers public for test purposes
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
ScopedTransferKeeper capabilitykeeper.ScopedKeeper
ScopedMonitoringKeeper capabilitykeeper.ScopedKeeper
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
ScopedTransferKeeper capabilitykeeper.ScopedKeeper

CheckersKeeper checkersmodulekeeper.Keeper
// this line is used by starport scaffolding # stargate/app/keeperDeclaration
Expand All @@ -238,7 +234,8 @@ type App struct {
mm *module.Manager

// sm is the simulation manager
sm *module.SimulationManager
sm *module.SimulationManager
configurator module.Configurator
}

// New returns a reference to an initialized blockchain app
Expand Down Expand Up @@ -292,7 +289,7 @@ func NewApp(
authtypes.StoreKey, authz.ModuleName, banktypes.StoreKey, stakingtypes.StoreKey,
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, monitoringptypes.StoreKey,
evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey,
checkersmoduletypes.StoreKey,
// this line is used by starport scaffolding # stargate/app/storeKey
)
Expand Down Expand Up @@ -400,21 +397,6 @@ func NewApp(
&stakingKeeper, govRouter,
)

scopedMonitoringKeeper := app.CapabilityKeeper.ScopeToModule(monitoringptypes.ModuleName)
app.MonitoringKeeper = *monitoringpkeeper.NewKeeper(
appCodec,
keys[monitoringptypes.StoreKey],
keys[monitoringptypes.MemStoreKey],
app.GetSubspace(monitoringptypes.ModuleName),
app.StakingKeeper,
app.IBCKeeper.ClientKeeper,
app.IBCKeeper.ConnectionKeeper,
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
scopedMonitoringKeeper,
)
monitoringModule := monitoringp.NewAppModule(appCodec, app.MonitoringKeeper)

app.CheckersKeeper = *checkersmodulekeeper.NewKeeper(
app.BankKeeper,
appCodec,
Expand All @@ -429,7 +411,6 @@ func NewApp(
// Create static IBC router, add transfer route, then set and seal it
ibcRouter := ibcporttypes.NewRouter()
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule)
ibcRouter.AddRoute(monitoringptypes.ModuleName, monitoringModule)
// this line is used by starport scaffolding # ibc/app/router
app.IBCKeeper.SetRouter(ibcRouter)

Expand Down Expand Up @@ -464,7 +445,6 @@ func NewApp(
ibc.NewAppModule(app.IBCKeeper),
params.NewAppModule(app.ParamsKeeper),
transferModule,
monitoringModule,
checkersModule,
// this line is used by starport scaffolding # stargate/app/appModule
)
Expand Down Expand Up @@ -492,7 +472,6 @@ func NewApp(
genutiltypes.ModuleName,
feegrant.ModuleName,
paramstypes.ModuleName,
monitoringptypes.ModuleName,
checkersmoduletypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/beginBlockers
)
Expand All @@ -516,7 +495,6 @@ func NewApp(
upgradetypes.ModuleName,
ibchost.ModuleName,
ibctransfertypes.ModuleName,
monitoringptypes.ModuleName,
checkersmoduletypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/endBlockers
)
Expand Down Expand Up @@ -545,14 +523,14 @@ func NewApp(
upgradetypes.ModuleName,
ibctransfertypes.ModuleName,
feegrant.ModuleName,
monitoringptypes.ModuleName,
checkersmoduletypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/initGenesis
)

app.mm.RegisterInvariants(&app.CrisisKeeper)
app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino)
app.mm.RegisterServices(module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()))
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
app.mm.RegisterServices(app.configurator)

// create the simulation manager and define the order of the modules for deterministic simulations
app.sm = module.NewSimulationManager(
Expand All @@ -570,7 +548,6 @@ func NewApp(
evidence.NewAppModule(app.EvidenceKeeper),
ibc.NewAppModule(app.IBCKeeper),
transferModule,
monitoringModule,
checkersModule,
// this line is used by starport scaffolding # stargate/app/appModule
)
Expand Down Expand Up @@ -601,6 +578,8 @@ func NewApp(
app.SetAnteHandler(anteHandler)
app.SetEndBlocker(app.EndBlocker)

app.setupUpgradeHandlers()

if loadLatest {
if err := app.LoadLatestVersion(); err != nil {
tmos.Exit(err.Error())
Expand All @@ -609,7 +588,6 @@ func NewApp(

app.ScopedIBCKeeper = scopedIBCKeeper
app.ScopedTransferKeeper = scopedTransferKeeper
app.ScopedMonitoringKeeper = scopedMonitoringKeeper
// this line is used by starport scaffolding # stargate/app/beforeInitReturn

return app
Expand Down Expand Up @@ -760,7 +738,6 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
paramsKeeper.Subspace(crisistypes.ModuleName)
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
paramsKeeper.Subspace(ibchost.ModuleName)
paramsKeeper.Subspace(monitoringptypes.ModuleName)
paramsKeeper.Subspace(checkersmoduletypes.ModuleName)
// this line is used by starport scaffolding # stargate/app/paramSubspace

Expand All @@ -771,3 +748,36 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
func (app *App) SimulationManager() *module.SimulationManager {
return app.sm
}

func (app *App) setupUpgradeHandlers() {
// v1 to v1.1 upgrade handler
app.UpgradeKeeper.SetUpgradeHandler(
v1tov1_1.UpgradeName,
func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
return app.mm.RunMigrations(ctx, app.configurator, vm)
},
)

// When a planned update height is reached, the old binary will panic
// writing on disk the height and name of the update that triggered it
// This will read that value, and execute the preparations for the upgrade.
upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic(fmt.Errorf("failed to read upgrade info from disk: %w", err))
}

if app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
return
}

var storeUpgrades *storetypes.StoreUpgrades

switch upgradeInfo.Name {
case v1tov1_1.UpgradeName:
}

if storeUpgrades != nil {
// configure store loader that checks if version == upgradeHeight and applies store upgrades
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, storeUpgrades))
}
}
5 changes: 5 additions & 0 deletions app/upgrades/v1tov1_1/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package v1tov1_1

const (
UpgradeName = "v1tov1_1"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package cv3_test

import (
"testing"
"time"

checkersapp "github.com/b9lab/checkers/app"
"github.com/b9lab/checkers/x/checkers/keeper"
cv2types "github.com/b9lab/checkers/x/checkers/migrations/cv2/types"
"github.com/b9lab/checkers/x/checkers/types"
"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
module "github.com/cosmos/cosmos-sdk/types/module"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)

type IntegrationTestSuite struct {
suite.Suite

app *checkersapp.App
msgServer types.MsgServer
ctx sdk.Context
queryClient types.QueryClient
}

func TestUpgradeTestSuite(t *testing.T) {
suite.Run(t, new(IntegrationTestSuite))
}

func (suite *IntegrationTestSuite) SetupTest() {
app := checkersapp.Setup(false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()})

app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams())
app.BankKeeper.SetParams(ctx, banktypes.DefaultParams())
initialVM := module.VersionMap{types.ModuleName: cv2types.ConsensusVersion}
app.UpgradeKeeper.SetModuleVersionMap(ctx, initialVM)

queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, app.CheckersKeeper)
queryClient := types.NewQueryClient(queryHelper)

suite.app = app
suite.msgServer = keeper.NewMsgServerImpl(app.CheckersKeeper)
suite.ctx = ctx
suite.queryClient = queryClient
}
110 changes: 110 additions & 0 deletions tests/integration/checkers/migrations/cv3/upgrade_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package cv3_test

import (
"github.com/b9lab/checkers/app/upgrades/v1tov1_1"
cv2types "github.com/b9lab/checkers/x/checkers/migrations/cv2/types"
cv3types "github.com/b9lab/checkers/x/checkers/migrations/cv3/types"
"github.com/b9lab/checkers/x/checkers/rules"
"github.com/b9lab/checkers/x/checkers/testutil"
"github.com/b9lab/checkers/x/checkers/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

const (
alice = testutil.Alice
bob = testutil.Bob
carol = testutil.Carol
)

func (suite *IntegrationTestSuite) TestUpgradeConsensusVersion() {
vmBefore := suite.app.UpgradeKeeper.GetModuleVersionMap(suite.ctx)
suite.Require().Equal(cv2types.ConsensusVersion, vmBefore[types.ModuleName])

v1Tov1_1Plan := upgradetypes.Plan{
Name: v1tov1_1.UpgradeName,
Info: "some text here",
Height: 123450000,
}
suite.app.UpgradeKeeper.ApplyUpgrade(suite.ctx, v1Tov1_1Plan)

vmAfter := suite.app.UpgradeKeeper.GetModuleVersionMap(suite.ctx)
suite.Require().Equal(cv3types.ConsensusVersion, vmAfter[types.ModuleName])
}

func (suite *IntegrationTestSuite) TestNotUpgradeConsensusVersion() {
vmBefore := suite.app.UpgradeKeeper.GetModuleVersionMap(suite.ctx)
suite.Require().Equal(cv2types.ConsensusVersion, vmBefore[types.ModuleName])

dummyPlan := upgradetypes.Plan{
Name: v1tov1_1.UpgradeName + "no",
Info: "some text here",
Height: 123450000,
}
defer func() {
r := recover()
suite.Require().NotNil(r, "The code did not panic")
suite.Require().Equal(r, "ApplyUpgrade should never be called without first checking HasHandler")

vmAfter := suite.app.UpgradeKeeper.GetModuleVersionMap(suite.ctx)
suite.Require().Equal(cv2types.ConsensusVersion, vmAfter[types.ModuleName])
}()
suite.app.UpgradeKeeper.ApplyUpgrade(suite.ctx, dummyPlan)
}

func (suite *IntegrationTestSuite) TestUpgradeTallyPlayerInfo() {
suite.app.CheckersKeeper.SetStoredGame(suite.ctx, types.StoredGame{
Index: "1",
Black: alice,
Red: bob,
Winner: rules.PieceStrings[rules.BLACK_PLAYER],
})
suite.app.CheckersKeeper.SetStoredGame(suite.ctx, types.StoredGame{
Index: "2",
Black: alice,
Red: carol,
Winner: rules.PieceStrings[rules.RED_PLAYER],
})
suite.app.CheckersKeeper.SetStoredGame(suite.ctx, types.StoredGame{
Index: "3",
Black: alice,
Red: carol,
Winner: rules.PieceStrings[rules.BLACK_PLAYER],
})
suite.app.CheckersKeeper.SetStoredGame(suite.ctx, types.StoredGame{
Index: "4",
Black: alice,
Red: bob,
Winner: rules.PieceStrings[rules.NO_PLAYER],
})
suite.Require().EqualValues([]types.PlayerInfo(nil), suite.app.CheckersKeeper.GetAllPlayerInfo(suite.ctx))

v1Tov1_1Plan := upgradetypes.Plan{
Name: v1tov1_1.UpgradeName,
Info: "some text here",
Height: 123450000,
}
suite.app.UpgradeKeeper.ApplyUpgrade(suite.ctx, v1Tov1_1Plan)

expectedInfos := map[string]types.PlayerInfo{
alice: {
Index: alice,
LostCount: 1,
WonCount: 2,
},
bob: {
Index: bob,
LostCount: 1,
},
carol: {
Index: carol,
LostCount: 1,
WonCount: 1,
},
}

for who, expectedInfo := range expectedInfos {
storedInfo, found := suite.app.CheckersKeeper.GetPlayerInfo(suite.ctx, who)
suite.Require().True(found)
suite.Require().Equal(expectedInfo, storedInfo)
}
}
5 changes: 5 additions & 0 deletions x/checkers/migrations/cv2/types/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package types

const (
ConsensusVersion = uint64(2)
)
Loading

0 comments on commit ae255f6

Please sign in to comment.