Merge PR #5017: ADR 011: Generalize Genesis Accounts Implementation
This commit is contained in:
committed by
Alexander Bezobchuk
parent
e660adc6e5
commit
ed6366679c
+4
-8
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
"github.com/cosmos/cosmos-sdk/x/genaccounts"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||
@@ -43,9 +42,9 @@ var (
|
||||
// non-dependant module elements, such as codec registration
|
||||
// and genesis verification.
|
||||
ModuleBasics = module.NewBasicManager(
|
||||
genaccounts.AppModuleBasic{},
|
||||
genutil.AppModuleBasic{},
|
||||
auth.AppModuleBasic{},
|
||||
supply.AppModuleBasic{},
|
||||
genutil.AppModuleBasic{},
|
||||
bank.AppModuleBasic{},
|
||||
staking.AppModuleBasic{},
|
||||
mint.AppModuleBasic{},
|
||||
@@ -55,7 +54,6 @@ var (
|
||||
crisis.AppModuleBasic{},
|
||||
slashing.AppModuleBasic{},
|
||||
nft.AppModuleBasic{},
|
||||
supply.AppModuleBasic{},
|
||||
)
|
||||
|
||||
// module account permissions
|
||||
@@ -178,7 +176,6 @@ func NewSimApp(
|
||||
// NOTE: Any module instantiated in the module manager that is later modified
|
||||
// must be passed by reference here.
|
||||
app.mm = module.NewManager(
|
||||
genaccounts.NewAppModule(app.AccountKeeper),
|
||||
genutil.NewAppModule(app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx),
|
||||
auth.NewAppModule(app.AccountKeeper),
|
||||
bank.NewAppModule(app.BankKeeper, app.AccountKeeper),
|
||||
@@ -202,8 +199,8 @@ func NewSimApp(
|
||||
// NOTE: The genutils moodule must occur after staking so that pools are
|
||||
// properly initialized with tokens from genesis accounts.
|
||||
app.mm.SetOrderInitGenesis(
|
||||
genaccounts.ModuleName, distr.ModuleName, staking.ModuleName,
|
||||
auth.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName,
|
||||
auth.ModuleName, distr.ModuleName, staking.ModuleName,
|
||||
bank.ModuleName, slashing.ModuleName, gov.ModuleName,
|
||||
mint.ModuleName, supply.ModuleName, crisis.ModuleName, nft.ModuleName,
|
||||
genutil.ModuleName,
|
||||
)
|
||||
@@ -216,7 +213,6 @@ func NewSimApp(
|
||||
// NOTE: this is not required apps that don't use the simulator for fuzz testing
|
||||
// transactions
|
||||
app.sm = module.NewSimulationManager(
|
||||
genaccounts.NewAppModule(app.AccountKeeper),
|
||||
auth.NewAppModule(app.AccountKeeper),
|
||||
bank.NewAppModule(app.BankKeeper, app.AccountKeeper),
|
||||
supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper),
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package simapp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
)
|
||||
|
||||
var _ authexported.GenesisAccount = (*SimGenesisAccount)(nil)
|
||||
|
||||
// SimGenesisAccount defines a type that implements the GenesisAccount interface
|
||||
// to be used for simulation accounts in the genesis state.
|
||||
type SimGenesisAccount struct {
|
||||
*authtypes.BaseAccount
|
||||
|
||||
// vesting account fields
|
||||
OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"` // total vesting coins upon initialization
|
||||
DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"` // delegated vested coins at time of delegation
|
||||
DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"` // delegated vesting coins at time of delegation
|
||||
StartTime int64 `json:"start_time" yaml:"start_time"` // vesting start time (UNIX Epoch time)
|
||||
EndTime int64 `json:"end_time" yaml:"end_time"` // vesting end time (UNIX Epoch time)
|
||||
|
||||
// module account fields
|
||||
ModuleName string `json:"module_name" yaml:"module_name"` // name of the module account
|
||||
ModulePermissions []string `json:"module_permissions" yaml:"module_permissions"` // permissions of module account
|
||||
}
|
||||
|
||||
// Validate checks for errors on the vesting and module account parameters
|
||||
func (sga SimGenesisAccount) Validate() error {
|
||||
if !sga.OriginalVesting.IsZero() {
|
||||
if sga.OriginalVesting.IsAnyGT(sga.Coins) {
|
||||
return errors.New("vesting amount cannot be greater than total amount")
|
||||
}
|
||||
if sga.StartTime >= sga.EndTime {
|
||||
return errors.New("vesting start-time cannot be before end-time")
|
||||
}
|
||||
}
|
||||
|
||||
if sga.ModuleName != "" {
|
||||
ma := supply.ModuleAccount{
|
||||
BaseAccount: sga.BaseAccount, Name: sga.ModuleName, Permissions: sga.ModulePermissions,
|
||||
}
|
||||
if err := ma.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return sga.BaseAccount.Validate()
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package simapp_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
)
|
||||
|
||||
func TestSimGenesisAccountValidate(t *testing.T) {
|
||||
pubkey := secp256k1.GenPrivKey().PubKey()
|
||||
addr := sdk.AccAddress(pubkey.Address())
|
||||
|
||||
vestingStart := time.Now().UTC()
|
||||
|
||||
coins := sdk.NewCoins(sdk.NewInt64Coin("test", 1000))
|
||||
baseAcc := authtypes.NewBaseAccount(addr, nil, pubkey, 0, 0)
|
||||
require.NoError(t, baseAcc.SetCoins(coins))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
sga simapp.SimGenesisAccount
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
"valid basic account",
|
||||
simapp.SimGenesisAccount{
|
||||
BaseAccount: baseAcc,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid basic account with mismatching address/pubkey",
|
||||
simapp.SimGenesisAccount{
|
||||
BaseAccount: authtypes.NewBaseAccount(addr, nil, secp256k1.GenPrivKey().PubKey(), 0, 0),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"valid basic account with module name",
|
||||
simapp.SimGenesisAccount{
|
||||
BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(crypto.AddressHash([]byte("testmod"))), nil, nil, 0, 0),
|
||||
ModuleName: "testmod",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"valid basic account with invalid module name/pubkey pair",
|
||||
simapp.SimGenesisAccount{
|
||||
BaseAccount: baseAcc,
|
||||
ModuleName: "testmod",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"valid basic account with valid vesting attributes",
|
||||
simapp.SimGenesisAccount{
|
||||
BaseAccount: baseAcc,
|
||||
OriginalVesting: coins,
|
||||
StartTime: vestingStart.Unix(),
|
||||
EndTime: vestingStart.Add(1 * time.Hour).Unix(),
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"valid basic account with invalid vesting end time",
|
||||
simapp.SimGenesisAccount{
|
||||
BaseAccount: baseAcc,
|
||||
OriginalVesting: coins,
|
||||
StartTime: vestingStart.Add(2 * time.Hour).Unix(),
|
||||
EndTime: vestingStart.Add(1 * time.Hour).Unix(),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"valid basic account with invalid original vesting coins",
|
||||
simapp.SimGenesisAccount{
|
||||
BaseAccount: baseAcc,
|
||||
OriginalVesting: coins.Add(coins),
|
||||
StartTime: vestingStart.Unix(),
|
||||
EndTime: vestingStart.Add(1 * time.Hour).Unix(),
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
require.Equal(t, tc.wantErr, tc.sga.Validate() != nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
+7
-4
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/genaccounts"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
@@ -126,9 +126,12 @@ func AppStateFromGenesisFileFn(r *rand.Rand, cdc *codec.Codec, genesisFile strin
|
||||
var appState GenesisState
|
||||
cdc.MustUnmarshalJSON(genesis.AppState, &appState)
|
||||
|
||||
accounts := genaccounts.GetGenesisStateFromAppState(cdc, appState)
|
||||
var authGenesis auth.GenesisState
|
||||
if appState[auth.ModuleName] != nil {
|
||||
cdc.MustUnmarshalJSON(appState[auth.ModuleName], &authGenesis)
|
||||
}
|
||||
|
||||
for _, acc := range accounts {
|
||||
for _, acc := range authGenesis.Accounts {
|
||||
// Pick a random private key, since we don't know the actual key
|
||||
// This should be fine as it's only used for mock Tendermint validators
|
||||
// and these keys are never actually used to sign by mock Tendermint.
|
||||
@@ -140,7 +143,7 @@ func AppStateFromGenesisFileFn(r *rand.Rand, cdc *codec.Codec, genesisFile strin
|
||||
privKey := secp256k1.GenPrivKeySecp256k1(privkeySeed)
|
||||
|
||||
// create simulator accounts
|
||||
simAcc := simulation.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: acc.Address}
|
||||
simAcc := simulation.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: acc.GetAddress()}
|
||||
newAccs = append(newAccs, simAcc)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/genaccounts"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
)
|
||||
|
||||
@@ -45,13 +45,17 @@ func Setup(isCheckTx bool) *SimApp {
|
||||
|
||||
// SetupWithGenesisAccounts initializes a new SimApp with the passed in
|
||||
// genesis accounts.
|
||||
func SetupWithGenesisAccounts(genAccs genaccounts.GenesisAccounts) *SimApp {
|
||||
func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount) *SimApp {
|
||||
db := dbm.NewMemDB()
|
||||
app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0)
|
||||
|
||||
// initialize the chain with the passed in genesis accounts
|
||||
genesisState := NewDefaultGenesisState()
|
||||
genesisState = genaccounts.SetGenesisStateInAppState(app.Codec(), genesisState, genaccounts.GenesisState(genAccs))
|
||||
|
||||
authGenesis := auth.NewGenesisState(auth.DefaultParams(), genAccs)
|
||||
genesisStateBz := app.cdc.MustMarshalJSON(authGenesis)
|
||||
genesisState[auth.ModuleName] = genesisStateBz
|
||||
|
||||
stateBytes, err := codec.MarshalJSONIndent(app.cdc, genesisState)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
Reference in New Issue
Block a user