Add 0.43 CLI JSON `migrate` command (#8880)

* Add aadr-037 json migration

* Add 0.43 to CLI migraet command

* Add comment

* Don't cover .pb.go

* Bez says (2)

* Reviews

Co-authored-by: Alessio Treglia <alessio@tendermint.com>
This commit is contained in:
Amaury 2021-03-22 12:30:26 +01:00 committed by GitHub
parent 7b1d80e6e4
commit 3f52d5a44f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 837 additions and 23 deletions

View File

@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#8346](https://github.com/cosmos/cosmos-sdk/pull/8346) All CLI `tx` commands generate ServiceMsgs by default. Graceful Amino support has been added to ServiceMsgs to support signing legacy Msgs.
* (crypto/ed25519) [\#8690] Adopt zip1215 ed2559 verification rules.
* [\#8849](https://github.com/cosmos/cosmos-sdk/pull/8849) Upgrade module no longer supports time based upgrades.
* [\#8880](https://github.com/cosmos/cosmos-sdk/pull/8880) The CLI `simd migrate v0.40 ...` command has been renamed to `simd migrate v0.42`.
### API Breaking Changes

View File

@ -18,6 +18,7 @@ import (
v038 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v038"
v039 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v039"
v040 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v040"
v043 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v043"
"github.com/cosmos/cosmos-sdk/x/genutil/types"
)
@ -28,9 +29,10 @@ const flagGenesisTime = "genesis-time"
// Ref: https://github.com/cosmos/cosmos-sdk/issues/5041
var migrationMap = types.MigrationMap{
"v0.36": v036.Migrate,
"v0.38": v038.Migrate, // NOTE: v0.37 and v0.38 are genesis compatible
"v0.38": v038.Migrate, // NOTE: v0.37 and v0.38 are genesis compatible.
"v0.39": v039.Migrate,
"v0.40": v040.Migrate,
"v0.42": v040.Migrate, // NOTE: v0.40, v0.41 and v0.42 are genesis compatible.
"v0.43": v043.Migrate,
}
// GetMigrationCallback returns a MigrationCallback for a given version.
@ -131,7 +133,7 @@ $ %s migrate v0.36 /path/to/genesis.json --chain-id=cosmoshub-3 --genesis-time=2
return errors.Wrap(err, "failed to sort JSON genesis doc")
}
fmt.Println(string(sortedBz))
cmd.Println(string(sortedBz))
return nil
},
}

View File

@ -25,35 +25,41 @@ func (s *IntegrationTestSuite) TestMigrateGenesis() {
target string
expErr bool
expErrMsg string
check func(jsonOut string)
}{
{
"migrate to 0.36",
"migrate 0.34 to 0.36",
`{"chain_id":"test","app_state":{}}`,
"v0.36",
false, "",
false, "", func(_ string) {},
},
{
"exported 0.37 genesis file",
"migrate 0.37 to 0.42",
v037Exported,
"v0.40",
true, "Make sure that you have correctly migrated all Tendermint consensus params",
"v0.42",
true, "Make sure that you have correctly migrated all Tendermint consensus params", func(_ string) {},
},
{
"valid 0.40 genesis file",
"migrate 0.42 to 0.43",
v040Valid,
"v0.40",
"v0.43",
false, "",
func(jsonOut string) {
// Make sure the json output contains the ADR-037 gov weighted votes.
s.Require().Contains(jsonOut, "\"weight\":\"1.000000000000000000\"")
},
},
}
for _, tc := range testCases {
s.Run(tc.name, func() {
genesisFile := testutil.WriteToNewTempFile(s.T(), tc.genesis)
_, err := clitestutil.ExecTestCLICmd(val0.ClientCtx, cli.MigrateGenesisCmd(), []string{tc.target, genesisFile.Name()})
jsonOutput, err := clitestutil.ExecTestCLICmd(val0.ClientCtx, cli.MigrateGenesisCmd(), []string{tc.target, genesisFile.Name()})
if tc.expErr {
s.Require().Contains(err.Error(), tc.expErrMsg)
} else {
s.Require().NoError(err)
tc.check(jsonOutput.String())
}
})
}

View File

@ -26,9 +26,28 @@ var v037Exported = `{
}`
// An example exported genesis file that's 0.40 compatible.
// We added the following app_state:
//
// - x/gov: added votes to test ADR-037 split votes migration.
var v040Valid = `{
"app_hash": "",
"app_state": {},
"app_state": {
"gov": {
"starting_proposal_id": "0",
"deposits": [],
"votes": [
{
"proposal_id": "5",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh",
"option": "VOTE_OPTION_YES"
}
],
"proposals": [],
"deposit_params": { "min_deposit": [], "max_deposit_period": "0s" },
"voting_params": { "voting_period": "0s" },
"tally_params": { "quorum": "0", "threshold": "0", "veto_threshold": "0" }
}
},
"chain_id": "test",
"consensus_params": {
"block": {

View File

@ -0,0 +1,27 @@
package v043
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/x/genutil/types"
v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040"
v043gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v043"
)
// Migrate migrates exported state from v0.40 to a v0.43 genesis state.
func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap {
// Migrate x/gov.
if appState[v040gov.ModuleName] != nil {
// unmarshal relative source genesis application state
var oldGovState v040gov.GenesisState
clientCtx.JSONMarshaler.MustUnmarshalJSON(appState[v040gov.ModuleName], &oldGovState)
// delete deprecated x/gov genesis state
delete(appState, v040gov.ModuleName)
// Migrate relative source genesis application state and marshal it into
// the respective key.
appState[v043gov.ModuleName] = clientCtx.JSONMarshaler.MustMarshalJSON(v043gov.MigrateJSON(&oldGovState))
}
return appState
}

View File

@ -0,0 +1,592 @@
// Package v040 is taken from:
// https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/gov/types/genesis.pb.go
// by copy-pasted only the relevants parts for Genesis.
//nolint
package v040
import (
fmt "fmt"
io "io"
math_bits "math/bits"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
"github.com/cosmos/cosmos-sdk/x/gov/types"
)
// GenesisState defines the gov module's genesis state.
type GenesisState struct {
// starting_proposal_id is the ID of the starting proposal.
StartingProposalId uint64 `protobuf:"varint,1,opt,name=starting_proposal_id,json=startingProposalId,proto3" json:"starting_proposal_id,omitempty" yaml:"starting_proposal_id"`
// deposits defines all the deposits present at genesis.
Deposits types.Deposits `protobuf:"bytes,2,rep,name=deposits,proto3,castrepeated=Deposits" json:"deposits"`
// votes defines all the votes present at genesis.
Votes Votes `protobuf:"bytes,3,rep,name=votes,proto3,castrepeated=Votes" json:"votes"`
// proposals defines all the proposals present at genesis.
Proposals types.Proposals `protobuf:"bytes,4,rep,name=proposals,proto3,castrepeated=Proposals" json:"proposals"`
// params defines all the paramaters of related to deposit.
DepositParams types.DepositParams `protobuf:"bytes,5,opt,name=deposit_params,json=depositParams,proto3" json:"deposit_params" yaml:"deposit_params"`
// params defines all the paramaters of related to voting.
VotingParams types.VotingParams `protobuf:"bytes,6,opt,name=voting_params,json=votingParams,proto3" json:"voting_params" yaml:"voting_params"`
// params defines all the paramaters of related to tally.
TallyParams types.TallyParams `protobuf:"bytes,7,opt,name=tally_params,json=tallyParams,proto3" json:"tally_params" yaml:"tally_params"`
}
func (m *GenesisState) Reset() { *m = GenesisState{} }
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
func (*GenesisState) ProtoMessage() {}
func (m *GenesisState) GetStartingProposalId() uint64 {
if m != nil {
return m.StartingProposalId
}
return 0
}
func (m *GenesisState) GetDeposits() types.Deposits {
if m != nil {
return m.Deposits
}
return nil
}
func (m *GenesisState) GetVotes() Votes {
if m != nil {
return m.Votes
}
return nil
}
func (m *GenesisState) GetProposals() types.Proposals {
if m != nil {
return m.Proposals
}
return nil
}
func (m *GenesisState) GetDepositParams() types.DepositParams {
if m != nil {
return m.DepositParams
}
return types.DepositParams{}
}
func (m *GenesisState) GetVotingParams() types.VotingParams {
if m != nil {
return m.VotingParams
}
return types.VotingParams{}
}
func (m *GenesisState) GetTallyParams() types.TallyParams {
if m != nil {
return m.TallyParams
}
return types.TallyParams{}
}
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
{
size, err := m.TallyParams.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x3a
{
size, err := m.VotingParams.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x32
{
size, err := m.DepositParams.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x2a
if len(m.Proposals) > 0 {
for iNdEx := len(m.Proposals) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Proposals[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x22
}
}
if len(m.Votes) > 0 {
for iNdEx := len(m.Votes) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Votes[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
}
if len(m.Deposits) > 0 {
for iNdEx := len(m.Deposits) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Deposits[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
}
if m.StartingProposalId != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.StartingProposalId))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
offset -= sovGenesis(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *GenesisState) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.StartingProposalId != 0 {
n += 1 + sovGenesis(uint64(m.StartingProposalId))
}
if len(m.Deposits) > 0 {
for _, e := range m.Deposits {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
if len(m.Votes) > 0 {
for _, e := range m.Votes {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
if len(m.Proposals) > 0 {
for _, e := range m.Proposals {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
l = m.DepositParams.Size()
n += 1 + l + sovGenesis(uint64(l))
l = m.VotingParams.Size()
n += 1 + l + sovGenesis(uint64(l))
l = m.TallyParams.Size()
n += 1 + l + sovGenesis(uint64(l))
return n
}
func sovGenesis(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func (m *GenesisState) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field StartingProposalId", wireType)
}
m.StartingProposalId = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.StartingProposalId |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Deposits", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Deposits = append(m.Deposits, types.Deposit{})
if err := m.Deposits[len(m.Deposits)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Votes", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Votes = append(m.Votes, Vote{})
if err := m.Votes[len(m.Votes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Proposals", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Proposals = append(m.Proposals, types.Proposal{})
if err := m.Proposals[len(m.Proposals)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field DepositParams", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.DepositParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VotingParams", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.VotingParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TallyParams", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.TallyParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGenesis(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthGenesis
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupGenesis
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthGenesis
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -1,4 +1,4 @@
// Package v040 is take from:
// Package v040 is taken from:
// https://github.com/cosmos/cosmos-sdk/blob/v0.41.1/x/gov/types/gov.pb.go
// by copy-pasted only the relevants parts for Vote.
package v040

32
x/gov/legacy/v043/json.go Normal file
View File

@ -0,0 +1,32 @@
package v043
import (
v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040"
"github.com/cosmos/cosmos-sdk/x/gov/types"
)
// migrateWeightedVotes migrates the ADR-037 weighted votes.
func migrateJSONWeightedVotes(oldVotes v040gov.Votes) types.Votes {
newVotes := make(types.Votes, len(oldVotes))
for i, oldVote := range oldVotes {
newVotes[i] = migrateVote(oldVote)
}
return newVotes
}
// MigrateJSON accepts exported v0.40 x/gov genesis state and migrates it to
// v0.43 x/gov genesis state. The migration includes:
//
// - Gov weighted votes.
func MigrateJSON(oldState *v040gov.GenesisState) *types.GenesisState {
return &types.GenesisState{
StartingProposalId: oldState.StartingProposalId,
Deposits: oldState.Deposits,
Votes: migrateJSONWeightedVotes(oldState.Votes),
Proposals: oldState.Proposals,
DepositParams: oldState.DepositParams,
VotingParams: oldState.VotingParams,
TallyParams: oldState.TallyParams,
}
}

View File

@ -0,0 +1,124 @@
package v043_test
import (
"encoding/json"
"fmt"
"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"
v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040"
v043gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v043"
"github.com/cosmos/cosmos-sdk/x/gov/types"
)
func TestMigrateJSON(t *testing.T) {
encodingConfig := simapp.MakeTestEncodingConfig()
clientCtx := client.Context{}.
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
WithTxConfig(encodingConfig.TxConfig).
WithJSONMarshaler(encodingConfig.Marshaler)
voter, err := sdk.AccAddressFromBech32("cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh")
require.NoError(t, err)
govGenState := &v040gov.GenesisState{
Votes: v040gov.Votes{
v040gov.NewVote(1, voter, types.OptionAbstain),
v040gov.NewVote(2, voter, types.OptionEmpty),
v040gov.NewVote(3, voter, types.OptionNo),
v040gov.NewVote(4, voter, types.OptionNoWithVeto),
v040gov.NewVote(5, voter, types.OptionYes),
},
}
migrated := v043gov.MigrateJSON(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, "", "\t")
require.NoError(t, err)
// Make sure about:
// - Votes are all ADR-037 weighted votes with weight 1.
expected := `{
"deposit_params": {
"max_deposit_period": "0s",
"min_deposit": []
},
"deposits": [],
"proposals": [],
"starting_proposal_id": "0",
"tally_params": {
"quorum": "0",
"threshold": "0",
"veto_threshold": "0"
},
"votes": [
{
"options": [
{
"option": "VOTE_OPTION_ABSTAIN",
"weight": "1.000000000000000000"
}
],
"proposal_id": "1",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
},
{
"options": [
{
"option": "VOTE_OPTION_UNSPECIFIED",
"weight": "1.000000000000000000"
}
],
"proposal_id": "2",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
},
{
"options": [
{
"option": "VOTE_OPTION_NO",
"weight": "1.000000000000000000"
}
],
"proposal_id": "3",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
},
{
"options": [
{
"option": "VOTE_OPTION_NO_WITH_VETO",
"weight": "1.000000000000000000"
}
],
"proposal_id": "4",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
},
{
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1.000000000000000000"
}
],
"proposal_id": "5",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
}
],
"voting_params": {
"voting_period": "0s"
}
}`
fmt.Println(string(indentedBz))
require.Equal(t, expected, string(indentedBz))
}

View File

@ -0,0 +1,6 @@
package v043
const (
// ModuleName is the name of the module
ModuleName = "gov"
)

View File

@ -32,8 +32,17 @@ func migratePrefixProposalAddress(store sdk.KVStore, prefixBz []byte) {
}
}
// migrateWeightedVotes migrates the ADR-037 weighted votes.
func migrateWeightedVotes(store sdk.KVStore, cdc codec.BinaryMarshaler) error {
// migrateStoreWeightedVotes migrates a legacy vote to an ADR-037 weighted vote.
func migrateVote(oldVote v040gov.Vote) types.Vote {
return types.Vote{
ProposalId: oldVote.ProposalId,
Voter: oldVote.Voter,
Options: []types.WeightedVoteOption{{Option: oldVote.Option, Weight: sdk.NewDec(1)}},
}
}
// migrateStoreWeightedVotes migrates in-place all legacy votes to ADR-037 weighted votes.
func migrateStoreWeightedVotes(store sdk.KVStore, cdc codec.BinaryMarshaler) error {
iterator := sdk.KVStorePrefixIterator(store, v040gov.VotesKeyPrefix)
defer iterator.Close()
@ -44,12 +53,8 @@ func migrateWeightedVotes(store sdk.KVStore, cdc codec.BinaryMarshaler) error {
return err
}
newVote := &types.Vote{
ProposalId: oldVote.ProposalId,
Voter: oldVote.Voter,
Options: []types.WeightedVoteOption{{Option: oldVote.Option, Weight: sdk.NewDec(1)}},
}
bz, err := cdc.MarshalBinaryBare(newVote)
newVote := migrateVote(oldVote)
bz, err := cdc.MarshalBinaryBare(&newVote)
if err != nil {
return err
}
@ -68,5 +73,5 @@ func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryMarsha
store := ctx.KVStore(storeKey)
migratePrefixProposalAddress(store, v040gov.DepositsKeyPrefix)
migratePrefixProposalAddress(store, v040gov.VotesKeyPrefix)
return migrateWeightedVotes(store, cdc)
return migrateStoreWeightedVotes(store, cdc)
}

View File

@ -16,7 +16,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/gov/types"
)
func TestStoreMigration(t *testing.T) {
func TestMigrateStore(t *testing.T) {
cdc := simapp.MakeTestEncodingConfig().Marshaler
govKey := sdk.NewKVStoreKey("gov")
ctx := testutil.DefaultContext(govKey, sdk.NewTransientStoreKey("transient_test"))