From 80ad0a7a7159bde70bc7aeae8f62bead8bcc3f11 Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Tue, 6 Aug 2024 12:25:20 +0200 Subject: [PATCH 01/11] Remove legacy-submit-proposal consumer-addition --- app/provider/app.go | 2 - tests/e2e/actions.go | 108 ++++++++++-------- tests/e2e/state.go | 4 +- tests/integration/provider_gov_hooks.go | 40 ++++--- testutil/integration/debug_test.go | 12 +- testutil/keeper/unit_test_helpers.go | 24 ++++ .../client/legacy_proposal_handler.go | 91 --------------- x/ccv/provider/keeper/hooks.go | 45 +++++--- x/ccv/provider/types/codec.go | 4 +- 9 files changed, 144 insertions(+), 186 deletions(-) diff --git a/app/provider/app.go b/app/provider/app.go index 214d191b71..d0ecfb8c3b 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -144,7 +144,6 @@ var ( gov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - ibcproviderclient.ConsumerAdditionProposalHandler, ibcproviderclient.ConsumerRemovalProposalHandler, ibcproviderclient.ConsumerModificationProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, @@ -579,7 +578,6 @@ func New( govtypes.ModuleName: gov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - ibcproviderclient.ConsumerAdditionProposalHandler, ibcproviderclient.ConsumerRemovalProposalHandler, ibcproviderclient.ConsumerModificationProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 2efd0b69e7..50cf987ce4 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "encoding/base64" "encoding/json" "fmt" "log" @@ -273,57 +274,74 @@ func (tr Chain) submitConsumerAdditionProposal( ) { spawnTime := tr.testConfig.containerConfig.Now.Add(time.Duration(action.SpawnTime) * time.Millisecond) params := ccvtypes.DefaultParams() - prop := client.ConsumerAdditionProposalJSON{ - Title: "Propose the addition of a new chain", - Summary: "Gonna be a great chain", - ChainId: string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), - InitialHeight: action.InitialHeight, - GenesisHash: []byte("gen_hash"), - BinaryHash: []byte("bin_hash"), - SpawnTime: spawnTime, - ConsumerRedistributionFraction: params.ConsumerRedistributionFraction, - BlocksPerDistributionTransmission: params.BlocksPerDistributionTransmission, - HistoricalEntries: params.HistoricalEntries, - CcvTimeoutPeriod: params.CcvTimeoutPeriod, - TransferTimeoutPeriod: params.TransferTimeoutPeriod, - UnbondingPeriod: params.UnbondingPeriod, - Deposit: fmt.Sprint(action.Deposit) + `stake`, - DistributionTransmissionChannel: action.DistributionChannel, - TopN: action.TopN, - ValidatorsPowerCap: action.ValidatorsPowerCap, - ValidatorSetCap: action.ValidatorSetCap, - Allowlist: action.Allowlist, - Denylist: action.Denylist, - MinStake: action.MinStake, - AllowInactiveVals: action.AllowInactiveVals, - } - - bz, err := json.Marshal(prop) - if err != nil { - log.Fatal(err) - } - - jsonStr := string(bz) - if strings.Contains(jsonStr, "'") { - log.Fatal("prop json contains single quote") - } + template := ` + { + "messages": [ + { + "@type": "/interchain_security.ccv.provider.v1.MsgConsumerAddition", + "chain_id": "%s", + "initial_height": { + "revision_number": "%d", + "revision_height": "%d" + }, + "genesis_hash": "%s", + "binary_hash": "%s", + "spawn_time": "%s", + "unbonding_period": "%s", + "ccv_timeout_period": "%s", + "transfer_timeout_period": "%s", + "consumer_redistribution_fraction": "%s", + "blocks_per_distribution_transmission": "%d", + "historical_entries": "%d", + "distribution_transmission_channel": "%s", + "top_N": %d, + "validators_power_cap": %d, + "validator_set_cap": %d, + "allowlist": %s, + "denylist": %s, + "authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn" + } + ], +"metadata": "ipfs://CID", +"deposit": "%dstake", +"title": "Propose the addition of a new chain", +"summary": "Gonna be a great chain", +"expedited": false +}` + jsonStr := fmt.Sprintf(template, + string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), + action.InitialHeight.RevisionNumber, + action.InitialHeight.RevisionHeight, + base64.StdEncoding.EncodeToString([]byte("gen_hash")), + base64.StdEncoding.EncodeToString([]byte("bin_hash")), + spawnTime.Local().Format(time.RFC3339Nano), + params.UnbondingPeriod, + params.CcvTimeoutPeriod, + params.TransferTimeoutPeriod, + params.ConsumerRedistributionFraction, + params.BlocksPerDistributionTransmission, + params.HistoricalEntries, + action.DistributionChannel, + action.TopN, + action.ValidatorsPowerCap, + action.ValidatorSetCap, + action.Allowlist, + action.Denylist, + action.Deposit) //#nosec G204 -- bypass unsafe quoting warning (no production code) - cmd := tr.target.ExecCommand( - "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json")) - bz, err = cmd.CombinedOutput() - if verbose { - log.Println("submitConsumerAdditionProposal cmd: ", cmd.String()) - } - + proposalFile := "/consumer-addition.proposal" + bz, err := tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, proposalFile), + ).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } // CONSUMER ADDITION PROPOSAL - cmd = tr.target.ExecCommand( + cmd := tr.target.ExecCommand( tr.testConfig.chainConfigs[action.Chain].BinaryName, - "tx", "gov", "submit-legacy-proposal", "consumer-addition", "/temp-proposal.json", + "tx", "gov", "submit-proposal", proposalFile, `--from`, `validator`+fmt.Sprint(action.From), `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), @@ -339,7 +357,7 @@ func (tr Chain) submitConsumerAdditionProposal( } bz, err = cmd.CombinedOutput() if err != nil { - log.Fatal(err, "\n", string(bz)) + log.Fatal("submit-proposal failed:", err, "\n", string(bz)) } if verbose { @@ -347,7 +365,7 @@ func (tr Chain) submitConsumerAdditionProposal( } // wait for inclusion in a block -> '--broadcast-mode block' is deprecated - tr.waitBlocks(ChainID("provi"), 2, 10*time.Second) + tr.waitBlocks(action.Chain, 2, 10*time.Second) } type SubmitConsumerRemovalProposalAction struct { diff --git a/tests/e2e/state.go b/tests/e2e/state.go index fba5e36c3a..a9864123ac 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -465,7 +465,7 @@ func (tr Commands) GetProposal(chain ChainID, proposal uint) Proposal { Title: title, Description: description, } - case "/interchain_security.ccv.provider.v1.ConsumerAdditionProposal": + case "/interchain_security.ccv.provider.v1.MsgConsumerAddition": chainId := rawContent.Get("chain_id").String() spawnTime := rawContent.Get("spawn_time").Time().Sub(tr.containerConfig.Now) @@ -555,7 +555,7 @@ func (tr Commands) GetProposal(chain ChainID, proposal uint) Proposal { } } - log.Fatal("received unknown proposal type: ", propType, "proposal JSON:", propRaw) + log.Fatal("received unknown proposal type: '", propType, "', proposal JSON:", propRaw) return nil } diff --git a/tests/integration/provider_gov_hooks.go b/tests/integration/provider_gov_hooks.go index e3f9cc8ace..6fe5260b17 100644 --- a/tests/integration/provider_gov_hooks.go +++ b/tests/integration/provider_gov_hooks.go @@ -21,15 +21,9 @@ func (s *CCVTestSuite) TestAfterPropSubmissionAndVotingPeriodEnded() { govKeeper := s.providerApp.GetTestGovKeeper() proposer := s.providerChain.SenderAccount - content := testkeeper.GetTestConsumerAdditionProp() - content.ChainId = "newchain-0" - legacyPropContent, err := v1.NewLegacyContent( - content, - authtypes.NewModuleAddress("gov").String(), - ) - s.Require().NoError(err) + addConsumerProp := testkeeper.GetTestMsgConsumerAddition() - proposal, err := v1.NewProposal([]sdk.Msg{legacyPropContent}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", proposer.GetAddress(), false) + proposal, err := v1.NewProposal([]sdk.Msg{&addConsumerProp}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", proposer.GetAddress(), false) s.Require().NoError(err) err = govKeeper.SetProposal(ctx, proposal) @@ -41,14 +35,14 @@ func (s *CCVTestSuite) TestAfterPropSubmissionAndVotingPeriodEnded() { proposalIdOnProvider, ok := providerKeeper.GetProposedConsumerChain(ctx, proposal.Id) s.Require().True(ok) s.Require().NotEmpty(proposalIdOnProvider) - s.Require().Equal(content.ChainId, proposalIdOnProvider) + s.Require().Equal(addConsumerProp.ChainId, proposalIdOnProvider) providerKeeper.Hooks().AfterProposalVotingPeriodEnded(ctx, proposal.Id) // verify that the proposal ID is deleted s.Require().Empty(providerKeeper.GetProposedConsumerChain(ctx, proposal.Id)) } -func (s *CCVTestSuite) TestGetConsumerAdditionLegacyPropFromProp() { +func (s *CCVTestSuite) TestGetConsumerAdditionFromProp() { ctx := s.providerChain.GetContext() proposer := s.providerChain.SenderAccount @@ -59,13 +53,19 @@ func (s *CCVTestSuite) TestGetConsumerAdditionLegacyPropFromProp() { Amount: sdk.NewCoins(sdk.NewCoin("stake", math.OneInt())), } + // create a legacy proposal textProp, err := v1.NewLegacyContent( v1beta1.NewTextProposal("a title", "a legacy text prop"), authtypes.NewModuleAddress("gov").String(), ) s.Require().NoError(err) - addConsumerProp, err := v1.NewLegacyContent( + // create a valid consumer addition proposal + addConsumerProp := testkeeper.GetTestMsgConsumerAddition() + + // create a legacy consumer addition proposal content + // (not supported anymore) + addConsumerPropLegacy, err := v1.NewLegacyContent( testkeeper.GetTestConsumerAdditionProp(), authtypes.NewModuleAddress("gov").String(), ) @@ -84,7 +84,7 @@ func (s *CCVTestSuite) TestGetConsumerAdditionLegacyPropFromProp() { expPanic: false, }, { - name: "msgs in prop contain no legacy props", + name: "msgs in prop contain no consumer addition props", propMsg: dummyMsg, expectConsumerPropFound: false, expPanic: false, @@ -98,11 +98,17 @@ func (s *CCVTestSuite) TestGetConsumerAdditionLegacyPropFromProp() { name: "msgs contain an invalid legacy prop", propMsg: &v1.MsgExecLegacyContent{}, expectConsumerPropFound: false, - expPanic: true, + expPanic: false, + }, + { + name: "msg contains a prop of legacy ConsumerAdditionProposal type - hook should NOT create a new proposed chain", + propMsg: addConsumerPropLegacy, + expectConsumerPropFound: false, + expPanic: false, }, { - name: "msg contains a prop of ConsumerAdditionProposal type - hook should create a new proposed chain", - propMsg: addConsumerProp, + name: "msg contains a prop of legacy ConsumerAdditionProposal type - hook should create a new proposed chain", + propMsg: &addConsumerProp, expectConsumerPropFound: true, expPanic: false, }, @@ -132,12 +138,12 @@ func (s *CCVTestSuite) TestGetConsumerAdditionLegacyPropFromProp() { if tc.expPanic { s.Require().Panics(func() { // this panics with a nil pointer dereference because the proposal is invalid and cannot be unmarshalled - providerKeeper.Hooks().GetConsumerAdditionLegacyPropFromProp(ctx, proposal.Id) + providerKeeper.Hooks().GetConsumerAdditionFromProp(ctx, proposal.Id) }) return } - savedProp, found := providerKeeper.Hooks().GetConsumerAdditionLegacyPropFromProp(ctx, proposal.Id) + savedProp, found := providerKeeper.Hooks().GetConsumerAdditionFromProp(ctx, proposal.Id) if tc.expectConsumerPropFound { s.Require().True(found) s.Require().NotEmpty(savedProp, savedProp) diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index 022cc71429..dedd937eaa 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -265,8 +265,8 @@ func TestAfterPropSubmissionAndVotingPeriodEnded(t *testing.T) { runCCVTestByName(t, "TestAfterPropSubmissionAndVotingPeriodEnded") } -func TestGetConsumerAdditionLegacyPropFromProp(t *testing.T) { - runCCVTestByName(t, "TestGetConsumerAdditionLegacyPropFromProp") +func TestGetConsumerAdditionFromProp(t *testing.T) { + runCCVTestByName(t, "TestGetConsumerAdditionFromProp") } func TestIBCTransferMiddleware(t *testing.T) { @@ -277,14 +277,6 @@ func TestAllocateTokens(t *testing.T) { runCCVTestByName(t, "TestAllocateTokens") } -func TestTransferConsumerRewardsToDistributionModule(t *testing.T) { - runCCVTestByName(t, "TransferConsumerRewardsToDistributionModule") -} - -func TestAllocateTokensToValidator(t *testing.T) { - runCCVTestByName(t, "TestAllocateTokensToValidator") -} - func TestMultiConsumerRewardsDistribution(t *testing.T) { runCCVTestByName(t, "TestMultiConsumerRewardsDistribution") } diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index 72a59a1207..0ac48f8e6c 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -2,6 +2,7 @@ package keeper import ( "crypto/rand" + "encoding/base64" "encoding/binary" "testing" "time" @@ -293,6 +294,29 @@ func GetTestConsumerAdditionProp() *providertypes.ConsumerAdditionProposal { return prop } +func GetTestMsgConsumerAddition() providertypes.MsgConsumerAddition { + return providertypes.MsgConsumerAddition{ + ChainId: "a ChainID", + InitialHeight: clienttypes.NewHeight(4, 5), + GenesisHash: []byte(base64.StdEncoding.EncodeToString([]byte("gen_hash"))), + BinaryHash: []byte(base64.StdEncoding.EncodeToString([]byte("bin_hash"))), + SpawnTime: time.Now(), + UnbondingPeriod: types.DefaultConsumerUnbondingPeriod, + CcvTimeoutPeriod: types.DefaultCCVTimeoutPeriod, + TransferTimeoutPeriod: types.DefaultTransferTimeoutPeriod, + ConsumerRedistributionFraction: types.DefaultConsumerRedistributeFrac, + BlocksPerDistributionTransmission: types.DefaultBlocksPerDistributionTransmission, + HistoricalEntries: types.DefaultHistoricalEntries, + DistributionTransmissionChannel: "", + Top_N: 10, + ValidatorsPowerCap: 0, + ValidatorSetCap: 0, + Allowlist: nil, + Denylist: nil, + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + } +} + // Obtains a CrossChainValidator with a newly generated key, and randomized field values func GetNewCrossChainValidator(t *testing.T) consumertypes.CrossChainValidator { t.Helper() diff --git a/x/ccv/provider/client/legacy_proposal_handler.go b/x/ccv/provider/client/legacy_proposal_handler.go index 6a792ef4b0..cd301dcad6 100644 --- a/x/ccv/provider/client/legacy_proposal_handler.go +++ b/x/ccv/provider/client/legacy_proposal_handler.go @@ -15,102 +15,11 @@ import ( ) var ( - ConsumerAdditionProposalHandler = govclient.NewProposalHandler(SubmitConsumerAdditionPropTxCmd) ConsumerRemovalProposalHandler = govclient.NewProposalHandler(SubmitConsumerRemovalProposalTxCmd) ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) ConsumerModificationProposalHandler = govclient.NewProposalHandler(SubmitConsumerModificationProposalTxCmd) ) -// SubmitConsumerAdditionPropTxCmd returns a CLI command handler for submitting -// a consumer addition proposal via a transaction. -func SubmitConsumerAdditionPropTxCmd() *cobra.Command { - return &cobra.Command{ - Use: "consumer-addition [proposal-file]", - Args: cobra.ExactArgs(1), - Short: "Submit a consumer addition proposal", - Long: ` -Submit a consumer addition proposal along with an initial deposit. -The proposal details must be supplied via a JSON file. -Unbonding period, transfer timeout period and ccv timeout period should be provided as nanosecond time periods. - -Example: -$ tx gov submit-legacy-proposal consumer-addition --from= - -Where proposal.json contains: - -{ - "title": "Create the FooChain", - "summary": "Gonna be a great chain", - "chain_id": "foochain", - "initial_height": { - "revision_number": 2, - "revision_height": 3 - }, - "genesis_hash": "Z2VuZXNpcyBoYXNo", - "binary_hash": "YmluYXJ5IGhhc2g=", - "spawn_time": "2022-01-27T15:59:50.121607-08:00", - "blocks_per_distribution_transmission": 1000, - "consumer_redistribution_fraction": "0.75", - "distribution_transmission_channel": "", - "historical_entries": 10000, - "transfer_timeout_period": 3600000000000, - "ccv_timeout_period": 2419200000000000, - "unbonding_period": 1728000000000000, - "deposit": "10000stake", - "top_n": 0, - "validators_power_cap": 32, - "validator_set_cap": 50, - "allowlist": [], - "denylist": ["validatorAConsensusAddress", "validatorBConsensusAddress"], - "min_stake": 100000000000, - "allow_inactive_vals": false -} - `, - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposal, err := ParseConsumerAdditionProposalJSON(args[0]) - if err != nil { - return err - } - - // do not fail for errors regarding the unbonding period, but just log a warning - CheckPropUnbondingPeriod(clientCtx, proposal.UnbondingPeriod) - - content := types.NewConsumerAdditionProposal( - proposal.Title, proposal.Summary, proposal.ChainId, proposal.InitialHeight, - proposal.GenesisHash, proposal.BinaryHash, proposal.SpawnTime, - proposal.ConsumerRedistributionFraction, proposal.BlocksPerDistributionTransmission, - proposal.DistributionTransmissionChannel, proposal.HistoricalEntries, - proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod, proposal.TopN, - proposal.ValidatorsPowerCap, proposal.ValidatorSetCap, proposal.Allowlist, proposal.Denylist, - proposal.MinStake, proposal.AllowInactiveVals) - - from := clientCtx.GetFromAddress() - - deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) - if err != nil { - return err - } - - msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) - if err != nil { - return err - } - - msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary, false) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } -} - // SubmitConsumerRemovalPropTxCmd returns a CLI command handler for submitting // a consumer addition proposal via a transaction. func SubmitConsumerRemovalProposalTxCmd() *cobra.Command { diff --git a/x/ccv/provider/keeper/hooks.go b/x/ccv/provider/keeper/hooks.go index 15d5d0e769..5005795166 100644 --- a/x/ccv/provider/keeper/hooks.go +++ b/x/ccv/provider/keeper/hooks.go @@ -2,12 +2,10 @@ package keeper import ( "context" - "fmt" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkgov "github.com/cosmos/cosmos-sdk/x/gov/types" - v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" @@ -112,8 +110,7 @@ func (h Hooks) BeforeTokenizeShareRecordRemoved(_ context.Context, _ uint64) err // that maps the proposal ID to the consumer chain ID. func (h Hooks) AfterProposalSubmission(goCtx context.Context, proposalID uint64) error { ctx := sdk.UnwrapSDKContext(goCtx) - - if p, ok := h.GetConsumerAdditionLegacyPropFromProp(ctx, proposalID); ok { + if p, ok := h.GetConsumerAdditionFromProp(ctx, proposalID); ok { h.k.SetProposedConsumerChain(ctx, p.ChainId, proposalID) } return nil @@ -126,7 +123,7 @@ func (h Hooks) AfterProposalSubmission(goCtx context.Context, proposalID uint64) func (h Hooks) AfterProposalVotingPeriodEnded(goCtx context.Context, proposalID uint64) error { ctx := sdk.UnwrapSDKContext(goCtx) - if _, ok := h.GetConsumerAdditionLegacyPropFromProp(ctx, proposalID); ok { + if _, ok := h.GetConsumerAdditionFromProp(ctx, proposalID); ok { h.k.DeleteProposedConsumerChainInStore(ctx, proposalID) } return nil @@ -144,9 +141,9 @@ func (h Hooks) AfterProposalFailedMinDeposit(ctx context.Context, proposalID uin return nil } -// GetConsumerAdditionLegacyPropFromProp extracts a consumer addition legacy proposal from +// GetConsumerAdditionFromProp extracts a consumer addition legacy proposal from // the proposal with the given ID -func (h Hooks) GetConsumerAdditionLegacyPropFromProp( +func (h Hooks) GetConsumerAdditionFromProp( ctx sdk.Context, proposalID uint64, ) (providertypes.ConsumerAdditionProposal, bool) { @@ -158,21 +155,33 @@ func (h Hooks) GetConsumerAdditionLegacyPropFromProp( // Iterate over the messages in the proposal // Note that it's assumed that at most ONE message can contain a consumer addition proposal for _, msg := range p.GetMessages() { - sdkMsg, isLegacyProposal := msg.GetCachedValue().(*v1.MsgExecLegacyContent) - if !isLegacyProposal { + sdkMsg, isConsumerAddition := msg.GetCachedValue().(*providertypes.MsgConsumerAddition) + if !isConsumerAddition { continue } - content, err := v1.LegacyContentFromMessage(sdkMsg) - if err != nil { - panic(fmt.Errorf("failed to get legacy proposal %d from prop message", proposalID)) - } - - // returns if legacy prop is of ConsumerAddition proposal type - prop, ok := content.(*providertypes.ConsumerAdditionProposal) - if ok { - return *prop, true + proposal := providertypes.ConsumerAdditionProposal{ + Title: p.Title, + Description: p.Summary, + ChainId: sdkMsg.ChainId, + InitialHeight: sdkMsg.InitialHeight, + GenesisHash: sdkMsg.GenesisHash, + BinaryHash: sdkMsg.BinaryHash, + SpawnTime: sdkMsg.SpawnTime, + UnbondingPeriod: sdkMsg.UnbondingPeriod, + CcvTimeoutPeriod: sdkMsg.CcvTimeoutPeriod, + TransferTimeoutPeriod: sdkMsg.TransferTimeoutPeriod, + ConsumerRedistributionFraction: sdkMsg.ConsumerRedistributionFraction, + BlocksPerDistributionTransmission: sdkMsg.BlocksPerDistributionTransmission, + HistoricalEntries: sdkMsg.HistoricalEntries, + DistributionTransmissionChannel: sdkMsg.DistributionTransmissionChannel, + Top_N: sdkMsg.Top_N, + ValidatorsPowerCap: sdkMsg.ValidatorsPowerCap, + ValidatorSetCap: sdkMsg.ValidatorSetCap, + Allowlist: sdkMsg.Allowlist, + Denylist: sdkMsg.Denylist, } + return proposal, true } return providertypes.ConsumerAdditionProposal{}, false } diff --git a/x/ccv/provider/types/codec.go b/x/ccv/provider/types/codec.go index a3593fb22f..17ccc0deba 100644 --- a/x/ccv/provider/types/codec.go +++ b/x/ccv/provider/types/codec.go @@ -31,7 +31,9 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { registry.RegisterImplementations( (*sdk.Msg)(nil), &MsgAssignConsumerKey{}, - &MsgConsumerAddition{}, + &MsgConsumerAddition{}, //TOOD @permissionless: replace with below + //&MsgInitializeConsumer{}, //TOOD @permissionless: uncomment once implemented + //&MsgUpdateConsumer{}, //TOOD @permissionless: uncomment once implemented &MsgConsumerRemoval{}, &MsgChangeRewardDenoms{}, &MsgUpdateParams{}, From 7577eb6ae5df10476c20199aa954ee8794879e3b Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Tue, 6 Aug 2024 14:13:16 +0200 Subject: [PATCH 02/11] Remove legacy-submit-proposal consumer-removal --- app/provider/app.go | 2 - tests/e2e/actions.go | 68 ++++++++++++------- .../client/legacy_proposal_handler.go | 57 ---------------- 3 files changed, 44 insertions(+), 83 deletions(-) diff --git a/app/provider/app.go b/app/provider/app.go index d0ecfb8c3b..e61e8d4f2a 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -144,7 +144,6 @@ var ( gov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - ibcproviderclient.ConsumerRemovalProposalHandler, ibcproviderclient.ConsumerModificationProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, }, @@ -578,7 +577,6 @@ func New( govtypes.ModuleName: gov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - ibcproviderclient.ConsumerRemovalProposalHandler, ibcproviderclient.ConsumerModificationProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, }, diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 50cf987ce4..1d911d55f8 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -380,45 +380,65 @@ func (tr Chain) submitConsumerRemovalProposal( action SubmitConsumerRemovalProposalAction, verbose bool, ) { + template := ` + { + "messages": [ + { + "@type": "/interchain_security.ccv.provider.v1.MsgConsumerRemoval", + "chain_id": "%s", + "stop_time": "%s", + "authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn" + } + ], + "metadata": "ipfs://CID", + "deposit": "100000stake", + "title": "%s", + "summary": "It was a great chain", + "expedited": false + } +` + title := fmt.Sprintf("Stop the %v chain", action.ConsumerChain) stopTime := tr.testConfig.containerConfig.Now.Add(action.StopTimeOffset) - prop := client.ConsumerRemovalProposalJSON{ - Title: fmt.Sprintf("Stop the %v chain", action.ConsumerChain), - Summary: "It was a great chain", - ChainId: string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), - StopTime: stopTime, - Deposit: fmt.Sprint(action.Deposit) + `stake`, - } - - bz, err := json.Marshal(prop) - if err != nil { - log.Fatal(err) - } - jsonStr := string(bz) - if strings.Contains(jsonStr, "'") { - log.Fatal("prop json contains single quote") - } + jsonStr := fmt.Sprintf(template, + string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), + stopTime, + action.Deposit, + title) - bz, err = tr.target.ExecCommand( - "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json")).CombinedOutput() + // #nosec G204 -- bypass unsafe quoting warning (no production code) + proposalFile := "/consumer-removal.proposal" + bz, err := tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, proposalFile), + ).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } - bz, err = tr.target.ExecCommand( + // CONSUMER REMOVAL PROPOSAL + cmd := tr.target.ExecCommand( tr.testConfig.chainConfigs[action.Chain].BinaryName, - "tx", "gov", "submit-legacy-proposal", "consumer-removal", - "/temp-proposal.json", + "tx", "gov", "submit-proposal", proposalFile, `--from`, `validator`+fmt.Sprint(action.From), `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), + `--gas`, `900000`, `--node`, tr.getValidatorNode(action.Chain, action.From), - `--gas`, "900000", `--keyring-backend`, `test`, `-y`, - ).CombinedOutput() + ) + + if verbose { + fmt.Println("submitConsumerRemovalProposal cmd:", cmd.String()) + fmt.Println("submitConsumerRemovalProposal json:", jsonStr) + } + bz, err = cmd.CombinedOutput() if err != nil { - log.Fatal(err, "\n", string(bz)) + log.Fatal("submit consumer removal proposal failed:", err, "\n", string(bz)) + } + + if verbose { + fmt.Println("submitConsumerRemovalProposal output:", string(bz)) } // wait for inclusion in a block -> '--broadcast-mode block' is deprecated diff --git a/x/ccv/provider/client/legacy_proposal_handler.go b/x/ccv/provider/client/legacy_proposal_handler.go index cd301dcad6..09b936f54a 100644 --- a/x/ccv/provider/client/legacy_proposal_handler.go +++ b/x/ccv/provider/client/legacy_proposal_handler.go @@ -15,67 +15,10 @@ import ( ) var ( - ConsumerRemovalProposalHandler = govclient.NewProposalHandler(SubmitConsumerRemovalProposalTxCmd) ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) ConsumerModificationProposalHandler = govclient.NewProposalHandler(SubmitConsumerModificationProposalTxCmd) ) -// SubmitConsumerRemovalPropTxCmd returns a CLI command handler for submitting -// a consumer addition proposal via a transaction. -func SubmitConsumerRemovalProposalTxCmd() *cobra.Command { - return &cobra.Command{ - Use: "consumer-removal [proposal-file]", - Args: cobra.ExactArgs(1), - Short: "Submit a consumer chain removal proposal", - Long: ` -Submit a consumer chain removal proposal along with an initial deposit. -The proposal details must be supplied via a JSON file. - -Example: -$ tx gov submit-legacy-proposal consumer-removal --from= - -Where proposal.json contains: -{ - "title": "Stop the FooChain", - "summary": "It was a great chain", - "chain_id": "foochain", - "stop_time": "2022-01-27T15:59:50.121607-08:00", - "deposit": "10000stake" -} - `, RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposal, err := ParseConsumerRemovalProposalJSON(args[0]) - if err != nil { - return err - } - - content := types.NewConsumerRemovalProposal(proposal.Title, proposal.Summary, proposal.ChainId, proposal.StopTime) - from := clientCtx.GetFromAddress() - - msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) - if err != nil { - return err - } - - deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) - if err != nil { - return err - } - - msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary, false) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } -} - // SubmitChangeRewardDenomsProposalTxCmd returns a CLI command handler for submitting // a change reward denoms proposal via a transaction. func SubmitChangeRewardDenomsProposalTxCmd() *cobra.Command { From 2833350274c1abfa1a959949232c2865a6d8abe0 Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Tue, 6 Aug 2024 14:42:16 +0200 Subject: [PATCH 03/11] Remove legacy-submit-proposal consumer-modification --- app/provider/app.go | 2 - tests/e2e/actions.go | 75 ++++++++++++------- .../client/legacy_proposal_handler.go | 69 +---------------- 3 files changed, 47 insertions(+), 99 deletions(-) diff --git a/app/provider/app.go b/app/provider/app.go index e61e8d4f2a..6b9accb3e1 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -144,7 +144,6 @@ var ( gov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - ibcproviderclient.ConsumerModificationProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, }, ), @@ -577,7 +576,6 @@ func New( govtypes.ModuleName: gov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - ibcproviderclient.ConsumerModificationProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, }, ), diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 1d911d55f8..15e1f0fb19 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -391,7 +391,7 @@ func (tr Chain) submitConsumerRemovalProposal( } ], "metadata": "ipfs://CID", - "deposit": "100000stake", + "deposit": "%sstake", "title": "%s", "summary": "It was a great chain", "expedited": false @@ -461,31 +461,48 @@ func (tr Chain) submitConsumerModificationProposal( action SubmitConsumerModificationProposalAction, verbose bool, ) { - prop := client.ConsumerModificationProposalJSON{ - Title: "Propose the modification of the PSS parameters of a chain", - Summary: "summary of a modification proposal", - ChainId: string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), - Deposit: fmt.Sprint(action.Deposit) + `stake`, - TopN: action.TopN, - ValidatorsPowerCap: action.ValidatorsPowerCap, - ValidatorSetCap: action.ValidatorSetCap, - Allowlist: action.Allowlist, - Denylist: action.Denylist, - } - bz, err := json.Marshal(prop) - if err != nil { - log.Fatal(err) - } + template := ` - jsonStr := string(bz) - if strings.Contains(jsonStr, "'") { - log.Fatal("prop json contains single quote") - } +{ +"messages": [ + { + "@type": "/interchain_security.ccv.provider.v1.MsgConsumerModification", + "title": "Propose the modification of the PSS parameters of a chain", + "description": "description of the consumer modification proposal", + "chain_id": "%s", + "top_N": %d, + "validators_power_cap": %d, + "validator_set_cap": %d, + "allowlist": %s, + "denylist": %s, + "authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn", + "min_stake": "0", + "allow_inactive_vals": false + } + ], +"metadata": "ipfs://CID", +"deposit": "%sstake", +"title": "Propose the modification of the PSS parameters of a chain", +"summary": "summary of a modification proposal", +"expedited": false + } +` - //#nosec G204 -- bypass unsafe quoting warning (no production code) - bz, err = tr.target.ExecCommand( - "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json"), + jsonStr := fmt.Sprintf(template, + string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), + action.TopN, + action.ValidatorsPowerCap, + action.ValidatorSetCap, + action.Allowlist, + action.Denylist, + action.Deposit, + ) + + // #nosec G204 -- bypass unsafe quoting warning (no production code) + proposalFile := "/consumer-mod.proposal" + bz, err := tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, proposalFile), ).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) @@ -494,7 +511,7 @@ func (tr Chain) submitConsumerModificationProposal( // CONSUMER MODIFICATION PROPOSAL cmd := tr.target.ExecCommand( tr.testConfig.chainConfigs[action.Chain].BinaryName, - "tx", "gov", "submit-legacy-proposal", "consumer-modification", "/temp-proposal.json", + "tx", "gov", "submit-proposal", proposalFile, `--from`, `validator`+fmt.Sprint(action.From), `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), @@ -503,18 +520,18 @@ func (tr Chain) submitConsumerModificationProposal( `--keyring-backend`, `test`, `-y`, ) + if verbose { - log.Println("submitConsumerModificationProposal cmd: ", cmd.String()) - log.Println("submitConsumerModificationProposal json: ", jsonStr) + fmt.Println("submitConsumerModificationProposal cmd:", cmd.String()) + fmt.Println("submitConsumerModificationProposal json:", jsonStr) } - bz, err = cmd.CombinedOutput() if err != nil { - log.Fatal(err, "\n", string(bz)) + log.Fatal("submit consumer modification proposal failed:", err, "\n", string(bz)) } if verbose { - log.Println("submitConsumerModificationProposal output: ", string(bz)) + fmt.Println("submitConsumerModificationProposal output:", string(bz)) } // wait for inclusion in a block -> '--broadcast-mode block' is deprecated diff --git a/x/ccv/provider/client/legacy_proposal_handler.go b/x/ccv/provider/client/legacy_proposal_handler.go index 09b936f54a..8d89ed59f6 100644 --- a/x/ccv/provider/client/legacy_proposal_handler.go +++ b/x/ccv/provider/client/legacy_proposal_handler.go @@ -15,8 +15,7 @@ import ( ) var ( - ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) - ConsumerModificationProposalHandler = govclient.NewProposalHandler(SubmitConsumerModificationProposalTxCmd) + ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) ) // SubmitChangeRewardDenomsProposalTxCmd returns a CLI command handler for submitting @@ -75,69 +74,3 @@ func SubmitChangeRewardDenomsProposalTxCmd() *cobra.Command { }, } } - -// SubmitConsumerModificationProposalTxCmd returns a CLI command handler for submitting -// a consumer modification proposal via a transaction. -func SubmitConsumerModificationProposalTxCmd() *cobra.Command { - return &cobra.Command{ - Use: "consumer-modification [proposal-file]", - Args: cobra.ExactArgs(1), - Short: "Submit a consumer modification proposal", - Long: ` -Submit a consumer modification proposal along with an initial deposit. -The proposal details must be supplied via a JSON file. - -Example: -$ tx gov submit-legacy-proposal consumer-modification --from= - -Where proposal.json contains: - -{ - "title": "Modify FooChain", - "summary": "Make it an Opt In chain", - "chain_id": "foochain", - "top_n": 0, - "validators_power_cap": 32, - "validator_set_cap": 50, - "allowlist": [], - "denylist": ["validatorAConsensusAddress", "validatorBConsensusAddress"], - "min_stake": 100000000000, - "allow_inactive_vals": false -} - `, - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposal, err := ParseConsumerModificationProposalJSON(args[0]) - if err != nil { - return err - } - - content := types.NewConsumerModificationProposal( - proposal.Title, proposal.Summary, proposal.ChainId, proposal.TopN, - proposal.ValidatorsPowerCap, proposal.ValidatorSetCap, proposal.Allowlist, proposal.Denylist, proposal.MinStake, proposal.AllowInactiveVals) - - from := clientCtx.GetFromAddress() - - deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) - if err != nil { - return err - } - - msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) - if err != nil { - return err - } - - msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary, false) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } -} From 6257f41723214f59907efb6ebcae1d431db64c28 Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Tue, 6 Aug 2024 14:54:16 +0200 Subject: [PATCH 04/11] docs --- .../provider/2130-remove-legacy-proposal.md | 2 ++ docs/docs/upgrading/migrate_v4_v5.md | 34 ++++++++++++------- 2 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 .changelog/unreleased/api-breaking/provider/2130-remove-legacy-proposal.md diff --git a/.changelog/unreleased/api-breaking/provider/2130-remove-legacy-proposal.md b/.changelog/unreleased/api-breaking/provider/2130-remove-legacy-proposal.md new file mode 100644 index 0000000000..2d7a196aeb --- /dev/null +++ b/.changelog/unreleased/api-breaking/provider/2130-remove-legacy-proposal.md @@ -0,0 +1,2 @@ +- Remove support for legacy-proposal to add/modify/remove consumer proposals + ([\#2130](https://github.com/cosmos/interchain-security/pull/2130)) diff --git a/docs/docs/upgrading/migrate_v4_v5.md b/docs/docs/upgrading/migrate_v4_v5.md index bdec036804..0f4db14de5 100644 --- a/docs/docs/upgrading/migrate_v4_v5.md +++ b/docs/docs/upgrading/migrate_v4_v5.md @@ -159,28 +159,36 @@ interchain-security-pd q provider params -o json ### Governance proposals -Submitting the following legacy proposals is still supported: - # Consumer addition proposal ```shell -interchain-security-pd tx gov submit-legacy-proposal consumer-addition +interchain-security-pd tx gov submit-proposal ``` # Consumer removal proposal ```shell -interchain-security-pd tx gov submit-legacy-proposal consumer-removal +interchain-security-pd tx gov submit-proposal ``` -# Consumer addition proposal +# Consumer modification proposal ```shell -interchain-security-pd tx gov submit-legacy-proposal change-reward-denoms +interchain-security-pd tx gov submit-proposal ``` -You may also submit proposal messages above using `submit-proposal`. +Run `interchain-security-pd tx gov draft-proposal` command and select in `other` one of the following +message types to generate a draft example: +- `/interchain_security.ccv.provider.v1.MsgConsumerAddition` +- `/interchain_security.ccv.provider.v1.MsgConsumerModification` +- `/interchain_security.ccv.provider.v1.MsgConsumerRemoval` +# Change reward denoms + +```shell +interchain-security-pd tx gov submit-legacy-proposal change-reward-denoms +``` + ## Consumer ### Keeper initialization @@ -226,8 +234,8 @@ app.ConsumerKeeper = ibcconsumerkeeper.NewKeeper( // for x/ccv/democracy using the x/gov module address is correct // if you don't have a way of updating consumer params you may still use the line below as it will have no affect + authtypes.NewModuleAddress(govtypes.ModuleName).String(), - - // add address codecs + + // add address codecs + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) @@ -235,13 +243,13 @@ app.ConsumerKeeper = ibcconsumerkeeper.NewKeeper( * `authority` was added - requirement for executing `MsgUpdateParams` - * make sure the authority address makes sense for your chain + * make sure the authority address makes sense for your chain * the exact module account may differ depending on your setup (`x/gov`, `x/admin` or custom module) * for `x/ccv/democracy` using the `x/gov` module address is correct * if you don't have a way of updating consumer params you may use `authtypes.NewModuleAddress(govtypes.ModuleName).String()` (has no effect on functionality) * `validatorAddressCodec` & `consensusAddressCodec` were added - they must match the bech32 address codec used by `x/auth`, `x/bank`, `x/staking` - + ### Additions @@ -250,7 +258,7 @@ app.ConsumerKeeper = ibcconsumerkeeper.NewKeeper( **This functionality is not supported on `x/ccv/consumer` without additional configuration.** * if you are using `x/ccv/democracy` the feature is supported out of the box * if you are using custom logic for changing consumer params, please update your code by providing the appropriate `authority` module account during `ConsumerKeeper` initialization in `app.go`. - + **You must add `"/interchain_security.ccv.consumer.v1.MsgUpdateParams"` to your parameters whitelist to be able to change `ccvconsumer` parameters via governance.** It is available when using `gov` CLI commands: @@ -376,7 +384,7 @@ The consumer implements the `StakingKeeper` interface shown above. ## Democracy -Changes in `Consumer` also apply to `Democracy`. +Changes in `Consumer` also apply to `Democracy`. Democracy `x/staking`, `x/distribution` and `x/gov` were updated to reflect changes in `cosmos-sdk v0.50.x`. From 35978c724a203eb9fe528fd708deea078e7b9b95 Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Tue, 6 Aug 2024 16:08:18 +0200 Subject: [PATCH 05/11] fix e2e --- tests/e2e/actions.go | 4 ++-- tests/e2e/state.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 15e1f0fb19..4c0e5c5d93 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -391,14 +391,14 @@ func (tr Chain) submitConsumerRemovalProposal( } ], "metadata": "ipfs://CID", - "deposit": "%sstake", + "deposit": "%dstake", "title": "%s", "summary": "It was a great chain", "expedited": false } ` title := fmt.Sprintf("Stop the %v chain", action.ConsumerChain) - stopTime := tr.testConfig.containerConfig.Now.Add(action.StopTimeOffset) + stopTime := tr.testConfig.containerConfig.Now.Add(action.StopTimeOffset).Format(time.RFC3339Nano) jsonStr := fmt.Sprintf(template, string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), diff --git a/tests/e2e/state.go b/tests/e2e/state.go index a9864123ac..f29c8f59f0 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -498,7 +498,7 @@ func (tr Commands) GetProposal(chain ChainID, proposal uint) Proposal { Title: title, Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", } - case "/interchain_security.ccv.provider.v1.ConsumerRemovalProposal": + case "/interchain_security.ccv.provider.v1.MsgConsumerRemoval": chainId := rawContent.Get("chain_id").String() stopTime := rawContent.Get("stop_time").Time().Sub(tr.containerConfig.Now) @@ -529,7 +529,7 @@ func (tr Commands) GetProposal(chain ChainID, proposal uint) Proposal { Params: params, } - case "/interchain_security.ccv.provider.v1.ConsumerModificationProposal": + case "/interchain_security.ccv.provider.v1.MsgConsumerModification": chainId := rawContent.Get("chain_id").String() var chain ChainID From 6c92999010ce32ad1e4c78e9f7c0c0f5089b5dd4 Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Wed, 7 Aug 2024 08:09:23 +0200 Subject: [PATCH 06/11] addressed review comments --- app/provider/app.go | 3 - docs/docs/upgrading/migrate_v4_v5.md | 34 +++----- docs/docs/upgrading/migrate_v5_v6.md | 42 ++++++++++ tests/e2e/action_rapid_test.go | 1 + tests/e2e/actions.go | 80 +++++++++++-------- tests/e2e/steps_democracy.go | 1 + tests/integration/provider_gov_hooks.go | 6 +- .../client/legacy_proposal_handler.go | 76 ------------------ x/ccv/provider/types/codec.go | 4 +- 9 files changed, 108 insertions(+), 139 deletions(-) create mode 100644 docs/docs/upgrading/migrate_v5_v6.md delete mode 100644 x/ccv/provider/client/legacy_proposal_handler.go diff --git a/app/provider/app.go b/app/provider/app.go index 6b9accb3e1..0e6e4b3b80 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -114,7 +114,6 @@ import ( no_valupdates_genutil "github.com/cosmos/interchain-security/v5/x/ccv/no_valupdates_genutil" no_valupdates_staking "github.com/cosmos/interchain-security/v5/x/ccv/no_valupdates_staking" ibcprovider "github.com/cosmos/interchain-security/v5/x/ccv/provider" - ibcproviderclient "github.com/cosmos/interchain-security/v5/x/ccv/provider/client" ibcproviderkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) @@ -144,7 +143,6 @@ var ( gov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - ibcproviderclient.ChangeRewardDenomsProposalHandler, }, ), mint.AppModuleBasic{}, @@ -576,7 +574,6 @@ func New( govtypes.ModuleName: gov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - ibcproviderclient.ChangeRewardDenomsProposalHandler, }, ), }) diff --git a/docs/docs/upgrading/migrate_v4_v5.md b/docs/docs/upgrading/migrate_v4_v5.md index 0f4db14de5..bdec036804 100644 --- a/docs/docs/upgrading/migrate_v4_v5.md +++ b/docs/docs/upgrading/migrate_v4_v5.md @@ -159,36 +159,28 @@ interchain-security-pd q provider params -o json ### Governance proposals +Submitting the following legacy proposals is still supported: + # Consumer addition proposal ```shell -interchain-security-pd tx gov submit-proposal +interchain-security-pd tx gov submit-legacy-proposal consumer-addition ``` # Consumer removal proposal ```shell -interchain-security-pd tx gov submit-proposal +interchain-security-pd tx gov submit-legacy-proposal consumer-removal ``` -# Consumer modification proposal +# Consumer addition proposal ```shell -interchain-security-pd tx gov submit-proposal +interchain-security-pd tx gov submit-legacy-proposal change-reward-denoms ``` -Run `interchain-security-pd tx gov draft-proposal` command and select in `other` one of the following -message types to generate a draft example: -- `/interchain_security.ccv.provider.v1.MsgConsumerAddition` -- `/interchain_security.ccv.provider.v1.MsgConsumerModification` -- `/interchain_security.ccv.provider.v1.MsgConsumerRemoval` +You may also submit proposal messages above using `submit-proposal`. -# Change reward denoms - -```shell -interchain-security-pd tx gov submit-legacy-proposal change-reward-denoms -``` - ## Consumer ### Keeper initialization @@ -234,8 +226,8 @@ app.ConsumerKeeper = ibcconsumerkeeper.NewKeeper( // for x/ccv/democracy using the x/gov module address is correct // if you don't have a way of updating consumer params you may still use the line below as it will have no affect + authtypes.NewModuleAddress(govtypes.ModuleName).String(), - - // add address codecs + + // add address codecs + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) @@ -243,13 +235,13 @@ app.ConsumerKeeper = ibcconsumerkeeper.NewKeeper( * `authority` was added - requirement for executing `MsgUpdateParams` - * make sure the authority address makes sense for your chain + * make sure the authority address makes sense for your chain * the exact module account may differ depending on your setup (`x/gov`, `x/admin` or custom module) * for `x/ccv/democracy` using the `x/gov` module address is correct * if you don't have a way of updating consumer params you may use `authtypes.NewModuleAddress(govtypes.ModuleName).String()` (has no effect on functionality) * `validatorAddressCodec` & `consensusAddressCodec` were added - they must match the bech32 address codec used by `x/auth`, `x/bank`, `x/staking` - + ### Additions @@ -258,7 +250,7 @@ app.ConsumerKeeper = ibcconsumerkeeper.NewKeeper( **This functionality is not supported on `x/ccv/consumer` without additional configuration.** * if you are using `x/ccv/democracy` the feature is supported out of the box * if you are using custom logic for changing consumer params, please update your code by providing the appropriate `authority` module account during `ConsumerKeeper` initialization in `app.go`. - + **You must add `"/interchain_security.ccv.consumer.v1.MsgUpdateParams"` to your parameters whitelist to be able to change `ccvconsumer` parameters via governance.** It is available when using `gov` CLI commands: @@ -384,7 +376,7 @@ The consumer implements the `StakingKeeper` interface shown above. ## Democracy -Changes in `Consumer` also apply to `Democracy`. +Changes in `Consumer` also apply to `Democracy`. Democracy `x/staking`, `x/distribution` and `x/gov` were updated to reflect changes in `cosmos-sdk v0.50.x`. diff --git a/docs/docs/upgrading/migrate_v5_v6.md b/docs/docs/upgrading/migrate_v5_v6.md new file mode 100644 index 0000000000..8244f546c0 --- /dev/null +++ b/docs/docs/upgrading/migrate_v5_v6.md @@ -0,0 +1,42 @@ +--- +sidebar_position: 1 +--- + +# Upgrading to ICS v6.x from v5.x + +ICS specific changes are outlined below. + +Pre-requisite version for this upgrade: any from the `v5.x` release line. + +## Note + +## Provider + +### Migration (v5 -> v6) + +ConensusVersion was bumped to `6`. + +### Governance proposals + +#### Consumer addition proposal + +```shell +interchain-security-pd tx gov submit-proposal +``` + +#### Consumer removal proposal + +```shell +interchain-security-pd tx gov submit-proposal +``` + +#### Consumer modification proposal +```shell +interchain-security-pd tx gov submit-proposal +``` + +Run `interchain-security-pd tx gov draft-proposal` command and select in `other` one of the following +message types to generate a draft example: +- `/interchain_security.ccv.provider.v1.MsgConsumerAddition` +- `/interchain_security.ccv.provider.v1.MsgConsumerModification` +- `/interchain_security.ccv.provider.v1.MsgConsumerRemoval` diff --git a/tests/e2e/action_rapid_test.go b/tests/e2e/action_rapid_test.go index d0a9ede282..004eb30d95 100644 --- a/tests/e2e/action_rapid_test.go +++ b/tests/e2e/action_rapid_test.go @@ -99,6 +99,7 @@ func GetActionGen() *rapid.Generator[any] { func CreateSubmitChangeRewardDenomsProposalActionGen() *rapid.Generator[SubmitChangeRewardDenomsProposalAction] { return rapid.Custom(func(t *rapid.T) SubmitChangeRewardDenomsProposalAction { return SubmitChangeRewardDenomsProposalAction{ + Chain: GetChainIDGen().Draw(t, "Chain"), From: GetValidatorIDGen().Draw(t, "From"), Deposit: rapid.Uint().Draw(t, "Deposit"), Denom: rapid.String().Draw(t, "Denom"), diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 4c0e5c5d93..9ac3be5a3e 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -21,8 +21,6 @@ import ( "golang.org/x/mod/semver" e2e "github.com/cosmos/interchain-security/v5/tests/e2e/testlib" - "github.com/cosmos/interchain-security/v5/x/ccv/provider/client" - "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -2019,54 +2017,70 @@ func (tr Chain) registerRepresentative( } type SubmitChangeRewardDenomsProposalAction struct { + Chain ChainID Denom string Deposit uint From ValidatorID } func (tr Chain) submitChangeRewardDenomsProposal(action SubmitChangeRewardDenomsProposalAction, verbose bool) { - providerChain := tr.testConfig.chainConfigs[ChainID("provi")] - - prop := client.ChangeRewardDenomsProposalJSON{ - Summary: "Change reward denoms", - ChangeRewardDenomsProposal: types.ChangeRewardDenomsProposal{ - Title: "Change reward denoms", - Description: "Change reward denoms", - DenomsToAdd: []string{action.Denom}, - DenomsToRemove: []string{"stake"}, - }, - Deposit: fmt.Sprint(action.Deposit) + `stake`, - } - - bz, err := json.Marshal(prop) - if err != nil { - log.Fatal(err) - } + template := ` +{ + "messages": [ + { + "@type": "/interchain_security.ccv.provider.v1.MsgChangeRewardDenoms", + "denoms_to_add": %s, + "denoms_to_remove": %s, + "authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn" + } + ], + "metadata": "ipfs://CID", + "deposit": "%dstake", + "title": "change reward denoms", + "summary": "Proposal to change reward denoms", + "expedited": false +}` - jsonStr := string(bz) - if strings.Contains(jsonStr, "'") { - log.Fatal("prop json contains single quote") - } + denomsToAdd := []string{action.Denom} + denomsToRemove := []string{"stake"} + jsonStr := fmt.Sprintf(template, + denomsToAdd, + denomsToRemove, + action.Deposit) - bz, err = tr.target.ExecCommand( - "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/change-reward-denoms-proposal.json")).CombinedOutput() + //#nosec G204 -- bypass unsafe quoting warning (no production code) + proposalFile := "/consumer-addition.proposal" + bz, err := tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, proposalFile), + ).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } // CHANGE REWARDS DENOM PROPOSAL - bz, err = tr.target.ExecCommand(providerChain.BinaryName, - "tx", "gov", "submit-legacy-proposal", "change-reward-denoms", "/change-reward-denoms-proposal.json", + cmd := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, + "tx", "gov", "submit-proposal", proposalFile, `--from`, `validator`+fmt.Sprint(action.From), - `--chain-id`, string(providerChain.ChainId), - `--home`, tr.getValidatorHome(providerChain.ChainId, action.From), - `--node`, tr.getValidatorNode(providerChain.ChainId, action.From), - `--gas`, "9000000", + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), + `--home`, tr.getValidatorHome(action.Chain, action.From), + `--gas`, `900000`, + `--node`, tr.getValidatorNode(action.Chain, action.From), `--keyring-backend`, `test`, `-y`, - ).CombinedOutput() + ) + + if verbose { + fmt.Println("change rewards denom props cmd:", cmd.String()) + fmt.Println("change rewards denom props json:", jsonStr) + } + bz, err = cmd.CombinedOutput() if err != nil { - log.Fatal(err, "\n", string(bz)) + log.Fatal("submit-proposal failed:", err, "\n", string(bz)) + } + + if verbose { + fmt.Println("change rewards denom props output:", string(bz)) } // wait for inclusion in a block -> '--broadcast-mode block' is deprecated diff --git a/tests/e2e/steps_democracy.go b/tests/e2e/steps_democracy.go index 82e1d237af..ef9c3787f0 100644 --- a/tests/e2e/steps_democracy.go +++ b/tests/e2e/steps_democracy.go @@ -152,6 +152,7 @@ func stepsDemocracy(consumerName string, expectRegisteredRewardDistribution bool }, { Action: SubmitChangeRewardDenomsProposalAction{ + Chain: ChainID("provi"), Denom: consumerRewardDenom, Deposit: 10000001, From: ValidatorID("bob"), diff --git a/tests/integration/provider_gov_hooks.go b/tests/integration/provider_gov_hooks.go index 6fe5260b17..68152198d3 100644 --- a/tests/integration/provider_gov_hooks.go +++ b/tests/integration/provider_gov_hooks.go @@ -61,7 +61,7 @@ func (s *CCVTestSuite) TestGetConsumerAdditionFromProp() { s.Require().NoError(err) // create a valid consumer addition proposal - addConsumerProp := testkeeper.GetTestMsgConsumerAddition() + msgConsumerAddition := testkeeper.GetTestMsgConsumerAddition() // create a legacy consumer addition proposal content // (not supported anymore) @@ -107,8 +107,8 @@ func (s *CCVTestSuite) TestGetConsumerAdditionFromProp() { expPanic: false, }, { - name: "msg contains a prop of legacy ConsumerAdditionProposal type - hook should create a new proposed chain", - propMsg: &addConsumerProp, + name: "msg contains a prop of MsgConsumerAddition type - hook should create a new proposed chain", + propMsg: &msgConsumerAddition, expectConsumerPropFound: true, expPanic: false, }, diff --git a/x/ccv/provider/client/legacy_proposal_handler.go b/x/ccv/provider/client/legacy_proposal_handler.go deleted file mode 100644 index 8d89ed59f6..0000000000 --- a/x/ccv/provider/client/legacy_proposal_handler.go +++ /dev/null @@ -1,76 +0,0 @@ -package client - -import ( - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/tx" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govclient "github.com/cosmos/cosmos-sdk/x/gov/client" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - - "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" -) - -var ( - ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) -) - -// SubmitChangeRewardDenomsProposalTxCmd returns a CLI command handler for submitting -// a change reward denoms proposal via a transaction. -func SubmitChangeRewardDenomsProposalTxCmd() *cobra.Command { - return &cobra.Command{ - Use: "change-reward-denoms [proposal-file]", - Args: cobra.ExactArgs(1), - Short: "Submit a change reward denoms proposal", - Long: `Submit an change reward denoms proposal with an initial deposit. - The proposal details must be supplied via a JSON file. - - Example: - $ tx gov submit-legacy-proposal change-reward-denoms --from= - - Where proposal.json contains: - { - "title": "Change reward denoms", - "summary": "Change reward denoms", - "denoms_to_add": ["untrn"], - "denoms_to_remove": ["stake"], - "deposit": "10000stake" - } - `, - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposal, err := ParseChangeRewardDenomsProposalJSON(args[0]) - if err != nil { - return err - } - - content := types.NewChangeRewardDenomsProposal(proposal.Title, proposal.Summary, proposal.DenomsToAdd, proposal.DenomsToRemove) - - from := clientCtx.GetFromAddress() - - msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) - if err != nil { - return err - } - - deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) - if err != nil { - return err - } - - msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary, false) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } -} diff --git a/x/ccv/provider/types/codec.go b/x/ccv/provider/types/codec.go index 17ccc0deba..a3593fb22f 100644 --- a/x/ccv/provider/types/codec.go +++ b/x/ccv/provider/types/codec.go @@ -31,9 +31,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { registry.RegisterImplementations( (*sdk.Msg)(nil), &MsgAssignConsumerKey{}, - &MsgConsumerAddition{}, //TOOD @permissionless: replace with below - //&MsgInitializeConsumer{}, //TOOD @permissionless: uncomment once implemented - //&MsgUpdateConsumer{}, //TOOD @permissionless: uncomment once implemented + &MsgConsumerAddition{}, &MsgConsumerRemoval{}, &MsgChangeRewardDenoms{}, &MsgUpdateParams{}, From 942910f0495e27c4be1ef3d3f4bc4485595c73b2 Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Wed, 7 Aug 2024 11:30:22 +0200 Subject: [PATCH 07/11] fix compatibility tests --- .github/workflows/nightly-e2e.yml | 2 +- tests/e2e/actions.go | 247 ++++++++++++++++++++++++++++++ tests/e2e/test_driver.go | 32 +++- 3 files changed, 274 insertions(+), 7 deletions(-) diff --git a/.github/workflows/nightly-e2e.yml b/.github/workflows/nightly-e2e.yml index 5eeadba12d..33a67ec00d 100644 --- a/.github/workflows/nightly-e2e.yml +++ b/.github/workflows/nightly-e2e.yml @@ -36,7 +36,7 @@ jobs: # Run compatibility tests for different consumer (-cv) and provider (-pv) versions. # Combination of all provider versions with consumer versions are tested. # For new versions to be tested add/modify -pc/-cv parameters. - run: go run ./tests/e2e/... --tc compatibility -pv latest -pv v4.3.0-lsm -pv v3.3.3-lsm -cv latest -cv v4.3.0 -cv v3.3.0 + run: go run ./tests/e2e/... --tc compatibility -pv latest -pv v4.3.1-lsm -pv v3.3.3-lsm -cv latest -cv v4.4.0 -cv v3.3.0 happy-path-test: runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 9ac3be5a3e..22333aad8c 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -21,6 +21,8 @@ import ( "golang.org/x/mod/semver" e2e "github.com/cosmos/interchain-security/v5/tests/e2e/testlib" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/client" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -366,6 +368,89 @@ func (tr Chain) submitConsumerAdditionProposal( tr.waitBlocks(action.Chain, 2, 10*time.Second) } +func (tr Chain) submitConsumerAdditionLegacyProposal( + action SubmitConsumerAdditionProposalAction, + verbose bool, +) { + spawnTime := tr.testConfig.containerConfig.Now.Add(time.Duration(action.SpawnTime) * time.Millisecond) + params := ccvtypes.DefaultParams() + prop := client.ConsumerAdditionProposalJSON{ + Title: "Propose the addition of a new chain", + Summary: "Gonna be a great chain", + ChainId: string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), + InitialHeight: action.InitialHeight, + GenesisHash: []byte("gen_hash"), + BinaryHash: []byte("bin_hash"), + SpawnTime: spawnTime, + ConsumerRedistributionFraction: params.ConsumerRedistributionFraction, + BlocksPerDistributionTransmission: params.BlocksPerDistributionTransmission, + HistoricalEntries: params.HistoricalEntries, + CcvTimeoutPeriod: params.CcvTimeoutPeriod, + TransferTimeoutPeriod: params.TransferTimeoutPeriod, + UnbondingPeriod: params.UnbondingPeriod, + Deposit: fmt.Sprint(action.Deposit) + `stake`, + DistributionTransmissionChannel: action.DistributionChannel, + TopN: action.TopN, + ValidatorsPowerCap: action.ValidatorsPowerCap, + ValidatorSetCap: action.ValidatorSetCap, + Allowlist: action.Allowlist, + Denylist: action.Denylist, + MinStake: action.MinStake, + AllowInactiveVals: action.AllowInactiveVals, + } + + bz, err := json.Marshal(prop) + if err != nil { + log.Fatal(err) + } + + jsonStr := string(bz) + if strings.Contains(jsonStr, "'") { + log.Fatal("prop json contains single quote") + } + + //#nosec G204 -- bypass unsafe quoting warning (no production code) + cmd := tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json")) + bz, err = cmd.CombinedOutput() + if verbose { + log.Println("submitConsumerAdditionProposal cmd: ", cmd.String()) + } + + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + // CONSUMER ADDITION PROPOSAL + cmd = tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, + "tx", "gov", "submit-legacy-proposal", "consumer-addition", "/temp-proposal.json", + `--from`, `validator`+fmt.Sprint(action.From), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), + `--home`, tr.getValidatorHome(action.Chain, action.From), + `--gas`, `900000`, + `--node`, tr.getValidatorNode(action.Chain, action.From), + `--keyring-backend`, `test`, + `-y`, + ) + + if verbose { + fmt.Println("submitConsumerAdditionProposal cmd:", cmd.String()) + fmt.Println("submitConsumerAdditionProposal json:", jsonStr) + } + bz, err = cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + if verbose { + fmt.Println("submitConsumerAdditionProposal output:", string(bz)) + } + + // wait for inclusion in a block -> '--broadcast-mode block' is deprecated + tr.waitBlocks(ChainID("provi"), 2, 10*time.Second) +} + type SubmitConsumerRemovalProposalAction struct { Chain ChainID From ValidatorID @@ -443,6 +528,55 @@ func (tr Chain) submitConsumerRemovalProposal( tr.waitBlocks(ChainID("provi"), 2, 20*time.Second) } +func (tr Chain) submitConsumerRemovalLegacyProposal( + action SubmitConsumerRemovalProposalAction, + verbose bool, +) { + stopTime := tr.testConfig.containerConfig.Now.Add(action.StopTimeOffset) + prop := client.ConsumerRemovalProposalJSON{ + Title: fmt.Sprintf("Stop the %v chain", action.ConsumerChain), + Summary: "It was a great chain", + ChainId: string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), + StopTime: stopTime, + Deposit: fmt.Sprint(action.Deposit) + `stake`, + } + + bz, err := json.Marshal(prop) + if err != nil { + log.Fatal(err) + } + + jsonStr := string(bz) + if strings.Contains(jsonStr, "'") { + log.Fatal("prop json contains single quote") + } + + bz, err = tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json")).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + bz, err = tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, + "tx", "gov", "submit-legacy-proposal", "consumer-removal", + "/temp-proposal.json", + `--from`, `validator`+fmt.Sprint(action.From), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), + `--home`, tr.getValidatorHome(action.Chain, action.From), + `--node`, tr.getValidatorNode(action.Chain, action.From), + `--gas`, "900000", + `--keyring-backend`, `test`, + `-y`, + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + // wait for inclusion in a block -> '--broadcast-mode block' is deprecated + tr.waitBlocks(ChainID("provi"), 2, 20*time.Second) +} + type SubmitConsumerModificationProposalAction struct { Chain ChainID From ValidatorID @@ -536,6 +670,70 @@ func (tr Chain) submitConsumerModificationProposal( tr.waitBlocks(ChainID("provi"), 2, 10*time.Second) } +func (tr Chain) submitConsumerModificationLegacyProposal( + action SubmitConsumerModificationProposalAction, + verbose bool, +) { + prop := client.ConsumerModificationProposalJSON{ + Title: "Propose the modification of the PSS parameters of a chain", + Summary: "summary of a modification proposal", + ChainId: string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), + Deposit: fmt.Sprint(action.Deposit) + `stake`, + TopN: action.TopN, + ValidatorsPowerCap: action.ValidatorsPowerCap, + ValidatorSetCap: action.ValidatorSetCap, + Allowlist: action.Allowlist, + Denylist: action.Denylist, + } + + bz, err := json.Marshal(prop) + if err != nil { + log.Fatal(err) + } + + jsonStr := string(bz) + if strings.Contains(jsonStr, "'") { + log.Fatal("prop json contains single quote") + } + + //#nosec G204 -- bypass unsafe quoting warning (no production code) + bz, err = tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json"), + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + // CONSUMER MODIFICATION PROPOSAL + cmd := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, + "tx", "gov", "submit-legacy-proposal", "consumer-modification", "/temp-proposal.json", + `--from`, `validator`+fmt.Sprint(action.From), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), + `--home`, tr.getValidatorHome(action.Chain, action.From), + `--gas`, `900000`, + `--node`, tr.getValidatorNode(action.Chain, action.From), + `--keyring-backend`, `test`, + `-y`, + ) + if verbose { + log.Println("submitConsumerModificationProposal cmd: ", cmd.String()) + log.Println("submitConsumerModificationProposal json: ", jsonStr) + } + + bz, err = cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + if verbose { + log.Println("submitConsumerModificationProposal output: ", string(bz)) + } + + // wait for inclusion in a block -> '--broadcast-mode block' is deprecated + tr.waitBlocks(ChainID("provi"), 2, 10*time.Second) +} + type SubmitEnableTransfersProposalAction struct { Chain ChainID From ValidatorID @@ -2087,6 +2285,55 @@ func (tr Chain) submitChangeRewardDenomsProposal(action SubmitChangeRewardDenoms tr.waitBlocks(ChainID("provi"), 2, 30*time.Second) } +func (tr Chain) submitChangeRewardDenomsLegacyProposal(action SubmitChangeRewardDenomsProposalAction, verbose bool) { + providerChain := tr.testConfig.chainConfigs[action.Chain] + + prop := client.ChangeRewardDenomsProposalJSON{ + Summary: "Change reward denoms", + ChangeRewardDenomsProposal: types.ChangeRewardDenomsProposal{ + Title: "Change reward denoms", + Description: "Change reward denoms", + DenomsToAdd: []string{action.Denom}, + DenomsToRemove: []string{"stake"}, + }, + Deposit: fmt.Sprint(action.Deposit) + `stake`, + } + + bz, err := json.Marshal(prop) + if err != nil { + log.Fatal(err) + } + + jsonStr := string(bz) + if strings.Contains(jsonStr, "'") { + log.Fatal("prop json contains single quote") + } + + bz, err = tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/change-reward-denoms-proposal.json")).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + // CHANGE REWARDS DENOM PROPOSAL + bz, err = tr.target.ExecCommand(providerChain.BinaryName, + "tx", "gov", "submit-legacy-proposal", "change-reward-denoms", "/change-reward-denoms-proposal.json", + `--from`, `validator`+fmt.Sprint(action.From), + `--chain-id`, string(providerChain.ChainId), + `--home`, tr.getValidatorHome(providerChain.ChainId, action.From), + `--node`, tr.getValidatorNode(providerChain.ChainId, action.From), + `--gas`, "9000000", + `--keyring-backend`, `test`, + `-y`, + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + // wait for inclusion in a block -> '--broadcast-mode block' is deprecated + tr.waitBlocks(ChainID("provi"), 2, 30*time.Second) +} + // Creates an additional node on selected chain // by copying an existing validator's home folder // diff --git a/tests/e2e/test_driver.go b/tests/e2e/test_driver.go index 7a1996c01c..4eecbfe152 100644 --- a/tests/e2e/test_driver.go +++ b/tests/e2e/test_driver.go @@ -83,7 +83,7 @@ func (td *DefaultDriver) getTargetDriver(chainID ChainID) Chain { } icsVersion := td.getIcsVersion(chainID) switch icsVersion { - case "v4": + case "v3", "v4": if td.verbose { fmt.Println("Using 'v4' driver for chain ", chainID) } @@ -101,7 +101,7 @@ func (td *DefaultDriver) getTargetDriver(chainID ChainID) Chain { target: td.target, } if td.verbose { - fmt.Println("Using default driver ", icsVersion, " for chain ", chainID) + fmt.Println("Using default driver for version", icsVersion, " for chain ", chainID) } } @@ -140,13 +140,28 @@ func (td *DefaultDriver) runAction(action interface{}) error { case SubmitTextProposalAction: target.submitTextProposal(action, td.verbose) case SubmitConsumerAdditionProposalAction: - target.submitConsumerAdditionProposal(action, td.verbose) + target = td.getTargetDriver(action.Chain) + if semver.Compare(semver.Major(target.testConfig.providerVersion), "v5") < 0 { + target.submitConsumerAdditionLegacyProposal(action, td.verbose) + } else { + target.submitConsumerAdditionProposal(action, td.verbose) + } case SubmitConsumerRemovalProposalAction: - target.submitConsumerRemovalProposal(action, td.verbose) + target = td.getTargetDriver(action.Chain) + if semver.Compare(semver.Major(target.testConfig.providerVersion), "v5") < 0 { + target.submitConsumerRemovalLegacyProposal(action, td.verbose) + } else { + target.submitConsumerRemovalProposal(action, td.verbose) + } case SubmitEnableTransfersProposalAction: target.submitEnableTransfersProposalAction(action, td.verbose) case SubmitConsumerModificationProposalAction: - target.submitConsumerModificationProposal(action, td.verbose) + target = td.getTargetDriver(action.Chain) + if semver.Compare(semver.Major(target.testConfig.providerVersion), "v5") < 0 { + target.submitConsumerModificationLegacyProposal(action, td.verbose) + } else { + target.submitConsumerModificationProposal(action, td.verbose) + } case VoteGovProposalAction: target.voteGovProposal(action, td.verbose) case StartConsumerChainAction: @@ -202,7 +217,12 @@ func (td *DefaultDriver) runAction(action interface{}) error { case StartConsumerEvidenceDetectorAction: target.startConsumerEvidenceDetector(action, td.verbose) case SubmitChangeRewardDenomsProposalAction: - target.submitChangeRewardDenomsProposal(action, td.verbose) + target = td.getTargetDriver(action.Chain) + if semver.Compare(semver.Major(target.testConfig.providerVersion), "v5") < 0 { + target.submitChangeRewardDenomsLegacyProposal(action, td.verbose) + } else { + target.submitChangeRewardDenomsProposal(action, td.verbose) + } case OptInAction: target.optIn(action, td.target, td.verbose) case OptOutAction: From f499cd9ee14b5d47eb51dab7a6ca1da58254a684 Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Mon, 12 Aug 2024 10:00:26 +0200 Subject: [PATCH 08/11] addressed some more review comments --- docs/docs/upgrading/migrate_v5_v6.md | 17 +++-------------- tests/integration/provider_gov_hooks.go | 2 +- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/docs/docs/upgrading/migrate_v5_v6.md b/docs/docs/upgrading/migrate_v5_v6.md index 8244f546c0..3a38b386ff 100644 --- a/docs/docs/upgrading/migrate_v5_v6.md +++ b/docs/docs/upgrading/migrate_v5_v6.md @@ -18,25 +18,14 @@ ConensusVersion was bumped to `6`. ### Governance proposals -#### Consumer addition proposal - -```shell -interchain-security-pd tx gov submit-proposal -``` - -#### Consumer removal proposal - -```shell -interchain-security-pd tx gov submit-proposal -``` - -#### Consumer modification proposal +To submit a proposal to add/modify/remove a consumer use the following command ```shell interchain-security-pd tx gov submit-proposal ``` Run `interchain-security-pd tx gov draft-proposal` command and select in `other` one of the following -message types to generate a draft example: +message types to generate a draft proposal json file: - `/interchain_security.ccv.provider.v1.MsgConsumerAddition` - `/interchain_security.ccv.provider.v1.MsgConsumerModification` - `/interchain_security.ccv.provider.v1.MsgConsumerRemoval` +- `/interchain_security.ccv.provider.v1.MsgChangeRewardDenoms` diff --git a/tests/integration/provider_gov_hooks.go b/tests/integration/provider_gov_hooks.go index 68152198d3..813a62a671 100644 --- a/tests/integration/provider_gov_hooks.go +++ b/tests/integration/provider_gov_hooks.go @@ -60,7 +60,7 @@ func (s *CCVTestSuite) TestGetConsumerAdditionFromProp() { ) s.Require().NoError(err) - // create a valid consumer addition proposal + // create a valid consumer addition message msgConsumerAddition := testkeeper.GetTestMsgConsumerAddition() // create a legacy consumer addition proposal content From a4630a5e98e5c55250a04f109a16285311b186c0 Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Tue, 13 Aug 2024 12:16:14 +0200 Subject: [PATCH 09/11] addressed PR comments --- .../provider/2130-remove-legacy-proposal.md | 25 ++++- UPGRADING.md | 102 +++++++++++++++--- docs/docs/upgrading/migrate_v5_v6.md | 31 ------ x/ccv/provider/keeper/hooks.go | 2 +- 4 files changed, 110 insertions(+), 50 deletions(-) delete mode 100644 docs/docs/upgrading/migrate_v5_v6.md diff --git a/.changelog/unreleased/api-breaking/provider/2130-remove-legacy-proposal.md b/.changelog/unreleased/api-breaking/provider/2130-remove-legacy-proposal.md index 2d7a196aeb..404e134ea5 100644 --- a/.changelog/unreleased/api-breaking/provider/2130-remove-legacy-proposal.md +++ b/.changelog/unreleased/api-breaking/provider/2130-remove-legacy-proposal.md @@ -1,2 +1,25 @@ -- Remove support for legacy-proposal to add/modify/remove consumer proposals +- Remove support for legacy-proposal to add/modify/remove consumer proposals and change reward denoms ([\#2130](https://github.com/cosmos/interchain-security/pull/2130)) + To submit a proposal to add/modify/remove a consumer use the following command + ```shell + interchain-security-pd tx gov submit-proposal [proposal-file] + ``` + + Run `interchain-security-pd tx gov draft-proposal` command and select in `other` one of the following + message types to generate a draft proposal json file: + - `/interchain_security.ccv.provider.v1.MsgConsumerAddition` + + - `/interchain_security.ccv.provider.v1.MsgConsumerModification` + + - `/interchain_security.ccv.provider.v1.MsgConsumerRemoval` + + - `/interchain_security.ccv.provider.v1.MsgChangeRewardDenoms` + + This replaces the following command which are not supported anymore: + + ```shell + interchain-security-pd tx gov submit-legacy-proposal consumer-addition [proposal-file] + interchain-security-pd tx gov submit-legacy-proposal consumer-modification [proposal-file] + interchain-security-pd tx gov submit-legacy-proposal consumer-removal [proposal-file] + interchain-security-pd tx gov submit-legacy-proposal change-reward-denoms [proposal-file] + ``` \ No newline at end of file diff --git a/UPGRADING.md b/UPGRADING.md index 1cf021290b..a8d0ff1bcc 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -27,6 +27,74 @@ func InitializeMaxProviderConsensusParam(ctx sdk.Context, providerKeeper provide } ``` +### Governance Proposals + +Legacy proposals are not supported anymore by the current version of the provider. Legacy proposals which are still active (voting period or deposit period) and contains one of the following messages need to be migrated as described below: +- `ConsumerAdditionProposal` needs to be converted to `MsgConsumerAddition` +- `ConsumerModificationProposal` needs to be converted to `MsgConsumerModification` +- `ConsumerRemovalProposal` needs to be converted to `MsgConsumerRemoval` +- `ChangeRewardDenomsProposal` needs to be converted to `MsgChangeRewardDenoms` + +The following shows an example how to migrate a proposal containing a legacy consumer addition proposal message. +Migration for the other messages aobve follows the same pattern. The resulting migration code has to be added to the upgrade handler of the provider chain. + +#### Migrate Legacy Proposal Content + +```go + +// MigrateLegacyConsumerAddition converts a ConsumerAdditionProposal to a MsgConsumerAdditionProposal +// and returns it as `Any` suitable to replace the legacy message. +// `authority` contains the signer address +func MigrateLegacyConsumerAddition(msg providertypes.ConsumerAdditionProposal, authority string) (*codec.Any, error) { + sdkMsg := providertypes.MsgConsumerAddition{ + ChainId: msg.ChainId, + InitialHeight: msg.InitialHeight, + GenesisHash: msg.GenesisHash, + BinaryHash: msg.BinaryHash, + SpawnTime: msg.SpawnTime, + UnbondingPeriod: msg.UnbondingPeriod, + CcvTimeoutPeriod: msg.CcvTimeoutPeriod, + TransferTimeoutPeriod: msg.TransferTimeoutPeriod, + ConsumerRedistributionFraction: msg.ConsumerRedistributionFraction, + BlocksPerDistributionTransmission: msg.BlocksPerDistributionTransmission, + HistoricalEntries: msg.HistoricalEntries, + DistributionTransmissionChannel: msg.DistributionTransmissionChannel, + Top_N: msg.Top_N, + ValidatorsPowerCap: msg.ValidatorsPowerCap, + ValidatorSetCap: msg.ValidatorSetCap, + Allowlist: msg.Allowlist, + Denylist: msg.Denylist, + Authority: authority, + MinStake: msg.MinStake, + AllowInactiveVals: msg.AllowInactiveVals, + } + return codec.NewAnyWithValue(&sdkMsg) +} + +func MigrateProposal(proposal proposal govtypes.Proposal) err { + for idx, msg := range proposal.GetMessages() { + sdkLegacyMsg, isLegacyProposal := msg.GetCachedValue().(*govtypes.MsgExecLegacyContent) + if !isLegacyProposal { + continue + } + content, err := govtypes.LegacyContentFromMessage(sdkLegacyMsg) + if err != nil { + continue + } + + msgAdd, ok := content.(*providertypes.ConsumerAdditionProposal) + if ok { + anyMsg, err := migrateLegacyConsumerAddition(*msgAdd, govKeeper.GetAuthority()) + if err != nil { + return err + } + proposal.Messages[idx] = anyMsg + } + } + return govKeeper.SetProposal(ctx, proposal) +} +``` + ## [v5.1.x](https://github.com/cosmos/interchain-security/releases/tag/v5.1.0) ### Provider @@ -41,7 +109,7 @@ Upgrade code will be executed automatically during the upgrade procedure. ### Consumer -Upgrading the consumer from `v5.0.0` to `v5.1.0` will not require state migration. +Upgrading the consumer from `v5.0.0` to `v5.1.0` will not require state migration. This guide provides instructions for upgrading to specific versions of Replicated Security. @@ -55,7 +123,7 @@ v5.0.0 was a **consumer only release**. ### Consumer -Upgrading the consumer from `v4.x` to `v5.0.0` will require state migrations. +Upgrading the consumer from `v4.x` to `v5.0.0` will require state migrations. Consumer versions `v4.0.x`, `v4.1.x`, `v4.2.x`, `v4.3.x` and `v4.4.x` can cleanly be upgraded to `v5.0.0`. @@ -69,7 +137,7 @@ Upgrade code will be executed automatically during the upgrade procedure. ### Consumer -Upgrading the consumer from `v4.0.0` to `v4.4.0` will not require state migration. +Upgrading the consumer from `v4.0.0` to `v4.4.0` will not require state migration. This guide provides instructions for upgrading to specific versions of Replicated Security. @@ -77,7 +145,7 @@ This guide provides instructions for upgrading to specific versions of Replicate ### Provider -Upgrading a provider from `v4.2.0` to `v4.3.0` requires state migrations that will be done automatically via the upgrade module. +Upgrading a provider from `v4.2.0` to `v4.3.0` requires state migrations that will be done automatically via the upgrade module. ### Consumer @@ -132,17 +200,17 @@ func InitICSEpochs(ctx sdk.Context, pk providerkeeper.Keeper, sk stakingkeeper.K ## [v4.0.x](https://github.com/cosmos/interchain-security/tree/release/v4.0.x) -`v4.0.x` sets the minimum required version of Go to `1.21`, see https://github.com/cosmos/interchain-security/blob/release/v4.0.x/go.mod#L3. +`v4.0.x` sets the minimum required version of Go to `1.21`, see https://github.com/cosmos/interchain-security/blob/release/v4.0.x/go.mod#L3. -### Provider +### Provider -Upgrading a provider from `v3.3.0` to `v4.0.0` will require state migrations, see https://github.com/cosmos/interchain-security/blob/release/v4.0.x/x/ccv/provider/migrations/migrator.go#L31. +Upgrading a provider from `v3.3.0` to `v4.0.0` will require state migrations, see https://github.com/cosmos/interchain-security/blob/release/v4.0.x/x/ccv/provider/migrations/migrator.go#L31. -### Consumer +### Consumer -***Note that consumer chains can upgrade directly from `v3.1.0` to `v4.0.0`.*** +***Note that consumer chains can upgrade directly from `v3.1.0` to `v4.0.0`.*** -Upgrading a consumer from `v3.2.0` to `v4.0.0` will not require state migration, however, upgrading directly from `v3.1.0` to `v4.0.0` will require state migrations, see https://github.com/cosmos/interchain-security/blob/release/v4.0.x/x/ccv/consumer/keeper/migrations.go#L22. +Upgrading a consumer from `v3.2.0` to `v4.0.0` will not require state migration, however, upgrading directly from `v3.1.0` to `v4.0.0` will require state migrations, see https://github.com/cosmos/interchain-security/blob/release/v4.0.x/x/ccv/consumer/keeper/migrations.go#L22. In addition, the following migration needs to be added to the upgrade handler of the consumer chain: ```golang @@ -166,15 +234,15 @@ func migrateICSOutstandingDowntime(ctx sdk.Context, keepers *upgrades.UpgradeKee ## [v3.3.x](https://github.com/cosmos/interchain-security/tree/release/v3.2.x) -### Provider +### Provider -Upgrading the provider from `v2.x.y` to `v3.3.0` will not require state migration. +Upgrading the provider from `v2.x.y` to `v3.3.0` will not require state migration. ## [v3.2.x](https://github.com/cosmos/interchain-security/tree/release/v3.2.x) `v3.2.0` bumps IBC to `v7.3`. As a result, `legacy_ibc_testing` is not longer required and was removed, see https://github.com/cosmos/interchain-security/pull/1185. This means that when upgrading to `v3.2.0`, any customized tests relying on `legacy_ibc_testing` need to be updated. -### Consumer +### Consumer Upgrading the consumer from either `v3.0.0` or `v3.1.0` to `v3.2.0` will require state migrations, see https://github.com/cosmos/interchain-security/blob/release/v3.2.x/x/ccv/consumer/keeper/migration.go#L25. @@ -184,13 +252,13 @@ Upgrading the consumer from either `v3.0.0` or `v3.1.0` to `v3.2.0` will require The following should be considered as complementary to [Cosmos SDK v0.47 UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc2/UPGRADING.md). -#### Protobuf +#### Protobuf Protobuf code generation, linting and formatting have been updated to leverage the `ghcr.io/cosmos/proto-builder:0.11.5` docker container. Replicated Security protobuf definitions are now packaged and published to [buf.build/cosmos/interchain-security](https://buf.build/cosmos/interchain-security) via CI workflows. The `third_party/proto` directory has been removed in favour of dependency management using [buf.build](https://docs.buf.build/introduction). #### App modules -Legacy APIs of the `AppModule` interface have been removed from ccv modules. For example, for +Legacy APIs of the `AppModule` interface have been removed from ccv modules. For example, for ```diff - // Route implements the AppModule interface @@ -240,10 +308,10 @@ import ( ## [v2.0.x](https://github.com/cosmos/interchain-security/releases/tag/v2.0.0) -### Provider +### Provider Upgrading a provider from `v1.1.0-multiden` to `v2.0.0` will require state migrations. See [migration.go](https://github.com/cosmos/interchain-security/blob/v2.0.0/x/ccv/provider/keeper/migration.go). ### Consumer -Upgrading a consumer from `v1.2.0-multiden` to `v2.0.0` will NOT require state migrations. +Upgrading a consumer from `v1.2.0-multiden` to `v2.0.0` will NOT require state migrations. diff --git a/docs/docs/upgrading/migrate_v5_v6.md b/docs/docs/upgrading/migrate_v5_v6.md deleted file mode 100644 index 3a38b386ff..0000000000 --- a/docs/docs/upgrading/migrate_v5_v6.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Upgrading to ICS v6.x from v5.x - -ICS specific changes are outlined below. - -Pre-requisite version for this upgrade: any from the `v5.x` release line. - -## Note - -## Provider - -### Migration (v5 -> v6) - -ConensusVersion was bumped to `6`. - -### Governance proposals - -To submit a proposal to add/modify/remove a consumer use the following command -```shell -interchain-security-pd tx gov submit-proposal -``` - -Run `interchain-security-pd tx gov draft-proposal` command and select in `other` one of the following -message types to generate a draft proposal json file: -- `/interchain_security.ccv.provider.v1.MsgConsumerAddition` -- `/interchain_security.ccv.provider.v1.MsgConsumerModification` -- `/interchain_security.ccv.provider.v1.MsgConsumerRemoval` -- `/interchain_security.ccv.provider.v1.MsgChangeRewardDenoms` diff --git a/x/ccv/provider/keeper/hooks.go b/x/ccv/provider/keeper/hooks.go index 5005795166..a72f60080f 100644 --- a/x/ccv/provider/keeper/hooks.go +++ b/x/ccv/provider/keeper/hooks.go @@ -141,7 +141,7 @@ func (h Hooks) AfterProposalFailedMinDeposit(ctx context.Context, proposalID uin return nil } -// GetConsumerAdditionFromProp extracts a consumer addition legacy proposal from +// GetConsumerAdditionFromProp extracts a consumer addition proposal from // the proposal with the given ID func (h Hooks) GetConsumerAdditionFromProp( ctx sdk.Context, From 55835d1b9f705a92cabd7e2686f4995988058f5a Mon Sep 17 00:00:00 2001 From: Bernd Mueller Date: Tue, 13 Aug 2024 16:14:06 +0200 Subject: [PATCH 10/11] fix e2e when run on current ws (invalid sem version) --- tests/e2e/test_driver.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/e2e/test_driver.go b/tests/e2e/test_driver.go index 4eecbfe152..e25b27f330 100644 --- a/tests/e2e/test_driver.go +++ b/tests/e2e/test_driver.go @@ -141,14 +141,16 @@ func (td *DefaultDriver) runAction(action interface{}) error { target.submitTextProposal(action, td.verbose) case SubmitConsumerAdditionProposalAction: target = td.getTargetDriver(action.Chain) - if semver.Compare(semver.Major(target.testConfig.providerVersion), "v5") < 0 { + version := target.testConfig.providerVersion + if semver.IsValid(version) && semver.Compare(semver.Major(version), "v5") < 0 { target.submitConsumerAdditionLegacyProposal(action, td.verbose) } else { target.submitConsumerAdditionProposal(action, td.verbose) } case SubmitConsumerRemovalProposalAction: + version := target.testConfig.providerVersion target = td.getTargetDriver(action.Chain) - if semver.Compare(semver.Major(target.testConfig.providerVersion), "v5") < 0 { + if semver.IsValid(version) && semver.Compare(semver.Major(version), "v5") < 0 { target.submitConsumerRemovalLegacyProposal(action, td.verbose) } else { target.submitConsumerRemovalProposal(action, td.verbose) @@ -157,7 +159,8 @@ func (td *DefaultDriver) runAction(action interface{}) error { target.submitEnableTransfersProposalAction(action, td.verbose) case SubmitConsumerModificationProposalAction: target = td.getTargetDriver(action.Chain) - if semver.Compare(semver.Major(target.testConfig.providerVersion), "v5") < 0 { + version := target.testConfig.providerVersion + if semver.IsValid(version) && semver.Compare(semver.Major(version), "v5") < 0 { target.submitConsumerModificationLegacyProposal(action, td.verbose) } else { target.submitConsumerModificationProposal(action, td.verbose) From bd26ec6e09bd12107403db07410d1da9503dcaca Mon Sep 17 00:00:00 2001 From: bernd-m <43466467+bermuell@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:07:07 +0200 Subject: [PATCH 11/11] Apply suggestions from code review Co-authored-by: insumity --- UPGRADING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index a8d0ff1bcc..a3f2d5e84d 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -29,13 +29,13 @@ func InitializeMaxProviderConsensusParam(ctx sdk.Context, providerKeeper provide ### Governance Proposals -Legacy proposals are not supported anymore by the current version of the provider. Legacy proposals which are still active (voting period or deposit period) and contains one of the following messages need to be migrated as described below: +Legacy proposals are not supported anymore by the current version of the provider. Legacy proposals which are still active (voting period or deposit period) and contain one of the following messages that need to be migrated as described below: - `ConsumerAdditionProposal` needs to be converted to `MsgConsumerAddition` - `ConsumerModificationProposal` needs to be converted to `MsgConsumerModification` - `ConsumerRemovalProposal` needs to be converted to `MsgConsumerRemoval` - `ChangeRewardDenomsProposal` needs to be converted to `MsgChangeRewardDenoms` -The following shows an example how to migrate a proposal containing a legacy consumer addition proposal message. +The following shows an example on how to migrate a proposal containing a legacy consumer addition proposal message. Migration for the other messages aobve follows the same pattern. The resulting migration code has to be added to the upgrade handler of the provider chain. #### Migrate Legacy Proposal Content