Merge PR #5047: Fix Genesis Accounts Migration
This commit is contained in:
parent
6684cdf3e5
commit
943cc54811
|
@ -1,13 +1,52 @@
|
||||||
package v038
|
package v038
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
v036auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_36"
|
v036auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_36"
|
||||||
|
v036genaccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_36"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Migrate accepts exported genesis state from v0.34 and migrates it to v0.38
|
// Migrate accepts exported genesis state from v0.34 and migrates it to v0.38
|
||||||
// genesis state.
|
// genesis state.
|
||||||
func Migrate(oldGenState v036auth.GenesisState, accounts json.RawMessage) GenesisState {
|
func Migrate(authGenState v036auth.GenesisState, genAccountsGenState v036genaccounts.GenesisState) GenesisState {
|
||||||
return NewGenesisState(oldGenState.Params, accounts)
|
accounts := make(GenesisAccounts, len(genAccountsGenState))
|
||||||
|
|
||||||
|
for i, acc := range genAccountsGenState {
|
||||||
|
var genAccount GenesisAccount
|
||||||
|
|
||||||
|
baseAccount := NewBaseAccount(acc.Address, acc.Coins.Sort(), acc.AccountNumber, acc.Sequence)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case !acc.OriginalVesting.IsZero():
|
||||||
|
baseVestingAccount := NewBaseVestingAccount(
|
||||||
|
baseAccount, acc.OriginalVesting.Sort(), acc.DelegatedFree.Sort(),
|
||||||
|
acc.DelegatedVesting.Sort(), acc.EndTime,
|
||||||
|
)
|
||||||
|
|
||||||
|
if acc.StartTime != 0 && acc.EndTime != 0 {
|
||||||
|
// continuous vesting account type
|
||||||
|
genAccount = NewContinuousVestingAccountRaw(baseVestingAccount, acc.StartTime)
|
||||||
|
} else if acc.EndTime != 0 {
|
||||||
|
// delayed vesting account type
|
||||||
|
genAccount = NewDelayedVestingAccountRaw(baseVestingAccount)
|
||||||
|
}
|
||||||
|
|
||||||
|
case acc.ModuleName != "":
|
||||||
|
// module account type
|
||||||
|
genAccount = NewModuleAccount(baseAccount, acc.ModuleName, acc.ModulePermissions...)
|
||||||
|
|
||||||
|
default:
|
||||||
|
// standard account type
|
||||||
|
genAccount = baseAccount
|
||||||
|
}
|
||||||
|
|
||||||
|
accounts[i] = genAccount
|
||||||
|
}
|
||||||
|
|
||||||
|
accounts = sanitizeGenesisAccounts(accounts)
|
||||||
|
|
||||||
|
if err := validateGenAccounts(accounts); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewGenesisState(authGenState.Params, accounts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,23 @@
|
||||||
package v038
|
package v038
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34"
|
v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34"
|
||||||
v036auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_36"
|
v036auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_36"
|
||||||
|
v036genaccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v0_36"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func accAddressFromBech32(t *testing.T, addrStr string) sdk.AccAddress {
|
||||||
|
addr, err := sdk.AccAddressFromBech32(addrStr)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
func TestMigrate(t *testing.T) {
|
func TestMigrate(t *testing.T) {
|
||||||
var genesisState GenesisState
|
var genesisState GenesisState
|
||||||
|
|
||||||
|
@ -20,105 +28,155 @@ func TestMigrate(t *testing.T) {
|
||||||
SigVerifyCostED25519: 10,
|
SigVerifyCostED25519: 10,
|
||||||
SigVerifyCostSecp256k1: 10,
|
SigVerifyCostSecp256k1: 10,
|
||||||
}
|
}
|
||||||
rawAccounts := `[
|
|
||||||
{
|
acc1 := v036genaccounts.GenesisAccount{
|
||||||
"address": "cosmos1dfp05pasnts7a4lupn889vptjtrxzkk5f7027f",
|
Address: accAddressFromBech32(t, "cosmos1f9xjhxm0plzrh9cskf4qee4pc2xwp0n0556gh0"),
|
||||||
"coins": [
|
Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 400000)),
|
||||||
{
|
Sequence: 1,
|
||||||
"denom": "node0token",
|
AccountNumber: 1,
|
||||||
"amount": "1000000000"
|
}
|
||||||
},
|
acc2 := v036genaccounts.GenesisAccount{
|
||||||
{
|
Address: accAddressFromBech32(t, "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"),
|
||||||
"denom": "stake",
|
Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 400000000)),
|
||||||
"amount": "500000000"
|
Sequence: 4,
|
||||||
}
|
AccountNumber: 2,
|
||||||
],
|
ModuleName: "bonded_tokens_pool",
|
||||||
"sequence_number": "0",
|
ModulePermissions: []string{"burner", "staking"},
|
||||||
"account_number": "0",
|
}
|
||||||
"original_vesting": [],
|
acc3 := v036genaccounts.GenesisAccount{
|
||||||
"delegated_free": [],
|
Address: accAddressFromBech32(t, "cosmos17n9sztlhx32tfy0tg0zc2ttmkeeth50yyuv9he"),
|
||||||
"delegated_vesting": [],
|
Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 10000205)),
|
||||||
"start_time": "0",
|
OriginalVesting: sdk.NewCoins(sdk.NewInt64Coin("stake", 10000205)),
|
||||||
"end_time": "0",
|
StartTime: time.Now().Unix(),
|
||||||
"module_name": "",
|
EndTime: time.Now().Add(48 * time.Hour).Unix(),
|
||||||
"module_permissions": null
|
Sequence: 5,
|
||||||
},
|
AccountNumber: 3,
|
||||||
{
|
}
|
||||||
"address": "cosmos1f6dangl9ggdhuvkcwhswserr8fzra6vfzfjvh2",
|
acc4 := v036genaccounts.GenesisAccount{
|
||||||
"coins": [
|
Address: accAddressFromBech32(t, "cosmos1fmk5elg4r62mlexd36tqjcwyafs7mek0js5m4d"),
|
||||||
{
|
Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 10000205)),
|
||||||
"denom": "node1token",
|
OriginalVesting: sdk.NewCoins(sdk.NewInt64Coin("stake", 10000205)),
|
||||||
"amount": "1000000000"
|
EndTime: time.Now().Add(48 * time.Hour).Unix(),
|
||||||
},
|
Sequence: 15,
|
||||||
{
|
AccountNumber: 4,
|
||||||
"denom": "stake",
|
}
|
||||||
"amount": "500000000"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sequence_number": "0",
|
|
||||||
"account_number": "0",
|
|
||||||
"original_vesting": [],
|
|
||||||
"delegated_free": [],
|
|
||||||
"delegated_vesting": [],
|
|
||||||
"start_time": "0",
|
|
||||||
"end_time": "0",
|
|
||||||
"module_name": "",
|
|
||||||
"module_permissions": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "cosmos1gudmxhn5anh5m6m2rr4rsfhgvps8fchtgmk7a6",
|
|
||||||
"coins": [
|
|
||||||
{
|
|
||||||
"denom": "node2token",
|
|
||||||
"amount": "1000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"denom": "stake",
|
|
||||||
"amount": "500000000"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sequence_number": "0",
|
|
||||||
"account_number": "0",
|
|
||||||
"original_vesting": [],
|
|
||||||
"delegated_free": [],
|
|
||||||
"delegated_vesting": [],
|
|
||||||
"start_time": "0",
|
|
||||||
"end_time": "0",
|
|
||||||
"module_name": "",
|
|
||||||
"module_permissions": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "cosmos1kluvs8ff2s3hxad4jpmhvca4crqpcwn9xyhchv",
|
|
||||||
"coins": [
|
|
||||||
{
|
|
||||||
"denom": "node3token",
|
|
||||||
"amount": "1000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"denom": "stake",
|
|
||||||
"amount": "500000000"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sequence_number": "0",
|
|
||||||
"account_number": "0",
|
|
||||||
"original_vesting": [],
|
|
||||||
"delegated_free": [],
|
|
||||||
"delegated_vesting": [],
|
|
||||||
"start_time": "0",
|
|
||||||
"end_time": "0",
|
|
||||||
"module_name": "",
|
|
||||||
"module_permissions": null
|
|
||||||
}
|
|
||||||
]`
|
|
||||||
|
|
||||||
require.NotPanics(t, func() {
|
require.NotPanics(t, func() {
|
||||||
genesisState = Migrate(
|
genesisState = Migrate(
|
||||||
v036auth.GenesisState{
|
v036auth.GenesisState{
|
||||||
Params: params,
|
Params: params,
|
||||||
},
|
},
|
||||||
json.RawMessage(rawAccounts),
|
v036genaccounts.GenesisState{acc1, acc2, acc3, acc4},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
require.Equal(t, genesisState, GenesisState{Params: params, Accounts: json.RawMessage(rawAccounts)})
|
expectedAcc1 := NewBaseAccount(acc1.Address, acc1.Coins, acc1.AccountNumber, acc1.Sequence)
|
||||||
|
expectedAcc2 := NewModuleAccount(
|
||||||
|
NewBaseAccount(acc2.Address, acc2.Coins, acc2.AccountNumber, acc2.Sequence),
|
||||||
|
acc2.ModuleName, acc2.ModulePermissions...,
|
||||||
|
)
|
||||||
|
expectedAcc3 := NewContinuousVestingAccountRaw(
|
||||||
|
NewBaseVestingAccount(
|
||||||
|
NewBaseAccount(acc3.Address, acc3.Coins, 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),
|
||||||
|
acc4.OriginalVesting, acc4.DelegatedFree, acc4.DelegatedVesting, acc4.EndTime,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.Equal(
|
||||||
|
t, genesisState, GenesisState{
|
||||||
|
Params: params,
|
||||||
|
Accounts: GenesisAccounts{expectedAcc1, expectedAcc2, expectedAcc3, expectedAcc4},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMigrateInvalid(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
acc v036genaccounts.GenesisAccount
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"vesting account with no base coins",
|
||||||
|
v036genaccounts.GenesisAccount{
|
||||||
|
Address: accAddressFromBech32(t, "cosmos17n9sztlhx32tfy0tg0zc2ttmkeeth50yyuv9he"),
|
||||||
|
Coins: sdk.Coins{},
|
||||||
|
OriginalVesting: sdk.NewCoins(sdk.NewInt64Coin("stake", 10000205)),
|
||||||
|
StartTime: time.Now().Unix(),
|
||||||
|
EndTime: time.Now().Add(48 * time.Hour).Unix(),
|
||||||
|
Sequence: 5,
|
||||||
|
AccountNumber: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"vesting account with base coins <= original vesting",
|
||||||
|
v036genaccounts.GenesisAccount{
|
||||||
|
Address: accAddressFromBech32(t, "cosmos17n9sztlhx32tfy0tg0zc2ttmkeeth50yyuv9he"),
|
||||||
|
Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 10000205)),
|
||||||
|
OriginalVesting: sdk.NewCoins(sdk.NewInt64Coin("stake", 50000205)),
|
||||||
|
StartTime: time.Now().Unix(),
|
||||||
|
EndTime: time.Now().Add(48 * time.Hour).Unix(),
|
||||||
|
Sequence: 5,
|
||||||
|
AccountNumber: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"module account with invalid name",
|
||||||
|
v036genaccounts.GenesisAccount{
|
||||||
|
Address: accAddressFromBech32(t, "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"),
|
||||||
|
Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 400000000)),
|
||||||
|
Sequence: 4,
|
||||||
|
AccountNumber: 2,
|
||||||
|
ModuleName: " ",
|
||||||
|
ModulePermissions: []string{"burner", "staking"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"module account with invalid permissions",
|
||||||
|
v036genaccounts.GenesisAccount{
|
||||||
|
Address: accAddressFromBech32(t, "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"),
|
||||||
|
Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 400000000)),
|
||||||
|
Sequence: 4,
|
||||||
|
AccountNumber: 2,
|
||||||
|
ModuleName: "bonded_tokens_pool",
|
||||||
|
ModulePermissions: []string{""},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"module account with invalid address",
|
||||||
|
v036genaccounts.GenesisAccount{
|
||||||
|
Address: accAddressFromBech32(t, "cosmos17n9sztlhx32tfy0tg0zc2ttmkeeth50yyuv9he"),
|
||||||
|
Coins: sdk.NewCoins(sdk.NewInt64Coin("stake", 400000000)),
|
||||||
|
Sequence: 4,
|
||||||
|
AccountNumber: 2,
|
||||||
|
ModuleName: "bonded_tokens_pool",
|
||||||
|
ModulePermissions: []string{"burner", "staking"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
require.Panics(t, func() {
|
||||||
|
Migrate(
|
||||||
|
v036auth.GenesisState{
|
||||||
|
Params: v034auth.Params{
|
||||||
|
MaxMemoCharacters: 10,
|
||||||
|
TxSigLimit: 10,
|
||||||
|
TxSizeCostPerByte: 10,
|
||||||
|
SigVerifyCostED25519: 10,
|
||||||
|
SigVerifyCostSecp256k1: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
v036genaccounts.GenesisState{tc.acc},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,262 @@
|
||||||
package v038
|
package v038
|
||||||
|
|
||||||
import (
|
// DONTCOVER
|
||||||
"encoding/json"
|
// 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"
|
v034auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v0_34"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DONTCOVER
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
const (
|
const (
|
||||||
ModuleName = "auth"
|
ModuleName = "auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GenesisState struct {
|
type (
|
||||||
Params v034auth.Params `json:"params"`
|
// partial interface needed only for amino encoding and sanitization
|
||||||
Accounts json.RawMessage `json:"accounts"`
|
Account interface {
|
||||||
}
|
GetAddress() sdk.AccAddress
|
||||||
|
GetAccountNumber() uint64
|
||||||
|
GetCoins() sdk.Coins
|
||||||
|
SetCoins(sdk.Coins) error
|
||||||
|
}
|
||||||
|
|
||||||
func NewGenesisState(params v034auth.Params, accounts json.RawMessage) GenesisState {
|
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" 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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
ContinuousVestingAccount struct {
|
||||||
|
*BaseVestingAccount
|
||||||
|
|
||||||
|
StartTime int64 `json:"start_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
DelayedVestingAccount struct {
|
||||||
|
*BaseVestingAccount
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleAccount struct {
|
||||||
|
*BaseAccount
|
||||||
|
|
||||||
|
Name string `json:"name" yaml:"name"`
|
||||||
|
Permissions []string `json:"permissions" yaml:"permissions"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewGenesisState(params v034auth.Params, accounts GenesisAccounts) GenesisState {
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
Params: params,
|
Params: params,
|
||||||
Accounts: accounts,
|
Accounts: accounts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewBaseAccountWithAddress(addr sdk.AccAddress) BaseAccount {
|
||||||
|
return BaseAccount{
|
||||||
|
Address: addr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBaseAccount(
|
||||||
|
address sdk.AccAddress, coins sdk.Coins, accountNumber, sequence uint64,
|
||||||
|
) *BaseAccount {
|
||||||
|
|
||||||
|
return &BaseAccount{
|
||||||
|
Address: address,
|
||||||
|
Coins: coins,
|
||||||
|
PubKey: nil,
|
||||||
|
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) 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 NewDelayedVestingAccountRaw(bva *BaseVestingAccount) *DelayedVestingAccount {
|
||||||
|
return &DelayedVestingAccount{
|
||||||
|
BaseVestingAccount: bva,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dva DelayedVestingAccount) Validate() error {
|
||||||
|
return dva.BaseVestingAccount.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewModuleAddress(name string) sdk.AccAddress {
|
||||||
|
return sdk.AccAddress(crypto.AddressHash([]byte(name)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewModuleAccount(baseAccount *BaseAccount, name string, permissions ...string) *ModuleAccount {
|
||||||
|
return &ModuleAccount{
|
||||||
|
BaseAccount: baseAccount,
|
||||||
|
Name: name,
|
||||||
|
Permissions: permissions,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
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 RegisterCodec(cdc *codec.Codec) {
|
||||||
|
cdc.RegisterInterface((*GenesisAccount)(nil), nil)
|
||||||
|
cdc.RegisterInterface((*Account)(nil), nil)
|
||||||
|
cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/Account", nil)
|
||||||
|
cdc.RegisterConcrete(&BaseVestingAccount{}, "cosmos-sdk/BaseVestingAccount", nil)
|
||||||
|
cdc.RegisterConcrete(&ContinuousVestingAccount{}, "cosmos-sdk/ContinuousVestingAccount", nil)
|
||||||
|
cdc.RegisterConcrete(&DelayedVestingAccount{}, "cosmos-sdk/DelayedVestingAccount", nil)
|
||||||
|
cdc.RegisterConcrete(&ModuleAccount{}, "cosmos-sdk/ModuleAccount", nil)
|
||||||
|
}
|
||||||
|
|
|
@ -196,9 +196,10 @@ type BaseVestingAccount struct {
|
||||||
EndTime int64 `json:"end_time"` // when the coins become unlocked
|
EndTime int64 `json:"end_time"` // when the coins become unlocked
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBaseVestingAccount creates a new BaseVestingAccount object
|
// NewBaseVestingAccount creates a new BaseVestingAccount object.
|
||||||
func NewBaseVestingAccount(baseAccount *BaseAccount, originalVesting sdk.Coins,
|
func NewBaseVestingAccount(
|
||||||
delegatedFree sdk.Coins, delegatedVesting sdk.Coins, endTime int64) *BaseVestingAccount {
|
baseAccount *BaseAccount, originalVesting, delegatedFree, delegatedVesting sdk.Coins, endTime int64,
|
||||||
|
) *BaseVestingAccount {
|
||||||
|
|
||||||
return &BaseVestingAccount{
|
return &BaseVestingAccount{
|
||||||
BaseAccount: baseAccount,
|
BaseAccount: baseAccount,
|
||||||
|
@ -382,9 +383,7 @@ type ContinuousVestingAccount struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContinuousVestingAccountRaw creates a new ContinuousVestingAccount object from BaseVestingAccount
|
// NewContinuousVestingAccountRaw creates a new ContinuousVestingAccount object from BaseVestingAccount
|
||||||
func NewContinuousVestingAccountRaw(bva *BaseVestingAccount,
|
func NewContinuousVestingAccountRaw(bva *BaseVestingAccount, startTime int64) *ContinuousVestingAccount {
|
||||||
startTime int64) *ContinuousVestingAccount {
|
|
||||||
|
|
||||||
return &ContinuousVestingAccount{
|
return &ContinuousVestingAccount{
|
||||||
BaseVestingAccount: bva,
|
BaseVestingAccount: bva,
|
||||||
StartTime: startTime,
|
StartTime: startTime,
|
||||||
|
|
|
@ -15,13 +15,20 @@ func Migrate(appState genutil.AppMap) genutil.AppMap {
|
||||||
|
|
||||||
v038Codec := codec.New()
|
v038Codec := codec.New()
|
||||||
codec.RegisterCrypto(v038Codec)
|
codec.RegisterCrypto(v038Codec)
|
||||||
|
v038auth.RegisterCodec(v038Codec)
|
||||||
|
|
||||||
if appState[v036genaccounts.ModuleName] != nil {
|
if appState[v036genaccounts.ModuleName] != nil {
|
||||||
|
// unmarshal relative source genesis application state
|
||||||
var authGenState v036auth.GenesisState
|
var authGenState v036auth.GenesisState
|
||||||
v036Codec.MustUnmarshalJSON(appState[v036auth.ModuleName], &authGenState)
|
v036Codec.MustUnmarshalJSON(appState[v036auth.ModuleName], &authGenState)
|
||||||
|
|
||||||
|
var genAccountsGenState v036genaccounts.GenesisState
|
||||||
|
v036Codec.MustUnmarshalJSON(appState[v036genaccounts.ModuleName], &genAccountsGenState)
|
||||||
|
|
||||||
|
// Migrate relative source genesis application state and marshal it into
|
||||||
|
// the respective key.
|
||||||
appState[v038auth.ModuleName] = v038Codec.MustMarshalJSON(
|
appState[v038auth.ModuleName] = v038Codec.MustMarshalJSON(
|
||||||
v038auth.Migrate(authGenState, appState[v036genaccounts.ModuleName]),
|
v038auth.Migrate(authGenState, genAccountsGenState),
|
||||||
)
|
)
|
||||||
|
|
||||||
// delete deprecated genaccounts genesis state
|
// delete deprecated genaccounts genesis state
|
||||||
|
|
Loading…
Reference in New Issue