Merge PR #5561: v0.38 Migration Fixes

This commit is contained in:
Alexander Bezobchuk 2020-01-23 13:15:22 -05:00 committed by GitHub
parent 1feb22c4f0
commit a4b36b9dcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 316 additions and 21 deletions

View File

@ -13,7 +13,7 @@ func Migrate(authGenState v036auth.GenesisState, genAccountsGenState v036genacco
for i, acc := range genAccountsGenState {
var genAccount GenesisAccount
baseAccount := NewBaseAccount(acc.Address, acc.Coins.Sort(), acc.AccountNumber, acc.Sequence)
baseAccount := NewBaseAccount(acc.Address, acc.Coins.Sort(), nil, acc.AccountNumber, acc.Sequence)
switch {
case !acc.OriginalVesting.IsZero():

View File

@ -70,21 +70,21 @@ func TestMigrate(t *testing.T) {
)
})
expectedAcc1 := NewBaseAccount(acc1.Address, acc1.Coins, acc1.AccountNumber, acc1.Sequence)
expectedAcc1 := NewBaseAccount(acc1.Address, acc1.Coins, nil, acc1.AccountNumber, acc1.Sequence)
expectedAcc2 := NewModuleAccount(
NewBaseAccount(acc2.Address, acc2.Coins, acc2.AccountNumber, acc2.Sequence),
NewBaseAccount(acc2.Address, acc2.Coins, nil, acc2.AccountNumber, acc2.Sequence),
acc2.ModuleName, acc2.ModulePermissions...,
)
expectedAcc3 := NewContinuousVestingAccountRaw(
NewBaseVestingAccount(
NewBaseAccount(acc3.Address, acc3.Coins, acc3.AccountNumber, acc3.Sequence),
NewBaseAccount(acc3.Address, acc3.Coins, nil, acc3.AccountNumber, acc3.Sequence),
acc3.OriginalVesting, acc3.DelegatedFree, acc3.DelegatedVesting, acc3.EndTime,
),
acc3.StartTime,
)
expectedAcc4 := NewDelayedVestingAccountRaw(
NewBaseVestingAccount(
NewBaseAccount(acc4.Address, acc4.Coins, acc4.AccountNumber, acc4.Sequence),
NewBaseAccount(acc4.Address, acc4.Coins, nil, acc4.AccountNumber, acc4.Sequence),
acc4.OriginalVesting, acc4.DelegatedFree, acc4.DelegatedVesting, acc4.EndTime,
),
)

View File

@ -5,6 +5,7 @@ package v038
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"sort"
@ -51,6 +52,14 @@ type (
Sequence uint64 `json:"sequence" yaml:"sequence"`
}
baseAccountPretty struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey string `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
}
BaseVestingAccount struct {
*BaseAccount
@ -61,6 +70,21 @@ type (
EndTime int64 `json:"end_time"`
}
vestingAccountPretty struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey string `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"`
DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"`
DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"`
EndTime int64 `json:"end_time" yaml:"end_time"`
// custom fields based on concrete vesting type which can be omitted
StartTime int64 `json:"start_time,omitempty" yaml:"start_time,omitempty"`
}
ContinuousVestingAccount struct {
*BaseVestingAccount
@ -77,6 +101,16 @@ type (
Name string `json:"name" yaml:"name"`
Permissions []string `json:"permissions" yaml:"permissions"`
}
moduleAccountPretty struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey string `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
Name string `json:"name" yaml:"name"`
Permissions []string `json:"permissions" yaml:"permissions"`
}
)
func NewGenesisState(params v034auth.Params, accounts GenesisAccounts) GenesisState {
@ -93,13 +127,13 @@ func NewBaseAccountWithAddress(addr sdk.AccAddress) BaseAccount {
}
func NewBaseAccount(
address sdk.AccAddress, coins sdk.Coins, accountNumber, sequence uint64,
address sdk.AccAddress, coins sdk.Coins, pk crypto.PubKey, accountNumber, sequence uint64,
) *BaseAccount {
return &BaseAccount{
Address: address,
Coins: coins,
PubKey: nil,
PubKey: pk,
AccountNumber: accountNumber,
Sequence: sequence,
}
@ -131,6 +165,50 @@ func (acc BaseAccount) Validate() error {
return nil
}
func (acc BaseAccount) MarshalJSON() ([]byte, error) {
alias := baseAccountPretty{
Address: acc.Address,
Coins: acc.Coins,
AccountNumber: acc.AccountNumber,
Sequence: acc.Sequence,
}
if acc.PubKey != nil {
pks, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, acc.PubKey)
if err != nil {
return nil, err
}
alias.PubKey = pks
}
return json.Marshal(alias)
}
// UnmarshalJSON unmarshals raw JSON bytes into a BaseAccount.
func (acc *BaseAccount) UnmarshalJSON(bz []byte) error {
var alias baseAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
if alias.PubKey != "" {
pk, err := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}
acc.PubKey = pk
}
acc.Address = alias.Address
acc.Coins = alias.Coins
acc.AccountNumber = alias.AccountNumber
acc.Sequence = alias.Sequence
return nil
}
func NewBaseVestingAccount(
baseAccount *BaseAccount, originalVesting, delegatedFree, delegatedVesting sdk.Coins, endTime int64,
) *BaseVestingAccount {
@ -153,6 +231,59 @@ func (bva BaseVestingAccount) Validate() error {
return bva.BaseAccount.Validate()
}
// MarshalJSON returns the JSON representation of a BaseVestingAccount.
func (bva BaseVestingAccount) MarshalJSON() ([]byte, error) {
alias := vestingAccountPretty{
Address: bva.Address,
Coins: bva.Coins,
AccountNumber: bva.AccountNumber,
Sequence: bva.Sequence,
OriginalVesting: bva.OriginalVesting,
DelegatedFree: bva.DelegatedFree,
DelegatedVesting: bva.DelegatedVesting,
EndTime: bva.EndTime,
}
if bva.PubKey != nil {
pks, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, bva.PubKey)
if err != nil {
return nil, err
}
alias.PubKey = pks
}
return json.Marshal(alias)
}
// UnmarshalJSON unmarshals raw JSON bytes into a BaseVestingAccount.
func (bva *BaseVestingAccount) UnmarshalJSON(bz []byte) error {
var alias vestingAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
var (
pk crypto.PubKey
err error
)
if alias.PubKey != "" {
pk, err = sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}
}
bva.BaseAccount = NewBaseAccount(alias.Address, alias.Coins, pk, alias.AccountNumber, alias.Sequence)
bva.OriginalVesting = alias.OriginalVesting
bva.DelegatedFree = alias.DelegatedFree
bva.DelegatedVesting = alias.DelegatedVesting
bva.EndTime = alias.EndTime
return nil
}
func NewContinuousVestingAccountRaw(bva *BaseVestingAccount, startTime int64) *ContinuousVestingAccount {
return &ContinuousVestingAccount{
BaseVestingAccount: bva,
@ -168,6 +299,63 @@ func (cva ContinuousVestingAccount) Validate() error {
return cva.BaseVestingAccount.Validate()
}
// MarshalJSON returns the JSON representation of a ContinuousVestingAccount.
func (cva ContinuousVestingAccount) MarshalJSON() ([]byte, error) {
alias := vestingAccountPretty{
Address: cva.Address,
Coins: cva.Coins,
AccountNumber: cva.AccountNumber,
Sequence: cva.Sequence,
OriginalVesting: cva.OriginalVesting,
DelegatedFree: cva.DelegatedFree,
DelegatedVesting: cva.DelegatedVesting,
EndTime: cva.EndTime,
StartTime: cva.StartTime,
}
if cva.PubKey != nil {
pks, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, cva.PubKey)
if err != nil {
return nil, err
}
alias.PubKey = pks
}
return json.Marshal(alias)
}
// UnmarshalJSON unmarshals raw JSON bytes into a ContinuousVestingAccount.
func (cva *ContinuousVestingAccount) UnmarshalJSON(bz []byte) error {
var alias vestingAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
var (
pk crypto.PubKey
err error
)
if alias.PubKey != "" {
pk, err = sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}
}
cva.BaseVestingAccount = &BaseVestingAccount{
BaseAccount: NewBaseAccount(alias.Address, alias.Coins, pk, alias.AccountNumber, alias.Sequence),
OriginalVesting: alias.OriginalVesting,
DelegatedFree: alias.DelegatedFree,
DelegatedVesting: alias.DelegatedVesting,
EndTime: alias.EndTime,
}
cva.StartTime = alias.StartTime
return nil
}
func NewDelayedVestingAccountRaw(bva *BaseVestingAccount) *DelayedVestingAccount {
return &DelayedVestingAccount{
BaseVestingAccount: bva,
@ -178,6 +366,61 @@ func (dva DelayedVestingAccount) Validate() error {
return dva.BaseVestingAccount.Validate()
}
// MarshalJSON returns the JSON representation of a DelayedVestingAccount.
func (dva DelayedVestingAccount) MarshalJSON() ([]byte, error) {
alias := vestingAccountPretty{
Address: dva.Address,
Coins: dva.Coins,
AccountNumber: dva.AccountNumber,
Sequence: dva.Sequence,
OriginalVesting: dva.OriginalVesting,
DelegatedFree: dva.DelegatedFree,
DelegatedVesting: dva.DelegatedVesting,
EndTime: dva.EndTime,
}
if dva.PubKey != nil {
pks, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, dva.PubKey)
if err != nil {
return nil, err
}
alias.PubKey = pks
}
return json.Marshal(alias)
}
// UnmarshalJSON unmarshals raw JSON bytes into a DelayedVestingAccount.
func (dva *DelayedVestingAccount) UnmarshalJSON(bz []byte) error {
var alias vestingAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
var (
pk crypto.PubKey
err error
)
if alias.PubKey != "" {
pk, err = sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}
}
dva.BaseVestingAccount = &BaseVestingAccount{
BaseAccount: NewBaseAccount(alias.Address, alias.Coins, pk, alias.AccountNumber, alias.Sequence),
OriginalVesting: alias.OriginalVesting,
DelegatedFree: alias.DelegatedFree,
DelegatedVesting: alias.DelegatedVesting,
EndTime: alias.EndTime,
}
return nil
}
func NewModuleAddress(name string) sdk.AccAddress {
return sdk.AccAddress(crypto.AddressHash([]byte(name)))
}
@ -190,16 +433,6 @@ func NewModuleAccount(baseAccount *BaseAccount, name string, permissions ...stri
}
}
func validatePermissions(permissions ...string) error {
for _, perm := range permissions {
if strings.TrimSpace(perm) == "" {
return fmt.Errorf("module permission is empty")
}
}
return nil
}
func (ma ModuleAccount) Validate() error {
if err := validatePermissions(ma.Permissions...); err != nil {
return err
@ -216,6 +449,43 @@ func (ma ModuleAccount) Validate() error {
return ma.BaseAccount.Validate()
}
// MarshalJSON returns the JSON representation of a ModuleAccount.
func (ma ModuleAccount) MarshalJSON() ([]byte, error) {
return json.Marshal(moduleAccountPretty{
Address: ma.Address,
Coins: ma.Coins,
PubKey: "",
AccountNumber: ma.AccountNumber,
Sequence: ma.Sequence,
Name: ma.Name,
Permissions: ma.Permissions,
})
}
// UnmarshalJSON unmarshals raw JSON bytes into a ModuleAccount.
func (ma *ModuleAccount) UnmarshalJSON(bz []byte) error {
var alias moduleAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
ma.BaseAccount = NewBaseAccount(alias.Address, alias.Coins, nil, alias.AccountNumber, alias.Sequence)
ma.Name = alias.Name
ma.Permissions = alias.Permissions
return nil
}
func validatePermissions(permissions ...string) error {
for _, perm := range permissions {
if strings.TrimSpace(perm) == "" {
return fmt.Errorf("module permission is empty")
}
}
return nil
}
func sanitizeGenesisAccounts(genAccounts GenesisAccounts) GenesisAccounts {
sort.Slice(genAccounts, func(i, j int) bool {
return genAccounts[i].GetAccountNumber() < genAccounts[j].GetAccountNumber()

View File

@ -146,4 +146,11 @@ func TestBaseAccountJSON(t *testing.T) {
var a BaseAccount
require.NoError(t, json.Unmarshal(bz, &a))
require.Equal(t, baseAcc.String(), a.String())
bz, err = ModuleCdc.MarshalJSON(baseAcc)
require.NoError(t, err)
var b BaseAccount
require.NoError(t, ModuleCdc.UnmarshalJSON(bz, &b))
require.Equal(t, baseAcc.String(), b.String())
}

View File

@ -6,6 +6,13 @@ import (
v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_36"
)
// DONTCOVER
// nolint
const (
ModuleName = "distribution"
)
type (
GenesisState struct {
Params Params `json:"params" yaml:"params"`

View File

@ -4,13 +4,15 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
v036auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_36"
v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38"
v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_36"
v038distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_38"
v036genaccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_36"
"github.com/cosmos/cosmos-sdk/x/genutil"
v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_36"
v038staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_38"
)
// Migrate migrates exported state from v0.34 to a v0.36 genesis state.
// Migrate migrates exported state from v0.36/v0.37 to a v0.38 genesis state.
func Migrate(appState genutil.AppMap) genutil.AppMap {
v036Codec := codec.New()
codec.RegisterCrypto(v036Codec)
@ -27,14 +29,14 @@ func Migrate(appState genutil.AppMap) genutil.AppMap {
var genAccountsGenState v036genaccounts.GenesisState
v036Codec.MustUnmarshalJSON(appState[v036genaccounts.ModuleName], &genAccountsGenState)
// delete deprecated genaccounts genesis state
delete(appState, v036genaccounts.ModuleName)
// Migrate relative source genesis application state and marshal it into
// the respective key.
appState[v038auth.ModuleName] = v038Codec.MustMarshalJSON(
v038auth.Migrate(authGenState, genAccountsGenState),
)
// delete deprecated genaccounts genesis state
delete(appState, v036genaccounts.ModuleName)
}
// migrate staking state
@ -46,5 +48,14 @@ func Migrate(appState genutil.AppMap) genutil.AppMap {
appState[v038staking.ModuleName] = v038Codec.MustMarshalJSON(v038staking.Migrate(stakingGenState))
}
// migrate distribution state
if appState[v036distr.ModuleName] != nil {
var distrGenState v036distr.GenesisState
v036Codec.MustUnmarshalJSON(appState[v036distr.ModuleName], &distrGenState)
delete(appState, v036distr.ModuleName) // delete old key in case the name changed
appState[v038distr.ModuleName] = v038Codec.MustMarshalJSON(v038distr.Migrate(distrGenState))
}
return appState
}