diff --git a/PENDING.md b/PENDING.md index daab6b8d44..eb8a9dda68 100644 --- a/PENDING.md +++ b/PENDING.md @@ -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 diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index f84b3f2b72..dd5371e8d6 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -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) diff --git a/cmd/gaia/app/export.go b/cmd/gaia/app/export.go index 2b51c444be..f2f751b528 100644 --- a/cmd/gaia/app/export.go +++ b/cmd/gaia/app/export.go @@ -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), diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 0c8f7a08bf..d0a7d4cc7b 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -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, diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index e84b334d13..9af6d65f31 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -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), diff --git a/cmd/gaia/cmd/gaiadebug/hack.go b/cmd/gaia/cmd/gaiadebug/hack.go index 35202dd7ff..41b9e41faf 100644 --- a/cmd/gaia/cmd/gaiadebug/hack.go +++ b/cmd/gaia/cmd/gaiadebug/hack.go @@ -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) diff --git a/docs/examples/basecoin/app/app.go b/docs/examples/basecoin/app/app.go index fba42cc465..502d0f0987 100644 --- a/docs/examples/basecoin/app/app.go +++ b/docs/examples/basecoin/app/app.go @@ -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{} }, diff --git a/docs/examples/democoin/app/app.go b/docs/examples/democoin/app/app.go index dba5e8d5db..cbfe6e5c33 100644 --- a/docs/examples/democoin/app/app.go +++ b/docs/examples/democoin/app/app.go @@ -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. diff --git a/docs/examples/democoin/x/cool/keeper_test.go b/docs/examples/democoin/x/cool/keeper_test.go index 904681382c..cfebb343dd 100644 --- a/docs/examples/democoin/x/cool/keeper_test.go +++ b/docs/examples/democoin/x/cool/keeper_test.go @@ -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) diff --git a/docs/examples/democoin/x/pow/handler_test.go b/docs/examples/democoin/x/pow/handler_test.go index ce398b7c28..fc30cbda1e 100644 --- a/docs/examples/democoin/x/pow/handler_test.go +++ b/docs/examples/democoin/x/pow/handler_test.go @@ -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 diff --git a/docs/examples/democoin/x/pow/keeper_test.go b/docs/examples/democoin/x/pow/keeper_test.go index c8d5406f9c..19d828bd62 100644 --- a/docs/examples/democoin/x/pow/keeper_test.go +++ b/docs/examples/democoin/x/pow/keeper_test.go @@ -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) diff --git a/docs/examples/democoin/x/simplestake/keeper_test.go b/docs/examples/democoin/x/simplestake/keeper_test.go index 53c6c8a7c9..8ad87e530b 100644 --- a/docs/examples/democoin/x/simplestake/keeper_test.go +++ b/docs/examples/democoin/x/simplestake/keeper_test.go @@ -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) diff --git a/x/auth/account_test.go b/x/auth/account_test.go index 8b75e8ce5c..25749b79b9 100644 --- a/x/auth/account_test.go +++ b/x/auth/account_test.go @@ -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() diff --git a/x/auth/ante.go b/x/auth/ante.go index aafbd540ee..60c50f3e69 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -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, + ) } diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index 902ee4c983..78c9438793 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -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) diff --git a/x/auth/context.go b/x/auth/context.go deleted file mode 100644 index 28d159c972..0000000000 --- a/x/auth/context.go +++ /dev/null @@ -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) -} diff --git a/x/auth/context_test.go b/x/auth/context_test.go deleted file mode 100644 index b58547328d..0000000000 --- a/x/auth/context_test.go +++ /dev/null @@ -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))) -} diff --git a/x/auth/feekeeper_test.go b/x/auth/feekeeper_test.go index d481511617..a624fb38c1 100644 --- a/x/auth/feekeeper_test.go +++ b/x/auth/feekeeper_test.go @@ -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)) } diff --git a/x/auth/genesis.go b/x/auth/genesis.go index abc4fc3aea..fa9fa2d82a 100644 --- a/x/auth/genesis.go +++ b/x/auth/genesis.go @@ -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 } diff --git a/x/auth/keeper.go b/x/auth/keeper.go index 3c00c9bb70..f2cf868206 100644 --- a/x/auth/keeper.go +++ b/x/auth/keeper.go @@ -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, ¶ms) +} + +// GetParams gets the auth module's parameters. +func (ak AccountKeeper) GetParams(ctx sdk.Context) (params Params) { + ak.paramSubspace.GetParamSet(ctx, ¶ms) + 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) } diff --git a/x/auth/keeper_bench_test.go b/x/auth/keeper_bench_test.go index 413cd6afdf..8a3ae6da59 100644 --- a/x/auth/keeper_bench_test.go +++ b/x/auth/keeper_bench_test.go @@ -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) } } diff --git a/x/auth/keeper_test.go b/x/auth/keeper_test.go index ad05c0f8ed..4285132cb6 100644 --- a/x/auth/keeper_test.go +++ b/x/auth/keeper_test.go @@ -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) +} diff --git a/x/auth/params.go b/x/auth/params.go new file mode 100644 index 0000000000..94cf69ff0b --- /dev/null +++ b/x/auth/params.go @@ -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, ¶ms) + if err != nil { + return Params{}, err + } + + return +} diff --git a/x/auth/params_test.go b/x/auth/params_test.go new file mode 100644 index 0000000000..67699c4304 --- /dev/null +++ b/x/auth/params_test.go @@ -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) +} diff --git a/x/auth/stdtx.go b/x/auth/stdtx.go index 5b9561cf37..ceba13c6df 100644 --- a/x/auth/stdtx.go +++ b/x/auth/stdtx.go @@ -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 { diff --git a/x/auth/stdtx_test.go b/x/auth/stdtx_test.go index f89e2b8cfe..0cc6ced233 100644 --- a/x/auth/stdtx_test.go +++ b/x/auth/stdtx_test.go @@ -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} diff --git a/x/auth/test_utils.go b/x/auth/test_utils.go new file mode 100644 index 0000000000..096b3897a2 --- /dev/null +++ b/x/auth/test_utils.go @@ -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 +} diff --git a/x/bank/keeper_test.go b/x/bank/keeper_test.go index 14f40f9c4f..3236fa4ed1 100644 --- a/x/bank/keeper_test.go +++ b/x/bank/keeper_test.go @@ -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)}) diff --git a/x/distribution/keeper/test_common.go b/x/distribution/keeper/test_common.go index ae1c56c5b9..25bebe4329 100644 --- a/x/distribution/keeper/test_common.go +++ b/x/distribution/keeper/test_common.go @@ -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()) diff --git a/x/gov/test_common.go b/x/gov/test_common.go index b55f10f4d4..3c4cb3676a 100644 --- a/x/gov/test_common.go +++ b/x/gov/test_common.go @@ -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)}) diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index 2fa24a6c7c..9b9bbf93a4 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -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) diff --git a/x/mock/app.go b/x/mock/app.go index 326d7fb93e..541d923dcd 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -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{} } diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index 9cddc10ad8..99cfa1f4e3 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -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 } diff --git a/x/slashing/test_common.go b/x/slashing/test_common.go index 33a94684f1..87a7d13527 100644 --- a/x/slashing/test_common.go +++ b/x/slashing/test_common.go @@ -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() diff --git a/x/stake/app_test.go b/x/stake/app_test.go index 610089c03d..f55dc2548c 100644 --- a/x/stake/app_test.go +++ b/x/stake/app_test.go @@ -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 } diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index 828df46e41..82d04cef75 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -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())