package v2_test import ( "bytes" "testing" "time" "github.com/stretchr/testify/require" "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" "git.cw.tr/mukan-network/mukan-sdk/runtime" "git.cw.tr/mukan-network/mukan-sdk/testutil" "git.cw.tr/mukan-network/mukan-sdk/testutil/testdata" sdk "git.cw.tr/mukan-network/mukan-sdk/types" "git.cw.tr/mukan-network/mukan-sdk/types/address" moduletestutil "git.cw.tr/mukan-network/mukan-sdk/types/module/testutil" v1 "git.cw.tr/mukan-network/mukan-sdk/x/gov/migrations/v1" v2 "git.cw.tr/mukan-network/mukan-sdk/x/gov/migrations/v2" "git.cw.tr/mukan-network/mukan-sdk/x/gov/types" "git.cw.tr/mukan-network/mukan-sdk/x/gov/types/v1beta1" ) func TestMigrateStore(t *testing.T) { cdc := moduletestutil.MakeTestEncodingConfig().Codec govKey := storetypes.NewKVStoreKey("gov") ctx := testutil.DefaultContext(govKey, storetypes.NewTransientStoreKey("transient_test")) store := ctx.KVStore(govKey) _, _, addr1 := testdata.KeyTestPubAddr() proposalID := uint64(6) now := time.Now() // Use dummy value for keys where we don't test values. dummyValue := []byte("foo") // Use real values for votes, as we're testing weighted votes. oldVote := v1beta1.Vote{ProposalId: 1, Voter: "foobar", Option: v1beta1.OptionNoWithVeto} oldVoteValue := cdc.MustMarshal(&oldVote) newVote := v1beta1.Vote{ProposalId: 1, Voter: "foobar", Options: v1beta1.WeightedVoteOptions{{Option: v1beta1.OptionNoWithVeto, Weight: math.LegacyNewDec(1)}}} newVoteValue := cdc.MustMarshal(&newVote) testCases := []struct { name string oldKey, oldValue, newKey, newValue []byte }{ { "ProposalKey", v1.ProposalKey(proposalID), dummyValue, append(types.ProposalsKeyPrefix, sdk.Uint64ToBigEndian(proposalID)...), dummyValue, }, { "ActiveProposalQueue", v1.ActiveProposalQueueKey(proposalID, now), dummyValue, activeProposalQueueKey(proposalID, now), dummyValue, }, { "InactiveProposalQueue", v1.InactiveProposalQueueKey(proposalID, now), dummyValue, inactiveProposalQueueKey(proposalID, now), dummyValue, }, { "ProposalIDKey", v1.ProposalIDKey, dummyValue, types.ProposalIDKey, dummyValue, }, { "DepositKey", v1.DepositKey(proposalID, addr1), dummyValue, depositKey(proposalID, addr1), dummyValue, }, { "VotesKeyPrefix", v1.VoteKey(proposalID, addr1), oldVoteValue, voteKey(proposalID, addr1), newVoteValue, }, } // Set all the old keys to the store for _, tc := range testCases { store.Set(tc.oldKey, tc.oldValue) } // Run migration storeService := runtime.NewKVStoreService(govKey) err := v2.MigrateStore(ctx, storeService, cdc) require.NoError(t, err) // Make sure the new keys are set and old keys are deleted. for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { if !bytes.Equal(tc.oldKey, tc.newKey) { require.Nil(t, store.Get(tc.oldKey)) } require.Equal(t, tc.newValue, store.Get(tc.newKey)) }) } } // TODO(tip): remove all the functions below once we delete the migrations func depositKey(proposalID uint64, depositorAddr sdk.AccAddress) []byte { return append(append(types.DepositsKeyPrefix, sdk.Uint64ToBigEndian(proposalID)...), address.MustLengthPrefix(depositorAddr.Bytes())...) } func voteKey(proposalID uint64, addr sdk.AccAddress) []byte { return append(append(types.VotesKeyPrefix, sdk.Uint64ToBigEndian(proposalID)...), address.MustLengthPrefix(addr.Bytes())...) } func activeProposalQueueKey(proposalID uint64, endTime time.Time) []byte { return append(append(types.ActiveProposalQueuePrefix, sdk.FormatTimeBytes(endTime)...), sdk.Uint64ToBigEndian(proposalID)...) } // InactiveProposalQueueKey returns the key for a proposalID in the inactiveProposalQueue func inactiveProposalQueueKey(proposalID uint64, endTime time.Time) []byte { return append(append(types.InactiveProposalQueuePrefix, sdk.FormatTimeBytes(endTime)...), sdk.Uint64ToBigEndian(proposalID)...) }