Auth Module Param Store (#2998)

This commit is contained in:
Alexander Bezobchuk 2018-12-20 14:09:43 -05:00 committed by Jack Zampolin
parent 0c0bff7ea0
commit 217a2925dc
36 changed files with 919 additions and 774 deletions

View File

@ -34,6 +34,8 @@ FEATURES
* [\#2182] [x/stake] Added querier for querying a single redelegation
* SDK
* \#2996 Update the `AccountKeeper` to contain params used in the context of
the ante handler.
* Tendermint

View File

@ -91,11 +91,14 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
tkeyParams: sdk.NewTransientStoreKey(params.TStoreKey),
}
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams)
// define the accountKeeper
app.accountKeeper = auth.NewAccountKeeper(
app.cdc,
app.keyAccount, // target store
auth.ProtoBaseAccount, // prototype
app.keyAccount,
app.paramsKeeper.Subspace(auth.DefaultParamspace),
auth.ProtoBaseAccount,
)
// add handlers
@ -104,10 +107,6 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
app.cdc,
app.keyFeeCollection,
)
app.paramsKeeper = params.NewKeeper(
app.cdc,
app.keyParams, app.tkeyParams,
)
stakeKeeper := stake.NewKeeper(
app.cdc,
app.keyStake, app.tkeyStake,
@ -246,7 +245,7 @@ func (app *GaiaApp) initFromGenesisState(ctx sdk.Context, genesisState GenesisSt
}
// initialize module-specific stores
auth.InitGenesis(ctx, app.feeCollectionKeeper, genesisState.AuthData)
auth.InitGenesis(ctx, app.accountKeeper, app.feeCollectionKeeper, genesisState.AuthData)
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
mint.InitGenesis(ctx, app.mintKeeper, genesisState.MintData)

View File

@ -39,7 +39,7 @@ func (app *GaiaApp) ExportAppStateAndValidators(forZeroHeight bool) (
genState := NewGenesisState(
accounts,
auth.ExportGenesis(ctx, app.feeCollectionKeeper),
auth.ExportGenesis(ctx, app.accountKeeper, app.feeCollectionKeeper),
stake.ExportGenesis(ctx, app.stakeKeeper),
mint.ExportGenesis(ctx, app.mintKeeper),
distr.ExportGenesis(ctx, app.distrKeeper),

View File

@ -143,6 +143,7 @@ func GaiaAppGenState(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []js
func NewDefaultGenesisState() GenesisState {
return GenesisState{
Accounts: nil,
AuthData: auth.DefaultGenesisState(),
StakeData: stake.DefaultGenesisState(),
MintData: mint.DefaultGenesisState(),
DistrData: distr.DefaultGenesisState(),
@ -157,37 +158,32 @@ func NewDefaultGenesisState() GenesisState {
// TODO: Error if there is a duplicate validator (#1708)
// TODO: Ensure all state machine parameters are in genesis (#1704)
func GaiaValidateGenesisState(genesisState GenesisState) error {
err := validateGenesisStateAccounts(genesisState.Accounts)
if err != nil {
if err := validateGenesisStateAccounts(genesisState.Accounts); err != nil {
return err
}
// skip stakeData validation as genesis is created from txs
if len(genesisState.GenTxs) > 0 {
return nil
}
err = stake.ValidateGenesis(genesisState.StakeData)
if err != nil {
if err := auth.ValidateGenesis(genesisState.AuthData); err != nil {
return err
}
err = mint.ValidateGenesis(genesisState.MintData)
if err != nil {
if err := stake.ValidateGenesis(genesisState.StakeData); err != nil {
return err
}
err = distr.ValidateGenesis(genesisState.DistrData)
if err != nil {
if err := mint.ValidateGenesis(genesisState.MintData); err != nil {
return err
}
err = gov.ValidateGenesis(genesisState.GovData)
if err != nil {
if err := distr.ValidateGenesis(genesisState.DistrData); err != nil {
return err
}
err = slashing.ValidateGenesis(genesisState.SlashingData)
if err != nil {
if err := gov.ValidateGenesis(genesisState.GovData); err != nil {
return err
}
return nil
return slashing.ValidateGenesis(genesisState.SlashingData)
}
// Ensures that there are no duplicate accounts in the genesis state,

View File

@ -18,6 +18,7 @@ import (
"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authsim "github.com/cosmos/cosmos-sdk/x/auth/simulation"
banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
@ -75,6 +76,17 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
})
}
authGenesis := auth.GenesisState{
Params: auth.Params{
MemoCostPerByte: uint64(r.Intn(10) + 1),
MaxMemoCharacters: uint64(r.Intn(200-100) + 100),
TxSigLimit: uint64(r.Intn(7) + 1),
SigVerifyCostED25519: uint64(r.Intn(1000-500) + 500),
SigVerifyCostSecp256k1: uint64(r.Intn(1000-500) + 500),
},
}
fmt.Printf("Selected randomly generated auth parameters:\n\t%+v\n", authGenesis)
// Random genesis states
vp := time.Duration(r.Intn(2*172800)) * time.Second
govGenesis := gov.GenesisState{
@ -151,6 +163,7 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
genesis := GenesisState{
Accounts: genesisAccounts,
AuthData: authGenesis,
StakeData: stakeGenesis,
MintData: mintGenesis,
DistrData: distr.DefaultGenesisWithValidators(valAddrs),

View File

@ -165,16 +165,18 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.BaseAp
tkeyParams: sdk.NewTransientStoreKey(params.TStoreKey),
}
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams)
// define the accountKeeper
app.accountKeeper = auth.NewAccountKeeper(
app.cdc,
app.keyAccount, // target store
app.keyAccount, // target store
app.paramsKeeper.Subspace(auth.DefaultParamspace),
auth.ProtoBaseAccount, // prototype
)
// add handlers
app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper)
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams)
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.tkeyStake, app.bankKeeper, app.paramsKeeper.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamspace), slashing.DefaultCodespace)

View File

@ -17,6 +17,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/ibc"
"github.com/cosmos/cosmos-sdk/x/params"
)
const (
@ -41,12 +42,15 @@ type BasecoinApp struct {
keyMain *sdk.KVStoreKey
keyAccount *sdk.KVStoreKey
keyIBC *sdk.KVStoreKey
keyParams *sdk.KVStoreKey
tkeyParams *sdk.TransientStoreKey
// manage getting and setting accounts
accountKeeper auth.AccountKeeper
feeCollectionKeeper auth.FeeCollectionKeeper
bankKeeper bank.Keeper
ibcMapper ibc.Mapper
paramsKeeper params.Keeper
}
// NewBasecoinApp returns a reference to a new BasecoinApp given a logger and
@ -65,12 +69,17 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.Ba
keyMain: sdk.NewKVStoreKey(bam.MainStoreKey),
keyAccount: sdk.NewKVStoreKey(auth.StoreKey),
keyIBC: sdk.NewKVStoreKey("ibc"),
keyParams: sdk.NewKVStoreKey("params"),
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
}
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams)
// define and attach the mappers and keepers
app.accountKeeper = auth.NewAccountKeeper(
cdc,
app.keyAccount, // target store
app.paramsKeeper.Subspace(auth.DefaultParamspace),
func() auth.Account {
return &types.AppAccount{}
},

View File

@ -16,6 +16,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/ibc"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/cosmos-sdk/docs/examples/democoin/types"
@ -46,8 +47,11 @@ type DemocoinApp struct {
capKeyPowStore *sdk.KVStoreKey
capKeyIBCStore *sdk.KVStoreKey
capKeyStakingStore *sdk.KVStoreKey
keyParams *sdk.KVStoreKey
tkeyParams *sdk.TransientStoreKey
// keepers
paramsKeeper params.Keeper
feeCollectionKeeper auth.FeeCollectionKeeper
bankKeeper bank.Keeper
coolKeeper cool.Keeper
@ -73,13 +77,18 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp {
capKeyPowStore: sdk.NewKVStoreKey("pow"),
capKeyIBCStore: sdk.NewKVStoreKey("ibc"),
capKeyStakingStore: sdk.NewKVStoreKey(stake.StoreKey),
keyParams: sdk.NewKVStoreKey("params"),
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
}
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams)
// Define the accountKeeper.
app.accountKeeper = auth.NewAccountKeeper(
cdc,
app.capKeyAccountStore, // target store
types.ProtoAppAccount, // prototype
app.capKeyAccountStore,
app.paramsKeeper.Subspace(auth.DefaultParamspace),
types.ProtoAppAccount,
)
// Add handlers.

View File

@ -13,26 +13,44 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
auth "github.com/cosmos/cosmos-sdk/x/auth"
bank "github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/params"
)
func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) {
db := dbm.NewMemDB()
capKey := sdk.NewKVStoreKey("capkey")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.LoadLatestVersion()
return ms, capKey
type testInput struct {
cdc *codec.Codec
ctx sdk.Context
capKey *sdk.KVStoreKey
bk bank.BaseKeeper
}
func TestCoolKeeper(t *testing.T) {
ms, capKey := setupMultiStore()
func setupTestInput() testInput {
db := dbm.NewMemDB()
cdc := codec.New()
auth.RegisterBaseAccount(cdc)
am := auth.NewAccountKeeper(cdc, capKey, auth.ProtoBaseAccount)
capKey := sdk.NewKVStoreKey("capkey")
keyParams := sdk.NewKVStoreKey("params")
tkeyParams := sdk.NewTransientStoreKey("transient_params")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
ms.LoadLatestVersion()
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
ak := auth.NewAccountKeeper(cdc, capKey, pk.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount)
bk := bank.NewBaseKeeper(ak)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil)
ck := bank.NewBaseKeeper(am)
keeper := NewKeeper(capKey, ck, DefaultCodespace)
return testInput{cdc: cdc, ctx: ctx, capKey: capKey, bk: bk}
}
func TestCoolKeeper(t *testing.T) {
input := setupTestInput()
keeper := NewKeeper(input.capKey, input.bk, DefaultCodespace)
ctx := input.ctx
err := InitGenesis(ctx, keeper, Genesis{"icy"})
require.Nil(t, err)

View File

@ -5,25 +5,15 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
codec "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
auth "github.com/cosmos/cosmos-sdk/x/auth"
bank "github.com/cosmos/cosmos-sdk/x/bank"
)
func TestPowHandler(t *testing.T) {
ms, capKey := setupMultiStore()
cdc := codec.New()
auth.RegisterBaseAccount(cdc)
input := setupTestInput()
ctx := input.ctx
am := auth.NewAccountKeeper(cdc, capKey, auth.ProtoBaseAccount)
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
config := NewConfig("pow", int64(1))
ck := bank.NewBaseKeeper(am)
keeper := NewKeeper(capKey, config, ck, DefaultCodespace)
keeper := NewKeeper(input.capKey, config, input.bk, DefaultCodespace)
handler := keeper.Handler

View File

@ -7,36 +7,52 @@ import (
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
auth "github.com/cosmos/cosmos-sdk/x/auth"
bank "github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/params"
)
// possibly share this kind of setup functionality between module testsuites?
func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) {
db := dbm.NewMemDB()
capKey := sdk.NewKVStoreKey("capkey")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.LoadLatestVersion()
return ms, capKey
type testInput struct {
cdc *codec.Codec
ctx sdk.Context
capKey *sdk.KVStoreKey
bk bank.BaseKeeper
}
func TestPowKeeperGetSet(t *testing.T) {
ms, capKey := setupMultiStore()
func setupTestInput() testInput {
db := dbm.NewMemDB()
cdc := codec.New()
auth.RegisterBaseAccount(cdc)
am := auth.NewAccountKeeper(cdc, capKey, auth.ProtoBaseAccount)
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
capKey := sdk.NewKVStoreKey("capkey")
keyParams := sdk.NewKVStoreKey("params")
tkeyParams := sdk.NewTransientStoreKey("transient_params")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
ms.LoadLatestVersion()
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
ak := auth.NewAccountKeeper(cdc, capKey, pk.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount)
bk := bank.NewBaseKeeper(ak)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil)
return testInput{cdc: cdc, ctx: ctx, capKey: capKey, bk: bk}
}
func TestPowKeeperGetSet(t *testing.T) {
input := setupTestInput()
ctx := input.ctx
config := NewConfig("pow", int64(1))
ck := bank.NewBaseKeeper(am)
keeper := NewKeeper(capKey, config, ck, DefaultCodespace)
keeper := NewKeeper(input.capKey, config, input.bk, DefaultCodespace)
err := InitGenesis(ctx, keeper, Genesis{uint64(1), uint64(0)})
require.Nil(t, err)

View File

@ -10,35 +10,52 @@ import (
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/ed25519"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
"github.com/cosmos/cosmos-sdk/x/params"
staketypes "github.com/cosmos/cosmos-sdk/x/stake/types"
)
func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) {
db := dbm.NewMemDB()
authKey := sdk.NewKVStoreKey("authkey")
capKey := sdk.NewKVStoreKey("capkey")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(authKey, sdk.StoreTypeIAVL, db)
ms.LoadLatestVersion()
return ms, authKey, capKey
type testInput struct {
cdc *codec.Codec
ctx sdk.Context
capKey *sdk.KVStoreKey
bk bank.BaseKeeper
}
func TestKeeperGetSet(t *testing.T) {
ms, authKey, capKey := setupMultiStore()
func setupTestInput() testInput {
db := dbm.NewMemDB()
cdc := codec.New()
auth.RegisterBaseAccount(cdc)
accountKeeper := auth.NewAccountKeeper(cdc, authKey, auth.ProtoBaseAccount)
stakeKeeper := NewKeeper(capKey, bank.NewBaseKeeper(accountKeeper), DefaultCodespace)
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
capKey := sdk.NewKVStoreKey("capkey")
keyParams := sdk.NewKVStoreKey("params")
tkeyParams := sdk.NewTransientStoreKey("transient_params")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
ms.LoadLatestVersion()
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
ak := auth.NewAccountKeeper(cdc, capKey, pk.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount)
bk := bank.NewBaseKeeper(ak)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil)
return testInput{cdc: cdc, ctx: ctx, capKey: capKey, bk: bk}
}
func TestKeeperGetSet(t *testing.T) {
input := setupTestInput()
ctx := input.ctx
stakeKeeper := NewKeeper(input.capKey, input.bk, DefaultCodespace)
addr := sdk.AccAddress([]byte("some-address"))
bi := stakeKeeper.getBondInfo(ctx, addr)
@ -60,15 +77,10 @@ func TestKeeperGetSet(t *testing.T) {
}
func TestBonding(t *testing.T) {
ms, authKey, capKey := setupMultiStore()
cdc := codec.New()
auth.RegisterBaseAccount(cdc)
input := setupTestInput()
ctx := input.ctx
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
accountKeeper := auth.NewAccountKeeper(cdc, authKey, auth.ProtoBaseAccount)
bankKeeper := bank.NewBaseKeeper(accountKeeper)
stakeKeeper := NewKeeper(capKey, bankKeeper, DefaultCodespace)
stakeKeeper := NewKeeper(input.capKey, input.bk, DefaultCodespace)
addr := sdk.AccAddress([]byte("some-address"))
privKey := ed25519.GenPrivKey()
pubKey := privKey.PubKey()
@ -76,10 +88,10 @@ func TestBonding(t *testing.T) {
_, _, err := stakeKeeper.unbondWithoutCoins(ctx, addr)
require.Equal(t, err, ErrInvalidUnbond(DefaultCodespace))
_, err = stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 10))
_, err = stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.NewInt64Coin(staketypes.DefaultBondDenom, 10))
require.Nil(t, err)
power, err := stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 10))
power, err := stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.NewInt64Coin(staketypes.DefaultBondDenom, 10))
require.Nil(t, err)
require.Equal(t, int64(20), power)

View File

@ -5,20 +5,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
codec "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) {
key := ed25519.GenPrivKey()
pub := key.PubKey()
addr := sdk.AccAddress(pub.Address())
return key, pub, addr
}
func TestBaseAddressPubKey(t *testing.T) {
_, pub1, addr1 := keyPubAddr()
_, pub2, addr2 := keyPubAddr()

View File

@ -4,31 +4,24 @@ import (
"bytes"
"encoding/hex"
"fmt"
"strings"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/secp256k1"
sdk "github.com/cosmos/cosmos-sdk/types"
)
const (
memoCostPerByte sdk.Gas = 3
ed25519VerifyCost = 590
secp256k1VerifyCost = 1000
maxMemoCharacters = 256
// how much gas = 1 atom
gasPerUnitCost = 10000
// max total number of sigs per tx
txSigLimit = 7
var (
// TODO: Allow this to be configurable in the same way as minimum fees.
// ref: https://github.com/cosmos/cosmos-sdk/issues/3101
gasPerUnitCost uint64 = 10000 // how much gas = 1 atom
)
// NewAnteHandler returns an AnteHandler that checks and increments sequence
// numbers, checks signatures & account numbers, and deducts fees from the first
// signer.
func NewAnteHandler(am AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler {
func NewAnteHandler(ak AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler {
return func(
ctx sdk.Context, tx sdk.Tx, simulate bool,
) (newCtx sdk.Context, res sdk.Result, abort bool) {
@ -39,6 +32,8 @@ func NewAnteHandler(am AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler {
return ctx, sdk.ErrInternal("tx must be StdTx").Result(), true
}
params := ak.GetParams(ctx)
// Ensure that the provided fees meet a minimum threshold for the validator,
// if this is a CheckTx. This is only for local mempool purposes, and thus
// is only ran on check tx.
@ -74,7 +69,9 @@ func NewAnteHandler(am AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler {
return newCtx, err.Result(), true
}
newCtx.GasMeter().ConsumeGas(memoCostPerByte*sdk.Gas(len(stdTx.GetMemo())), "memo")
if res := ValidateMemo(newCtx.GasMeter(), stdTx, params); !res.IsOK() {
return newCtx, res, true
}
// stdSigs contains the sequence number, account number, and signatures.
// When simulating, this would just be a 0-length slice.
@ -83,7 +80,7 @@ func NewAnteHandler(am AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler {
isGenesis := ctx.BlockHeight() == 0
// fetch first signer, who's going to pay the fees
signerAccs[0], res = GetSignerAcc(newCtx, am, signerAddrs[0])
signerAccs[0], res = GetSignerAcc(newCtx, ak, signerAddrs[0])
if !res.IsOK() {
return newCtx, res, true
}
@ -103,41 +100,57 @@ func NewAnteHandler(am AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler {
for i := 0; i < len(stdSigs); i++ {
// skip the fee payer, account is cached and fees were deducted already
if i != 0 {
signerAccs[i], res = GetSignerAcc(newCtx, am, signerAddrs[i])
signerAccs[i], res = GetSignerAcc(newCtx, ak, signerAddrs[i])
if !res.IsOK() {
return newCtx, res, true
}
}
// check signature, return account with incremented nonce
signBytes := GetSignBytes(newCtx.ChainID(), stdTx, signerAccs[i], isGenesis)
signerAccs[i], res = processSig(newCtx, signerAccs[i], stdSigs[i], signBytes, simulate)
signerAccs[i], res = processSig(newCtx, signerAccs[i], stdSigs[i], signBytes, simulate, params)
if !res.IsOK() {
return newCtx, res, true
}
am.SetAccount(newCtx, signerAccs[i])
ak.SetAccount(newCtx, signerAccs[i])
}
// cache the signer accounts in the context
newCtx = WithSigners(newCtx, signerAccs)
// TODO: tx tags (?)
return newCtx, sdk.Result{GasWanted: stdTx.Fee.Gas}, false // continue...
}
}
// GetSignerAcc a signers for a given address that is expected to sign a transaction.
func GetSignerAcc(ctx sdk.Context, am AccountKeeper, addr sdk.AccAddress) (Account, sdk.Result) {
if acc := am.GetAccount(ctx, addr); acc != nil {
// GetSignerAcc returns an account for a given address that is expected to sign
// a transaction.
func GetSignerAcc(ctx sdk.Context, ak AccountKeeper, addr sdk.AccAddress) (Account, sdk.Result) {
if acc := ak.GetAccount(ctx, addr); acc != nil {
return acc, sdk.Result{}
}
return nil, sdk.ErrUnknownAddress(addr.String()).Result()
}
// ValidateMemo validates the memo and if successful consumes gas for
// verification.
func ValidateMemo(gasMeter sdk.GasMeter, stdTx StdTx, params Params) sdk.Result {
memoLength := len(stdTx.GetMemo())
if uint64(memoLength) > params.MaxMemoCharacters {
return sdk.ErrMemoTooLarge(
fmt.Sprintf(
"maximum number of characters is %d but received %d characters",
params.MaxMemoCharacters, memoLength,
),
).Result()
}
gasMeter.ConsumeGas(params.MemoCostPerByte*sdk.Gas(memoLength), "memo")
return sdk.Result{}
}
// verify the signature and increment the sequence. If the account doesn't have
// a pubkey, set it.
func processSig(
ctx sdk.Context, acc Account, sig StdSignature, signBytes []byte, simulate bool,
ctx sdk.Context, acc Account, sig StdSignature, signBytes []byte, simulate bool, params Params,
) (updatedAcc Account, res sdk.Result) {
pubKey, res := ProcessPubKey(acc, sig, simulate)
@ -150,7 +163,7 @@ func processSig(
return nil, sdk.ErrInternal("setting PubKey on signer's account").Result()
}
consumeSignatureVerificationGas(ctx.GasMeter(), pubKey)
consumeSignatureVerificationGas(ctx.GasMeter(), pubKey, params)
if !simulate && !pubKey.VerifyBytes(signBytes, sig.Signature) {
return nil, sdk.ErrUnauthorized("signature verification failed").Result()
}
@ -204,14 +217,20 @@ func ProcessPubKey(acc Account, sig StdSignature, simulate bool) (crypto.PubKey,
return pubKey, sdk.Result{}
}
func consumeSignatureVerificationGas(meter sdk.GasMeter, pubkey crypto.PubKey) {
switch pubkey.(type) {
case ed25519.PubKeyEd25519:
meter.ConsumeGas(ed25519VerifyCost, "ante verify: ed25519")
case secp256k1.PubKeySecp256k1:
meter.ConsumeGas(secp256k1VerifyCost, "ante verify: secp256k1")
// consumeSignatureVerificationGas consumes gas for signature verification based
// upon the public key type. The cost is fetched from the given params and is
// matched by the concrete type.
//
// TODO: Design a cleaner and flexible way to match concrete public key types.
func consumeSignatureVerificationGas(meter sdk.GasMeter, pubkey crypto.PubKey, params Params) {
pubkeyType := strings.ToLower(fmt.Sprintf("%T", pubkey))
switch {
case strings.Contains(pubkeyType, "ed25519"):
meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519")
case strings.Contains(pubkeyType, "secp256k1"):
meter.ConsumeGas(params.SigVerifyCostSecp256k1, "ante verify: secp256k1")
default:
panic("Unrecognized signature type")
panic(fmt.Sprintf("unrecognized signature type: %s", pubkeyType))
}
}
@ -300,11 +319,12 @@ func SetGasMeter(simulate bool, ctx sdk.Context, stdTx StdTx) sdk.Context {
// GetSignBytes returns a slice of bytes to sign over for a given transaction
// and an account.
func GetSignBytes(chainID string, stdTx StdTx, acc Account, genesis bool) []byte {
accNum := acc.GetAccountNumber()
if genesis {
accNum = 0
var accNum uint64
if !genesis {
accNum = acc.GetAccountNumber()
}
return StdSignBytes(chainID,
accNum, acc.GetSequence(),
stdTx.Fee, stdTx.Msgs, stdTx.Memo)
return StdSignBytes(
chainID, accNum, acc.GetSequence(), stdTx.Fee, stdTx.Msgs, stdTx.Memo,
)
}

View File

@ -6,41 +6,14 @@ import (
"testing"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/multisig"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/tendermint/tendermint/libs/log"
codec "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func newTestMsg(addrs ...sdk.AccAddress) *sdk.TestMsg {
return sdk.NewTestMsg(addrs...)
}
func newStdFee() StdFee {
return NewStdFee(50000,
sdk.Coins{sdk.NewInt64Coin("atom", 150)},
)
}
// coins to more than cover the fee
func newCoins() sdk.Coins {
return sdk.Coins{
sdk.NewInt64Coin("atom", 10000000),
}
}
// generate a priv key and return it with its address
func privAndAddr() (crypto.PrivKey, sdk.AccAddress) {
priv := ed25519.GenPrivKey()
addr := sdk.AccAddress(priv.PubKey().Address())
return priv, addr
}
// run the tx through the anteHandler and ensure its valid
func checkValidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, simulate bool) {
_, result, abort := anteHandler(ctx, tx, simulate)
@ -68,63 +41,17 @@ func checkInvalidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context,
}
}
func newTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, accNums []uint64, seqs []uint64, fee StdFee) sdk.Tx {
sigs := make([]StdSignature, len(privs))
for i, priv := range privs {
signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], fee, msgs, "")
sig, err := priv.Sign(signBytes)
if err != nil {
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, "")
return tx
}
func newTestTxWithMemo(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, accNums []uint64, seqs []uint64, fee StdFee, memo string) sdk.Tx {
sigs := make([]StdSignature, len(privs))
for i, priv := range privs {
signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], fee, msgs, memo)
sig, err := priv.Sign(signBytes)
if err != nil {
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, memo)
return tx
}
// All signers sign over the same StdSignDoc. Should always create invalid signatures
func newTestTxWithSignBytes(msgs []sdk.Msg, privs []crypto.PrivKey, accNums []uint64, seqs []uint64, fee StdFee, signBytes []byte, memo string) sdk.Tx {
sigs := make([]StdSignature, len(privs))
for i, priv := range privs {
sig, err := priv.Sign(signBytes)
if err != nil {
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, memo)
return tx
}
// Test various error cases in the AnteHandler control flow.
func TestAnteHandlerSigErrors(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
input := setupTestInput()
ctx := input.ctx
anteHandler := NewAnteHandler(input.ak, input.fck)
// keys and addresses
priv1, addr1 := privAndAddr()
priv2, addr2 := privAndAddr()
priv3, addr3 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
priv2, _, addr2 := keyPubAddr()
priv3, _, addr3 := keyPubAddr()
// msg and signatures
var tx sdk.Tx
@ -157,35 +84,30 @@ func TestAnteHandlerSigErrors(t *testing.T) {
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnknownAddress)
// save the first account, but second is still unrecognized
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
acc1.SetCoins(fee.Amount)
mapper.SetAccount(ctx, acc1)
input.ak.SetAccount(ctx, acc1)
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnknownAddress)
}
// Test logic around account number checking with one signer and many signers.
func TestAnteHandlerAccountNumbers(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
ctx = ctx.WithBlockHeight(1)
input := setupTestInput()
anteHandler := NewAnteHandler(input.ak, input.fck)
ctx := input.ctx.WithBlockHeight(1)
// keys and addresses
priv1, addr1 := privAndAddr()
priv2, addr2 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
priv2, _, addr2 := keyPubAddr()
// set the accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
acc1.SetCoins(newCoins())
mapper.SetAccount(ctx, acc1)
acc2 := mapper.NewAccountWithAddress(ctx, addr2)
input.ak.SetAccount(ctx, acc1)
acc2 := input.ak.NewAccountWithAddress(ctx, addr2)
acc2.SetCoins(newCoins())
mapper.SetAccount(ctx, acc2)
input.ak.SetAccount(ctx, acc2)
// msg and signatures
var tx sdk.Tx
@ -226,26 +148,21 @@ func TestAnteHandlerAccountNumbers(t *testing.T) {
// Test logic around account number checking with many signers when BlockHeight is 0.
func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
ctx = ctx.WithBlockHeight(0)
input := setupTestInput()
anteHandler := NewAnteHandler(input.ak, input.fck)
ctx := input.ctx.WithBlockHeight(0)
// keys and addresses
priv1, addr1 := privAndAddr()
priv2, addr2 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
priv2, _, addr2 := keyPubAddr()
// set the accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
acc1.SetCoins(newCoins())
mapper.SetAccount(ctx, acc1)
acc2 := mapper.NewAccountWithAddress(ctx, addr2)
input.ak.SetAccount(ctx, acc1)
acc2 := input.ak.NewAccountWithAddress(ctx, addr2)
acc2.SetCoins(newCoins())
mapper.SetAccount(ctx, acc2)
input.ak.SetAccount(ctx, acc2)
// msg and signatures
var tx sdk.Tx
@ -286,30 +203,25 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) {
// Test logic around sequence checking with one signer and many signers.
func TestAnteHandlerSequences(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
ctx = ctx.WithBlockHeight(1)
input := setupTestInput()
anteHandler := NewAnteHandler(input.ak, input.fck)
ctx := input.ctx.WithBlockHeight(1)
// keys and addresses
priv1, addr1 := privAndAddr()
priv2, addr2 := privAndAddr()
priv3, addr3 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
priv2, _, addr2 := keyPubAddr()
priv3, _, addr3 := keyPubAddr()
// set the accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
acc1.SetCoins(newCoins())
mapper.SetAccount(ctx, acc1)
acc2 := mapper.NewAccountWithAddress(ctx, addr2)
input.ak.SetAccount(ctx, acc1)
acc2 := input.ak.NewAccountWithAddress(ctx, addr2)
acc2.SetCoins(newCoins())
mapper.SetAccount(ctx, acc2)
acc3 := mapper.NewAccountWithAddress(ctx, addr3)
input.ak.SetAccount(ctx, acc2)
acc3 := input.ak.NewAccountWithAddress(ctx, addr3)
acc3.SetCoins(newCoins())
mapper.SetAccount(ctx, acc3)
input.ak.SetAccount(ctx, acc3)
// msg and signatures
var tx sdk.Tx
@ -365,20 +277,16 @@ func TestAnteHandlerSequences(t *testing.T) {
// Test logic around fee deduction.
func TestAnteHandlerFees(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
input := setupTestInput()
ctx := input.ctx
anteHandler := NewAnteHandler(input.ak, input.fck)
// keys and addresses
priv1, addr1 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
// set the accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
mapper.SetAccount(ctx, acc1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
input.ak.SetAccount(ctx, acc1)
// msg and signatures
var tx sdk.Tx
@ -392,38 +300,33 @@ func TestAnteHandlerFees(t *testing.T) {
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInsufficientFunds)
acc1.SetCoins(sdk.Coins{sdk.NewInt64Coin("atom", 149)})
mapper.SetAccount(ctx, acc1)
input.ak.SetAccount(ctx, acc1)
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInsufficientFunds)
require.True(t, feeCollector.GetCollectedFees(ctx).IsEqual(emptyCoins))
require.True(t, mapper.GetAccount(ctx, addr1).GetCoins().AmountOf("atom").Equal(sdk.NewInt(149)))
require.True(t, input.fck.GetCollectedFees(ctx).IsEqual(emptyCoins))
require.True(t, input.ak.GetAccount(ctx, addr1).GetCoins().AmountOf("atom").Equal(sdk.NewInt(149)))
acc1.SetCoins(sdk.Coins{sdk.NewInt64Coin("atom", 150)})
mapper.SetAccount(ctx, acc1)
input.ak.SetAccount(ctx, acc1)
checkValidTx(t, anteHandler, ctx, tx, false)
require.True(t, feeCollector.GetCollectedFees(ctx).IsEqual(sdk.Coins{sdk.NewInt64Coin("atom", 150)}))
require.True(t, mapper.GetAccount(ctx, addr1).GetCoins().AmountOf("atom").Equal(sdk.NewInt(0)))
require.True(t, input.fck.GetCollectedFees(ctx).IsEqual(sdk.Coins{sdk.NewInt64Coin("atom", 150)}))
require.True(t, input.ak.GetAccount(ctx, addr1).GetCoins().AmountOf("atom").Equal(sdk.NewInt(0)))
}
// Test logic around memo gas consumption.
func TestAnteHandlerMemoGas(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
ctx = ctx.WithBlockHeight(1)
input := setupTestInput()
anteHandler := NewAnteHandler(input.ak, input.fck)
ctx := input.ctx.WithBlockHeight(1)
// keys and addresses
priv1, addr1 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
// set the accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
mapper.SetAccount(ctx, acc1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
input.ak.SetAccount(ctx, acc1)
// msg and signatures
var tx sdk.Tx
@ -453,30 +356,25 @@ func TestAnteHandlerMemoGas(t *testing.T) {
func TestAnteHandlerMultiSigner(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
ctx = ctx.WithBlockHeight(1)
input := setupTestInput()
anteHandler := NewAnteHandler(input.ak, input.fck)
ctx := input.ctx.WithBlockHeight(1)
// keys and addresses
priv1, addr1 := privAndAddr()
priv2, addr2 := privAndAddr()
priv3, addr3 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
priv2, _, addr2 := keyPubAddr()
priv3, _, addr3 := keyPubAddr()
// set the accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
acc1.SetCoins(newCoins())
mapper.SetAccount(ctx, acc1)
acc2 := mapper.NewAccountWithAddress(ctx, addr2)
input.ak.SetAccount(ctx, acc1)
acc2 := input.ak.NewAccountWithAddress(ctx, addr2)
acc2.SetCoins(newCoins())
mapper.SetAccount(ctx, acc2)
acc3 := mapper.NewAccountWithAddress(ctx, addr3)
input.ak.SetAccount(ctx, acc2)
acc3 := input.ak.NewAccountWithAddress(ctx, addr3)
acc3.SetCoins(newCoins())
mapper.SetAccount(ctx, acc3)
input.ak.SetAccount(ctx, acc3)
// set up msgs and fee
var tx sdk.Tx
@ -505,26 +403,21 @@ func TestAnteHandlerMultiSigner(t *testing.T) {
func TestAnteHandlerBadSignBytes(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
ctx = ctx.WithBlockHeight(1)
input := setupTestInput()
anteHandler := NewAnteHandler(input.ak, input.fck)
ctx := input.ctx.WithBlockHeight(1)
// keys and addresses
priv1, addr1 := privAndAddr()
priv2, addr2 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
priv2, _, addr2 := keyPubAddr()
// set the accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
acc1.SetCoins(newCoins())
mapper.SetAccount(ctx, acc1)
acc2 := mapper.NewAccountWithAddress(ctx, addr2)
input.ak.SetAccount(ctx, acc1)
acc2 := input.ak.NewAccountWithAddress(ctx, addr2)
acc2.SetCoins(newCoins())
mapper.SetAccount(ctx, acc2)
input.ak.SetAccount(ctx, acc2)
var tx sdk.Tx
msg := newTestMsg(addr1)
@ -563,7 +456,6 @@ func TestAnteHandlerBadSignBytes(t *testing.T) {
privs, seqs = []crypto.PrivKey{priv1}, []uint64{1}
for _, cs := range cases {
tx := newTestTxWithSignBytes(
msgs, privs, accnums, seqs, fee,
StdSignBytes(cs.chainID, cs.accnum, cs.seq, cs.fee, cs.msgs, ""),
"",
@ -582,31 +474,25 @@ func TestAnteHandlerBadSignBytes(t *testing.T) {
privs, accnums, seqs = []crypto.PrivKey{priv1}, []uint64{1}, []uint64{0}
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey)
}
func TestAnteHandlerSetPubKey(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
ctx = ctx.WithBlockHeight(1)
input := setupTestInput()
anteHandler := NewAnteHandler(input.ak, input.fck)
ctx := input.ctx.WithBlockHeight(1)
// keys and addresses
priv1, addr1 := privAndAddr()
_, addr2 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
_, _, addr2 := keyPubAddr()
// set the accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
acc1.SetCoins(newCoins())
mapper.SetAccount(ctx, acc1)
acc2 := mapper.NewAccountWithAddress(ctx, addr2)
input.ak.SetAccount(ctx, acc1)
acc2 := input.ak.NewAccountWithAddress(ctx, addr2)
acc2.SetCoins(newCoins())
mapper.SetAccount(ctx, acc2)
input.ak.SetAccount(ctx, acc2)
var tx sdk.Tx
@ -618,7 +504,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) {
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
checkValidTx(t, anteHandler, ctx, tx, false)
acc1 = mapper.GetAccount(ctx, addr1)
acc1 = input.ak.GetAccount(ctx, addr1)
require.Equal(t, acc1.GetPubKey(), priv1.PubKey())
// test public key not found
@ -629,29 +515,29 @@ func TestAnteHandlerSetPubKey(t *testing.T) {
sigs[0].PubKey = nil
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey)
acc2 = mapper.GetAccount(ctx, addr2)
acc2 = input.ak.GetAccount(ctx, addr2)
require.Nil(t, acc2.GetPubKey())
// test invalid signature and public key
tx = newTestTx(ctx, msgs, privs, []uint64{1}, seqs, fee)
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey)
acc2 = mapper.GetAccount(ctx, addr2)
acc2 = input.ak.GetAccount(ctx, addr2)
require.Nil(t, acc2.GetPubKey())
}
func TestProcessPubKey(t *testing.T) {
ms, capKey, _ := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
input := setupTestInput()
ctx := input.ctx
// keys
_, addr1 := privAndAddr()
priv2, addr2 := privAndAddr()
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc2 := mapper.NewAccountWithAddress(ctx, addr2)
_, _, addr1 := keyPubAddr()
priv2, _, addr2 := keyPubAddr()
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
acc2 := input.ak.NewAccountWithAddress(ctx, addr2)
acc2.SetPubKey(priv2.PubKey())
type args struct {
acc Account
sig StdSignature
@ -677,9 +563,12 @@ func TestProcessPubKey(t *testing.T) {
}
func TestConsumeSignatureVerificationGas(t *testing.T) {
params := DefaultParams()
type args struct {
meter sdk.GasMeter
pubkey crypto.PubKey
params Params
}
tests := []struct {
name string
@ -687,16 +576,16 @@ func TestConsumeSignatureVerificationGas(t *testing.T) {
gasConsumed uint64
wantPanic bool
}{
{"PubKeyEd25519", args{sdk.NewInfiniteGasMeter(), ed25519.GenPrivKey().PubKey()}, ed25519VerifyCost, false},
{"PubKeySecp256k1", args{sdk.NewInfiniteGasMeter(), secp256k1.GenPrivKey().PubKey()}, secp256k1VerifyCost, false},
{"unknown key", args{sdk.NewInfiniteGasMeter(), nil}, 0, true},
{"PubKeyEd25519", args{sdk.NewInfiniteGasMeter(), ed25519.GenPrivKey().PubKey(), params}, DefaultSigVerifyCostED25519, false},
{"PubKeySecp256k1", args{sdk.NewInfiniteGasMeter(), secp256k1.GenPrivKey().PubKey(), params}, DefaultSigVerifyCostSecp256k1, false},
{"unknown key", args{sdk.NewInfiniteGasMeter(), nil, params}, 0, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.wantPanic {
require.Panics(t, func() { consumeSignatureVerificationGas(tt.args.meter, tt.args.pubkey) })
require.Panics(t, func() { consumeSignatureVerificationGas(tt.args.meter, tt.args.pubkey, tt.args.params) })
} else {
consumeSignatureVerificationGas(tt.args.meter, tt.args.pubkey)
consumeSignatureVerificationGas(tt.args.meter, tt.args.pubkey, tt.args.params)
require.Equal(t, tt.args.meter.GasConsumed(), tt.gasConsumed)
}
})
@ -758,32 +647,27 @@ func TestCountSubkeys(t *testing.T) {
func TestAnteHandlerSigLimitExceeded(t *testing.T) {
// setup
ms, capKey, capKey2 := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
feeCollector := NewFeeCollectionKeeper(cdc, capKey2)
anteHandler := NewAnteHandler(mapper, feeCollector)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
ctx = ctx.WithBlockHeight(1)
input := setupTestInput()
anteHandler := NewAnteHandler(input.ak, input.fck)
ctx := input.ctx.WithBlockHeight(1)
// keys and addresses
priv1, addr1 := privAndAddr()
priv2, addr2 := privAndAddr()
priv3, addr3 := privAndAddr()
priv4, addr4 := privAndAddr()
priv5, addr5 := privAndAddr()
priv6, addr6 := privAndAddr()
priv7, addr7 := privAndAddr()
priv8, addr8 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
priv2, _, addr2 := keyPubAddr()
priv3, _, addr3 := keyPubAddr()
priv4, _, addr4 := keyPubAddr()
priv5, _, addr5 := keyPubAddr()
priv6, _, addr6 := keyPubAddr()
priv7, _, addr7 := keyPubAddr()
priv8, _, addr8 := keyPubAddr()
// set the accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc1 := input.ak.NewAccountWithAddress(ctx, addr1)
acc1.SetCoins(newCoins())
mapper.SetAccount(ctx, acc1)
acc2 := mapper.NewAccountWithAddress(ctx, addr2)
input.ak.SetAccount(ctx, acc1)
acc2 := input.ak.NewAccountWithAddress(ctx, addr2)
acc2.SetCoins(newCoins())
mapper.SetAccount(ctx, acc2)
input.ak.SetAccount(ctx, acc2)
var tx sdk.Tx
msg := newTestMsg(addr1, addr2, addr3, addr4, addr5, addr6, addr7, addr8)

View File

@ -1,48 +0,0 @@
package auth
import (
"github.com/cosmos/cosmos-sdk/types"
)
/*
Usage:
var accounts types.AccountKeeper
// Fetch all signer accounts.
addrs := tx.GetSigners()
signers := make([]types.Account, len(addrs))
for i, addr := range addrs {
acc := accounts.GetAccount(ctx)
signers[i] = acc
}
ctx = auth.SetSigners(ctx, signers)
// Get all signer accounts.
signers := auth.GetSigners(ctx)
for i, signer := range signers {
signer.Address() == tx.GetSigners()[i]
}
*/
type contextKey int // local to the auth module
const (
contextKeySigners contextKey = iota
)
// add the signers to the context
func WithSigners(ctx types.Context, accounts []Account) types.Context {
return ctx.WithValue(contextKeySigners, accounts)
}
// get the signers from the context
func GetSigners(ctx types.Context) []Account {
v := ctx.Value(contextKeySigners)
if v == nil {
return []Account{}
}
return v.([]Account)
}

View File

@ -1,40 +0,0 @@
package auth
import (
"testing"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func TestContextWithSigners(t *testing.T) {
ms, _, _ := setupMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
_, _, addr1 := keyPubAddr()
_, _, addr2 := keyPubAddr()
acc1 := NewBaseAccountWithAddress(addr1)
acc1.SetSequence(7132)
acc2 := NewBaseAccountWithAddress(addr2)
acc2.SetSequence(8821)
// new ctx has no signers
signers := GetSigners(ctx)
require.Equal(t, 0, len(signers))
ctx2 := WithSigners(ctx, []Account{&acc1, &acc2})
// original context is unchanged
signers = GetSigners(ctx)
require.Equal(t, 0, len(signers))
// new context has signers
signers = GetSigners(ctx2)
require.Equal(t, 2, len(signers))
require.Equal(t, acc1, *(signers[0].(*BaseAccount)))
require.Equal(t, acc2, *(signers[1].(*BaseAccount)))
}

View File

@ -5,10 +5,6 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
codec "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -19,57 +15,45 @@ var (
)
func TestFeeCollectionKeeperGetSet(t *testing.T) {
ms, _, capKey2 := setupMultiStore()
cdc := codec.New()
// make context and keeper
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
fck := NewFeeCollectionKeeper(cdc, capKey2)
input := setupTestInput()
ctx := input.ctx
// no coins initially
currFees := fck.GetCollectedFees(ctx)
currFees := input.fck.GetCollectedFees(ctx)
require.True(t, currFees.IsEqual(emptyCoins))
// set feeCollection to oneCoin
fck.setCollectedFees(ctx, oneCoin)
input.fck.setCollectedFees(ctx, oneCoin)
// check that it is equal to oneCoin
require.True(t, fck.GetCollectedFees(ctx).IsEqual(oneCoin))
require.True(t, input.fck.GetCollectedFees(ctx).IsEqual(oneCoin))
}
func TestFeeCollectionKeeperAdd(t *testing.T) {
ms, _, capKey2 := setupMultiStore()
cdc := codec.New()
// make context and keeper
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
fck := NewFeeCollectionKeeper(cdc, capKey2)
input := setupTestInput()
ctx := input.ctx
// no coins initially
require.True(t, fck.GetCollectedFees(ctx).IsEqual(emptyCoins))
require.True(t, input.fck.GetCollectedFees(ctx).IsEqual(emptyCoins))
// add oneCoin and check that pool is now oneCoin
fck.AddCollectedFees(ctx, oneCoin)
require.True(t, fck.GetCollectedFees(ctx).IsEqual(oneCoin))
input.fck.AddCollectedFees(ctx, oneCoin)
require.True(t, input.fck.GetCollectedFees(ctx).IsEqual(oneCoin))
// add oneCoin again and check that pool is now twoCoins
fck.AddCollectedFees(ctx, oneCoin)
require.True(t, fck.GetCollectedFees(ctx).IsEqual(twoCoins))
input.fck.AddCollectedFees(ctx, oneCoin)
require.True(t, input.fck.GetCollectedFees(ctx).IsEqual(twoCoins))
}
func TestFeeCollectionKeeperClear(t *testing.T) {
ms, _, capKey2 := setupMultiStore()
cdc := codec.New()
// make context and keeper
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
fck := NewFeeCollectionKeeper(cdc, capKey2)
input := setupTestInput()
ctx := input.ctx
// set coins initially
fck.setCollectedFees(ctx, twoCoins)
require.True(t, fck.GetCollectedFees(ctx).IsEqual(twoCoins))
input.fck.setCollectedFees(ctx, twoCoins)
require.True(t, input.fck.GetCollectedFees(ctx).IsEqual(twoCoins))
// clear fees and see that pool is now empty
fck.ClearCollectedFees(ctx)
require.True(t, fck.GetCollectedFees(ctx).IsEqual(emptyCoins))
input.fck.ClearCollectedFees(ctx)
require.True(t, input.fck.GetCollectedFees(ctx).IsEqual(emptyCoins))
}

View File

@ -1,33 +1,62 @@
package auth
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// GenesisState - all auth state that must be provided at genesis
type GenesisState struct {
CollectedFees sdk.Coins `json:"collected_fees"` // collected fees
Params Params `json:"params"`
}
// Create a new genesis state
func NewGenesisState(collectedFees sdk.Coins) GenesisState {
func NewGenesisState(collectedFees sdk.Coins, params Params) GenesisState {
return GenesisState{
CollectedFees: collectedFees,
Params: params,
}
}
// Return a default genesis state
func DefaultGenesisState() GenesisState {
return NewGenesisState(sdk.Coins{})
return NewGenesisState(sdk.Coins{}, DefaultParams())
}
// Init store state from genesis data
func InitGenesis(ctx sdk.Context, keeper FeeCollectionKeeper, data GenesisState) {
keeper.setCollectedFees(ctx, data.CollectedFees)
func InitGenesis(ctx sdk.Context, ak AccountKeeper, fck FeeCollectionKeeper, data GenesisState) {
ak.SetParams(ctx, data.Params)
fck.setCollectedFees(ctx, data.CollectedFees)
}
// ExportGenesis returns a GenesisState for a given context and keeper
func ExportGenesis(ctx sdk.Context, keeper FeeCollectionKeeper) GenesisState {
collectedFees := keeper.GetCollectedFees(ctx)
return NewGenesisState(collectedFees)
func ExportGenesis(ctx sdk.Context, ak AccountKeeper, fck FeeCollectionKeeper) GenesisState {
collectedFees := fck.GetCollectedFees(ctx)
params := ak.GetParams(ctx)
return NewGenesisState(collectedFees, params)
}
// ValidateGenesis performs basic validation of auth genesis data returning an
// error for any failed validation criteria.
func ValidateGenesis(data GenesisState) error {
if data.Params.TxSigLimit == 0 {
return fmt.Errorf("invalid tx signature limit: %d", data.Params.TxSigLimit)
}
if data.Params.SigVerifyCostED25519 == 0 {
return fmt.Errorf("invalid ED25519 signature verification cost: %d", data.Params.SigVerifyCostED25519)
}
if data.Params.SigVerifyCostSecp256k1 == 0 {
return fmt.Errorf("invalid SECK256k1 signature verification cost: %d", data.Params.SigVerifyCostSecp256k1)
}
if data.Params.MaxMemoCharacters == 0 {
return fmt.Errorf("invalid max memo characters: %d", data.Params.MaxMemoCharacters)
}
if data.Params.MemoCostPerByte == 0 {
return fmt.Errorf("invalid memo cost per byte: %d", data.Params.MemoCostPerByte)
}
return nil
}

View File

@ -5,6 +5,7 @@ import (
codec "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/params"
)
var (
@ -20,10 +21,9 @@ var (
FeeStoreKey = "fee"
)
// This AccountKeeper encodes/decodes accounts using the
// go-amino (binary) encoding/decoding library.
// This AccountKeeper encodes/decodes accounts using the go-amino (binary)
// encoding/decoding library.
type AccountKeeper struct {
// The (unexposed) key used to access the store from the Context.
key sdk.StoreKey
@ -32,28 +32,34 @@ type AccountKeeper struct {
// The codec codec for binary encoding/decoding of accounts.
cdc *codec.Codec
paramSubspace params.Subspace
}
// NewAccountKeeper returns a new sdk.AccountKeeper that
// uses go-amino to (binary) encode and decode concrete sdk.Accounts.
// NewAccountKeeper returns a new sdk.AccountKeeper that uses go-amino to
// (binary) encode and decode concrete sdk.Accounts.
// nolint
func NewAccountKeeper(cdc *codec.Codec, key sdk.StoreKey, proto func() Account) AccountKeeper {
func NewAccountKeeper(
cdc *codec.Codec, key sdk.StoreKey, paramstore params.Subspace, proto func() Account,
) AccountKeeper {
return AccountKeeper{
key: key,
proto: proto,
cdc: cdc,
key: key,
proto: proto,
cdc: cdc,
paramSubspace: paramstore.WithTypeTable(ParamTypeTable()),
}
}
// Implaements sdk.AccountKeeper.
func (am AccountKeeper) NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) Account {
acc := am.proto()
func (ak AccountKeeper) NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) Account {
acc := ak.proto()
err := acc.SetAddress(addr)
if err != nil {
// Handle w/ #870
panic(err)
}
err = acc.SetAccountNumber(am.GetNextAccountNumber(ctx))
err = acc.SetAccountNumber(ak.GetNextAccountNumber(ctx))
if err != nil {
// Handle w/ #870
panic(err)
@ -62,8 +68,8 @@ func (am AccountKeeper) NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddre
}
// New Account
func (am AccountKeeper) NewAccount(ctx sdk.Context, acc Account) Account {
err := acc.SetAccountNumber(am.GetNextAccountNumber(ctx))
func (ak AccountKeeper) NewAccount(ctx sdk.Context, acc Account) Account {
err := acc.SetAccountNumber(ak.GetNextAccountNumber(ctx))
if err != nil {
// TODO: Handle with #870
panic(err)
@ -77,34 +83,34 @@ func AddressStoreKey(addr sdk.AccAddress) []byte {
}
// Implements sdk.AccountKeeper.
func (am AccountKeeper) GetAccount(ctx sdk.Context, addr sdk.AccAddress) Account {
store := ctx.KVStore(am.key)
func (ak AccountKeeper) GetAccount(ctx sdk.Context, addr sdk.AccAddress) Account {
store := ctx.KVStore(ak.key)
bz := store.Get(AddressStoreKey(addr))
if bz == nil {
return nil
}
acc := am.decodeAccount(bz)
acc := ak.decodeAccount(bz)
return acc
}
// Implements sdk.AccountKeeper.
func (am AccountKeeper) SetAccount(ctx sdk.Context, acc Account) {
func (ak AccountKeeper) SetAccount(ctx sdk.Context, acc Account) {
addr := acc.GetAddress()
store := ctx.KVStore(am.key)
bz := am.encodeAccount(acc)
store := ctx.KVStore(ak.key)
bz := ak.encodeAccount(acc)
store.Set(AddressStoreKey(addr), bz)
}
// RemoveAccount removes an account for the account mapper store.
func (am AccountKeeper) RemoveAccount(ctx sdk.Context, acc Account) {
func (ak AccountKeeper) RemoveAccount(ctx sdk.Context, acc Account) {
addr := acc.GetAddress()
store := ctx.KVStore(am.key)
store := ctx.KVStore(ak.key)
store.Delete(AddressStoreKey(addr))
}
// Implements sdk.AccountKeeper.
func (am AccountKeeper) IterateAccounts(ctx sdk.Context, process func(Account) (stop bool)) {
store := ctx.KVStore(am.key)
func (ak AccountKeeper) IterateAccounts(ctx sdk.Context, process func(Account) (stop bool)) {
store := ctx.KVStore(ak.key)
iter := sdk.KVStorePrefixIterator(store, AddressStoreKeyPrefix)
defer iter.Close()
for {
@ -112,7 +118,7 @@ func (am AccountKeeper) IterateAccounts(ctx sdk.Context, process func(Account) (
return
}
val := iter.Value()
acc := am.decodeAccount(val)
acc := ak.decodeAccount(val)
if process(acc) {
return
}
@ -121,8 +127,8 @@ func (am AccountKeeper) IterateAccounts(ctx sdk.Context, process func(Account) (
}
// Returns the PubKey of the account at address
func (am AccountKeeper) GetPubKey(ctx sdk.Context, addr sdk.AccAddress) (crypto.PubKey, sdk.Error) {
acc := am.GetAccount(ctx, addr)
func (ak AccountKeeper) GetPubKey(ctx sdk.Context, addr sdk.AccAddress) (crypto.PubKey, sdk.Error) {
acc := ak.GetAccount(ctx, addr)
if acc == nil {
return nil, sdk.ErrUnknownAddress(addr.String())
}
@ -130,16 +136,16 @@ func (am AccountKeeper) GetPubKey(ctx sdk.Context, addr sdk.AccAddress) (crypto.
}
// Returns the Sequence of the account at address
func (am AccountKeeper) GetSequence(ctx sdk.Context, addr sdk.AccAddress) (uint64, sdk.Error) {
acc := am.GetAccount(ctx, addr)
func (ak AccountKeeper) GetSequence(ctx sdk.Context, addr sdk.AccAddress) (uint64, sdk.Error) {
acc := ak.GetAccount(ctx, addr)
if acc == nil {
return 0, sdk.ErrUnknownAddress(addr.String())
}
return acc.GetSequence(), nil
}
func (am AccountKeeper) setSequence(ctx sdk.Context, addr sdk.AccAddress, newSequence uint64) sdk.Error {
acc := am.GetAccount(ctx, addr)
func (ak AccountKeeper) setSequence(ctx sdk.Context, addr sdk.AccAddress, newSequence uint64) sdk.Error {
acc := ak.GetAccount(ctx, addr)
if acc == nil {
return sdk.ErrUnknownAddress(addr.String())
}
@ -148,43 +154,57 @@ func (am AccountKeeper) setSequence(ctx sdk.Context, addr sdk.AccAddress, newSeq
// Handle w/ #870
panic(err)
}
am.SetAccount(ctx, acc)
ak.SetAccount(ctx, acc)
return nil
}
// Returns and increments the global account number counter
func (am AccountKeeper) GetNextAccountNumber(ctx sdk.Context) uint64 {
func (ak AccountKeeper) GetNextAccountNumber(ctx sdk.Context) uint64 {
var accNumber uint64
store := ctx.KVStore(am.key)
store := ctx.KVStore(ak.key)
bz := store.Get(globalAccountNumberKey)
if bz == nil {
accNumber = 0
} else {
err := am.cdc.UnmarshalBinaryLengthPrefixed(bz, &accNumber)
err := ak.cdc.UnmarshalBinaryLengthPrefixed(bz, &accNumber)
if err != nil {
panic(err)
}
}
bz = am.cdc.MustMarshalBinaryLengthPrefixed(accNumber + 1)
bz = ak.cdc.MustMarshalBinaryLengthPrefixed(accNumber + 1)
store.Set(globalAccountNumberKey, bz)
return accNumber
}
//----------------------------------------
// misc.
//-----------------------------------------------------------------------------
// Params
func (am AccountKeeper) encodeAccount(acc Account) []byte {
bz, err := am.cdc.MarshalBinaryBare(acc)
// SetParams sets the auth module's parameters.
func (ak AccountKeeper) SetParams(ctx sdk.Context, params Params) {
ak.paramSubspace.SetParamSet(ctx, &params)
}
// GetParams gets the auth module's parameters.
func (ak AccountKeeper) GetParams(ctx sdk.Context) (params Params) {
ak.paramSubspace.GetParamSet(ctx, &params)
return
}
//-----------------------------------------------------------------------------
// Misc.
func (ak AccountKeeper) encodeAccount(acc Account) []byte {
bz, err := ak.cdc.MarshalBinaryBare(acc)
if err != nil {
panic(err)
}
return bz
}
func (am AccountKeeper) decodeAccount(bz []byte) (acc Account) {
err := am.cdc.UnmarshalBinaryBare(bz, &acc)
func (ak AccountKeeper) decodeAccount(bz []byte) (acc Account) {
err := ak.cdc.UnmarshalBinaryBare(bz, &acc)
if err != nil {
panic(err)
}

View File

@ -3,46 +3,29 @@ package auth
import (
"testing"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func BenchmarkAccountMapperGetAccountFound(b *testing.B) {
ms, capKey, _ := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
// make context and mapper
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
input := setupTestInput()
// assumes b.N < 2**24
for i := 0; i < b.N; i++ {
arr := []byte{byte((i & 0xFF0000) >> 16), byte((i & 0xFF00) >> 8), byte(i & 0xFF)}
addr := sdk.AccAddress(arr)
acc := mapper.NewAccountWithAddress(ctx, addr)
mapper.SetAccount(ctx, acc)
acc := input.ak.NewAccountWithAddress(input.ctx, addr)
input.ak.SetAccount(input.ctx, acc)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
arr := []byte{byte((i & 0xFF0000) >> 16), byte((i & 0xFF00) >> 8), byte(i & 0xFF)}
mapper.GetAccount(ctx, sdk.AccAddress(arr))
input.ak.GetAccount(input.ctx, sdk.AccAddress(arr))
}
}
func BenchmarkAccountMapperGetAccountFoundWithCoins(b *testing.B) {
ms, capKey, _ := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
// make context and mapper
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
input := setupTestInput()
coins := sdk.Coins{
sdk.NewCoin("LTC", sdk.NewInt(1000)),
sdk.NewCoin("BTC", sdk.NewInt(1000)),
@ -56,46 +39,34 @@ func BenchmarkAccountMapperGetAccountFoundWithCoins(b *testing.B) {
for i := 0; i < b.N; i++ {
arr := []byte{byte((i & 0xFF0000) >> 16), byte((i & 0xFF00) >> 8), byte(i & 0xFF)}
addr := sdk.AccAddress(arr)
acc := mapper.NewAccountWithAddress(ctx, addr)
acc := input.ak.NewAccountWithAddress(input.ctx, addr)
acc.SetCoins(coins)
mapper.SetAccount(ctx, acc)
input.ak.SetAccount(input.ctx, acc)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
arr := []byte{byte((i & 0xFF0000) >> 16), byte((i & 0xFF00) >> 8), byte(i & 0xFF)}
mapper.GetAccount(ctx, sdk.AccAddress(arr))
input.ak.GetAccount(input.ctx, sdk.AccAddress(arr))
}
}
func BenchmarkAccountMapperSetAccount(b *testing.B) {
ms, capKey, _ := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
// make context and mapper
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
input := setupTestInput()
b.ResetTimer()
// assumes b.N < 2**24
for i := 0; i < b.N; i++ {
arr := []byte{byte((i & 0xFF0000) >> 16), byte((i & 0xFF00) >> 8), byte(i & 0xFF)}
addr := sdk.AccAddress(arr)
acc := mapper.NewAccountWithAddress(ctx, addr)
mapper.SetAccount(ctx, acc)
acc := input.ak.NewAccountWithAddress(input.ctx, addr)
input.ak.SetAccount(input.ctx, acc)
}
}
func BenchmarkAccountMapperSetAccountWithCoins(b *testing.B) {
ms, capKey, _ := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
// make context and mapper
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
input := setupTestInput()
coins := sdk.Coins{
sdk.NewCoin("LTC", sdk.NewInt(1000)),
sdk.NewCoin("BTC", sdk.NewInt(1000)),
@ -106,12 +77,13 @@ func BenchmarkAccountMapperSetAccountWithCoins(b *testing.B) {
}
b.ResetTimer()
// assumes b.N < 2**24
for i := 0; i < b.N; i++ {
arr := []byte{byte((i & 0xFF0000) >> 16), byte((i & 0xFF00) >> 8), byte(i & 0xFF)}
addr := sdk.AccAddress(arr)
acc := mapper.NewAccountWithAddress(ctx, addr)
acc := input.ak.NewAccountWithAddress(input.ctx, addr)
acc.SetCoins(coins)
mapper.SetAccount(ctx, acc)
input.ak.SetAccount(input.ctx, acc)
}
}

View File

@ -4,96 +4,87 @@ import (
"testing"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
codec "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) {
db := dbm.NewMemDB()
capKey := sdk.NewKVStoreKey("capkey")
capKey2 := sdk.NewKVStoreKey("capkey2")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db)
ms.LoadLatestVersion()
return ms, capKey, capKey2
}
func TestAccountMapperGetSet(t *testing.T) {
ms, capKey, _ := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
// make context and mapper
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
input := setupTestInput()
addr := sdk.AccAddress([]byte("some-address"))
// no account before its created
acc := mapper.GetAccount(ctx, addr)
acc := input.ak.GetAccount(input.ctx, addr)
require.Nil(t, acc)
// create account and check default values
acc = mapper.NewAccountWithAddress(ctx, addr)
acc = input.ak.NewAccountWithAddress(input.ctx, addr)
require.NotNil(t, acc)
require.Equal(t, addr, acc.GetAddress())
require.EqualValues(t, nil, acc.GetPubKey())
require.EqualValues(t, 0, acc.GetSequence())
// NewAccount doesn't call Set, so it's still nil
require.Nil(t, mapper.GetAccount(ctx, addr))
require.Nil(t, input.ak.GetAccount(input.ctx, addr))
// set some values on the account and save it
newSequence := uint64(20)
acc.SetSequence(newSequence)
mapper.SetAccount(ctx, acc)
input.ak.SetAccount(input.ctx, acc)
// check the new values
acc = mapper.GetAccount(ctx, addr)
acc = input.ak.GetAccount(input.ctx, addr)
require.NotNil(t, acc)
require.Equal(t, newSequence, acc.GetSequence())
}
func TestAccountMapperRemoveAccount(t *testing.T) {
ms, capKey, _ := setupMultiStore()
cdc := codec.New()
RegisterBaseAccount(cdc)
// make context and mapper
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
mapper := NewAccountKeeper(cdc, capKey, ProtoBaseAccount)
input := setupTestInput()
addr1 := sdk.AccAddress([]byte("addr1"))
addr2 := sdk.AccAddress([]byte("addr2"))
// create accounts
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
acc2 := mapper.NewAccountWithAddress(ctx, addr2)
acc1 := input.ak.NewAccountWithAddress(input.ctx, addr1)
acc2 := input.ak.NewAccountWithAddress(input.ctx, addr2)
accSeq1 := uint64(20)
accSeq2 := uint64(40)
acc1.SetSequence(accSeq1)
acc2.SetSequence(accSeq2)
mapper.SetAccount(ctx, acc1)
mapper.SetAccount(ctx, acc2)
input.ak.SetAccount(input.ctx, acc1)
input.ak.SetAccount(input.ctx, acc2)
acc1 = mapper.GetAccount(ctx, addr1)
acc1 = input.ak.GetAccount(input.ctx, addr1)
require.NotNil(t, acc1)
require.Equal(t, accSeq1, acc1.GetSequence())
// remove one account
mapper.RemoveAccount(ctx, acc1)
acc1 = mapper.GetAccount(ctx, addr1)
input.ak.RemoveAccount(input.ctx, acc1)
acc1 = input.ak.GetAccount(input.ctx, addr1)
require.Nil(t, acc1)
acc2 = mapper.GetAccount(ctx, addr2)
acc2 = input.ak.GetAccount(input.ctx, addr2)
require.NotNil(t, acc2)
require.Equal(t, accSeq2, acc2.GetSequence())
}
func TestSetParams(t *testing.T) {
input := setupTestInput()
params := DefaultParams()
input.ak.SetParams(input.ctx, params)
newParams := Params{}
input.ak.paramSubspace.Get(input.ctx, KeyTxSigLimit, &newParams.TxSigLimit)
require.Equal(t, newParams.TxSigLimit, DefaultTxSigLimit)
}
func TestGetParams(t *testing.T) {
input := setupTestInput()
params := DefaultParams()
input.ak.SetParams(input.ctx, params)
newParams := input.ak.GetParams(input.ctx)
require.Equal(t, params, newParams)
}

115
x/auth/params.go Normal file
View File

@ -0,0 +1,115 @@
package auth
import (
"bytes"
"fmt"
"strings"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/params"
)
// DefaultParamspace defines the default auth module parameter subspace
const DefaultParamspace = "auth"
// Default parameter values
const (
DefaultMemoCostPerByte sdk.Gas = 3
DefaultMaxMemoCharacters uint64 = 256
DefaultTxSigLimit uint64 = 7
DefaultSigVerifyCostED25519 uint64 = 590
DefaultSigVerifyCostSecp256k1 uint64 = 1000
)
// Parameter keys
var (
KeyMemoCostPerByte = []byte("MemoCostPerByte")
KeyMaxMemoCharacters = []byte("MaxMemoCharacters")
KeyTxSigLimit = []byte("TxSigLimit")
KeySigVerifyCostED25519 = []byte("SigVerifyCostED25519")
KeySigVerifyCostSecp256k1 = []byte("SigVerifyCostSecp256k1")
)
var _ params.ParamSet = &Params{}
// Params defines the parameters for the auth module.
type Params struct {
MemoCostPerByte sdk.Gas
MaxMemoCharacters uint64
TxSigLimit uint64 // max total number of signatures per tx
SigVerifyCostED25519 uint64
SigVerifyCostSecp256k1 uint64
}
// ParamTable for stake module
func ParamTypeTable() params.TypeTable {
return params.NewTypeTable().RegisterParamSet(&Params{})
}
// KeyValuePairs implements the ParamSet interface and returns all the key/value
// pairs of auth module's parameters.
// nolint
func (p *Params) KeyValuePairs() params.KeyValuePairs {
return params.KeyValuePairs{
{KeyMemoCostPerByte, &p.MemoCostPerByte},
{KeyMaxMemoCharacters, &p.MaxMemoCharacters},
{KeyTxSigLimit, &p.TxSigLimit},
{KeySigVerifyCostED25519, &p.SigVerifyCostED25519},
{KeySigVerifyCostSecp256k1, &p.SigVerifyCostSecp256k1},
}
}
// Equal returns a boolean determining if two Params types are identical.
func (p Params) Equal(p2 Params) bool {
bz1 := msgCdc.MustMarshalBinaryLengthPrefixed(&p)
bz2 := msgCdc.MustMarshalBinaryLengthPrefixed(&p2)
return bytes.Equal(bz1, bz2)
}
// DefaultParams returns a default set of parameters.
func DefaultParams() Params {
return Params{
MemoCostPerByte: DefaultMemoCostPerByte,
MaxMemoCharacters: DefaultMaxMemoCharacters,
TxSigLimit: DefaultTxSigLimit,
SigVerifyCostED25519: DefaultSigVerifyCostED25519,
SigVerifyCostSecp256k1: DefaultSigVerifyCostSecp256k1,
}
}
// String implements the stringer interface.
func (p Params) String() string {
var sb strings.Builder
sb.WriteString("Params: \n")
sb.WriteString(fmt.Sprintf("MemoCostPerByte: %v\n", p.MemoCostPerByte))
sb.WriteString(fmt.Sprintf("MaxMemoCharacters: %d\n", p.MaxMemoCharacters))
sb.WriteString(fmt.Sprintf("TxSigLimit: %d\n", p.TxSigLimit))
sb.WriteString(fmt.Sprintf("SigVerifyCostED25519: %d\n", p.SigVerifyCostED25519))
sb.WriteString(fmt.Sprintf("SigVerifyCostSecp256k1: %d\n", p.SigVerifyCostSecp256k1))
return sb.String()
}
// MustUnmarshalParams deserializes raw Params bytes into a Params structure. It
// will panic upon failure.
func MustUnmarshalParams(cdc *codec.Codec, value []byte) Params {
params, err := UnmarshalParams(cdc, value)
if err != nil {
panic(err)
}
return params
}
// UnmarshalParams deserializes raw Params bytes into a Params structure. It will
// return an error upon failure.
func UnmarshalParams(cdc *codec.Codec, value []byte) (params Params, err error) {
err = cdc.UnmarshalBinaryLengthPrefixed(value, &params)
if err != nil {
return Params{}, err
}
return
}

16
x/auth/params_test.go Normal file
View File

@ -0,0 +1,16 @@
package auth
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestParamsEqual(t *testing.T) {
p1 := DefaultParams()
p2 := DefaultParams()
require.Equal(t, p1, p2)
p1.TxSigLimit += 10
require.NotEqual(t, p1, p2)
}

View File

@ -55,21 +55,13 @@ func (tx StdTx) ValidateBasic() sdk.Error {
if len(stdSigs) != len(tx.GetSigners()) {
return sdk.ErrUnauthorized("wrong number of signers")
}
if len(tx.GetMemo()) > maxMemoCharacters {
return sdk.ErrMemoTooLarge(
fmt.Sprintf(
"maximum number of characters is %d but received %d characters",
maxMemoCharacters, len(tx.GetMemo()),
),
)
}
sigCount := 0
for i := 0; i < len(stdSigs); i++ {
sigCount += countSubKeys(stdSigs[i].PubKey)
if sigCount > txSigLimit {
if uint64(sigCount) > DefaultTxSigLimit {
return sdk.ErrTooManySignatures(
fmt.Sprintf("signatures: %d, limit: %d", sigCount, txSigLimit),
fmt.Sprintf("signatures: %d, limit: %d", sigCount, DefaultTxSigLimit),
)
}
}
@ -77,6 +69,7 @@ func (tx StdTx) ValidateBasic() sdk.Error {
return nil
}
// countSubKeys counts the total number of keys for a multi-sig public key.
func countSubKeys(pub crypto.PubKey) int {
v, ok := pub.(*multisig.PubKeyMultisigThreshold)
if !ok {

View File

@ -2,8 +2,6 @@ package auth
import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"strings"
"testing"
"github.com/stretchr/testify/require"
@ -12,6 +10,7 @@ import (
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -62,14 +61,14 @@ func TestTxValidateBasic(t *testing.T) {
ctx := sdk.NewContext(nil, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
// keys and addresses
priv1, addr1 := privAndAddr()
priv2, addr2 := privAndAddr()
priv3, addr3 := privAndAddr()
priv4, addr4 := privAndAddr()
priv5, addr5 := privAndAddr()
priv6, addr6 := privAndAddr()
priv7, addr7 := privAndAddr()
priv8, addr8 := privAndAddr()
priv1, _, addr1 := keyPubAddr()
priv2, _, addr2 := keyPubAddr()
priv3, _, addr3 := keyPubAddr()
priv4, _, addr4 := keyPubAddr()
priv5, _, addr5 := keyPubAddr()
priv6, _, addr6 := keyPubAddr()
priv7, _, addr7 := keyPubAddr()
priv8, _, addr8 := keyPubAddr()
// msg and signatures
msg1 := newTestMsg(addr1, addr2)
@ -102,15 +101,6 @@ func TestTxValidateBasic(t *testing.T) {
require.Error(t, err)
require.Equal(t, sdk.CodeUnauthorized, err.Result().Code)
// require to fail validation when memo is too large
badMemo := strings.Repeat("bad memo", 50)
privs, accNums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0}
tx = newTestTxWithMemo(ctx, msgs, privs, accNums, seqs, fee, badMemo)
err = tx.ValidateBasic()
require.Error(t, err)
require.Equal(t, sdk.CodeMemoTooLarge, err.Result().Code)
// require to fail validation when there are too many signatures
privs = []crypto.PrivKey{priv1, priv2, priv3, priv4, priv5, priv6, priv7, priv8}
accNums, seqs = []uint64{0, 0, 0, 0, 0, 0, 0, 0}, []uint64{0, 0, 0, 0, 0, 0, 0, 0}

123
x/auth/test_utils.go Normal file
View File

@ -0,0 +1,123 @@
// nolint
package auth
import (
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/params"
)
type testInput struct {
cdc *codec.Codec
ctx sdk.Context
ak AccountKeeper
fck FeeCollectionKeeper
}
func setupTestInput() testInput {
db := dbm.NewMemDB()
cdc := codec.New()
RegisterBaseAccount(cdc)
authCapKey := sdk.NewKVStoreKey("authCapKey")
fckCapKey := sdk.NewKVStoreKey("fckCapKey")
keyParams := sdk.NewKVStoreKey("params")
tkeyParams := sdk.NewTransientStoreKey("transient_params")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(authCapKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(fckCapKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
ms.LoadLatestVersion()
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
ak := NewAccountKeeper(cdc, authCapKey, pk.Subspace(DefaultParamspace), ProtoBaseAccount)
fck := NewFeeCollectionKeeper(cdc, fckCapKey)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "test-chain-id"}, false, log.NewNopLogger())
ak.SetParams(ctx, DefaultParams())
return testInput{cdc: cdc, ctx: ctx, ak: ak, fck: fck}
}
func newTestMsg(addrs ...sdk.AccAddress) *sdk.TestMsg {
return sdk.NewTestMsg(addrs...)
}
func newStdFee() StdFee {
return NewStdFee(50000,
sdk.Coins{sdk.NewInt64Coin("atom", 150)},
)
}
// coins to more than cover the fee
func newCoins() sdk.Coins {
return sdk.Coins{
sdk.NewInt64Coin("atom", 10000000),
}
}
func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) {
key := ed25519.GenPrivKey()
pub := key.PubKey()
addr := sdk.AccAddress(pub.Address())
return key, pub, addr
}
func newTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, accNums []uint64, seqs []uint64, fee StdFee) sdk.Tx {
sigs := make([]StdSignature, len(privs))
for i, priv := range privs {
signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], fee, msgs, "")
sig, err := priv.Sign(signBytes)
if err != nil {
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, "")
return tx
}
func newTestTxWithMemo(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, accNums []uint64, seqs []uint64, fee StdFee, memo string) sdk.Tx {
sigs := make([]StdSignature, len(privs))
for i, priv := range privs {
signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], fee, msgs, memo)
sig, err := priv.Sign(signBytes)
if err != nil {
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, memo)
return tx
}
func newTestTxWithSignBytes(msgs []sdk.Msg, privs []crypto.PrivKey, accNums []uint64, seqs []uint64, fee StdFee, signBytes []byte, memo string) sdk.Tx {
sigs := make([]StdSignature, len(privs))
for i, priv := range privs {
sig, err := priv.Sign(signBytes)
if err != nil {
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, memo)
return tx
}

View File

@ -3,46 +3,64 @@ package bank
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
codec "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
)
func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) {
db := dbm.NewMemDB()
authKey := sdk.NewKVStoreKey("authkey")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(authKey, sdk.StoreTypeIAVL, db)
ms.LoadLatestVersion()
return ms, authKey
type testInput struct {
cdc *codec.Codec
ctx sdk.Context
ak auth.AccountKeeper
}
func TestKeeper(t *testing.T) {
ms, authKey := setupMultiStore()
func setupTestInput() testInput {
db := dbm.NewMemDB()
cdc := codec.New()
auth.RegisterBaseAccount(cdc)
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
accountKeeper := auth.NewAccountKeeper(cdc, authKey, auth.ProtoBaseAccount)
bankKeeper := NewBaseKeeper(accountKeeper)
authCapKey := sdk.NewKVStoreKey("authCapKey")
fckCapKey := sdk.NewKVStoreKey("fckCapKey")
keyParams := sdk.NewKVStoreKey("params")
tkeyParams := sdk.NewTransientStoreKey("transient_params")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(authCapKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(fckCapKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
ms.LoadLatestVersion()
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
ak := auth.NewAccountKeeper(
cdc, authCapKey, pk.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount,
)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "test-chain-id"}, false, log.NewNopLogger())
ak.SetParams(ctx, auth.DefaultParams())
return testInput{cdc: cdc, ctx: ctx, ak: ak}
}
func TestKeeper(t *testing.T) {
input := setupTestInput()
ctx := input.ctx
bankKeeper := NewBaseKeeper(input.ak)
addr := sdk.AccAddress([]byte("addr1"))
addr2 := sdk.AccAddress([]byte("addr2"))
addr3 := sdk.AccAddress([]byte("addr3"))
acc := accountKeeper.NewAccountWithAddress(ctx, addr)
acc := input.ak.NewAccountWithAddress(ctx, addr)
// Test GetCoins/SetCoins
accountKeeper.SetAccount(ctx, acc)
input.ak.SetAccount(ctx, acc)
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{}))
bankKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
@ -79,7 +97,7 @@ func TestKeeper(t *testing.T) {
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
_, err2 := bankKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 50)})
assert.Implements(t, (*sdk.Error)(nil), err2)
require.Implements(t, (*sdk.Error)(nil), err2)
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
@ -112,22 +130,17 @@ func TestKeeper(t *testing.T) {
}
func TestSendKeeper(t *testing.T) {
ms, authKey := setupMultiStore()
cdc := codec.New()
auth.RegisterBaseAccount(cdc)
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
accountKeeper := auth.NewAccountKeeper(cdc, authKey, auth.ProtoBaseAccount)
bankKeeper := NewBaseKeeper(accountKeeper)
sendKeeper := NewBaseSendKeeper(accountKeeper)
input := setupTestInput()
ctx := input.ctx
bankKeeper := NewBaseKeeper(input.ak)
sendKeeper := NewBaseSendKeeper(input.ak)
addr := sdk.AccAddress([]byte("addr1"))
addr2 := sdk.AccAddress([]byte("addr2"))
acc := accountKeeper.NewAccountWithAddress(ctx, addr)
acc := input.ak.NewAccountWithAddress(ctx, addr)
// Test GetCoins/SetCoins
accountKeeper.SetAccount(ctx, acc)
input.ak.SetAccount(ctx, acc)
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{}))
bankKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
@ -147,7 +160,7 @@ func TestSendKeeper(t *testing.T) {
require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
_, err2 := sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 50)})
assert.Implements(t, (*sdk.Error)(nil), err2)
require.Implements(t, (*sdk.Error)(nil), err2)
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
@ -159,21 +172,16 @@ func TestSendKeeper(t *testing.T) {
}
func TestViewKeeper(t *testing.T) {
ms, authKey := setupMultiStore()
cdc := codec.New()
auth.RegisterBaseAccount(cdc)
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
accountKeeper := auth.NewAccountKeeper(cdc, authKey, auth.ProtoBaseAccount)
bankKeeper := NewBaseKeeper(accountKeeper)
viewKeeper := NewBaseViewKeeper(accountKeeper)
input := setupTestInput()
ctx := input.ctx
bankKeeper := NewBaseKeeper(input.ak)
viewKeeper := NewBaseViewKeeper(input.ak)
addr := sdk.AccAddress([]byte("addr1"))
acc := accountKeeper.NewAccountWithAddress(ctx, addr)
acc := input.ak.NewAccountWithAddress(ctx, addr)
// Test GetCoins/SetCoins
accountKeeper.SetAccount(ctx, acc)
input.ak.SetAccount(ctx, acc)
require.True(t, viewKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{}))
bankKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})

View File

@ -109,7 +109,7 @@ func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initCoins int64,
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger())
accountKeeper := auth.NewAccountKeeper(cdc, keyAcc, auth.ProtoBaseAccount)
accountKeeper := auth.NewAccountKeeper(cdc, keyAcc, pk.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount)
ck := bank.NewBaseKeeper(accountKeeper)
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
sk.SetPool(ctx, stake.InitialPool())

View File

@ -6,8 +6,6 @@ import (
"sort"
"testing"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
@ -27,13 +25,11 @@ func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper,
stake.RegisterCodec(mapp.Cdc)
RegisterCodec(mapp.Cdc)
keyGlobalParams := sdk.NewKVStoreKey(params.StoreKey)
tkeyGlobalParams := sdk.NewTransientStoreKey(params.TStoreKey)
keyStake := sdk.NewKVStoreKey(stake.StoreKey)
tkeyStake := sdk.NewTransientStoreKey(stake.TStoreKey)
keyGov := sdk.NewKVStoreKey(StoreKey)
pk := params.NewKeeper(mapp.Cdc, keyGlobalParams, tkeyGlobalParams)
pk := mapp.ParamsKeeper
ck := bank.NewBaseKeeper(mapp.AccountKeeper)
sk := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, ck, pk.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
keeper := NewKeeper(mapp.Cdc, keyGov, pk, pk.Subspace("testgov"), ck, sk, DefaultCodespace)
@ -44,7 +40,7 @@ func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper,
mapp.SetEndBlocker(getEndBlocker(keeper))
mapp.SetInitChainer(getInitChainer(mapp, keeper, sk))
require.NoError(t, mapp.CompleteSetup(keyStake, tkeyStake, keyGov, keyGlobalParams, tkeyGlobalParams))
require.NoError(t, mapp.CompleteSetup(keyStake, tkeyStake, keyGov))
genAccs, addrs, pubKeys, privKeys := mock.CreateGenAccounts(numGenAccs, sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 42)})

View File

@ -15,27 +15,47 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/params"
)
// AccountKeeper(/Keeper) and IBCMapper should use different StoreKey later
func defaultContext(key sdk.StoreKey) sdk.Context {
type testInput struct {
cdc *codec.Codec
ctx sdk.Context
ak auth.AccountKeeper
bk bank.BaseKeeper
ibcKey *sdk.KVStoreKey
}
func setupTestInput() testInput {
db := dbm.NewMemDB()
cms := store.NewCommitMultiStore(db)
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
cms.LoadLatestVersion()
ctx := sdk.NewContext(cms, abci.Header{}, false, log.NewNopLogger())
return ctx
}
cdc := makeCodec()
func newAddress() sdk.AccAddress {
return sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
}
ibcKey := sdk.NewKVStoreKey("ibcCapKey")
authCapKey := sdk.NewKVStoreKey("authCapKey")
fckCapKey := sdk.NewKVStoreKey("fckCapKey")
keyParams := sdk.NewKVStoreKey("params")
tkeyParams := sdk.NewTransientStoreKey("transient_params")
func getCoins(ck bank.Keeper, ctx sdk.Context, addr sdk.AccAddress) (sdk.Coins, sdk.Error) {
zero := sdk.Coins(nil)
coins, _, err := ck.AddCoins(ctx, addr, zero)
return coins, err
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(ibcKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(authCapKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(fckCapKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
ms.LoadLatestVersion()
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
ak := auth.NewAccountKeeper(
cdc, authCapKey, pk.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount,
)
bk := bank.NewBaseKeeper(ak)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "test-chain-id"}, false, log.NewNopLogger())
ak.SetParams(ctx, auth.DefaultParams())
return testInput{cdc: cdc, ctx: ctx, ak: ak, bk: bk, ibcKey: ibcKey}
}
func makeCodec() *codec.Codec {
@ -57,14 +77,19 @@ func makeCodec() *codec.Codec {
return cdc
}
func newAddress() sdk.AccAddress {
return sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
}
func getCoins(ck bank.Keeper, ctx sdk.Context, addr sdk.AccAddress) (sdk.Coins, sdk.Error) {
zero := sdk.Coins(nil)
coins, _, err := ck.AddCoins(ctx, addr, zero)
return coins, err
}
func TestIBC(t *testing.T) {
cdc := makeCodec()
key := sdk.NewKVStoreKey("ibc")
ctx := defaultContext(key)
am := auth.NewAccountKeeper(cdc, key, auth.ProtoBaseAccount)
ck := bank.NewBaseKeeper(am)
input := setupTestInput()
ctx := input.ctx
src := newAddress()
dest := newAddress()
@ -72,12 +97,12 @@ func TestIBC(t *testing.T) {
zero := sdk.Coins(nil)
mycoins := sdk.Coins{sdk.NewInt64Coin("mycoin", 10)}
coins, _, err := ck.AddCoins(ctx, src, mycoins)
coins, _, err := input.bk.AddCoins(ctx, src, mycoins)
require.Nil(t, err)
require.Equal(t, mycoins, coins)
ibcm := NewMapper(cdc, key, DefaultCodespace)
h := NewHandler(ibcm, ck)
ibcm := NewMapper(input.cdc, input.ibcKey, DefaultCodespace)
h := NewHandler(ibcm, input.bk)
packet := IBCPacket{
SrcAddr: src,
DestAddr: dest,
@ -86,7 +111,7 @@ func TestIBC(t *testing.T) {
DestChain: chainid,
}
store := ctx.KVStore(key)
store := ctx.KVStore(input.ibcKey)
var msg sdk.Msg
var res sdk.Result
@ -102,7 +127,7 @@ func TestIBC(t *testing.T) {
res = h(ctx, msg)
require.True(t, res.IsOK())
coins, err = getCoins(ck, ctx, src)
coins, err = getCoins(input.bk, ctx, src)
require.Nil(t, err)
require.Equal(t, zero, coins)
@ -120,7 +145,7 @@ func TestIBC(t *testing.T) {
res = h(ctx, msg)
require.True(t, res.IsOK())
coins, err = getCoins(ck, ctx, dest)
coins, err = getCoins(input.bk, ctx, dest)
require.Nil(t, err)
require.Equal(t, mycoins, coins)

View File

@ -18,6 +18,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/params"
)
const chainID = ""
@ -27,13 +28,17 @@ const chainID = ""
// capabilities aren't needed for testing.
type App struct {
*bam.BaseApp
Cdc *codec.Codec // Cdc is public since the codec is passed into the module anyways
KeyMain *sdk.KVStoreKey
KeyAccount *sdk.KVStoreKey
Cdc *codec.Codec // Cdc is public since the codec is passed into the module anyways
KeyMain *sdk.KVStoreKey
KeyAccount *sdk.KVStoreKey
KeyFeeCollection *sdk.KVStoreKey
KeyParams *sdk.KVStoreKey
TKeyParams *sdk.TransientStoreKey
// TODO: Abstract this out from not needing to be auth specifically
AccountKeeper auth.AccountKeeper
FeeCollectionKeeper auth.FeeCollectionKeeper
ParamsKeeper params.Keeper
GenesisAccounts []auth.Account
TotalCoinsSupply sdk.Coins
@ -58,14 +63,24 @@ func NewApp() *App {
KeyMain: sdk.NewKVStoreKey(bam.MainStoreKey),
KeyAccount: sdk.NewKVStoreKey(auth.StoreKey),
TotalCoinsSupply: sdk.Coins{},
KeyFeeCollection: sdk.NewKVStoreKey("fee"),
KeyParams: sdk.NewKVStoreKey("params"),
TKeyParams: sdk.NewTransientStoreKey("transient_params"),
}
app.ParamsKeeper = params.NewKeeper(app.Cdc, app.KeyParams, app.TKeyParams)
// Define the accountKeeper
app.AccountKeeper = auth.NewAccountKeeper(
app.Cdc,
app.KeyAccount,
app.ParamsKeeper.Subspace(auth.DefaultParamspace),
auth.ProtoBaseAccount,
)
app.FeeCollectionKeeper = auth.NewFeeCollectionKeeper(
app.Cdc,
app.KeyFeeCollection,
)
// Initialize the app. The chainers and blockers can be overwritten before
// calling complete setup.
@ -80,8 +95,10 @@ func NewApp() *App {
// CompleteSetup completes the application setup after the routes have been
// registered.
func (app *App) CompleteSetup(newKeys ...sdk.StoreKey) error {
newKeys = append(newKeys, app.KeyMain)
newKeys = append(newKeys, app.KeyAccount)
newKeys = append(
newKeys,
app.KeyMain, app.KeyAccount, app.KeyParams, app.TKeyParams, app.KeyFeeCollection,
)
for _, key := range newKeys {
switch key.(type) {
@ -109,6 +126,8 @@ func (app *App) InitChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.Respo
app.AccountKeeper.SetAccount(ctx, acc)
}
auth.InitGenesis(ctx, app.AccountKeeper, app.FeeCollectionKeeper, auth.DefaultGenesisState())
return abci.ResponseInitChain{}
}

View File

@ -11,7 +11,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/mock"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/stake"
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
)
@ -31,20 +30,16 @@ func getMockApp(t *testing.T) (*mock.App, stake.Keeper, Keeper) {
tkeyStake := sdk.NewTransientStoreKey(stake.TStoreKey)
keySlashing := sdk.NewKVStoreKey(StoreKey)
keyParams := sdk.NewKVStoreKey(params.StoreKey)
tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey)
bankKeeper := bank.NewBaseKeeper(mapp.AccountKeeper)
paramsKeeper := params.NewKeeper(mapp.Cdc, keyParams, tkeyParams)
stakeKeeper := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, bankKeeper, paramsKeeper.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
keeper := NewKeeper(mapp.Cdc, keySlashing, stakeKeeper, paramsKeeper.Subspace(DefaultParamspace), DefaultCodespace)
stakeKeeper := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, bankKeeper, mapp.ParamsKeeper.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
keeper := NewKeeper(mapp.Cdc, keySlashing, stakeKeeper, mapp.ParamsKeeper.Subspace(DefaultParamspace), DefaultCodespace)
mapp.Router().AddRoute(stake.RouterKey, stake.NewHandler(stakeKeeper))
mapp.Router().AddRoute(RouterKey, NewHandler(keeper))
mapp.SetEndBlocker(getEndBlocker(stakeKeeper))
mapp.SetInitChainer(getInitChainer(mapp, stakeKeeper))
require.NoError(t, mapp.CompleteSetup(keyStake, tkeyStake, keySlashing, keyParams, tkeyParams))
require.NoError(t, mapp.CompleteSetup(keyStake, tkeyStake, keySlashing))
return mapp, stakeKeeper, keeper
}

View File

@ -69,10 +69,10 @@ func createTestInput(t *testing.T, defaults Params) (sdk.Context, bank.Keeper, s
require.Nil(t, err)
ctx := sdk.NewContext(ms, abci.Header{Time: time.Unix(0, 0)}, false, log.NewTMLogger(os.Stdout))
cdc := createTestCodec()
accountKeeper := auth.NewAccountKeeper(cdc, keyAcc, auth.ProtoBaseAccount)
paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams)
accountKeeper := auth.NewAccountKeeper(cdc, keyAcc, paramsKeeper.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount)
ck := bank.NewBaseKeeper(accountKeeper)
paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams)
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, paramsKeeper.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
genesis := stake.DefaultGenesisState()

View File

@ -10,7 +10,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/mock"
"github.com/cosmos/cosmos-sdk/x/params"
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
)
@ -21,21 +20,16 @@ func getMockApp(t *testing.T) (*mock.App, Keeper) {
RegisterCodec(mApp.Cdc)
keyStake := sdk.NewKVStoreKey(StoreKey)
tkeyStake := sdk.NewTransientStoreKey(TStoreKey)
keyParams := sdk.NewKVStoreKey(params.StoreKey)
tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey)
bankKeeper := bank.NewBaseKeeper(mApp.AccountKeeper)
pk := params.NewKeeper(mApp.Cdc, keyParams, tkeyParams)
keeper := NewKeeper(mApp.Cdc, keyStake, tkeyStake, bankKeeper, pk.Subspace(DefaultParamspace), DefaultCodespace)
keeper := NewKeeper(mApp.Cdc, keyStake, tkeyStake, bankKeeper, mApp.ParamsKeeper.Subspace(DefaultParamspace), DefaultCodespace)
mApp.Router().AddRoute(RouterKey, NewHandler(keeper))
mApp.SetEndBlocker(getEndBlocker(keeper))
mApp.SetInitChainer(getInitChainer(mApp, keeper))
require.NoError(t, mApp.CompleteSetup(keyStake, tkeyStake, keyParams, tkeyParams))
require.NoError(t, mApp.CompleteSetup(keyStake, tkeyStake))
return mApp, keeper
}

View File

@ -96,15 +96,18 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger())
ctx = ctx.WithConsensusParams(&abci.ConsensusParams{Validator: &abci.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519}}})
cdc := MakeTestCodec()
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
accountKeeper := auth.NewAccountKeeper(
cdc, // amino codec
keyAcc, // target store
cdc, // amino codec
keyAcc, // target store
pk.Subspace(auth.DefaultParamspace),
auth.ProtoBaseAccount, // prototype
)
ck := bank.NewBaseKeeper(accountKeeper)
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
keeper := NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Subspace(DefaultParamspace), types.DefaultCodespace)
keeper.SetPool(ctx, types.InitialPool())
keeper.SetParams(ctx, types.DefaultParams())