diff --git a/.github/workflows/docker-publish-and-E2E.yaml b/.github/workflows/docker-publish-and-E2E.yaml index 60afc50e..a4b8fba0 100644 --- a/.github/workflows/docker-publish-and-E2E.yaml +++ b/.github/workflows/docker-publish-and-E2E.yaml @@ -119,7 +119,7 @@ jobs: - name: checkout chain uses: actions/checkout@v2 - - run: make ictest-paramauthorityChainUpgrade + - run: make ictest-chain-upgrade env: BRANCH_CI: ${{needs.build-and-push-image.outputs.branchTag}} diff --git a/Makefile b/Makefile index 8b619e62..7ede2ebf 100644 --- a/Makefile +++ b/Makefile @@ -111,7 +111,7 @@ ictest-packet-forward: ictest-paramauthority: cd interchaintest && go test -race -v -run ^TestNobleParamAuthority$$ . -ictest-paramauthorityChainUpgrade: +ictest-chain-upgrade: cd interchaintest && go test -race -v -run ^TestNobleChainUpgrade$$ . ictest-globalFee: diff --git a/app/app.go b/app/app.go index d16df68e..c4957873 100644 --- a/app/app.go +++ b/app/app.go @@ -88,7 +88,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/strangelove-ventures/noble/app/upgrades/neon" + neon "github.com/strangelove-ventures/noble/app/upgrades/neon" + radon "github.com/strangelove-ventures/noble/app/upgrades/radon" "github.com/strangelove-ventures/noble/cmd" "github.com/strangelove-ventures/noble/docs" "github.com/strangelove-ventures/noble/x/blockibc" @@ -96,6 +97,7 @@ import ( fiattokenfactorymodulekeeper "github.com/strangelove-ventures/noble/x/fiattokenfactory/keeper" fiattokenfactorymoduletypes "github.com/strangelove-ventures/noble/x/fiattokenfactory/types" "github.com/strangelove-ventures/noble/x/globalfee" + globalfeetypes "github.com/strangelove-ventures/noble/x/globalfee/types" tariff "github.com/strangelove-ventures/noble/x/tariff" tariffkeeper "github.com/strangelove-ventures/noble/x/tariff/keeper" tarifftypes "github.com/strangelove-ventures/noble/x/tariff/types" @@ -843,6 +845,16 @@ func (app *App) setupUpgradeHandlers() { app.BankKeeper, app.AccountKeeper)) + // radon upgrade + app.UpgradeKeeper.SetUpgradeHandler( + radon.UpgradeName, + radon.CreateRadonUpgradeHandler( + app.mm, + app.configurator, + app.ParamsKeeper, + app.FiatTokenFactoryKeeper, + )) + upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() if err != nil { panic(fmt.Errorf("failed to read upgrade info from disk: %w", err)) @@ -858,6 +870,10 @@ func (app *App) setupUpgradeHandlers() { stroreUpgrades = &storetypes.StoreUpgrades{ Added: []string{fiattokenfactorymoduletypes.StoreKey}, } + case radon.UpgradeName: + stroreUpgrades = &storetypes.StoreUpgrades{ + Added: []string{globalfeetypes.ModuleName, tarifftypes.ModuleName}, + } } if stroreUpgrades != nil { diff --git a/app/upgrades/radon/constants.go b/app/upgrades/radon/constants.go new file mode 100644 index 00000000..68a2d9df --- /dev/null +++ b/app/upgrades/radon/constants.go @@ -0,0 +1,8 @@ +package radon + +const ( + // UpgradeName is the shared upgrade plan name for mainnet + UpgradeName = "radon" + // UpgradeInfo defines the binaries that will be used for the upgrade + UpgradeInfo = "Noble Radon Upgrade" +) diff --git a/app/upgrades/radon/upgrade.go b/app/upgrades/radon/upgrade.go new file mode 100644 index 00000000..74eb6172 --- /dev/null +++ b/app/upgrades/radon/upgrade.go @@ -0,0 +1,65 @@ +package radon + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + paramauthoritykeeper "github.com/strangelove-ventures/paramauthority/x/params/keeper" + + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + fiattokenfactorykeeper "github.com/strangelove-ventures/noble/x/fiattokenfactory/keeper" + globalfeetypes "github.com/strangelove-ventures/noble/x/globalfee/types" + + tarifftypes "github.com/strangelove-ventures/noble/x/tariff/types" +) + +func CreateRadonUpgradeHandler( + mm *module.Manager, + cfg module.Configurator, + paramauthoritykeeper paramauthoritykeeper.Keeper, + fiatTFKeeper *fiattokenfactorykeeper.Keeper, + +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + + // New modules run AFTER the migrations, so to set the correct params after the default + // becasuse RunMigrations runs `InitGenesis` on new modules`. + versionMap, err := mm.RunMigrations(ctx, cfg, vm) + + // -- globalfee params -- + minGasPrices := sdk.DecCoins{ + sdk.NewDecCoinFromDec("udrachma", sdk.NewDecWithPrec(1, 2)), + } + globlaFeeParamsSubspace, ok := paramauthoritykeeper.GetSubspace(globalfeetypes.ModuleName) + if !ok { + panic("global fee params subspace not found") + } + globlaFeeParamsSubspace.Set(ctx, globalfeetypes.ParamStoreKeyMinGasPrices, minGasPrices) + // -- -- + + // -- tariff params -- + tariffParamsSubspace, ok := paramauthoritykeeper.GetSubspace(tarifftypes.ModuleName) + if !ok { + panic("tariff params subspace not found") + } + paramAuth := paramauthoritykeeper.GetAuthority(ctx) + distributionEntities := []tarifftypes.DistributionEntity{ + { + Address: paramAuth, + Share: sdk.NewDec(1), + }, + } + feeDenom := fiatTFKeeper.GetMintingDenom(ctx) + tariffParams := tarifftypes.Params{ + Share: sdk.NewDecWithPrec(8, 1), + DistributionEntities: distributionEntities, + TransferFeeBps: sdk.OneInt(), + TransferFeeMax: sdk.NewInt(5000000), + TransferFeeDenom: feeDenom.Denom, + } + tariffParamsSubspace.SetParamSet(ctx, &tariffParams) + // -- -- + + return versionMap, err + } +} diff --git a/interchaintest/upgrade_test.go b/interchaintest/upgrade_test.go new file mode 100644 index 00000000..96767a86 --- /dev/null +++ b/interchaintest/upgrade_test.go @@ -0,0 +1,371 @@ +package interchaintest_test + +import ( + "context" + "encoding/json" + "fmt" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkupgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + interchaintest "github.com/strangelove-ventures/interchaintest/v3" + "github.com/strangelove-ventures/interchaintest/v3/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v3/ibc" + "github.com/strangelove-ventures/interchaintest/v3/testreporter" + "github.com/strangelove-ventures/interchaintest/v3/testutil" + "github.com/strangelove-ventures/noble/cmd" + integration "github.com/strangelove-ventures/noble/interchaintest" + fiattokenfactorytypes "github.com/strangelove-ventures/noble/x/fiattokenfactory/types" + globalfeetypes "github.com/strangelove-ventures/noble/x/globalfee/types" + upgradetypes "github.com/strangelove-ventures/paramauthority/x/upgrade/types" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zaptest" +) + +const ( + haltHeightDelta = uint64(10) // will propose upgrade this many blocks in the future + blocksAfterUpgrade = uint64(10) +) + +type ParamsQueryResponse struct { + Subspace string `json:"subspace"` + Key string `json:"key"` + Value string `json:"value"` +} + +func TestNobleChainUpgrade(t *testing.T) { + if testing.Short() { + t.Skip() + } + + t.Parallel() + + ctx := context.Background() + + rep := testreporter.NewNopReporter() + eRep := rep.RelayerExecReporter(t) + + client, network := interchaintest.DockerSetup(t) + + repo, version := integration.GetDockerImageInfo() + + var noble *cosmos.CosmosChain + var roles NobleRoles + var paramauthorityWallet Authority + + var ( + upgradeName = "v0.4.1" + preUpgradeRepo = "ghcr.io/strangelove-ventures/noble" + preUpgradeVersion = "v0.3.0" + ) + + chainCfg := ibc.ChainConfig{ + Type: "cosmos", + Name: "noble", + ChainID: "noble-1", + Bin: "nobled", + Denom: "token", + Bech32Prefix: "noble", + CoinType: "118", + GasPrices: "0.0token", + GasAdjustment: 1.1, + TrustingPeriod: "504h", + NoHostMount: false, + Images: []ibc.DockerImage{ + { + Repository: preUpgradeRepo, + Version: preUpgradeVersion, + UidGid: "1025:1025", + }, + }, + EncodingConfig: NobleEncoding(), + PreGenesis: func(cc ibc.ChainConfig) error { + val := noble.Validators[0] + err := createTokenfactoryRoles(ctx, &roles, DenomMetadata_rupee, val, true) + if err != nil { + return err + } + paramauthorityWallet, err = createParamAuthAtGenesis(ctx, val) + return err + }, + ModifyGenesis: func(cc ibc.ChainConfig, b []byte) ([]byte, error) { + g := make(map[string]interface{}) + if err := json.Unmarshal(b, &g); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis file: %w", err) + } + if err := modifyGenesisTokenfactory(g, "tokenfactory", DenomMetadata_rupee, &roles, true); err != nil { + return nil, err + } + if err := modifyGenesisParamAuthority(g, paramauthorityWallet.Authority.Address); err != nil { + return nil, err + } + out, err := json.Marshal(&g) + if err != nil { + return nil, fmt.Errorf("failed to marshal genesis bytes to json: %w", err) + } + return out, nil + }, + } + + nv := 2 + nf := 0 + + logger := zaptest.NewLogger(t) + + cf := interchaintest.NewBuiltinChainFactory(logger, []*interchaintest.ChainSpec{ + { + ChainConfig: chainCfg, + NumValidators: &nv, + NumFullNodes: &nf, + }, + }) + + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + + noble = chains[0].(*cosmos.CosmosChain) + + ic := interchaintest.NewInterchain(). + AddChain(noble) + + require.NoError(t, ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ + TestName: t.Name(), + Client: client, + NetworkID: network, + BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + + SkipPathCreation: false, + })) + t.Cleanup(func() { + _ = ic.Close() + }) + + height, err := noble.Height(ctx) + require.NoError(t, err, "error fetching height before submit upgrade proposal") + + haltHeight := height + haltHeightDelta + + cmd.SetPrefixes(chainCfg.Bech32Prefix) + + broadcaster := cosmos.NewBroadcaster(t, noble) + + upgradePlan := sdkupgradetypes.Plan{ + Name: upgradeName, + Height: int64(haltHeight), + Info: upgradeName + " chain upgrade", + } + + decoded := sdk.MustAccAddressFromBech32(paramauthorityWallet.Authority.Address) + wallet := &ibc.Wallet{ + Address: string(decoded), + Mnemonic: paramauthorityWallet.Authority.Mnemonic, + KeyName: paramauthorityWallet.Authority.KeyName, + CoinType: paramauthorityWallet.Authority.CoinType, + } + + _, err = cosmos.BroadcastTx( + ctx, + broadcaster, + wallet, + &upgradetypes.MsgSoftwareUpgrade{ + Authority: paramauthorityWallet.Authority.Address, + Plan: upgradePlan, + }, + ) + require.NoError(t, err, "error submitting software upgrade tx") + + stdout, stderr, err := noble.Validators[0].ExecQuery(ctx, "upgrade", "plan") + require.NoError(t, err, "error submitting software upgrade tx") + + logger.Debug("Upgrade", zap.String("plan_stdout", string(stdout)), zap.String("plan_stderr", string(stderr))) + + timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Second*45) + defer timeoutCtxCancel() + + height, err = noble.Height(ctx) + require.NoError(t, err, "error fetching height before upgrade") + + // this should timeout due to chain halt at upgrade height. + _ = testutil.WaitForBlocks(timeoutCtx, int(haltHeight-height)+1, noble) + + height, err = noble.Height(ctx) + require.NoError(t, err, "error fetching height after chain should have halted") + + // make sure that chain is halted + require.Equal(t, haltHeight, height, "height is not equal to halt height") + + // bring down nodes to prepare for upgrade + err = noble.StopAllNodes(ctx) + require.NoError(t, err, "error stopping node(s)") + + noble.UpgradeVersion(ctx, client, "v0.4.2") + + // start all nodes back up. + // validators reach consensus on first block after upgrade height + // and chain block production resumes. + err = noble.StartAllNodes(ctx) + require.NoError(t, err, "error starting upgraded node(s)") + + timeoutCtx, timeoutCtxCancel = context.WithTimeout(ctx, time.Second*45) + defer timeoutCtxCancel() + + err = testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble) + require.NoError(t, err, "chain did not produce blocks after upgrade") + + height, err = noble.Height(ctx) + require.NoError(t, err, "error fetching height after upgrade") + + require.GreaterOrEqual(t, height, haltHeight+blocksAfterUpgrade, "height did not increment enough after upgrade") + + height, err = noble.Height(ctx) + require.NoError(t, err, "error fetching height before submit upgrade proposal") + + haltHeight = height + haltHeightDelta + + upgradeName = "radon" + + upgradePlan = sdkupgradetypes.Plan{ + Name: upgradeName, + Height: int64(haltHeight), + Info: upgradeName + " chain upgrade", + } + + _, err = cosmos.BroadcastTx( + ctx, + broadcaster, + wallet, + &upgradetypes.MsgSoftwareUpgrade{ + Authority: paramauthorityWallet.Authority.Address, + Plan: upgradePlan, + }, + ) + require.NoError(t, err, "error submitting software upgrade tx") + + stdout, stderr, err = noble.Validators[0].ExecQuery(ctx, "upgrade", "plan") + require.NoError(t, err, "error submitting software upgrade tx") + + logger.Debug("Upgrade", zap.String("plan_stdout", string(stdout)), zap.String("plan_stderr", string(stderr))) + + timeoutCtx, timeoutCtxCancel = context.WithTimeout(ctx, time.Second*45) + defer timeoutCtxCancel() + + height, err = noble.Height(ctx) + require.NoError(t, err, "error fetching height before upgrade") + + // this should timeout due to chain halt at upgrade height. + _ = testutil.WaitForBlocks(timeoutCtx, int(haltHeight-height)+1, noble) + + height, err = noble.Height(ctx) + require.NoError(t, err, "error fetching height after chain should have halted") + + // make sure that chain is halted + require.Equal(t, haltHeight, height, "height is not equal to halt height") + + // bring down nodes to prepare for upgrade + err = noble.StopAllNodes(ctx) + require.NoError(t, err, "error stopping node(s)") + + // upgrade version and repo on all nodes + for _, n := range noble.Nodes() { + n.Image.Repository = repo + } + noble.UpgradeVersion(ctx, client, version) + + // start all nodes back up. + // validators reach consensus on first block after upgrade height + // and chain block production resumes. + err = noble.StartAllNodes(ctx) + require.NoError(t, err, "error starting upgraded node(s)") + + timeoutCtx, timeoutCtxCancel = context.WithTimeout(ctx, time.Second*45) + defer timeoutCtxCancel() + + err = testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble) + require.NoError(t, err, "chain did not produce blocks after upgrade") + + height, err = noble.Height(ctx) + require.NoError(t, err, "error fetching height after upgrade") + + require.GreaterOrEqual(t, height, haltHeight+blocksAfterUpgrade, "height did not increment enough after upgrade") + + queryResult, _, err := noble.Validators[0].ExecQuery(ctx, "globalfee", "parameters") + require.NoError(t, err, "error querying globalfee params") + + var globalFeeParams globalfeetypes.Params + err = json.Unmarshal(queryResult, &globalFeeParams) + require.NoError(t, err, "failed to unmarshall globalfee params") + + expectedMinGasPrices := sdk.DecCoins{ + sdk.NewDecCoinFromDec("udrachma", sdk.NewDecWithPrec(1, 2)), + } + require.Equal(t, expectedMinGasPrices, globalFeeParams.MinimumGasPrices, "global fee min gas prices are not as expected") + + expectedDefaultMsgTypes := globalfeetypes.DefaultParams().BypassMinFeeMsgTypes + require.Equal(t, expectedDefaultMsgTypes, globalFeeParams.BypassMinFeeMsgTypes, "global fee bypass message types are not as expected") + + queryResult, _, err = noble.Validators[0].ExecQuery(ctx, "params", "subspace", "tariff", "Share") + require.NoError(t, err, "error querying tariff 'Share' param") + + var tariffParamShare ParamsQueryResponse + + err = json.Unmarshal(queryResult, &tariffParamShare) + require.NoError(t, err, "failed to unmarshall tariff share param") + + require.Equal(t, `"`+sdk.NewDecWithPrec(8, 1).String()+`"`, tariffParamShare.Value) + + queryResult, _, err = noble.Validators[0].ExecQuery(ctx, "params", "subspace", "tariff", "DistributionEntities") + require.NoError(t, err, "error querying tariff 'DistributionEntities' param") + + var tariffParamDistributionentities ParamsQueryResponse + + err = json.Unmarshal(queryResult, &tariffParamDistributionentities) + require.NoError(t, err, "failed to unmarshall tariff DistributionEntities param") + + var distributionEntities []DistributionEntity + + err = json.Unmarshal([]byte(tariffParamDistributionentities.Value), &distributionEntities) + require.NoError(t, err, "failed to unmarshall tariff distribution_entities param") + require.Len(t, distributionEntities, 1) + require.Equal(t, paramauthorityWallet.Authority.Address, distributionEntities[0].Address) + require.Equal(t, sdk.OneDec().String(), distributionEntities[0].Share) + require.Equal(t, `"`+sdk.NewDecWithPrec(8, 1).String()+`"`, tariffParamShare.Value) + + queryResult, _, err = noble.Validators[0].ExecQuery(ctx, "params", "subspace", "tariff", "TransferFeeBPS") + require.NoError(t, err, "failed to unmarshall tariff TransferFeeBPS param") + + var tariffParamTransferFeeBPS ParamsQueryResponse + + err = json.Unmarshal(queryResult, &tariffParamTransferFeeBPS) + require.NoError(t, err, "failed to unmarshall tariff transfer fee BPS param") + + require.Equal(t, `"`+sdk.OneInt().String()+`"`, tariffParamTransferFeeBPS.Value) + + queryResult, _, err = noble.Validators[0].ExecQuery(ctx, "params", "subspace", "tariff", "TransferFeeMax") + require.NoError(t, err, "failed to unmarshall tariff TransferFeeMax param") + + var tariffParamTransferFeeMax ParamsQueryResponse + + err = json.Unmarshal(queryResult, &tariffParamTransferFeeMax) + require.NoError(t, err, "failed to unmarshall tariff transfer fee BPS param") + + require.Equal(t, `"`+sdk.NewInt(5000000).String()+`"`, tariffParamTransferFeeMax.Value) + + queryResult, _, err = noble.Validators[0].ExecQuery(ctx, "params", "subspace", "tariff", "TransferFeeDenom") + require.NoError(t, err, "failed to unmarshall tariff TransferFeeDenom param") + + var tariffParamTransferFeeDenom ParamsQueryResponse + + err = json.Unmarshal(queryResult, &tariffParamTransferFeeDenom) + require.NoError(t, err, "failed to unmarshall tariff transfer fee BPS param") + + queryResult, _, err = noble.Validators[0].ExecQuery(ctx, "fiat-tokenfactory", "show-minting-denom") + require.NoError(t, err, "failed to query minting denom") + var mintingDenom fiattokenfactorytypes.QueryGetMintingDenomResponse + + err = json.Unmarshal(queryResult, &mintingDenom) + require.NoError(t, err, "failed to unmarshall minting denom") + + require.Equal(t, `"`+mintingDenom.MintingDenom.Denom+`"`, tariffParamTransferFeeDenom.Value) +} diff --git a/interchaintest/upgradeauthority_test.go b/interchaintest/upgradeauthority_test.go deleted file mode 100644 index 493c267b..00000000 --- a/interchaintest/upgradeauthority_test.go +++ /dev/null @@ -1,218 +0,0 @@ -package interchaintest_test - -import ( - "context" - "encoding/json" - "fmt" - "testing" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkupgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - interchaintest "github.com/strangelove-ventures/interchaintest/v3" - "github.com/strangelove-ventures/interchaintest/v3/chain/cosmos" - "github.com/strangelove-ventures/interchaintest/v3/ibc" - "github.com/strangelove-ventures/interchaintest/v3/testreporter" - "github.com/strangelove-ventures/interchaintest/v3/testutil" - "github.com/strangelove-ventures/noble/cmd" - integration "github.com/strangelove-ventures/noble/interchaintest" - upgradetypes "github.com/strangelove-ventures/paramauthority/x/upgrade/types" - "github.com/stretchr/testify/require" - "go.uber.org/zap" - "go.uber.org/zap/zaptest" -) - -const ( - haltHeightDelta = uint64(10) // will propose upgrade this many blocks in the future - blocksAfterUpgrade = uint64(10) -) - -func TestNobleChainUpgrade(t *testing.T) { - if testing.Short() { - t.Skip() - } - - t.Parallel() - - ctx := context.Background() - - rep := testreporter.NewNopReporter() - eRep := rep.RelayerExecReporter(t) - - client, network := interchaintest.DockerSetup(t) - - repo, version := integration.GetDockerImageInfo() - - var noble *cosmos.CosmosChain - var roles NobleRoles - var paramauthorityWallet Authority - - const ( - upgradeName = "v0.4.1" - preUpgradeRepo = "ghcr.io/strangelove-ventures/noble" - preUpgradeVersion = "v0.3.0" - ) - - chainCfg := ibc.ChainConfig{ - Type: "cosmos", - Name: "noble", - ChainID: "noble-1", - Bin: "nobled", - Denom: "token", - Bech32Prefix: "noble", - CoinType: "118", - GasPrices: "0.0token", - GasAdjustment: 1.1, - TrustingPeriod: "504h", - NoHostMount: false, - Images: []ibc.DockerImage{ - { - Repository: preUpgradeRepo, - Version: preUpgradeVersion, - UidGid: "1025:1025", - }, - }, - EncodingConfig: NobleEncoding(), - PreGenesis: func(cc ibc.ChainConfig) error { - val := noble.Validators[0] - err := createTokenfactoryRoles(ctx, &roles, DenomMetadata_rupee, val, true) - if err != nil { - return err - } - paramauthorityWallet, err = createParamAuthAtGenesis(ctx, val) - return err - }, - ModifyGenesis: func(cc ibc.ChainConfig, b []byte) ([]byte, error) { - g := make(map[string]interface{}) - if err := json.Unmarshal(b, &g); err != nil { - return nil, fmt.Errorf("failed to unmarshal genesis file: %w", err) - } - if err := modifyGenesisTokenfactory(g, "tokenfactory", DenomMetadata_rupee, &roles, true); err != nil { - return nil, err - } - if err := modifyGenesisParamAuthority(g, paramauthorityWallet.Authority.Address); err != nil { - return nil, err - } - out, err := json.Marshal(&g) - if err != nil { - return nil, fmt.Errorf("failed to marshal genesis bytes to json: %w", err) - } - return out, nil - }, - } - - nv := 2 - nf := 0 - - logger := zaptest.NewLogger(t) - - cf := interchaintest.NewBuiltinChainFactory(logger, []*interchaintest.ChainSpec{ - { - ChainConfig: chainCfg, - NumValidators: &nv, - NumFullNodes: &nf, - }, - }) - - chains, err := cf.Chains(t.Name()) - require.NoError(t, err) - - noble = chains[0].(*cosmos.CosmosChain) - - ic := interchaintest.NewInterchain(). - AddChain(noble) - - require.NoError(t, ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ - TestName: t.Name(), - Client: client, - NetworkID: network, - BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), - - SkipPathCreation: false, - })) - t.Cleanup(func() { - _ = ic.Close() - }) - - height, err := noble.Height(ctx) - require.NoError(t, err, "error fetching height before submit upgrade proposal") - - haltHeight := height + haltHeightDelta - - cmd.SetPrefixes(chainCfg.Bech32Prefix) - - broadcaster := cosmos.NewBroadcaster(t, noble) - - upgradePlan := sdkupgradetypes.Plan{ - Name: upgradeName, - Height: int64(haltHeight), - Info: upgradeName + " chain upgrade", - } - - decoded := sdk.MustAccAddressFromBech32(paramauthorityWallet.Authority.Address) - wallet := &ibc.Wallet{ - Address: string(decoded), - Mnemonic: paramauthorityWallet.Authority.Mnemonic, - KeyName: paramauthorityWallet.Authority.KeyName, - CoinType: paramauthorityWallet.Authority.CoinType, - } - - _, err = cosmos.BroadcastTx( - ctx, - broadcaster, - wallet, - &upgradetypes.MsgSoftwareUpgrade{ - Authority: paramauthorityWallet.Authority.Address, - Plan: upgradePlan, - }, - ) - require.NoError(t, err, "error submitting software upgrade tx") - - stdout, stderr, err := noble.Validators[0].ExecQuery(ctx, "upgrade", "plan") - require.NoError(t, err, "error submitting software upgrade tx") - - logger.Debug("Upgrade", zap.String("plan_stdout", string(stdout)), zap.String("plan_stderr", string(stderr))) - - timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Second*45) - defer timeoutCtxCancel() - - height, err = noble.Height(ctx) - require.NoError(t, err, "error fetching height before upgrade") - - // this should timeout due to chain halt at upgrade height. - _ = testutil.WaitForBlocks(timeoutCtx, int(haltHeight-height)+1, noble) - - height, err = noble.Height(ctx) - require.NoError(t, err, "error fetching height after chain should have halted") - - // make sure that chain is halted - require.Equal(t, haltHeight, height, "height is not equal to halt height") - - // bring down nodes to prepare for upgrade - err = noble.StopAllNodes(ctx) - require.NoError(t, err, "error stopping node(s)") - - // upgrade version and repo on all nodes - for _, n := range noble.Nodes() { - n.Image.Repository = repo - } - noble.UpgradeVersion(ctx, client, version) - - // start all nodes back up. - // validators reach consensus on first block after upgrade height - // and chain block production resumes. - err = noble.StartAllNodes(ctx) - require.NoError(t, err, "error starting upgraded node(s)") - - timeoutCtx, timeoutCtxCancel = context.WithTimeout(ctx, time.Second*45) - defer timeoutCtxCancel() - - err = testutil.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), noble) - require.NoError(t, err, "chain did not produce blocks after upgrade") - - height, err = noble.Height(ctx) - require.NoError(t, err, "error fetching height after upgrade") - - require.GreaterOrEqual(t, height, haltHeight+blocksAfterUpgrade, "height did not increment enough after upgrade") - -}