Skip to content

Commit

Permalink
Better upgrade structure an minor updates
Browse files Browse the repository at this point in the history
  • Loading branch information
alpe committed Oct 5, 2023
1 parent e61ca43 commit 32a01da
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 44 deletions.
74 changes: 42 additions & 32 deletions app/upgrades.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,64 @@
package app

import (
"fmt"
"github.com/CosmWasm/wasmd/app/upgrades"
v043 "github.com/CosmWasm/wasmd/app/upgrades/v043"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"
icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types"
ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"
ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"

storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
)

// UpgradeName defines the on-chain upgrade name for the sample SimApp upgrade
// from v046 to v047.
//
// NOTE: This upgrade defines a reference implementation of what an upgrade
// could look like when an application is migrating from Cosmos SDK version
// v0.46.x to v0.47.x.
const UpgradeName = "v0.43.x"
// Upgrades list of chain upgrades
var Upgrades = []upgrades.Upgrade{v043.Upgrade}

// RegisterUpgradeHandlers registers the chain upgrade handlers
func (app WasmApp) RegisterUpgradeHandlers() {
setupLegacyKeyTables(app.ParamsKeeper)

keepers := upgrades.AppKeepers{AccountKeeper: app.AccountKeeper}
// register all upgrade handlers
for _, upgrade := range Upgrades {
app.UpgradeKeeper.SetUpgradeHandler(
upgrade.UpgradeName,
upgrade.CreateUpgradeHandler(
app.ModuleManager,
app.configurator,
&keepers,
),
)
}

upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic(fmt.Sprintf("failed to read upgrade info from disk %s", err))
}

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

// register store loader for current upgrade
for _, upgrade := range Upgrades {
if upgradeInfo.Name == upgrade.UpgradeName {
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &upgrade.StoreUpgrades))
break
}
}
}

func setupLegacyKeyTables(k paramskeeper.Keeper) {
// Set param key table for params module migration
for _, subspace := range app.ParamsKeeper.GetSubspaces() {
for _, subspace := range k.GetSubspaces() {
subspace := subspace

var keyTable paramstypes.KeyTable
Expand All @@ -53,25 +84,4 @@ func (app WasmApp) RegisterUpgradeHandlers() {
subspace.WithKeyTable(keyTable)
}
}

app.UpgradeKeeper.SetUpgradeHandler(
UpgradeName,
func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
return app.ModuleManager.RunMigrations(ctx, app.Configurator(), fromVM)
},
)

upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic(err)
}

if upgradeInfo.Name == UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := storetypes.StoreUpgrades{
Added: []string{},
}

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

import (
store "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/types/module"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

type AppKeepers struct {
authkeeper.AccountKeeper
}

// Upgrade defines a struct containing necessary fields that a SoftwareUpgradeProposal
// must have written, in order for the state migration to go smoothly.
// An upgrade must implement this struct, and then set it in the app.go.
// The app.go will then define the handler.
type Upgrade struct {
// Upgrade version name, for the upgrade handler, e.g. `v7`
UpgradeName string

// CreateUpgradeHandler defines the function that creates an upgrade handler
CreateUpgradeHandler func(*module.Manager, module.Configurator, *AppKeepers) upgradetypes.UpgradeHandler
StoreUpgrades store.StoreUpgrades
}
31 changes: 31 additions & 0 deletions app/upgrades/v043/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package v043

import (
"github.com/CosmWasm/wasmd/app/upgrades"
store "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

// UpgradeName defines the on-chain upgrade name
const UpgradeName = "v0.43"

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: store.StoreUpgrades{
Added: []string{},
Deleted: []string{},
},
}

func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
ak *upgrades.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
return mm.RunMigrations(ctx, configurator, fromVM)
}
}
2 changes: 1 addition & 1 deletion cmd/wasmd/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ Example:

addTestnetFlagsToCmd(cmd)
cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)")
cmd.Flags().String(flagNodeDaemonHome, "wasmd", "Home directory of the node's daemon configuration")
cmd.Flags().String(flagNodeDaemonHome, version.AppName, "Home directory of the node's daemon configuration")
cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
cmd.Flags().Duration(flagCommitTimeout, 5*time.Second, "Time to wait after a block commit before starting on the new height")
Expand Down
4 changes: 2 additions & 2 deletions tests/system/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func (c WasmdCli) CustomCommand(args ...string) string {
if !ok {
return execOutput
}
rsp, committed := c.awaitTxCommitted(execOutput, defaultWaitTime)
rsp, committed := c.awaitTxCommitted(execOutput, DefaultWaitTime)
c.t.Logf("tx committed: %v", committed)
require.Equal(c.t, c.expTXCommitted, committed, "expected tx committed: %v", c.expTXCommitted)
return rsp
Expand Down Expand Up @@ -218,7 +218,7 @@ func (c WasmdCli) runWithInput(args []string, input io.Reader) (output string, o
err = fmt.Errorf("recovered from panic: %v", r)
}
}()
cmd := exec.Command(locateExecutable("wasmd"), args...) //nolint:gosec
cmd := exec.Command(locateExecutable(c.execBinary), args...) //nolint:gosec
cmd.Dir = WorkDir
cmd.Stdin = input
return cmd.CombinedOutput()
Expand Down
4 changes: 2 additions & 2 deletions tests/system/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var (

func TestMain(m *testing.M) {
rebuild := flag.Bool("rebuild", false, "rebuild artifacts")
waitTime := flag.Duration("wait-time", defaultWaitTime, "time to wait for chain events")
waitTime := flag.Duration("wait-time", DefaultWaitTime, "time to wait for chain events")
nodesCount := flag.Int("nodes-count", 4, "number of nodes in the cluster")
blockTime := flag.Duration("block-time", 1000*time.Millisecond, "block creation time")
execBinary := flag.String("binary", "wasmd", "executable binary for server/ client side")
Expand All @@ -48,7 +48,7 @@ func TestMain(m *testing.M) {
}
initSDKConfig(*bech32Prefix)

defaultWaitTime = *waitTime
DefaultWaitTime = *waitTime
if *execBinary == "" {
panic("executable binary name must not be empty")
}
Expand Down
10 changes: 5 additions & 5 deletions tests/system/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func (s *SystemUnderTest) AwaitChainStopped() {
func (s *SystemUnderTest) AwaitNodeUp(t *testing.T, rpcAddr string) {
t.Helper()
t.Logf("Await node is up: %s", rpcAddr)
timeout := defaultWaitTime
timeout := DefaultWaitTime
ctx, done := context.WithTimeout(context.Background(), timeout)
defer done()

Expand Down Expand Up @@ -745,7 +745,7 @@ func NewEventListener(t *testing.T, rpcAddr string) *EventListener {
return &EventListener{client: httpClient, t: t}
}

var defaultWaitTime = 30 * time.Second
var DefaultWaitTime = 30 * time.Second

type (
CleanupFn func()
Expand All @@ -760,7 +760,7 @@ func (l *EventListener) Subscribe(query string, cb EventConsumer) func() {
eventsChan, err := l.client.WSEvents.Subscribe(ctx, "testing", query)
require.NoError(l.t, err)
cleanup := func() {
ctx, _ := context.WithTimeout(ctx, defaultWaitTime) //nolint:govet
ctx, _ := context.WithTimeout(ctx, DefaultWaitTime) //nolint:govet
go l.client.WSEvents.Unsubscribe(ctx, "testing", query) //nolint:errcheck
done()
}
Expand All @@ -778,7 +778,7 @@ func (l *EventListener) Subscribe(query string, cb EventConsumer) func() {
// For query syntax See https://docs.cosmos.network/master/core/events.html#subscribing-to-events
func (l *EventListener) AwaitQuery(query string, optMaxWaitTime ...time.Duration) *ctypes.ResultEvent {
c, result := CaptureSingleEventConsumer()
maxWaitTime := defaultWaitTime
maxWaitTime := DefaultWaitTime
if len(optMaxWaitTime) != 0 {
maxWaitTime = optMaxWaitTime[0]
}
Expand Down Expand Up @@ -840,7 +840,7 @@ func CaptureSingleEventConsumer() (EventConsumer, *ctypes.ResultEvent) {
//
// assert.Len(t, done(), 1) // then verify your assumption
func CaptureAllEventsConsumer(t *testing.T, optMaxWaitTime ...time.Duration) (c EventConsumer, done func() []ctypes.ResultEvent) {
maxWaitTime := defaultWaitTime
maxWaitTime := DefaultWaitTime
if len(optMaxWaitTime) != 0 {
maxWaitTime = optMaxWaitTime[0]
}
Expand Down
8 changes: 6 additions & 2 deletions tests/system/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ func TestChainUpgrade(t *testing.T) {
votingPeriod := 10 * time.Second // enough time to vote
sut.ModifyGenesisJSON(t, SetGovVotingPeriod(t, votingPeriod))

const upgradeHeight int64 = 22
const (
upgradeHeight int64 = 22
upgradeName = "v0.43"
)

sut.StartChain(t, fmt.Sprintf("--halt-height=%d", upgradeHeight))

cli := NewWasmdCLI(t, sut, verbose)
Expand Down Expand Up @@ -67,7 +71,7 @@ func TestChainUpgrade(t *testing.T) {
"deposit": "100000000stake",
"title": "my upgrade",
"summary": "testing"
}`, "v0.43.x", upgradeHeight)
}`, upgradeName, upgradeHeight)
proposalID := cli.SubmitAndVoteGovProposal(proposal)
t.Logf("current_height: %d\n", sut.currentHeight)
raw := cli.CustomQuery("q", "gov", "proposal", proposalID)
Expand Down

0 comments on commit 32a01da

Please sign in to comment.