github.com/cosmos/cosmos-sdk@v0.50.10/x/gov/migrations/v2/store.go (about)

     1  package v2
     2  
     3  import (
     4  	"fmt"
     5  
     6  	corestoretypes "cosmossdk.io/core/store"
     7  	"cosmossdk.io/store/prefix"
     8  	storetypes "cosmossdk.io/store/types"
     9  
    10  	"github.com/cosmos/cosmos-sdk/codec"
    11  	"github.com/cosmos/cosmos-sdk/runtime"
    12  	sdk "github.com/cosmos/cosmos-sdk/types"
    13  	"github.com/cosmos/cosmos-sdk/types/address"
    14  	"github.com/cosmos/cosmos-sdk/x/gov/types"
    15  	"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
    16  )
    17  
    18  const proposalIDLen = 8
    19  
    20  // migratePrefixProposalAddress is a helper function that migrates all keys of format:
    21  // <prefix_bytes><proposal_id (8 bytes)><address_bytes>
    22  // into format:
    23  // <prefix_bytes><proposal_id (8 bytes)><address_len (1 byte)><address_bytes>
    24  func migratePrefixProposalAddress(store corestoretypes.KVStore, prefixBz []byte) error {
    25  	oldStore := prefix.NewStore(runtime.KVStoreAdapter(store), prefixBz)
    26  
    27  	oldStoreIter := oldStore.Iterator(nil, nil)
    28  	defer oldStoreIter.Close()
    29  
    30  	for ; oldStoreIter.Valid(); oldStoreIter.Next() {
    31  		proposalID := oldStoreIter.Key()[:proposalIDLen]
    32  		addr := oldStoreIter.Key()[proposalIDLen:]
    33  		newStoreKey := append(append(prefixBz, proposalID...), address.MustLengthPrefix(addr)...)
    34  
    35  		// Set new key on store. Values don't change.
    36  		err := store.Set(newStoreKey, oldStoreIter.Value())
    37  		if err != nil {
    38  			return err
    39  		}
    40  		oldStore.Delete(oldStoreIter.Key())
    41  	}
    42  	return nil
    43  }
    44  
    45  // migrateStoreWeightedVotes migrates a legacy vote to an ADR-037 weighted vote.
    46  // Important: the `oldVote` has its `Option` field set, whereas the new weighted
    47  // vote has its `Options` field set.
    48  func migrateVote(oldVote v1beta1.Vote) v1beta1.Vote {
    49  	return v1beta1.Vote{
    50  		ProposalId: oldVote.ProposalId,
    51  		Voter:      oldVote.Voter,
    52  		Options:    v1beta1.NewNonSplitVoteOption(oldVote.Option),
    53  	}
    54  }
    55  
    56  // migrateStoreWeightedVotes migrates in-place all legacy votes to ADR-037 weighted votes.
    57  func migrateStoreWeightedVotes(store corestoretypes.KVStore, cdc codec.BinaryCodec) error {
    58  	iterator := storetypes.KVStorePrefixIterator(runtime.KVStoreAdapter(store), types.VotesKeyPrefix)
    59  
    60  	defer iterator.Close()
    61  	for ; iterator.Valid(); iterator.Next() {
    62  		var oldVote v1beta1.Vote
    63  		err := cdc.Unmarshal(iterator.Value(), &oldVote)
    64  		if err != nil {
    65  			return err
    66  		}
    67  
    68  		newVote := migrateVote(oldVote)
    69  		fmt.Println("migrateStoreWeightedVotes newVote=", newVote)
    70  		bz, err := cdc.Marshal(&newVote)
    71  		if err != nil {
    72  			return err
    73  		}
    74  
    75  		err = store.Set(iterator.Key(), bz)
    76  		if err != nil {
    77  			return err
    78  		}
    79  	}
    80  
    81  	return nil
    82  }
    83  
    84  // MigrateStore performs in-place store migrations from v1 (v0.40) to v2 (v0.43). The
    85  // migration includes:
    86  //
    87  // - Change addresses to be length-prefixed.
    88  // - Change all legacy votes to ADR-037 weighted votes.
    89  func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec) error {
    90  	store := storeService.OpenKVStore(ctx)
    91  	err := migratePrefixProposalAddress(store, types.DepositsKeyPrefix)
    92  	if err != nil {
    93  		return err
    94  	}
    95  
    96  	err = migratePrefixProposalAddress(store, types.VotesKeyPrefix)
    97  	if err != nil {
    98  		return err
    99  	}
   100  
   101  	return migrateStoreWeightedVotes(store, cdc)
   102  }