Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(gov): support v1.Proposal in v1beta1.Proposal.Content (backport #14347) #14400

Merged
merged 2 commits into from
Dec 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

### Improvements

* (x/gov) [#14347](https://github.com/cosmos/cosmos-sdk/pull/14347) Support `v1.Proposal` message in `v1beta1.Proposal.Content`.

## [v0.46.7](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.7) - 2022-12-13

### Features
Expand Down
28 changes: 19 additions & 9 deletions x/gov/migrations/v046/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
Expand All @@ -13,6 +14,7 @@ import (
// ConvertToLegacyProposal takes a new proposal and attempts to convert it to the
// legacy proposal format. This conversion is best effort. New proposal types that
// don't have a legacy message will return a "nil" content.
// Returns error when the amount of messages in `proposal` is different than one.
func ConvertToLegacyProposal(proposal v1.Proposal) (v1beta1.Proposal, error) {
var err error
legacyProposal := v1beta1.Proposal{
Expand Down Expand Up @@ -46,17 +48,25 @@ func ConvertToLegacyProposal(proposal v1.Proposal) (v1beta1.Proposal, error) {
if err != nil {
return v1beta1.Proposal{}, err
}
for _, msg := range msgs {
if legacyMsg, ok := msg.(*v1.MsgExecLegacyContent); ok {
// check that the content struct can be unmarshalled
_, err := v1.LegacyContentFromMessage(legacyMsg)
if err != nil {
return v1beta1.Proposal{}, err
}
legacyProposal.Content = legacyMsg.Content
if len(msgs) != 1 {
return v1beta1.Proposal{}, sdkerrors.ErrInvalidType.Wrap("can't convert a gov/v1 Proposal to gov/v1beta1 Proposal when amount of proposal messages is more than one")
}
if legacyMsg, ok := msgs[0].(*v1.MsgExecLegacyContent); ok {
// check that the content struct can be unmarshalled
_, err := v1.LegacyContentFromMessage(legacyMsg)
if err != nil {
return v1beta1.Proposal{}, err
}
legacyProposal.Content = legacyMsg.Content
return legacyProposal, nil
}
return legacyProposal, nil
// hack to fill up the content with the first message
// this is to support clients that have not yet (properly) use gov/v1 endpoints
// https://github.com/cosmos/cosmos-sdk/issues/14334
// VerifyBasic assures that we have at least one message.
legacyProposal.Content, err = codectypes.NewAnyWithValue(msgs[0])

return legacyProposal, err
}

func ConvertToLegacyTallyResult(tally *v1.TallyResult) (v1beta1.TallyResult, error) {
Expand Down
36 changes: 36 additions & 0 deletions x/gov/migrations/v046/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx"
v046 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v046"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -60,11 +62,45 @@ func TestConvertToLegacyProposal(t *testing.T) {
require.Equal(t, v1beta1Proposal.FinalTallyResult.No, sdk.NewInt(0))
require.Equal(t, v1beta1Proposal.FinalTallyResult.NoWithVeto, sdk.NewInt(0))
require.Equal(t, v1beta1Proposal.FinalTallyResult.Abstain, sdk.NewInt(0))
tp, ok := v1beta1Proposal.Content.GetCachedValue().(*v1beta1.TextProposal)
require.Truef(t, ok, "expected *TextProposal, got %T", v1beta1Proposal.Content.GetCachedValue())
require.Equal(t, tp.Title, "title")
require.Equal(t, tp.Description, "description")
}
})
}
}

func TestConvertToLegacyProposalContent(t *testing.T) {
msg := upgradetypes.MsgSoftwareUpgrade{Authority: "gov module", Plan: upgradetypes.Plan{Name: "test upgrade"}}
msgsAny, err := tx.SetMsgs([]sdk.Msg{&msg})
require.NoError(t, err)
tallyResult := v1.EmptyTallyResult()
proposal := v1.Proposal{
Id: 1,
Status: v1.StatusDepositPeriod,
Messages: msgsAny,
Metadata: "proposal metadata",
FinalTallyResult: &tallyResult,
}

legacyP, err := v046.ConvertToLegacyProposal(proposal)
require.NoError(t, err)
tp, ok := legacyP.Content.GetCachedValue().(*upgradetypes.MsgSoftwareUpgrade)
require.Truef(t, ok, "expected *MsgSoftwareUpgrade, got %T", legacyP.Content.GetCachedValue())
require.Equal(t, &msg, tp)

// more than one message is not supported
proposal.Messages, err = tx.SetMsgs([]sdk.Msg{&msg, &msg})
require.NoError(t, err)
_, err = v046.ConvertToLegacyProposal(proposal)
require.ErrorIs(t, sdkerrors.ErrInvalidType, err)

// zero messages is not supported
proposal.Messages = nil
_, err = v046.ConvertToLegacyProposal(proposal)
require.ErrorIs(t, sdkerrors.ErrInvalidType, err)
}
func TestConvertToLegacyTallyResult(t *testing.T) {
tallyResult := v1.EmptyTallyResult()
testCases := map[string]struct {
Expand Down