diff --git a/proto/cosmos/upgrade/v1beta1/upgrade.proto b/proto/cosmos/upgrade/v1beta1/upgrade.proto index 826440e5d7..6d6839ca56 100644 --- a/proto/cosmos/upgrade/v1beta1/upgrade.proto +++ b/proto/cosmos/upgrade/v1beta1/upgrade.proto @@ -40,7 +40,6 @@ message Plan { // previous version of the chain. // This will allow IBC connections to persist smoothly across planned chain upgrades google.protobuf.Any upgraded_client_state = 5 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; - ; } // SoftwareUpgradeProposal is a gov Content type for initiating a software diff --git a/x/upgrade/types/proposal.go b/x/upgrade/types/proposal.go index d4ae8422ea..a8ea9b6290 100644 --- a/x/upgrade/types/proposal.go +++ b/x/upgrade/types/proposal.go @@ -3,6 +3,7 @@ package types import ( "fmt" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" gov "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -17,6 +18,7 @@ func NewSoftwareUpgradeProposal(title, description string, plan Plan) gov.Conten // Implements Proposal Interface var _ gov.Content = &SoftwareUpgradeProposal{} +var _ codectypes.UnpackInterfacesMessage = SoftwareUpgradeProposal{} func init() { gov.RegisterProposalType(ProposalTypeSoftwareUpgrade) @@ -43,6 +45,11 @@ func (sup SoftwareUpgradeProposal) String() string { `, sup.Title, sup.Description) } +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces +func (sup SoftwareUpgradeProposal) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + return sup.Plan.UnpackInterfaces(unpacker) +} + func NewCancelSoftwareUpgradeProposal(title, description string) gov.Content { return &CancelSoftwareUpgradeProposal{title, description} } @@ -50,19 +57,19 @@ func NewCancelSoftwareUpgradeProposal(title, description string) gov.Content { // Implements Proposal Interface var _ gov.Content = &CancelSoftwareUpgradeProposal{} -func (sup *CancelSoftwareUpgradeProposal) GetTitle() string { return sup.Title } -func (sup *CancelSoftwareUpgradeProposal) GetDescription() string { return sup.Description } -func (sup *CancelSoftwareUpgradeProposal) ProposalRoute() string { return RouterKey } -func (sup *CancelSoftwareUpgradeProposal) ProposalType() string { +func (csup *CancelSoftwareUpgradeProposal) GetTitle() string { return csup.Title } +func (csup *CancelSoftwareUpgradeProposal) GetDescription() string { return csup.Description } +func (csup *CancelSoftwareUpgradeProposal) ProposalRoute() string { return RouterKey } +func (csup *CancelSoftwareUpgradeProposal) ProposalType() string { return ProposalTypeCancelSoftwareUpgrade } -func (sup *CancelSoftwareUpgradeProposal) ValidateBasic() error { - return gov.ValidateAbstract(sup) +func (csup *CancelSoftwareUpgradeProposal) ValidateBasic() error { + return gov.ValidateAbstract(csup) } -func (sup CancelSoftwareUpgradeProposal) String() string { +func (csup CancelSoftwareUpgradeProposal) String() string { return fmt.Sprintf(`Cancel Software Upgrade Proposal: Title: %s Description: %s -`, sup.Title, sup.Description) +`, csup.Title, csup.Description) } diff --git a/x/upgrade/types/proposal_test.go b/x/upgrade/types/proposal_test.go index 8f5ffb07a7..d39b89135c 100644 --- a/x/upgrade/types/proposal_test.go +++ b/x/upgrade/types/proposal_test.go @@ -7,7 +7,10 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" gov "github.com/cosmos/cosmos-sdk/x/gov/types" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) @@ -75,3 +78,41 @@ func TestContentAccessors(t *testing.T) { } } + +// tests a software update proposal can be marshaled and unmarshaled, and the +// client state can be unpacked +func TestMarshalSoftwareUpdateProposal(t *testing.T) { + cs, err := clienttypes.PackClientState(&ibctmtypes.ClientState{}) + require.NoError(t, err) + + // create proposal + plan := types.Plan{ + Name: "upgrade ibc", + Height: 1000, + UpgradedClientState: cs, + } + content := types.NewSoftwareUpgradeProposal("title", "description", plan) + sup, ok := content.(*types.SoftwareUpgradeProposal) + require.True(t, ok) + + // create codec + ir := codectypes.NewInterfaceRegistry() + types.RegisterInterfaces(ir) + clienttypes.RegisterInterfaces(ir) + gov.RegisterInterfaces(ir) + ibctmtypes.RegisterInterfaces(ir) + cdc := codec.NewProtoCodec(ir) + + // marshal message + bz, err := cdc.MarshalJSON(sup) + require.NoError(t, err) + + // unmarshal proposal + newSup := &types.SoftwareUpgradeProposal{} + err = cdc.UnmarshalJSON(bz, newSup) + require.NoError(t, err) + + // unpack client state + _, err = clienttypes.UnpackClientState(newSup.Plan.UpgradedClientState) + require.NoError(t, err) +}