Add CommunitySpendProposals in migration (#7607)
* Add CommunitySpendProposals in migration * Fix lint * Avoid double registration Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
c6558fbcb9
commit
3c43370d0c
|
@ -3,8 +3,14 @@
|
|||
package v036
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v034distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v034"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -13,6 +19,12 @@ import (
|
|||
|
||||
const (
|
||||
ModuleName = "distribution"
|
||||
|
||||
// RouterKey is the message route for distribution
|
||||
RouterKey = ModuleName
|
||||
|
||||
// ProposalTypeCommunityPoolSpend defines the type for a CommunityPoolSpendProposal
|
||||
ProposalTypeCommunityPoolSpend = "CommunityPoolSpend"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -40,6 +52,14 @@ type (
|
|||
DelegatorStartingInfos []v034distr.DelegatorStartingInfoRecord `json:"delegator_starting_infos"`
|
||||
ValidatorSlashEvents []ValidatorSlashEventRecord `json:"validator_slash_events"`
|
||||
}
|
||||
|
||||
// CommunityPoolSpendProposal spends from the community pool
|
||||
CommunityPoolSpendProposal struct {
|
||||
Title string `json:"title" yaml:"title"`
|
||||
Description string `json:"description" yaml:"description"`
|
||||
Recipient sdk.AccAddress `json:"recipient" yaml:"recipient"`
|
||||
Amount sdk.Coins `json:"amount" yaml:"amount"`
|
||||
}
|
||||
)
|
||||
|
||||
func NewGenesisState(
|
||||
|
@ -66,3 +86,49 @@ func NewGenesisState(
|
|||
ValidatorSlashEvents: slashes,
|
||||
}
|
||||
}
|
||||
|
||||
var _ v036gov.Content = CommunityPoolSpendProposal{}
|
||||
|
||||
// GetTitle returns the title of a community pool spend proposal.
|
||||
func (csp CommunityPoolSpendProposal) GetTitle() string { return csp.Title }
|
||||
|
||||
// GetDescription returns the description of a community pool spend proposal.
|
||||
func (csp CommunityPoolSpendProposal) GetDescription() string { return csp.Description }
|
||||
|
||||
// GetDescription returns the routing key of a community pool spend proposal.
|
||||
func (csp CommunityPoolSpendProposal) ProposalRoute() string { return RouterKey }
|
||||
|
||||
// ProposalType returns the type of a community pool spend proposal.
|
||||
func (csp CommunityPoolSpendProposal) ProposalType() string { return ProposalTypeCommunityPoolSpend }
|
||||
|
||||
// ValidateBasic runs basic stateless validity checks
|
||||
func (csp CommunityPoolSpendProposal) ValidateBasic() error {
|
||||
err := v036gov.ValidateAbstract(csp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !csp.Amount.IsValid() {
|
||||
return types.ErrInvalidProposalAmount
|
||||
}
|
||||
if csp.Recipient.Empty() {
|
||||
return types.ErrEmptyProposalRecipient
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements the Stringer interface.
|
||||
func (csp CommunityPoolSpendProposal) String() string {
|
||||
var b strings.Builder
|
||||
b.WriteString(fmt.Sprintf(`Community Pool Spend Proposal:
|
||||
Title: %s
|
||||
Description: %s
|
||||
Recipient: %s
|
||||
Amount: %s
|
||||
`, csp.Title, csp.Description, csp.Recipient, csp.Amount))
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
||||
cdc.RegisterConcrete(CommunityPoolSpendProposal{}, "cosmos-sdk/CommunityPoolSpendProposal", nil)
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ func Migrate(appState types.AppMap, _ client.Context) types.AppMap {
|
|||
v036Codec := codec.NewLegacyAmino()
|
||||
cryptocodec.RegisterCrypto(v036Codec)
|
||||
v036gov.RegisterLegacyAminoCodec(v036Codec)
|
||||
v036distr.RegisterLegacyAminoCodec(v036Codec)
|
||||
|
||||
// migrate genesis accounts state
|
||||
if appState[v034genAccounts.ModuleName] != nil {
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
v038distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v038"
|
||||
v036genaccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v036"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036"
|
||||
v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v036"
|
||||
v038staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v038"
|
||||
)
|
||||
|
@ -18,10 +19,14 @@ import (
|
|||
func Migrate(appState types.AppMap, _ client.Context) types.AppMap {
|
||||
v036Codec := codec.NewLegacyAmino()
|
||||
cryptocodec.RegisterCrypto(v036Codec)
|
||||
v036gov.RegisterLegacyAminoCodec(v036Codec)
|
||||
v036distr.RegisterLegacyAminoCodec(v036Codec)
|
||||
|
||||
v038Codec := codec.NewLegacyAmino()
|
||||
cryptocodec.RegisterCrypto(v038Codec)
|
||||
v038auth.RegisterLegacyAminoCodec(v038Codec)
|
||||
v036gov.RegisterLegacyAminoCodec(v038Codec)
|
||||
v036distr.RegisterLegacyAminoCodec(v038Codec)
|
||||
|
||||
if appState[v036genaccounts.ModuleName] != nil {
|
||||
// unmarshal relative source genesis application state
|
||||
|
|
|
@ -6,7 +6,9 @@ import (
|
|||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v038"
|
||||
v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v039"
|
||||
v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v036"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036"
|
||||
)
|
||||
|
||||
// Migrate migrates exported state from v0.38 to a v0.39 genesis state.
|
||||
|
@ -17,10 +19,14 @@ func Migrate(appState types.AppMap, _ client.Context) types.AppMap {
|
|||
v038Codec := codec.NewLegacyAmino()
|
||||
cryptocodec.RegisterCrypto(v038Codec)
|
||||
v038auth.RegisterLegacyAminoCodec(v038Codec)
|
||||
v036gov.RegisterLegacyAminoCodec(v038Codec)
|
||||
v036distr.RegisterLegacyAminoCodec(v038Codec)
|
||||
|
||||
v039Codec := codec.NewLegacyAmino()
|
||||
cryptocodec.RegisterCrypto(v039Codec)
|
||||
v039auth.RegisterLegacyAminoCodec(v039Codec)
|
||||
v036gov.RegisterLegacyAminoCodec(v039Codec)
|
||||
v036distr.RegisterLegacyAminoCodec(v039Codec)
|
||||
|
||||
// migrate x/auth state (JSON serialization only)
|
||||
if appState[v038auth.ModuleName] != nil {
|
||||
|
|
|
@ -11,8 +11,9 @@ import (
|
|||
v040bank "github.com/cosmos/cosmos-sdk/x/bank/legacy/v040"
|
||||
v039crisis "github.com/cosmos/cosmos-sdk/x/crisis/legacy/v039"
|
||||
v040crisis "github.com/cosmos/cosmos-sdk/x/crisis/legacy/v040"
|
||||
v038distribution "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v038"
|
||||
v040distribution "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v040"
|
||||
v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v036"
|
||||
v038distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v038"
|
||||
v040distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v040"
|
||||
v038evidence "github.com/cosmos/cosmos-sdk/x/evidence/legacy/v038"
|
||||
v040evidence "github.com/cosmos/cosmos-sdk/x/evidence/legacy/v040"
|
||||
v039genutil "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v039"
|
||||
|
@ -38,6 +39,8 @@ func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap {
|
|||
v039Codec := codec.NewLegacyAmino()
|
||||
cryptocodec.RegisterCrypto(v039Codec)
|
||||
v039auth.RegisterLegacyAminoCodec(v039Codec)
|
||||
v036gov.RegisterLegacyAminoCodec(v039Codec)
|
||||
v036distr.RegisterLegacyAminoCodec(v039Codec)
|
||||
|
||||
v040Codec := clientCtx.JSONMarshaler
|
||||
|
||||
|
@ -94,17 +97,17 @@ func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap {
|
|||
}
|
||||
|
||||
// Migrate x/distribution.
|
||||
if appState[v038distribution.ModuleName] != nil {
|
||||
if appState[v038distr.ModuleName] != nil {
|
||||
// unmarshal relative source genesis application state
|
||||
var distributionGenState v038distribution.GenesisState
|
||||
v039Codec.MustUnmarshalJSON(appState[v038distribution.ModuleName], &distributionGenState)
|
||||
var distributionGenState v038distr.GenesisState
|
||||
v039Codec.MustUnmarshalJSON(appState[v038distr.ModuleName], &distributionGenState)
|
||||
|
||||
// delete deprecated x/distribution genesis state
|
||||
delete(appState, v038distribution.ModuleName)
|
||||
delete(appState, v038distr.ModuleName)
|
||||
|
||||
// Migrate relative source genesis application state and marshal it into
|
||||
// the respective key.
|
||||
appState[v040distribution.ModuleName] = v040Codec.MustMarshalJSON(v040distribution.Migrate(distributionGenState))
|
||||
appState[v040distr.ModuleName] = v040Codec.MustMarshalJSON(v040distr.Migrate(distributionGenState))
|
||||
}
|
||||
|
||||
// Migrate x/evidence.
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"fmt"
|
||||
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v036"
|
||||
v040distr "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v034"
|
||||
v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036"
|
||||
v040gov "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
|
@ -59,10 +61,30 @@ func migrateProposalStatus(oldProposalStatus v034gov.ProposalStatus) v040gov.Pro
|
|||
|
||||
func migrateContent(oldContent v036gov.Content) *codectypes.Any {
|
||||
switch oldContent := oldContent.(type) {
|
||||
case *v040gov.TextProposal:
|
||||
case v036gov.TextProposal:
|
||||
{
|
||||
protoProposal := &v040gov.TextProposal{
|
||||
Title: oldContent.Title,
|
||||
Description: oldContent.Description,
|
||||
}
|
||||
// Convert the content into Any.
|
||||
contentAny, err := codectypes.NewAnyWithValue(oldContent)
|
||||
contentAny, err := codectypes.NewAnyWithValue(protoProposal)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return contentAny
|
||||
}
|
||||
case v036distr.CommunityPoolSpendProposal:
|
||||
{
|
||||
protoProposal := &v040distr.CommunityPoolSpendProposal{
|
||||
Title: oldContent.Title,
|
||||
Description: oldContent.Description,
|
||||
Recipient: oldContent.Recipient.String(),
|
||||
Amount: oldContent.Amount,
|
||||
}
|
||||
// Convert the content into Any.
|
||||
contentAny, err := codectypes.NewAnyWithValue(protoProposal)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
package v040_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v036"
|
||||
v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036"
|
||||
v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040"
|
||||
)
|
||||
|
||||
func TestMigrate(t *testing.T) {
|
||||
encodingConfig := simapp.MakeEncodingConfig()
|
||||
clientCtx := client.Context{}.
|
||||
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
|
||||
WithTxConfig(encodingConfig.TxConfig).
|
||||
WithLegacyAmino(encodingConfig.Amino).
|
||||
WithJSONMarshaler(encodingConfig.Marshaler)
|
||||
|
||||
recipient, err := sdk.AccAddressFromBech32("cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh")
|
||||
require.NoError(t, err)
|
||||
govGenState := v036gov.GenesisState{
|
||||
Proposals: []v036gov.Proposal{
|
||||
{
|
||||
Content: v036gov.TextProposal{
|
||||
Title: "foo_test",
|
||||
Description: "bar_test",
|
||||
},
|
||||
},
|
||||
{
|
||||
Content: v036distr.CommunityPoolSpendProposal{
|
||||
Title: "foo_community",
|
||||
Description: "bar_community",
|
||||
Recipient: recipient,
|
||||
Amount: sdk.NewCoins(sdk.NewCoin("footoken", sdk.NewInt(2))),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migrated := v040gov.Migrate(govGenState)
|
||||
|
||||
bz, err := clientCtx.JSONMarshaler.MarshalJSON(migrated)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Indent the JSON bz correctly.
|
||||
var jsonObj map[string]interface{}
|
||||
err = json.Unmarshal(bz, &jsonObj)
|
||||
require.NoError(t, err)
|
||||
indentedBz, err := json.MarshalIndent(jsonObj, "", " ")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Make sure about:
|
||||
// - TextProposal and CommunityPoolSpendProposal have correct any JSON.
|
||||
expected := `{
|
||||
"deposit_params": {
|
||||
"max_deposit_period": "0s",
|
||||
"min_deposit": []
|
||||
},
|
||||
"deposits": [],
|
||||
"proposals": [
|
||||
{
|
||||
"content": {
|
||||
"@type": "/cosmos.gov.v1beta1.TextProposal",
|
||||
"description": "bar_test",
|
||||
"title": "foo_test"
|
||||
},
|
||||
"deposit_end_time": "0001-01-01T00:00:00Z",
|
||||
"final_tally_result": {
|
||||
"abstain": "0",
|
||||
"no": "0",
|
||||
"no_with_veto": "0",
|
||||
"yes": "0"
|
||||
},
|
||||
"proposal_id": "0",
|
||||
"status": "PROPOSAL_STATUS_UNSPECIFIED",
|
||||
"submit_time": "0001-01-01T00:00:00Z",
|
||||
"total_deposit": [],
|
||||
"voting_end_time": "0001-01-01T00:00:00Z",
|
||||
"voting_start_time": "0001-01-01T00:00:00Z"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"@type": "/cosmos.distribution.v1beta1.CommunityPoolSpendProposal",
|
||||
"amount": [
|
||||
{
|
||||
"amount": "2",
|
||||
"denom": "footoken"
|
||||
}
|
||||
],
|
||||
"description": "bar_community",
|
||||
"recipient": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh",
|
||||
"title": "foo_community"
|
||||
},
|
||||
"deposit_end_time": "0001-01-01T00:00:00Z",
|
||||
"final_tally_result": {
|
||||
"abstain": "0",
|
||||
"no": "0",
|
||||
"no_with_veto": "0",
|
||||
"yes": "0"
|
||||
},
|
||||
"proposal_id": "0",
|
||||
"status": "PROPOSAL_STATUS_UNSPECIFIED",
|
||||
"submit_time": "0001-01-01T00:00:00Z",
|
||||
"total_deposit": [],
|
||||
"voting_end_time": "0001-01-01T00:00:00Z",
|
||||
"voting_start_time": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
],
|
||||
"starting_proposal_id": "0",
|
||||
"tally_params": {
|
||||
"quorum": "0",
|
||||
"threshold": "0",
|
||||
"veto_threshold": "0"
|
||||
},
|
||||
"votes": [],
|
||||
"voting_params": {
|
||||
"voting_period": "0s"
|
||||
}
|
||||
}`
|
||||
|
||||
require.Equal(t, expected, string(indentedBz))
|
||||
}
|
Loading…
Reference in New Issue