Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 0.39 x/auth Migration Types #6870

Merged
merged 5 commits into from
Jul 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions x/auth/legacy/v0_38/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ func NewModuleAccount(baseAccount *BaseAccount, name string, permissions ...stri
}

func (ma ModuleAccount) Validate() error {
if err := validatePermissions(ma.Permissions...); err != nil {
if err := ValidatePermissions(ma.Permissions...); err != nil {
return err
}

Expand Down Expand Up @@ -476,7 +476,7 @@ func (ma *ModuleAccount) UnmarshalJSON(bz []byte) error {
return nil
}

func validatePermissions(permissions ...string) error {
func ValidatePermissions(permissions ...string) error {
for _, perm := range permissions {
if strings.TrimSpace(perm) == "" {
return fmt.Errorf("module permission is empty")
Expand Down
60 changes: 60 additions & 0 deletions x/auth/legacy/v0_39/migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package v039

import (
"fmt"

v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38"
)

// Migrate accepts exported genesis state from v0.38 and migrates it to v0.39
// genesis state.
func Migrate(oldAuthGenState v038auth.GenesisState) GenesisState {
accounts := make(v038auth.GenesisAccounts, len(oldAuthGenState.Accounts))

for i, acc := range oldAuthGenState.Accounts {
switch t := acc.(type) {
case *v038auth.BaseAccount:
accounts[i] = NewBaseAccount(t.Address, t.Coins, t.PubKey, t.AccountNumber, t.Sequence)

case *v038auth.BaseVestingAccount:
accounts[i] = NewBaseVestingAccount(
NewBaseAccount(t.Address, t.Coins, t.PubKey, t.AccountNumber, t.Sequence),
t.OriginalVesting, t.DelegatedFree, t.DelegatedVesting, t.EndTime,
)

case *v038auth.ContinuousVestingAccount:
accounts[i] = NewContinuousVestingAccountRaw(
NewBaseVestingAccount(
NewBaseAccount(t.Address, t.Coins, t.PubKey, t.AccountNumber, t.Sequence),
t.OriginalVesting, t.DelegatedFree, t.DelegatedVesting, t.EndTime,
),
t.StartTime,
)

case *v038auth.DelayedVestingAccount:
accounts[i] = NewDelayedVestingAccountRaw(
NewBaseVestingAccount(
NewBaseAccount(t.Address, t.Coins, t.PubKey, t.AccountNumber, t.Sequence),
t.OriginalVesting, t.DelegatedFree, t.DelegatedVesting, t.EndTime,
),
)

case *v038auth.ModuleAccount:
accounts[i] = NewModuleAccount(
NewBaseAccount(t.Address, t.Coins, t.PubKey, t.AccountNumber, t.Sequence),
t.Name, t.Permissions...,
)

default:
panic(fmt.Sprintf("unexpected account type: %T", acc))
}
}

accounts = v038auth.SanitizeGenesisAccounts(accounts)

if err := v038auth.ValidateGenAccounts(accounts); err != nil {
panic(err)
}

return NewGenesisState(oldAuthGenState.Params, accounts)
}
97 changes: 27 additions & 70 deletions x/auth/legacy/v0_39/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"bytes"
"errors"
"fmt"
"sort"
"strings"

"github.com/tendermint/tendermint/crypto"
Expand All @@ -16,32 +15,17 @@ import (
"github.com/cosmos/cosmos-sdk/codec/legacy"
sdk "github.com/cosmos/cosmos-sdk/types"
v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34"
v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38"
)

const (
ModuleName = "auth"
)

type (
// partial interface needed only for amino encoding and sanitization
Account interface {
GetAddress() sdk.AccAddress
GetAccountNumber() uint64
GetCoins() sdk.Coins
SetCoins(sdk.Coins) error
}

GenesisAccount interface {
Account

Validate() error
}

GenesisAccounts []GenesisAccount

GenesisState struct {
Params v034auth.Params `json:"params" yaml:"params"`
Accounts GenesisAccounts `json:"accounts" yaml:"accounts"`
Params v034auth.Params `json:"params" yaml:"params"`
Accounts v038auth.GenesisAccounts `json:"accounts" yaml:"accounts"`
}

BaseAccount struct {
Expand Down Expand Up @@ -119,7 +103,7 @@ type (
}
)

func NewGenesisState(params v034auth.Params, accounts GenesisAccounts) GenesisState {
func NewGenesisState(params v034auth.Params, accounts v038auth.GenesisAccounts) GenesisState {
return GenesisState{
Params: params,
Accounts: accounts,
Expand Down Expand Up @@ -187,6 +171,7 @@ func NewBaseVestingAccount(
func (bva BaseVestingAccount) MarshalJSON() ([]byte, error) {
alias := vestingAccountJSON{
Address: bva.Address,
Coins: bva.Coins,
PubKey: bva.PubKey,
AccountNumber: bva.AccountNumber,
Sequence: bva.Sequence,
Expand Down Expand Up @@ -245,6 +230,7 @@ func (cva ContinuousVestingAccount) Validate() error {
func (cva ContinuousVestingAccount) MarshalJSON() ([]byte, error) {
alias := vestingAccountJSON{
Address: cva.Address,
Coins: cva.Coins,
PubKey: cva.PubKey,
AccountNumber: cva.AccountNumber,
Sequence: cva.Sequence,
Expand Down Expand Up @@ -276,13 +262,20 @@ func (cva *ContinuousVestingAccount) UnmarshalJSON(bz []byte) error {
return nil
}

func NewDelayedVestingAccountRaw(bva *BaseVestingAccount) *DelayedVestingAccount {
return &DelayedVestingAccount{
BaseVestingAccount: bva,
}
}

func (dva DelayedVestingAccount) Validate() error {
return dva.BaseVestingAccount.Validate()
}

func (dva DelayedVestingAccount) MarshalJSON() ([]byte, error) {
alias := vestingAccountJSON{
Address: dva.Address,
Coins: dva.Coins,
PubKey: dva.PubKey,
AccountNumber: dva.AccountNumber,
Sequence: dva.Sequence,
Expand Down Expand Up @@ -340,6 +333,7 @@ func (pva PeriodicVestingAccount) Validate() error {
func (pva PeriodicVestingAccount) MarshalJSON() ([]byte, error) {
alias := vestingAccountJSON{
Address: pva.Address,
Coins: pva.Coins,
PubKey: pva.PubKey,
AccountNumber: pva.AccountNumber,
Sequence: pva.Sequence,
Expand Down Expand Up @@ -374,17 +368,25 @@ func (pva *PeriodicVestingAccount) UnmarshalJSON(bz []byte) error {
return nil
}

func NewModuleAccount(baseAccount *BaseAccount, name string, permissions ...string) *ModuleAccount {
return &ModuleAccount{
BaseAccount: baseAccount,
Name: name,
Permissions: permissions,
}
}

func (ma ModuleAccount) Validate() error {
if err := validatePermissions(ma.Permissions...); err != nil {
if err := v038auth.ValidatePermissions(ma.Permissions...); err != nil {
return err
}

if strings.TrimSpace(ma.Name) == "" {
return errors.New("module account name cannot be blank")
}

if !ma.Address.Equals(sdk.AccAddress(crypto.AddressHash([]byte(ma.Name)))) {
return fmt.Errorf("address %s cannot be derived from the module name '%s'", ma.Address, ma.Name)
if x := sdk.AccAddress(crypto.AddressHash([]byte(ma.Name))); !ma.Address.Equals(x) {
return fmt.Errorf("address %s cannot be derived from the module name '%s'; expected: %s", ma.Address, ma.Name, x)
}

return ma.BaseAccount.Validate()
Expand Down Expand Up @@ -417,54 +419,9 @@ func (ma *ModuleAccount) UnmarshalJSON(bz []byte) error {
return nil
}

func SanitizeGenesisAccounts(genAccounts GenesisAccounts) GenesisAccounts {
sort.Slice(genAccounts, func(i, j int) bool {
return genAccounts[i].GetAccountNumber() < genAccounts[j].GetAccountNumber()
})

for _, acc := range genAccounts {
if err := acc.SetCoins(acc.GetCoins().Sort()); err != nil {
panic(err)
}
}

return genAccounts
}

func ValidateGenAccounts(genAccounts GenesisAccounts) error {
addrMap := make(map[string]bool, len(genAccounts))
for _, acc := range genAccounts {

// check for duplicated accounts
addrStr := acc.GetAddress().String()
if _, ok := addrMap[addrStr]; ok {
return fmt.Errorf("duplicate account found in genesis state; address: %s", addrStr)
}

addrMap[addrStr] = true

// check account specific validation
if err := acc.Validate(); err != nil {
return fmt.Errorf("invalid account found in genesis state; address: %s, error: %s", addrStr, err.Error())
}
}

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 RegisterCodec(cdc *codec.Codec) {
cdc.RegisterInterface((*GenesisAccount)(nil), nil)
cdc.RegisterInterface((*Account)(nil), nil)
cdc.RegisterInterface((*v038auth.GenesisAccount)(nil), nil)
cdc.RegisterInterface((*v038auth.Account)(nil), nil)
cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil)
cdc.RegisterConcrete(&BaseVestingAccount{}, "cosmos-sdk/BaseVestingAccount", nil)
cdc.RegisterConcrete(&ContinuousVestingAccount{}, "cosmos-sdk/ContinuousVestingAccount", nil)
Expand Down
3 changes: 2 additions & 1 deletion x/auth/legacy/v0_40/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package v040
import (
"fmt"

v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38"
v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_39"
)

Expand All @@ -18,6 +19,6 @@ func Migrate(authGenState v039auth.GenesisState) v039auth.GenesisState {
}
}

authGenState.Accounts = v039auth.SanitizeGenesisAccounts(authGenState.Accounts)
authGenState.Accounts = v038auth.SanitizeGenesisAccounts(authGenState.Accounts)
return authGenState
}
7 changes: 4 additions & 3 deletions x/auth/legacy/v0_40/migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ package v040_test
import (
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/codec"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34"
v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38"
v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_39"
v040 "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_40"

"github.com/stretchr/testify/require"
)

func TestMigrate(t *testing.T) {
Expand All @@ -36,7 +37,7 @@ func TestMigrate(t *testing.T) {
SigVerifyCostED25519: 10,
SigVerifyCostSecp256k1: 10,
},
Accounts: v039auth.GenesisAccounts{acc1, vaac},
Accounts: v038auth.GenesisAccounts{acc1, vaac},
}

migrated := v040.Migrate(gs)
Expand Down
2 changes: 1 addition & 1 deletion x/bank/legacy/v0_40/migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestMigrate(t *testing.T) {
SendEnabled: true,
}
authGenState := v039auth.GenesisState{
Accounts: v039auth.GenesisAccounts{acc1, vaac},
Accounts: v038auth.GenesisAccounts{acc1, vaac},
}

migrated := v040bank.Migrate(bankGenState, authGenState)
Expand Down
2 changes: 1 addition & 1 deletion x/genutil/legacy/v0_39/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func Migrate(appState types.AppMap) types.AppMap {
v038Codec.MustUnmarshalJSON(appState[v038auth.ModuleName], &authGenState)

delete(appState, v038auth.ModuleName) // delete old key in case the name changed
appState[v039auth.ModuleName] = v039Codec.MustMarshalJSON(authGenState)
appState[v039auth.ModuleName] = v039Codec.MustMarshalJSON(v039auth.Migrate(authGenState))
}

return appState
Expand Down
Loading