From baff4fc237cf32079765d077683dd165fd1efd82 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 28 Jul 2020 11:35:13 -0400 Subject: [PATCH 1/7] update x/genutil --- x/genutil/legacy/v0_36/migrate.go | 13 +++++----- x/genutil/legacy/v0_36/migrate_test.go | 6 ++--- x/genutil/legacy/v0_38/migrate.go | 13 +++++----- x/genutil/legacy/v0_38/migrate_test.go | 4 +-- x/genutil/legacy/v0_39/migrate.go | 34 ++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 x/genutil/legacy/v0_39/migrate.go diff --git a/x/genutil/legacy/v0_36/migrate.go b/x/genutil/legacy/v0_36/migrate.go index 2ec6d01a2a0a..cabfd285ef42 100644 --- a/x/genutil/legacy/v0_36/migrate.go +++ b/x/genutil/legacy/v0_36/migrate.go @@ -2,28 +2,29 @@ package v036 import ( "github.com/cosmos/cosmos-sdk/codec" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34" v036auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_36" + v036bank "github.com/cosmos/cosmos-sdk/x/bank/legacy/v0_36" v034distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_34" v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_36" v034genAccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_34" v036genAccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_36" - "github.com/cosmos/cosmos-sdk/x/genutil" + "github.com/cosmos/cosmos-sdk/x/genutil/types" v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_34" v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_36" v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_34" v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_36" - v036supply "github.com/cosmos/cosmos-sdk/x/supply/legacy/v0_36" ) // Migrate migrates exported state from v0.34 to a v0.36 genesis state. -func Migrate(appState genutil.AppMap) genutil.AppMap { +func Migrate(appState types.AppMap) types.AppMap { v034Codec := codec.New() - codec.RegisterCrypto(v034Codec) + cryptocodec.RegisterCrypto(v034Codec) v034gov.RegisterCodec(v034Codec) v036Codec := codec.New() - codec.RegisterCrypto(v036Codec) + cryptocodec.RegisterCrypto(v036Codec) v036gov.RegisterCodec(v036Codec) // migrate genesis accounts state @@ -90,7 +91,7 @@ func Migrate(appState genutil.AppMap) genutil.AppMap { } // migrate supply state - appState[v036supply.ModuleName] = v036Codec.MustMarshalJSON(v036supply.EmptyGenesisState()) + appState[v036bank.ModuleName] = v036Codec.MustMarshalJSON(v036bank.EmptyGenesisState()) return appState } diff --git a/x/genutil/legacy/v0_36/migrate_test.go b/x/genutil/legacy/v0_36/migrate_test.go index 3909d3d4b6a6..47553ce16268 100644 --- a/x/genutil/legacy/v0_36/migrate_test.go +++ b/x/genutil/legacy/v0_36/migrate_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/x/genutil" + "github.com/cosmos/cosmos-sdk/x/genutil/types" ) var basic034Gov = []byte(` @@ -86,7 +86,7 @@ var basic034Gov = []byte(` `) func TestDummyGenesis(t *testing.T) { - genesisDummy := genutil.AppMap{ + genesisDummy := types.AppMap{ "foo": {}, "bar": []byte(`{"custom": "module"}`), } @@ -98,7 +98,7 @@ func TestDummyGenesis(t *testing.T) { } func TestGovGenesis(t *testing.T) { - genesis := genutil.AppMap{ + genesis := types.AppMap{ "gov": basic034Gov, } diff --git a/x/genutil/legacy/v0_38/migrate.go b/x/genutil/legacy/v0_38/migrate.go index 59ba4772705f..6c9e8c003676 100644 --- a/x/genutil/legacy/v0_38/migrate.go +++ b/x/genutil/legacy/v0_38/migrate.go @@ -2,23 +2,24 @@ package v038 import ( "github.com/cosmos/cosmos-sdk/codec" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/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" + "github.com/cosmos/cosmos-sdk/x/genutil/types" 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.36/v0.37 to a v0.38 genesis state. -func Migrate(appState genutil.AppMap) genutil.AppMap { +func Migrate(appState types.AppMap) types.AppMap { v036Codec := codec.New() - codec.RegisterCrypto(v036Codec) + cryptocodec.RegisterCrypto(v036Codec) v038Codec := codec.New() - codec.RegisterCrypto(v038Codec) + cryptocodec.RegisterCrypto(v038Codec) v038auth.RegisterCodec(v038Codec) if appState[v036genaccounts.ModuleName] != nil { @@ -34,9 +35,7 @@ func Migrate(appState genutil.AppMap) genutil.AppMap { // Migrate relative source genesis application state and marshal it into // the respective key. - appState[v038auth.ModuleName] = v038Codec.MustMarshalJSON( - v038auth.Migrate(authGenState, genAccountsGenState), - ) + appState[v038auth.ModuleName] = v038Codec.MustMarshalJSON(v038auth.Migrate(authGenState, genAccountsGenState)) } // migrate staking state diff --git a/x/genutil/legacy/v0_38/migrate_test.go b/x/genutil/legacy/v0_38/migrate_test.go index 66ea18e2fc5d..d0c5e8293c2a 100644 --- a/x/genutil/legacy/v0_38/migrate_test.go +++ b/x/genutil/legacy/v0_38/migrate_test.go @@ -5,8 +5,8 @@ import ( v036auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_36" v036genaccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_36" - "github.com/cosmos/cosmos-sdk/x/genutil" v038 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v0_38" + "github.com/cosmos/cosmos-sdk/x/genutil/types" v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_36" "github.com/stretchr/testify/require" @@ -132,7 +132,7 @@ var genStakingState = []byte(`{ }`) func TestMigrate(t *testing.T) { - genesis := genutil.AppMap{ + genesis := types.AppMap{ v036auth.ModuleName: genAuthState, v036genaccounts.ModuleName: genAccountsState, v036staking.ModuleName: genStakingState, diff --git a/x/genutil/legacy/v0_39/migrate.go b/x/genutil/legacy/v0_39/migrate.go new file mode 100644 index 000000000000..0452b6dead01 --- /dev/null +++ b/x/genutil/legacy/v0_39/migrate.go @@ -0,0 +1,34 @@ +package v039 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38" + v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_39" + "github.com/cosmos/cosmos-sdk/x/genutil/types" +) + +// Migrate migrates exported state from v0.38 to a v0.39 genesis state. +// +// NOTE: No actual migration occurs since the types do not change, but JSON +// serialization of accounts do change. +func Migrate(appState types.AppMap) types.AppMap { + v038Codec := codec.New() + cryptocodec.RegisterCrypto(v038Codec) + v038auth.RegisterCodec(v038Codec) + + v039Codec := codec.New() + cryptocodec.RegisterCrypto(v039Codec) + v039auth.RegisterCodec(v039Codec) + + // migrate x/auth state (JSON serialization only) + if appState[v038auth.ModuleName] != nil { + var authGenState v038auth.GenesisState + v038Codec.MustUnmarshalJSON(appState[v038auth.ModuleName], &authGenState) + + delete(appState, v038auth.ModuleName) // delete old key in case the name changed + appState[v039auth.ModuleName] = v039Codec.MustMarshalJSON(authGenState) + } + + return appState +} From b471b41770926c4dbad517a022f4ec4aa6e2015f Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 28 Jul 2020 11:37:24 -0400 Subject: [PATCH 2/7] revert --- x/genutil/legacy/v0_36/migrate.go | 13 ++++++------- x/genutil/legacy/v0_36/migrate_test.go | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/x/genutil/legacy/v0_36/migrate.go b/x/genutil/legacy/v0_36/migrate.go index cabfd285ef42..2ec6d01a2a0a 100644 --- a/x/genutil/legacy/v0_36/migrate.go +++ b/x/genutil/legacy/v0_36/migrate.go @@ -2,29 +2,28 @@ package v036 import ( "github.com/cosmos/cosmos-sdk/codec" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34" v036auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_36" - v036bank "github.com/cosmos/cosmos-sdk/x/bank/legacy/v0_36" v034distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_34" v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v0_36" v034genAccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_34" v036genAccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_36" - "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/cosmos/cosmos-sdk/x/genutil" v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_34" v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v0_36" v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_34" v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v0_36" + v036supply "github.com/cosmos/cosmos-sdk/x/supply/legacy/v0_36" ) // Migrate migrates exported state from v0.34 to a v0.36 genesis state. -func Migrate(appState types.AppMap) types.AppMap { +func Migrate(appState genutil.AppMap) genutil.AppMap { v034Codec := codec.New() - cryptocodec.RegisterCrypto(v034Codec) + codec.RegisterCrypto(v034Codec) v034gov.RegisterCodec(v034Codec) v036Codec := codec.New() - cryptocodec.RegisterCrypto(v036Codec) + codec.RegisterCrypto(v036Codec) v036gov.RegisterCodec(v036Codec) // migrate genesis accounts state @@ -91,7 +90,7 @@ func Migrate(appState types.AppMap) types.AppMap { } // migrate supply state - appState[v036bank.ModuleName] = v036Codec.MustMarshalJSON(v036bank.EmptyGenesisState()) + appState[v036supply.ModuleName] = v036Codec.MustMarshalJSON(v036supply.EmptyGenesisState()) return appState } diff --git a/x/genutil/legacy/v0_36/migrate_test.go b/x/genutil/legacy/v0_36/migrate_test.go index 47553ce16268..3909d3d4b6a6 100644 --- a/x/genutil/legacy/v0_36/migrate_test.go +++ b/x/genutil/legacy/v0_36/migrate_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/cosmos/cosmos-sdk/x/genutil" ) var basic034Gov = []byte(` @@ -86,7 +86,7 @@ var basic034Gov = []byte(` `) func TestDummyGenesis(t *testing.T) { - genesisDummy := types.AppMap{ + genesisDummy := genutil.AppMap{ "foo": {}, "bar": []byte(`{"custom": "module"}`), } @@ -98,7 +98,7 @@ func TestDummyGenesis(t *testing.T) { } func TestGovGenesis(t *testing.T) { - genesis := types.AppMap{ + genesis := genutil.AppMap{ "gov": basic034Gov, } From fb08f99bfbcaf090cf5b52071326ec56aca59291 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 28 Jul 2020 11:42:25 -0400 Subject: [PATCH 3/7] add x/auth legacy --- x/auth/legacy/v0_39/types.go | 473 ++++++++++++++++++++++++++++++ x/genutil/legacy/v0_38/migrate.go | 5 +- x/genutil/legacy/v0_39/migrate.go | 5 +- 3 files changed, 477 insertions(+), 6 deletions(-) create mode 100644 x/auth/legacy/v0_39/types.go diff --git a/x/auth/legacy/v0_39/types.go b/x/auth/legacy/v0_39/types.go new file mode 100644 index 000000000000..bab54a391073 --- /dev/null +++ b/x/auth/legacy/v0_39/types.go @@ -0,0 +1,473 @@ +package v039 + +// DONTCOVER +// nolint + +import ( + "bytes" + "errors" + "fmt" + "sort" + "strings" + + "github.com/tendermint/tendermint/crypto" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34" +) + +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"` + } + + BaseAccount struct { + Address sdk.AccAddress `json:"address" yaml:"address"` + Coins sdk.Coins `json:"coins,omitempty" yaml:"coins,omitempty"` + PubKey crypto.PubKey `json:"public_key" yaml:"public_key"` + AccountNumber uint64 `json:"account_number" yaml:"account_number"` + Sequence uint64 `json:"sequence" yaml:"sequence"` + } + + BaseVestingAccount struct { + *BaseAccount + + OriginalVesting sdk.Coins `json:"original_vesting"` + DelegatedFree sdk.Coins `json:"delegated_free"` + DelegatedVesting sdk.Coins `json:"delegated_vesting"` + + EndTime int64 `json:"end_time"` + } + + vestingAccountJSON struct { + Address sdk.AccAddress `json:"address" yaml:"address"` + Coins sdk.Coins `json:"coins,omitempty" yaml:"coins"` + PubKey crypto.PubKey `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"` + VestingPeriods Periods `json:"vesting_periods,omitempty" yaml:"vesting_periods,omitempty"` + } + + ContinuousVestingAccount struct { + *BaseVestingAccount + + StartTime int64 `json:"start_time"` + } + + DelayedVestingAccount struct { + *BaseVestingAccount + } + + Period struct { + Length int64 `json:"length" yaml:"length"` // length of the period, in seconds + Amount sdk.Coins `json:"amount" yaml:"amount"` // amount of coins vesting during this period + } + + Periods []Period + + PeriodicVestingAccount struct { + *BaseVestingAccount + StartTime int64 `json:"start_time" yaml:"start_time"` // when the coins start to vest + VestingPeriods Periods `json:"vesting_periods" yaml:"vesting_periods"` // the vesting schedule + } + + ModuleAccount struct { + *BaseAccount + + 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,omitempty" 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 { + return GenesisState{ + Params: params, + Accounts: accounts, + } +} + +func NewBaseAccountWithAddress(addr sdk.AccAddress) BaseAccount { + return BaseAccount{ + Address: addr, + } +} + +func NewBaseAccount( + address sdk.AccAddress, coins sdk.Coins, pk crypto.PubKey, accountNumber, sequence uint64, +) *BaseAccount { + + return &BaseAccount{ + Address: address, + Coins: coins, + PubKey: pk, + AccountNumber: accountNumber, + Sequence: sequence, + } +} + +func (acc BaseAccount) GetAddress() sdk.AccAddress { + return acc.Address +} + +func (acc *BaseAccount) GetAccountNumber() uint64 { + return acc.AccountNumber +} + +func (acc *BaseAccount) GetCoins() sdk.Coins { + return acc.Coins +} + +func (acc *BaseAccount) SetCoins(coins sdk.Coins) error { + acc.Coins = coins + return nil +} + +func (acc BaseAccount) Validate() error { + if acc.PubKey != nil && acc.Address != nil && + !bytes.Equal(acc.PubKey.Address().Bytes(), acc.Address.Bytes()) { + return errors.New("pubkey and address pair is invalid") + } + + return nil +} + +func NewBaseVestingAccount( + baseAccount *BaseAccount, originalVesting, delegatedFree, delegatedVesting sdk.Coins, endTime int64, +) *BaseVestingAccount { + + return &BaseVestingAccount{ + BaseAccount: baseAccount, + OriginalVesting: originalVesting, + DelegatedFree: delegatedFree, + DelegatedVesting: delegatedVesting, + EndTime: endTime, + } +} + +func (bva BaseVestingAccount) MarshalJSON() ([]byte, error) { + alias := vestingAccountJSON{ + Address: bva.Address, + PubKey: bva.PubKey, + AccountNumber: bva.AccountNumber, + Sequence: bva.Sequence, + OriginalVesting: bva.OriginalVesting, + DelegatedFree: bva.DelegatedFree, + DelegatedVesting: bva.DelegatedVesting, + EndTime: bva.EndTime, + } + + return codec.Cdc.MarshalJSON(alias) +} + +func (bva *BaseVestingAccount) UnmarshalJSON(bz []byte) error { + var alias vestingAccountJSON + if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { + return err + } + + bva.BaseAccount = NewBaseAccount(alias.Address, alias.Coins, alias.PubKey, alias.AccountNumber, alias.Sequence) + bva.OriginalVesting = alias.OriginalVesting + bva.DelegatedFree = alias.DelegatedFree + bva.DelegatedVesting = alias.DelegatedVesting + bva.EndTime = alias.EndTime + + return nil +} + +func (bva BaseVestingAccount) GetEndTime() int64 { + return bva.EndTime +} + +func (bva BaseVestingAccount) Validate() error { + if (bva.Coins.IsZero() && !bva.OriginalVesting.IsZero()) || + bva.OriginalVesting.IsAnyGT(bva.Coins) { + return errors.New("vesting amount cannot be greater than total amount") + } + + return bva.BaseAccount.Validate() +} + +func NewContinuousVestingAccountRaw(bva *BaseVestingAccount, startTime int64) *ContinuousVestingAccount { + return &ContinuousVestingAccount{ + BaseVestingAccount: bva, + StartTime: startTime, + } +} + +func (cva ContinuousVestingAccount) Validate() error { + if cva.StartTime >= cva.EndTime { + return errors.New("vesting start-time cannot be before end-time") + } + + return cva.BaseVestingAccount.Validate() +} + +func (cva ContinuousVestingAccount) MarshalJSON() ([]byte, error) { + alias := vestingAccountJSON{ + Address: cva.Address, + PubKey: cva.PubKey, + AccountNumber: cva.AccountNumber, + Sequence: cva.Sequence, + OriginalVesting: cva.OriginalVesting, + DelegatedFree: cva.DelegatedFree, + DelegatedVesting: cva.DelegatedVesting, + EndTime: cva.EndTime, + StartTime: cva.StartTime, + } + + return codec.Cdc.MarshalJSON(alias) +} + +func (cva *ContinuousVestingAccount) UnmarshalJSON(bz []byte) error { + var alias vestingAccountJSON + if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { + return err + } + + cva.BaseVestingAccount = &BaseVestingAccount{ + BaseAccount: NewBaseAccount(alias.Address, alias.Coins, alias.PubKey, alias.AccountNumber, alias.Sequence), + OriginalVesting: alias.OriginalVesting, + DelegatedFree: alias.DelegatedFree, + DelegatedVesting: alias.DelegatedVesting, + EndTime: alias.EndTime, + } + cva.StartTime = alias.StartTime + + return nil +} + +func (dva DelayedVestingAccount) Validate() error { + return dva.BaseVestingAccount.Validate() +} + +func (dva DelayedVestingAccount) MarshalJSON() ([]byte, error) { + alias := vestingAccountJSON{ + Address: dva.Address, + PubKey: dva.PubKey, + AccountNumber: dva.AccountNumber, + Sequence: dva.Sequence, + OriginalVesting: dva.OriginalVesting, + DelegatedFree: dva.DelegatedFree, + DelegatedVesting: dva.DelegatedVesting, + EndTime: dva.EndTime, + } + + return codec.Cdc.MarshalJSON(alias) +} + +// UnmarshalJSON unmarshals raw JSON bytes into a DelayedVestingAccount. +func (dva *DelayedVestingAccount) UnmarshalJSON(bz []byte) error { + var alias vestingAccountJSON + if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { + return err + } + + dva.BaseVestingAccount = &BaseVestingAccount{ + BaseAccount: NewBaseAccount(alias.Address, alias.Coins, alias.PubKey, alias.AccountNumber, alias.Sequence), + OriginalVesting: alias.OriginalVesting, + DelegatedFree: alias.DelegatedFree, + DelegatedVesting: alias.DelegatedVesting, + EndTime: alias.EndTime, + } + + return nil +} + +func (pva PeriodicVestingAccount) GetStartTime() int64 { + return pva.StartTime +} + +func (pva PeriodicVestingAccount) Validate() error { + if pva.GetStartTime() >= pva.GetEndTime() { + return errors.New("vesting start-time cannot be before end-time") + } + endTime := pva.StartTime + originalVesting := sdk.NewCoins() + for _, p := range pva.VestingPeriods { + endTime += p.Length + originalVesting = originalVesting.Add(p.Amount...) + } + if endTime != pva.EndTime { + return errors.New("vesting end time does not match length of all vesting periods") + } + if !originalVesting.IsEqual(pva.OriginalVesting) { + return errors.New("original vesting coins does not match the sum of all coins in vesting periods") + } + + return pva.BaseVestingAccount.Validate() +} + +func (pva PeriodicVestingAccount) MarshalJSON() ([]byte, error) { + alias := vestingAccountJSON{ + Address: pva.Address, + PubKey: pva.PubKey, + AccountNumber: pva.AccountNumber, + Sequence: pva.Sequence, + OriginalVesting: pva.OriginalVesting, + DelegatedFree: pva.DelegatedFree, + DelegatedVesting: pva.DelegatedVesting, + EndTime: pva.EndTime, + StartTime: pva.StartTime, + VestingPeriods: pva.VestingPeriods, + } + + return codec.Cdc.MarshalJSON(alias) +} + +// UnmarshalJSON unmarshals raw JSON bytes into a PeriodicVestingAccount. +func (pva *PeriodicVestingAccount) UnmarshalJSON(bz []byte) error { + var alias vestingAccountJSON + if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { + return err + } + + pva.BaseVestingAccount = &BaseVestingAccount{ + BaseAccount: NewBaseAccount(alias.Address, alias.Coins, alias.PubKey, alias.AccountNumber, alias.Sequence), + OriginalVesting: alias.OriginalVesting, + DelegatedFree: alias.DelegatedFree, + DelegatedVesting: alias.DelegatedVesting, + EndTime: alias.EndTime, + } + pva.StartTime = alias.StartTime + pva.VestingPeriods = alias.VestingPeriods + + return nil +} + +func (ma ModuleAccount) Validate() error { + if err := 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) + } + + return ma.BaseAccount.Validate() +} + +// MarshalJSON returns the JSON representation of a ModuleAccount. +func (ma ModuleAccount) MarshalJSON() ([]byte, error) { + return codec.Cdc.MarshalJSON(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 := codec.Cdc.UnmarshalJSON(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 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.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil) + cdc.RegisterConcrete(&BaseVestingAccount{}, "cosmos-sdk/BaseVestingAccount", nil) + cdc.RegisterConcrete(&ContinuousVestingAccount{}, "cosmos-sdk/ContinuousVestingAccount", nil) + cdc.RegisterConcrete(&DelayedVestingAccount{}, "cosmos-sdk/DelayedVestingAccount", nil) + cdc.RegisterConcrete(&PeriodicVestingAccount{}, "cosmos-sdk/PeriodicVestingAccount", nil) + cdc.RegisterConcrete(&ModuleAccount{}, "cosmos-sdk/ModuleAccount", nil) +} diff --git a/x/genutil/legacy/v0_38/migrate.go b/x/genutil/legacy/v0_38/migrate.go index 6c9e8c003676..ae22212c3d14 100644 --- a/x/genutil/legacy/v0_38/migrate.go +++ b/x/genutil/legacy/v0_38/migrate.go @@ -2,7 +2,6 @@ package v038 import ( "github.com/cosmos/cosmos-sdk/codec" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/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" @@ -16,10 +15,10 @@ import ( // Migrate migrates exported state from v0.36/v0.37 to a v0.38 genesis state. func Migrate(appState types.AppMap) types.AppMap { v036Codec := codec.New() - cryptocodec.RegisterCrypto(v036Codec) + codec.RegisterCrypto(v036Codec) v038Codec := codec.New() - cryptocodec.RegisterCrypto(v038Codec) + codec.RegisterCrypto(v038Codec) v038auth.RegisterCodec(v038Codec) if appState[v036genaccounts.ModuleName] != nil { diff --git a/x/genutil/legacy/v0_39/migrate.go b/x/genutil/legacy/v0_39/migrate.go index 0452b6dead01..9c65722bca09 100644 --- a/x/genutil/legacy/v0_39/migrate.go +++ b/x/genutil/legacy/v0_39/migrate.go @@ -2,7 +2,6 @@ package v039 import ( "github.com/cosmos/cosmos-sdk/codec" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38" v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_39" "github.com/cosmos/cosmos-sdk/x/genutil/types" @@ -14,11 +13,11 @@ import ( // serialization of accounts do change. func Migrate(appState types.AppMap) types.AppMap { v038Codec := codec.New() - cryptocodec.RegisterCrypto(v038Codec) + codec.RegisterCrypto(v038Codec) v038auth.RegisterCodec(v038Codec) v039Codec := codec.New() - cryptocodec.RegisterCrypto(v039Codec) + codec.RegisterCrypto(v039Codec) v039auth.RegisterCodec(v039Codec) // migrate x/auth state (JSON serialization only) From 53514e829202fc98984b846115875027d7d8079a Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 28 Jul 2020 11:43:19 -0400 Subject: [PATCH 4/7] update cmd --- x/genutil/client/cli/migrate.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/genutil/client/cli/migrate.go b/x/genutil/client/cli/migrate.go index 3ae77c506d61..eeba89356a95 100644 --- a/x/genutil/client/cli/migrate.go +++ b/x/genutil/client/cli/migrate.go @@ -16,6 +16,7 @@ import ( extypes "github.com/cosmos/cosmos-sdk/x/genutil" v036 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v0_36" v038 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v0_38" + v039 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v0_39" ) const ( @@ -29,6 +30,7 @@ const ( var migrationMap = extypes.MigrationMap{ "v0.36": v036.Migrate, "v0.38": v038.Migrate, // NOTE: v0.37 and v0.38 are genesis compatible + "v0.39": v039.Migrate, } // GetMigrationCallback returns a MigrationCallback for a given version. From bcef712d8a5f029be7c4390e0efd804b063015bb Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 28 Jul 2020 15:47:43 -0400 Subject: [PATCH 5/7] update migration types --- x/auth/legacy/v0_38/types.go | 18 ++-- x/genutil/legacy/v0_38/migrate.go | 5 +- x/genutil/legacy/v0_39/migrate.go | 7 +- x/genutil/legacy/v0_39/migrate_test.go | 120 +++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 x/genutil/legacy/v0_39/migrate_test.go diff --git a/x/auth/legacy/v0_38/types.go b/x/auth/legacy/v0_38/types.go index 15896a39121f..b7004a4081e9 100644 --- a/x/auth/legacy/v0_38/types.go +++ b/x/auth/legacy/v0_38/types.go @@ -46,7 +46,7 @@ type ( BaseAccount struct { Address sdk.AccAddress `json:"address" yaml:"address"` - Coins sdk.Coins `json:"coins" yaml:"coins"` + Coins sdk.Coins `json:"coins,omitempty" yaml:"coins,omitempty"` PubKey crypto.PubKey `json:"public_key" yaml:"public_key"` AccountNumber uint64 `json:"account_number" yaml:"account_number"` Sequence uint64 `json:"sequence" yaml:"sequence"` @@ -54,7 +54,7 @@ type ( baseAccountPretty struct { Address sdk.AccAddress `json:"address" yaml:"address"` - Coins sdk.Coins `json:"coins" yaml:"coins"` + Coins sdk.Coins `json:"coins,omitempty" yaml:"coins,omitempty"` PubKey string `json:"public_key" yaml:"public_key"` AccountNumber uint64 `json:"account_number" yaml:"account_number"` Sequence uint64 `json:"sequence" yaml:"sequence"` @@ -72,7 +72,7 @@ type ( vestingAccountPretty struct { Address sdk.AccAddress `json:"address" yaml:"address"` - Coins sdk.Coins `json:"coins" yaml:"coins"` + Coins sdk.Coins `json:"coins,omitempty" yaml:"coins,omitempty"` PubKey string `json:"public_key" yaml:"public_key"` AccountNumber uint64 `json:"account_number" yaml:"account_number"` Sequence uint64 `json:"sequence" yaml:"sequence"` @@ -104,7 +104,7 @@ type ( moduleAccountPretty struct { Address sdk.AccAddress `json:"address" yaml:"address"` - Coins sdk.Coins `json:"coins" yaml:"coins"` + Coins sdk.Coins `json:"coins,omitempty" yaml:"coins,omitempty"` PubKey string `json:"public_key" yaml:"public_key"` AccountNumber uint64 `json:"account_number" yaml:"account_number"` Sequence uint64 `json:"sequence" yaml:"sequence"` @@ -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 } @@ -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") @@ -486,7 +486,7 @@ func validatePermissions(permissions ...string) error { return nil } -func sanitizeGenesisAccounts(genAccounts GenesisAccounts) GenesisAccounts { +func SanitizeGenesisAccounts(genAccounts GenesisAccounts) GenesisAccounts { sort.Slice(genAccounts, func(i, j int) bool { return genAccounts[i].GetAccountNumber() < genAccounts[j].GetAccountNumber() }) @@ -500,7 +500,7 @@ func sanitizeGenesisAccounts(genAccounts GenesisAccounts) GenesisAccounts { return genAccounts } -func validateGenAccounts(genAccounts GenesisAccounts) error { +func ValidateGenAccounts(genAccounts GenesisAccounts) error { addrMap := make(map[string]bool, len(genAccounts)) for _, acc := range genAccounts { @@ -524,7 +524,7 @@ func validateGenAccounts(genAccounts GenesisAccounts) error { func RegisterCodec(cdc *codec.Codec) { cdc.RegisterInterface((*GenesisAccount)(nil), nil) cdc.RegisterInterface((*Account)(nil), nil) - cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/Account", nil) + cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil) cdc.RegisterConcrete(&BaseVestingAccount{}, "cosmos-sdk/BaseVestingAccount", nil) cdc.RegisterConcrete(&ContinuousVestingAccount{}, "cosmos-sdk/ContinuousVestingAccount", nil) cdc.RegisterConcrete(&DelayedVestingAccount{}, "cosmos-sdk/DelayedVestingAccount", nil) diff --git a/x/genutil/legacy/v0_38/migrate.go b/x/genutil/legacy/v0_38/migrate.go index ae22212c3d14..6c9e8c003676 100644 --- a/x/genutil/legacy/v0_38/migrate.go +++ b/x/genutil/legacy/v0_38/migrate.go @@ -2,6 +2,7 @@ package v038 import ( "github.com/cosmos/cosmos-sdk/codec" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/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" @@ -15,10 +16,10 @@ import ( // Migrate migrates exported state from v0.36/v0.37 to a v0.38 genesis state. func Migrate(appState types.AppMap) types.AppMap { v036Codec := codec.New() - codec.RegisterCrypto(v036Codec) + cryptocodec.RegisterCrypto(v036Codec) v038Codec := codec.New() - codec.RegisterCrypto(v038Codec) + cryptocodec.RegisterCrypto(v038Codec) v038auth.RegisterCodec(v038Codec) if appState[v036genaccounts.ModuleName] != nil { diff --git a/x/genutil/legacy/v0_39/migrate.go b/x/genutil/legacy/v0_39/migrate.go index 9c65722bca09..f1d1b45d5868 100644 --- a/x/genutil/legacy/v0_39/migrate.go +++ b/x/genutil/legacy/v0_39/migrate.go @@ -2,6 +2,7 @@ package v039 import ( "github.com/cosmos/cosmos-sdk/codec" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38" v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_39" "github.com/cosmos/cosmos-sdk/x/genutil/types" @@ -13,11 +14,11 @@ import ( // serialization of accounts do change. func Migrate(appState types.AppMap) types.AppMap { v038Codec := codec.New() - codec.RegisterCrypto(v038Codec) + cryptocodec.RegisterCrypto(v038Codec) v038auth.RegisterCodec(v038Codec) v039Codec := codec.New() - codec.RegisterCrypto(v039Codec) + cryptocodec.RegisterCrypto(v039Codec) v039auth.RegisterCodec(v039Codec) // migrate x/auth state (JSON serialization only) @@ -26,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 diff --git a/x/genutil/legacy/v0_39/migrate_test.go b/x/genutil/legacy/v0_39/migrate_test.go new file mode 100644 index 000000000000..d6f68a0003fa --- /dev/null +++ b/x/genutil/legacy/v0_39/migrate_test.go @@ -0,0 +1,120 @@ +package v039_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38" + v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_39" + v039 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v0_39" + "github.com/cosmos/cosmos-sdk/x/genutil/types" +) + +var genAuthState = []byte(`{ + "params": { + "max_memo_characters": "10", + "tx_sig_limit": "10", + "tx_size_cost_per_byte": "10", + "sig_verify_cost_ed25519": "10", + "sig_verify_cost_secp256k1": "10" + }, + "accounts": [ + { + "type": "cosmos-sdk/BaseAccount", + "value": { + "address": "cosmos19hz3ee9e3lj9mne4jggj3v8hxjrpre22jukj9y", + "coins": [ + { + "denom": "stake", + "amount": "400000" + } + ], + "public_key": "cosmospub1addwnpepqtezq4ajkevh724ls45zp72x70rj8mhszqf5pxcaahazm8trv490swlf404", + "account_number": 1, + "sequence": 1 + } + }, + { + "type": "cosmos-sdk/ModuleAccount", + "value": { + "address": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh", + "coins": [ + { + "denom": "stake", + "amount": "400000000" + } + ], + "public_key": "", + "account_number": 2, + "sequence": 4, + "name": "bonded_tokens_pool", + "permissions": [ + "burner", + "staking" + ] + } + }, + { + "type": "cosmos-sdk/ContinuousVestingAccount", + "value": { + "address": "cosmos1vtzxzyjv506dvhl9pa527xsugf5gez4fnqxq0n", + "coins": [ + { + "denom": "stake", + "amount": "10000205" + } + ], + "public_key": "cosmospub1addwnpepqdxrk48q89xlmnzrr5nkssle05tkp73uknevzaavm53c02v26vlyzz6vcdh", + "account_number": 3, + "sequence": 5, + "original_vesting": [ + { + "denom": "stake", + "amount": "10000205" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": 1596125048, + "start_time": 1595952248 + } + }, + { + "type": "cosmos-sdk/DelayedVestingAccount", + "value": { + "address": "cosmos1prxkcqclweqa0g28p7vmf6z78ghyeckm4qak30", + "coins": [ + { + "denom": "stake", + "amount": "10000205" + } + ], + "public_key": "cosmospub1addwnpepqwewcad349e2yw3weatf8lzfyv5cd6am9jkk4ajach3f568k6gg47nls3p8", + "account_number": 4, + "sequence": 15, + "original_vesting": [ + { + "denom": "stake", + "amount": "10000205" + } + ], + "delegated_free": [], + "delegated_vesting": [], + "end_time": 1596125048 + } + } + ] +}`) + +var expectedGenAuthState = []byte(`{"params":{"max_memo_characters":"10","tx_sig_limit":"10","tx_size_cost_per_byte":"10","sig_verify_cost_ed25519":"10","sig_verify_cost_secp256k1":"10"},"accounts":[{"type":"cosmos-sdk/BaseAccount","value":{"address":"cosmos19hz3ee9e3lj9mne4jggj3v8hxjrpre22jukj9y","coins":[{"denom":"stake","amount":"400000"}],"public_key":{"type":"tendermint/PubKeySecp256k1","value":"AvIgV7K2WX8qv4VoIPlG88cj7vAQE0CbHe36LZ1jZUr4"},"account_number":"1","sequence":"1"}},{"type":"cosmos-sdk/ModuleAccount","value":{"address":"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh","coins":[{"denom":"stake","amount":"400000000"}],"public_key":"","account_number":"2","sequence":"4","name":"bonded_tokens_pool","permissions":["burner","staking"]}},{"type":"cosmos-sdk/ContinuousVestingAccount","value":{"address":"cosmos1vtzxzyjv506dvhl9pa527xsugf5gez4fnqxq0n","coins":[{"denom":"stake","amount":"10000205"}],"public_key":{"type":"tendermint/PubKeySecp256k1","value":"A0w7VOA5Tf3MQx0naEP5fRdg+jy08sF3rN0jh6mK0z5B"},"account_number":"3","sequence":"5","original_vesting":[{"denom":"stake","amount":"10000205"}],"delegated_free":[],"delegated_vesting":[],"end_time":"1596125048","start_time":"1595952248"}},{"type":"cosmos-sdk/DelayedVestingAccount","value":{"address":"cosmos1prxkcqclweqa0g28p7vmf6z78ghyeckm4qak30","coins":[{"denom":"stake","amount":"10000205"}],"public_key":{"type":"tendermint/PubKeySecp256k1","value":"A7LsdbGpcqI6Ls9Wk/xJIymG67ssrWr2XcXimmj20hFf"},"account_number":"4","sequence":"15","original_vesting":[{"denom":"stake","amount":"10000205"}],"delegated_free":[],"delegated_vesting":[],"end_time":"1596125048"}}]}`) + +func TestMigrate(t *testing.T) { + genesis := types.AppMap{ + v038auth.ModuleName: genAuthState, + } + + var migrated types.AppMap + require.NotPanics(t, func() { migrated = v039.Migrate(genesis) }) + require.Equal(t, string(expectedGenAuthState), string(migrated[v039auth.ModuleName])) +} From a9fb6a859dba8605a918150ad44974bfb43572eb Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 28 Jul 2020 15:49:17 -0400 Subject: [PATCH 6/7] update migration types --- x/auth/legacy/v0_39/migrate.go | 60 +++++++++++++++++ x/auth/legacy/v0_39/types.go | 118 +++++++++++---------------------- 2 files changed, 98 insertions(+), 80 deletions(-) create mode 100644 x/auth/legacy/v0_39/migrate.go diff --git a/x/auth/legacy/v0_39/migrate.go b/x/auth/legacy/v0_39/migrate.go new file mode 100644 index 000000000000..410283dc93fd --- /dev/null +++ b/x/auth/legacy/v0_39/migrate.go @@ -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) +} diff --git a/x/auth/legacy/v0_39/types.go b/x/auth/legacy/v0_39/types.go index bab54a391073..9de38e6d6fe5 100644 --- a/x/auth/legacy/v0_39/types.go +++ b/x/auth/legacy/v0_39/types.go @@ -7,14 +7,15 @@ import ( "bytes" "errors" "fmt" - "sort" "strings" "github.com/tendermint/tendermint/crypto" "github.com/cosmos/cosmos-sdk/codec" + "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 ( @@ -22,25 +23,9 @@ const ( ) 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 { @@ -118,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, @@ -186,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, @@ -195,12 +181,12 @@ func (bva BaseVestingAccount) MarshalJSON() ([]byte, error) { EndTime: bva.EndTime, } - return codec.Cdc.MarshalJSON(alias) + return legacy.Cdc.MarshalJSON(alias) } func (bva *BaseVestingAccount) UnmarshalJSON(bz []byte) error { var alias vestingAccountJSON - if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } @@ -244,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, @@ -254,12 +241,12 @@ func (cva ContinuousVestingAccount) MarshalJSON() ([]byte, error) { StartTime: cva.StartTime, } - return codec.Cdc.MarshalJSON(alias) + return legacy.Cdc.MarshalJSON(alias) } func (cva *ContinuousVestingAccount) UnmarshalJSON(bz []byte) error { var alias vestingAccountJSON - if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } @@ -275,6 +262,12 @@ 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() } @@ -282,6 +275,7 @@ func (dva DelayedVestingAccount) Validate() error { func (dva DelayedVestingAccount) MarshalJSON() ([]byte, error) { alias := vestingAccountJSON{ Address: dva.Address, + Coins: dva.Coins, PubKey: dva.PubKey, AccountNumber: dva.AccountNumber, Sequence: dva.Sequence, @@ -291,13 +285,13 @@ func (dva DelayedVestingAccount) MarshalJSON() ([]byte, error) { EndTime: dva.EndTime, } - return codec.Cdc.MarshalJSON(alias) + return legacy.Cdc.MarshalJSON(alias) } // UnmarshalJSON unmarshals raw JSON bytes into a DelayedVestingAccount. func (dva *DelayedVestingAccount) UnmarshalJSON(bz []byte) error { var alias vestingAccountJSON - if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } @@ -339,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, @@ -350,13 +345,13 @@ func (pva PeriodicVestingAccount) MarshalJSON() ([]byte, error) { VestingPeriods: pva.VestingPeriods, } - return codec.Cdc.MarshalJSON(alias) + return legacy.Cdc.MarshalJSON(alias) } // UnmarshalJSON unmarshals raw JSON bytes into a PeriodicVestingAccount. func (pva *PeriodicVestingAccount) UnmarshalJSON(bz []byte) error { var alias vestingAccountJSON - if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } @@ -373,8 +368,16 @@ 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 } @@ -382,8 +385,8 @@ func (ma ModuleAccount) Validate() error { 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() @@ -391,7 +394,7 @@ func (ma ModuleAccount) Validate() error { // MarshalJSON returns the JSON representation of a ModuleAccount. func (ma ModuleAccount) MarshalJSON() ([]byte, error) { - return codec.Cdc.MarshalJSON(moduleAccountPretty{ + return legacy.Cdc.MarshalJSON(moduleAccountPretty{ Address: ma.Address, Coins: ma.Coins, PubKey: "", @@ -405,7 +408,7 @@ func (ma ModuleAccount) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals raw JSON bytes into a ModuleAccount. func (ma *ModuleAccount) UnmarshalJSON(bz []byte) error { var alias moduleAccountPretty - if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } @@ -416,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) From 420d4ef6f651d8d6470f42afd229f3b5ef14abf9 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 28 Jul 2020 15:51:43 -0400 Subject: [PATCH 7/7] update migration types --- x/auth/legacy/v0_38/migrate.go | 4 ++-- x/auth/legacy/v0_39/types.go | 21 ++++++++++----------- x/genutil/legacy/v0_38/migrate.go | 5 ++--- x/genutil/legacy/v0_39/migrate.go | 5 ++--- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/x/auth/legacy/v0_38/migrate.go b/x/auth/legacy/v0_38/migrate.go index e76937777678..f4a32b4454c3 100644 --- a/x/auth/legacy/v0_38/migrate.go +++ b/x/auth/legacy/v0_38/migrate.go @@ -42,9 +42,9 @@ func Migrate(authGenState v036auth.GenesisState, genAccountsGenState v036genacco accounts[i] = genAccount } - accounts = sanitizeGenesisAccounts(accounts) + accounts = SanitizeGenesisAccounts(accounts) - if err := validateGenAccounts(accounts); err != nil { + if err := ValidateGenAccounts(accounts); err != nil { panic(err) } diff --git a/x/auth/legacy/v0_39/types.go b/x/auth/legacy/v0_39/types.go index 9de38e6d6fe5..b118b15f48ca 100644 --- a/x/auth/legacy/v0_39/types.go +++ b/x/auth/legacy/v0_39/types.go @@ -12,7 +12,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/cosmos/cosmos-sdk/codec" - "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" @@ -181,12 +180,12 @@ func (bva BaseVestingAccount) MarshalJSON() ([]byte, error) { EndTime: bva.EndTime, } - return legacy.Cdc.MarshalJSON(alias) + return codec.Cdc.MarshalJSON(alias) } func (bva *BaseVestingAccount) UnmarshalJSON(bz []byte) error { var alias vestingAccountJSON - if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } @@ -241,12 +240,12 @@ func (cva ContinuousVestingAccount) MarshalJSON() ([]byte, error) { StartTime: cva.StartTime, } - return legacy.Cdc.MarshalJSON(alias) + return codec.Cdc.MarshalJSON(alias) } func (cva *ContinuousVestingAccount) UnmarshalJSON(bz []byte) error { var alias vestingAccountJSON - if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } @@ -285,13 +284,13 @@ func (dva DelayedVestingAccount) MarshalJSON() ([]byte, error) { EndTime: dva.EndTime, } - return legacy.Cdc.MarshalJSON(alias) + return codec.Cdc.MarshalJSON(alias) } // UnmarshalJSON unmarshals raw JSON bytes into a DelayedVestingAccount. func (dva *DelayedVestingAccount) UnmarshalJSON(bz []byte) error { var alias vestingAccountJSON - if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } @@ -345,13 +344,13 @@ func (pva PeriodicVestingAccount) MarshalJSON() ([]byte, error) { VestingPeriods: pva.VestingPeriods, } - return legacy.Cdc.MarshalJSON(alias) + return codec.Cdc.MarshalJSON(alias) } // UnmarshalJSON unmarshals raw JSON bytes into a PeriodicVestingAccount. func (pva *PeriodicVestingAccount) UnmarshalJSON(bz []byte) error { var alias vestingAccountJSON - if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } @@ -394,7 +393,7 @@ func (ma ModuleAccount) Validate() error { // MarshalJSON returns the JSON representation of a ModuleAccount. func (ma ModuleAccount) MarshalJSON() ([]byte, error) { - return legacy.Cdc.MarshalJSON(moduleAccountPretty{ + return codec.Cdc.MarshalJSON(moduleAccountPretty{ Address: ma.Address, Coins: ma.Coins, PubKey: "", @@ -408,7 +407,7 @@ func (ma ModuleAccount) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals raw JSON bytes into a ModuleAccount. func (ma *ModuleAccount) UnmarshalJSON(bz []byte) error { var alias moduleAccountPretty - if err := legacy.Cdc.UnmarshalJSON(bz, &alias); err != nil { + if err := codec.Cdc.UnmarshalJSON(bz, &alias); err != nil { return err } diff --git a/x/genutil/legacy/v0_38/migrate.go b/x/genutil/legacy/v0_38/migrate.go index 6c9e8c003676..ae22212c3d14 100644 --- a/x/genutil/legacy/v0_38/migrate.go +++ b/x/genutil/legacy/v0_38/migrate.go @@ -2,7 +2,6 @@ package v038 import ( "github.com/cosmos/cosmos-sdk/codec" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/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" @@ -16,10 +15,10 @@ import ( // Migrate migrates exported state from v0.36/v0.37 to a v0.38 genesis state. func Migrate(appState types.AppMap) types.AppMap { v036Codec := codec.New() - cryptocodec.RegisterCrypto(v036Codec) + codec.RegisterCrypto(v036Codec) v038Codec := codec.New() - cryptocodec.RegisterCrypto(v038Codec) + codec.RegisterCrypto(v038Codec) v038auth.RegisterCodec(v038Codec) if appState[v036genaccounts.ModuleName] != nil { diff --git a/x/genutil/legacy/v0_39/migrate.go b/x/genutil/legacy/v0_39/migrate.go index f1d1b45d5868..6e614cc5a4af 100644 --- a/x/genutil/legacy/v0_39/migrate.go +++ b/x/genutil/legacy/v0_39/migrate.go @@ -2,7 +2,6 @@ package v039 import ( "github.com/cosmos/cosmos-sdk/codec" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" v038auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_38" v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_39" "github.com/cosmos/cosmos-sdk/x/genutil/types" @@ -14,11 +13,11 @@ import ( // serialization of accounts do change. func Migrate(appState types.AppMap) types.AppMap { v038Codec := codec.New() - cryptocodec.RegisterCrypto(v038Codec) + codec.RegisterCrypto(v038Codec) v038auth.RegisterCodec(v038Codec) v039Codec := codec.New() - cryptocodec.RegisterCrypto(v039Codec) + codec.RegisterCrypto(v039Codec) v039auth.RegisterCodec(v039Codec) // migrate x/auth state (JSON serialization only)