Merge PR #5042: Auxiliary Functionality for Genesis Accounts
This commit is contained in:
parent
ed6366679c
commit
1028283e6f
|
@ -55,7 +55,7 @@ var (
|
|||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
ValidateGenesis = types.ValidateGenesis
|
||||
Sanitize = types.Sanitize
|
||||
SanitizeGenesisAccounts = types.SanitizeGenesisAccounts
|
||||
AddressStoreKey = types.AddressStoreKey
|
||||
NewParams = types.NewParams
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
|
@ -70,6 +70,7 @@ var (
|
|||
NewTxBuilder = types.NewTxBuilder
|
||||
NewTxBuilderFromCLI = types.NewTxBuilderFromCLI
|
||||
MakeSignature = types.MakeSignature
|
||||
GetGenesisStateFromAppState = types.GetGenesisStateFromAppState
|
||||
|
||||
// variable aliases
|
||||
ModuleCdc = types.ModuleCdc
|
||||
|
@ -102,4 +103,5 @@ type (
|
|||
StdSignDoc = types.StdSignDoc
|
||||
StdSignature = types.StdSignature
|
||||
TxBuilder = types.TxBuilder
|
||||
GenesisAccountIterator = types.GenesisAccountIterator
|
||||
)
|
||||
|
|
|
@ -58,6 +58,21 @@ type VestingAccount interface {
|
|||
GetDelegatedVesting() sdk.Coins
|
||||
}
|
||||
|
||||
// GenesisAccounts defines a slice of GenesisAccount objects
|
||||
type GenesisAccounts []GenesisAccount
|
||||
|
||||
// Contains returns true if the given address exists in a slice of GenesisAccount
|
||||
// objects.
|
||||
func (ga GenesisAccounts) Contains(addr sdk.AccAddress) bool {
|
||||
for _, acc := range ga {
|
||||
if acc.GetAddress().Equals(addr) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// GenesisAccount defines a genesis account that embeds an Account with validation capabilities.
|
||||
type GenesisAccount interface {
|
||||
Account
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package exported_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
|
||||
func TestGenesisAccountsContains(t *testing.T) {
|
||||
pubkey := secp256k1.GenPrivKey().PubKey()
|
||||
addr := sdk.AccAddress(pubkey.Address())
|
||||
acc := authtypes.NewBaseAccount(addr, nil, secp256k1.GenPrivKey().PubKey(), 0, 0)
|
||||
|
||||
genAccounts := exported.GenesisAccounts{}
|
||||
require.False(t, genAccounts.Contains(acc.GetAddress()))
|
||||
|
||||
genAccounts = append(genAccounts, acc)
|
||||
require.True(t, genAccounts.Contains(acc.GetAddress()))
|
||||
}
|
|
@ -11,7 +11,7 @@ import (
|
|||
// a genesis port script to the new fee collector account
|
||||
func InitGenesis(ctx sdk.Context, ak AccountKeeper, data GenesisState) {
|
||||
ak.SetParams(ctx, data.Params)
|
||||
data.Accounts = Sanitize(data.Accounts)
|
||||
data.Accounts = SanitizeGenesisAccounts(data.Accounts)
|
||||
|
||||
for _, a := range data.Accounts {
|
||||
acc := ak.NewAccount(ctx, a)
|
||||
|
@ -23,7 +23,7 @@ func InitGenesis(ctx sdk.Context, ak AccountKeeper, data GenesisState) {
|
|||
func ExportGenesis(ctx sdk.Context, ak AccountKeeper) GenesisState {
|
||||
params := ak.GetParams(ctx)
|
||||
|
||||
var genAccounts []exported.GenesisAccount
|
||||
var genAccounts exported.GenesisAccounts
|
||||
ak.IterateAccounts(ctx, func(account exported.Account) bool {
|
||||
genAccount := account.(exported.GenesisAccount)
|
||||
genAccounts = append(genAccounts, genAccount)
|
||||
|
|
|
@ -91,7 +91,7 @@ func RandomizedGenState(simState *module.SimulationState) {
|
|||
}
|
||||
|
||||
// RandomGenesisAccounts returns randomly generated genesis accounts
|
||||
func RandomGenesisAccounts(simState *module.SimulationState) (genesisAccs []exported.GenesisAccount) {
|
||||
func RandomGenesisAccounts(simState *module.SimulationState) (genesisAccs exported.GenesisAccounts) {
|
||||
for i, acc := range simState.Accounts {
|
||||
coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(simState.InitialStake))}
|
||||
bacc := types.NewBaseAccountWithAddress(acc.Address)
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
)
|
||||
|
||||
// GenesisState - all auth state that must be provided at genesis
|
||||
type GenesisState struct {
|
||||
Params Params `json:"params" yaml:"params"`
|
||||
Accounts []exported.GenesisAccount `json:"accounts" yaml:"accounts"`
|
||||
Accounts exported.GenesisAccounts `json:"accounts" yaml:"accounts"`
|
||||
}
|
||||
|
||||
// NewGenesisState - Create a new genesis state
|
||||
func NewGenesisState(params Params, accounts []exported.GenesisAccount) GenesisState {
|
||||
func NewGenesisState(params Params, accounts exported.GenesisAccounts) GenesisState {
|
||||
return GenesisState{
|
||||
Params: params,
|
||||
Accounts: accounts,
|
||||
|
@ -23,7 +25,18 @@ func NewGenesisState(params Params, accounts []exported.GenesisAccount) GenesisS
|
|||
|
||||
// DefaultGenesisState - Return a default genesis state
|
||||
func DefaultGenesisState() GenesisState {
|
||||
return NewGenesisState(DefaultParams(), []exported.GenesisAccount{})
|
||||
return NewGenesisState(DefaultParams(), exported.GenesisAccounts{})
|
||||
}
|
||||
|
||||
// GetGenesisStateFromAppState returns x/auth GenesisState given raw application
|
||||
// genesis state.
|
||||
func GetGenesisStateFromAppState(cdc *codec.Codec, appState map[string]json.RawMessage) GenesisState {
|
||||
var genesisState GenesisState
|
||||
if appState[ModuleName] != nil {
|
||||
cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState)
|
||||
}
|
||||
|
||||
return genesisState
|
||||
}
|
||||
|
||||
// ValidateGenesis performs basic validation of auth genesis data returning an
|
||||
|
@ -36,8 +49,8 @@ func ValidateGenesis(data GenesisState) error {
|
|||
return validateGenAccounts(data.Accounts)
|
||||
}
|
||||
|
||||
// Sanitize sorts accounts and coin sets.
|
||||
func Sanitize(genAccs []exported.GenesisAccount) []exported.GenesisAccount {
|
||||
// SanitizeGenesisAccounts sorts accounts and coin sets.
|
||||
func SanitizeGenesisAccounts(genAccs exported.GenesisAccounts) exported.GenesisAccounts {
|
||||
sort.Slice(genAccs, func(i, j int) bool {
|
||||
return genAccs[i].GetAccountNumber() < genAccs[j].GetAccountNumber()
|
||||
})
|
||||
|
@ -51,7 +64,7 @@ func Sanitize(genAccs []exported.GenesisAccount) []exported.GenesisAccount {
|
|||
return genAccs
|
||||
}
|
||||
|
||||
func validateGenAccounts(accounts []exported.GenesisAccount) error {
|
||||
func validateGenAccounts(accounts exported.GenesisAccounts) error {
|
||||
addrMap := make(map[string]bool, len(accounts))
|
||||
for _, acc := range accounts {
|
||||
|
||||
|
@ -70,3 +83,20 @@ func validateGenAccounts(accounts []exported.GenesisAccount) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenesisAccountIterator implements genesis account iteration.
|
||||
type GenesisAccountIterator struct{}
|
||||
|
||||
// IterateGenesisAccounts iterates over all the genesis accounts found in
|
||||
// appGenesis and invokes a callback on each genesis account. If any call
|
||||
// returns true, iteration stops.
|
||||
func (GenesisAccountIterator) IterateGenesisAccounts(
|
||||
cdc *codec.Codec, appGenesis map[string]json.RawMessage, cb func(exported.Account) (stop bool),
|
||||
) {
|
||||
|
||||
for _, genAcc := range GetGenesisStateFromAppState(cdc, appGenesis).Accounts {
|
||||
if cb(genAcc) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -26,13 +27,13 @@ func TestSanitize(t *testing.T) {
|
|||
sdk.NewInt64Coin("bcoin", 150),
|
||||
})
|
||||
|
||||
genAccs := []exported.GenesisAccount{&authAcc1, &authAcc2}
|
||||
genAccs := exported.GenesisAccounts{&authAcc1, &authAcc2}
|
||||
|
||||
require.True(t, genAccs[0].GetAccountNumber() > genAccs[1].GetAccountNumber())
|
||||
require.Equal(t, genAccs[0].GetCoins()[0].Denom, "bcoin")
|
||||
require.Equal(t, genAccs[0].GetCoins()[1].Denom, "acoin")
|
||||
require.Equal(t, genAccs[1].GetAddress(), addr2)
|
||||
genAccs = Sanitize(genAccs)
|
||||
genAccs = SanitizeGenesisAccounts(genAccs)
|
||||
|
||||
require.False(t, genAccs[0].GetAccountNumber() > genAccs[1].GetAccountNumber())
|
||||
require.Equal(t, genAccs[1].GetAddress(), addr1)
|
||||
|
@ -52,7 +53,7 @@ func TestValidateGenesisDuplicateAccounts(t *testing.T) {
|
|||
acc1 := NewBaseAccountWithAddress(sdk.AccAddress(addr1))
|
||||
acc1.Coins = sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 150))
|
||||
|
||||
genAccs := make([]exported.GenesisAccount, 2)
|
||||
genAccs := make(exported.GenesisAccounts, 2)
|
||||
genAccs[0] = &acc1
|
||||
genAccs[1] = &acc1
|
||||
|
||||
|
@ -68,7 +69,7 @@ func TestValidateGenesisInvalidAccounts(t *testing.T) {
|
|||
acc2 := NewBaseAccountWithAddress(sdk.AccAddress(addr2))
|
||||
acc2.Coins = sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 150))
|
||||
|
||||
genAccs := make([]exported.GenesisAccount, 2)
|
||||
genAccs := make(exported.GenesisAccounts, 2)
|
||||
genAccs[0] = baseVestingAcc
|
||||
genAccs[1] = &acc2
|
||||
|
||||
|
@ -80,3 +81,34 @@ func TestValidateGenesisInvalidAccounts(t *testing.T) {
|
|||
genAccs[0] = NewContinuousVestingAccountRaw(baseVestingAcc, 1548888000)
|
||||
require.Error(t, validateGenAccounts(genAccs))
|
||||
}
|
||||
|
||||
func TestGenesisAccountIterator(t *testing.T) {
|
||||
acc1 := NewBaseAccountWithAddress(sdk.AccAddress(addr1))
|
||||
acc1.Coins = sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 150))
|
||||
|
||||
acc2 := NewBaseAccountWithAddress(sdk.AccAddress(addr2))
|
||||
acc2.Coins = sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 150))
|
||||
|
||||
genAccounts := exported.GenesisAccounts{&acc1, &acc2}
|
||||
|
||||
authGenState := DefaultGenesisState()
|
||||
authGenState.Accounts = genAccounts
|
||||
|
||||
appGenesis := make(map[string]json.RawMessage)
|
||||
authGenStateBz, err := ModuleCdc.MarshalJSON(authGenState)
|
||||
require.NoError(t, err)
|
||||
|
||||
appGenesis[ModuleName] = authGenStateBz
|
||||
|
||||
var addresses []sdk.AccAddress
|
||||
GenesisAccountIterator{}.IterateGenesisAccounts(
|
||||
ModuleCdc, appGenesis, func(acc exported.Account) (stop bool) {
|
||||
addresses = append(addresses, acc.GetAddress())
|
||||
return false
|
||||
},
|
||||
)
|
||||
|
||||
require.Len(t, addresses, 2)
|
||||
require.Equal(t, addresses[0], acc1.GetAddress())
|
||||
require.Equal(t, addresses[1], acc2.GetAddress())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue