Updates SDK and implement application genaccounts (#143)

* Transition to updated sdk with modular ante handler and new genaccounts setup

* Update genesis account type to be an Ethermint account

* Change default keybase and tidy modules

* Fix lint
This commit is contained in:
Austin Abell
2019-11-04 15:45:02 -05:00
committed by GitHub
parent 42227a1b8c
commit 97f73063a5
10 changed files with 298 additions and 261 deletions
+75 -181
View File
@@ -5,8 +5,9 @@ import (
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/ethermint/crypto"
@@ -19,164 +20,60 @@ import (
)
const (
memoCostPerByte sdk.Gas = 3
secp256k1VerifyCost uint64 = 21000
// TODO: Use this cost per byte through parameter or overriding NewConsumeGasForTxSizeDecorator
// which currently defaults at 10, if intended
// memoCostPerByte sdk.Gas = 3
secp256k1VerifyCost uint64 = 21000
)
// NewAnteHandler returns an ante handler responsible for attempting to route an
// Ethereum or SDK transaction to an internal ante handler for performing
// transaction-level processing (e.g. fee payment, signature verification) before
// being passed onto it's respective handler.
//
// NOTE: The EVM will already consume (intrinsic) gas for signature verification
// and covering input size as well as handling nonce incrementing.
func NewAnteHandler(ak auth.AccountKeeper, sk types.SupplyKeeper) sdk.AnteHandler {
return func(
ctx sdk.Context, tx sdk.Tx, sim bool,
) (newCtx sdk.Context, res sdk.Result, abort bool) {
) (newCtx sdk.Context, err error) {
switch castTx := tx.(type) {
case auth.StdTx:
return sdkAnteHandler(ctx, ak, sk, castTx, sim)
stdAnte := sdk.ChainAnteDecorators(
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
ante.NewMempoolFeeDecorator(),
ante.NewValidateBasicDecorator(),
ante.NewValidateMemoDecorator(ak),
ante.NewConsumeGasForTxSizeDecorator(ak),
ante.NewSetPubKeyDecorator(ak), // SetPubKeyDecorator must be called before all signature verification decorators
ante.NewValidateSigCountDecorator(ak),
ante.NewDeductFeeDecorator(ak, sk),
ante.NewSigGasConsumeDecorator(ak, consumeSigGas),
ante.NewSigVerificationDecorator(ak),
ante.NewIncrementSequenceDecorator(ak), // innermost AnteDecorator
)
return stdAnte(ctx, tx, sim)
case *evmtypes.EthereumTxMsg:
return ethAnteHandler(ctx, ak, sk, castTx, sim)
default:
return ctx, sdk.ErrInternal(fmt.Sprintf("transaction type invalid: %T", tx)).Result(), true
return ctx, sdk.ErrInternal(fmt.Sprintf("transaction type invalid: %T", tx))
}
}
}
// ----------------------------------------------------------------------------
// SDK Ante Handler
func sdkAnteHandler(
ctx sdk.Context, ak auth.AccountKeeper, sk types.SupplyKeeper, stdTx auth.StdTx, sim bool,
) (newCtx sdk.Context, res sdk.Result, abort bool) {
// 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.
if ctx.IsCheckTx() && !sim {
res := auth.EnsureSufficientMempoolFees(ctx, stdTx.Fee)
if !res.IsOK() {
return newCtx, res, true
}
}
newCtx = auth.SetGasMeter(sim, ctx, stdTx.Fee.Gas)
// AnteHandlers must have their own defer/recover in order for the BaseApp
// to know how much gas was used! This is because the GasMeter is created in
// the AnteHandler, but if it panics the context won't be set properly in
// runTx's recover call.
defer func() {
if r := recover(); r != nil {
switch rType := r.(type) {
case sdk.ErrorOutOfGas:
log := fmt.Sprintf("out of gas in location: %v", rType.Descriptor)
res = sdk.ErrOutOfGas(log).Result()
res.GasWanted = stdTx.Fee.Gas
res.GasUsed = newCtx.GasMeter().GasConsumed()
abort = true
default:
panic(r)
}
}
}()
if err := stdTx.ValidateBasic(); err != nil {
return newCtx, err.Result(), true
}
newCtx.GasMeter().ConsumeGas(memoCostPerByte*sdk.Gas(len(stdTx.GetMemo())), "memo")
// stdSigs contains the sequence number, account number, and signatures.
// When simulating, this would just be a 0-length slice.
signerAddrs := stdTx.GetSigners()
signerAccs := make([]exported.Account, len(signerAddrs))
isGenesis := ctx.BlockHeight() == 0
// fetch first signer, who's going to pay the fees
signerAccs[0], res = auth.GetSignerAcc(newCtx, ak, signerAddrs[0])
if !res.IsOK() {
return newCtx, res, true
}
// the first signer pays the transaction fees
if !stdTx.Fee.Amount.IsZero() {
res = auth.DeductFees(sk, newCtx, signerAccs[0], stdTx.Fee.Amount)
if !res.IsOK() {
return newCtx, res, true
}
// Reload account after fees deducted
signerAccs[0] = ak.GetAccount(newCtx, signerAccs[0].GetAddress())
}
stdSigs := stdTx.GetSignatures()
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 = auth.GetSignerAcc(newCtx, ak, signerAddrs[i])
if !res.IsOK() {
return newCtx, res, true
}
}
// check signature, return account with incremented nonce
signBytes := auth.GetSignBytes(newCtx.ChainID(), stdTx, signerAccs[i], isGenesis)
signerAccs[i], res = processSig(newCtx, signerAccs[i], stdSigs[i], signBytes, sim)
if !res.IsOK() {
return newCtx, res, true
}
ak.SetAccount(newCtx, signerAccs[i])
}
return newCtx, sdk.Result{GasWanted: stdTx.Fee.Gas}, false
}
// processSig verifies the signature and increments the nonce. If the account
// doesn't have a pubkey, set it.
func processSig(
ctx sdk.Context, acc auth.Account, sig auth.StdSignature, signBytes []byte, sim bool,
) (updatedAcc auth.Account, res sdk.Result) {
pubKey, res := auth.ProcessPubKey(acc, sig, sim)
if !res.IsOK() {
return nil, res
}
err := acc.SetPubKey(pubKey)
if err != nil {
return nil, sdk.ErrInternal("failed to set PubKey on signer account").Result()
}
consumeSigGas(ctx.GasMeter(), pubKey)
if !sim && !pubKey.VerifyBytes(signBytes, sig.Signature) {
return nil, sdk.ErrUnauthorized("signature verification failed").Result()
}
err = acc.SetSequence(acc.GetSequence() + 1)
if err != nil {
return nil, sdk.ErrInternal("failed to set account nonce").Result()
}
return acc, res
}
func consumeSigGas(meter sdk.GasMeter, pubkey tmcrypto.PubKey) {
func consumeSigGas(
meter sdk.GasMeter, sig []byte, pubkey tmcrypto.PubKey, params types.Params,
) error {
switch pubkey.(type) {
case crypto.PubKeySecp256k1:
meter.ConsumeGas(secp256k1VerifyCost, "ante verify: secp256k1")
// TODO: Remove allowing tm Pub key to sign transactions (if intended in final release)
// or until genesis utils are built into the evm or as their own module
return nil
case tmcrypto.PubKey:
meter.ConsumeGas(secp256k1VerifyCost, "ante verify: tendermint secp256k1")
return nil
default:
panic("Unrecognized signature type")
return sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, "unrecognized public key type: %T", pubkey)
}
}
@@ -193,7 +90,7 @@ func consumeSigGas(meter sdk.GasMeter, pubkey tmcrypto.PubKey) {
func ethAnteHandler(
ctx sdk.Context, ak auth.AccountKeeper, sk types.SupplyKeeper,
ethTxMsg *evmtypes.EthereumTxMsg, sim bool,
) (newCtx sdk.Context, res sdk.Result, abort bool) {
) (newCtx sdk.Context, err error) {
var senderAddr sdk.AccAddress
@@ -203,18 +100,18 @@ func ethAnteHandler(
if ctx.IsCheckTx() {
// Only perform pre-message (Ethereum transaction) execution validation
// during CheckTx. Otherwise, during DeliverTx the EVM will handle them.
if senderAddr, res = validateEthTxCheckTx(ctx, ak, ethTxMsg); !res.IsOK() {
return ctx, res, true
if senderAddr, err = validateEthTxCheckTx(ctx, ak, ethTxMsg); err != nil {
return ctx, err
}
} else {
// This is still currently needed to retrieve the sender address
if senderAddr, res = validateSignature(ctx, ethTxMsg); !res.IsOK() {
return ctx, res, true
if senderAddr, err = validateSignature(ctx, ethTxMsg); err != nil {
return ctx, err
}
// Explicit nonce check is also needed in case of multiple txs with same nonce not being handled
if res := checkNonce(ctx, ak, ethTxMsg, senderAddr); !res.IsOK() {
return ctx, res, true
if err := checkNonce(ctx, ak, ethTxMsg, senderAddr); err != nil {
return ctx, err
}
}
@@ -224,10 +121,7 @@ func ethAnteHandler(
switch rType := r.(type) {
case sdk.ErrorOutOfGas:
log := fmt.Sprintf("out of gas in location: %v", rType.Descriptor)
res = sdk.ErrOutOfGas(log).Result()
res.GasWanted = ethTxMsg.Data.GasLimit
res.GasUsed = ctx.GasMeter().GasConsumed()
abort = true
err = sdk.ErrOutOfGas(log)
default:
panic(r)
}
@@ -235,9 +129,9 @@ func ethAnteHandler(
}()
// Fetch sender account from signature
senderAcc, res := auth.GetSignerAcc(ctx, ak, senderAddr)
if !res.IsOK() {
return ctx, res, true
senderAcc, err := auth.GetSignerAcc(ctx, ak, senderAddr)
if err != nil {
return ctx, err
}
// Charge sender for gas up to limit
@@ -245,12 +139,12 @@ func ethAnteHandler(
// Cost calculates the fees paid to validators based on gas limit and price
cost := new(big.Int).Mul(ethTxMsg.Data.Price, new(big.Int).SetUint64(ethTxMsg.Data.GasLimit))
res = auth.DeductFees(sk, ctx, senderAcc, sdk.Coins{
err = auth.DeductFees(sk, ctx, senderAcc, sdk.Coins{
sdk.NewCoin(emint.DenomDefault, sdk.NewIntFromBigInt(cost)),
})
if !res.IsOK() {
return ctx, res, true
if err != nil {
return ctx, err
}
}
@@ -260,51 +154,51 @@ func ethAnteHandler(
gas, _ := ethcore.IntrinsicGas(ethTxMsg.Data.Payload, ethTxMsg.To() == nil, true)
newCtx.GasMeter().ConsumeGas(gas, "eth intrinsic gas")
return newCtx, sdk.Result{}, false
return newCtx, nil
}
func validateEthTxCheckTx(
ctx sdk.Context, ak auth.AccountKeeper, ethTxMsg *evmtypes.EthereumTxMsg,
) (sdk.AccAddress, sdk.Result) {
) (sdk.AccAddress, error) {
// Validate sufficient fees have been provided that meet a minimum threshold
// defined by the proposer (for mempool purposes during CheckTx).
if res := ensureSufficientMempoolFees(ctx, ethTxMsg); !res.IsOK() {
return nil, res
if err := ensureSufficientMempoolFees(ctx, ethTxMsg); err != nil {
return nil, err
}
// validate enough intrinsic gas
if res := validateIntrinsicGas(ethTxMsg); !res.IsOK() {
return nil, res
if err := validateIntrinsicGas(ethTxMsg); err != nil {
return nil, err
}
signer, res := validateSignature(ctx, ethTxMsg)
if !res.IsOK() {
return nil, res
signer, err := validateSignature(ctx, ethTxMsg)
if err != nil {
return nil, err
}
// validate account (nonce and balance checks)
if res := validateAccount(ctx, ak, ethTxMsg, signer); !res.IsOK() {
return nil, res
if err := validateAccount(ctx, ak, ethTxMsg, signer); err != nil {
return nil, err
}
return sdk.AccAddress(signer.Bytes()), sdk.Result{}
return sdk.AccAddress(signer.Bytes()), nil
}
// Validates signature and returns sender address
func validateSignature(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxMsg) (sdk.AccAddress, sdk.Result) {
func validateSignature(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxMsg) (sdk.AccAddress, error) {
// parse the chainID from a string to a base-10 integer
chainID, ok := new(big.Int).SetString(ctx.ChainID(), 10)
if !ok {
return nil, emint.ErrInvalidChainID(fmt.Sprintf("invalid chainID: %s", ctx.ChainID())).Result()
return nil, emint.ErrInvalidChainID(fmt.Sprintf("invalid chainID: %s", ctx.ChainID()))
}
// validate sender/signature
signer, err := ethTxMsg.VerifySig(chainID)
if err != nil {
return nil, sdk.ErrUnauthorized(fmt.Sprintf("signature verification failed: %s", err)).Result()
return nil, sdk.ErrUnauthorized(fmt.Sprintf("signature verification failed: %s", err))
}
return sdk.AccAddress(signer.Bytes()), sdk.Result{}
return sdk.AccAddress(signer.Bytes()), nil
}
// validateIntrinsicGas validates that the Ethereum tx message has enough to
@@ -312,26 +206,26 @@ func validateSignature(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxMsg) (sdk.A
// that the transaction uses before the transaction is executed. The gas is a
// constant value of 21000 plus any cost inccured by additional bytes of data
// supplied with the transaction.
func validateIntrinsicGas(ethTxMsg *evmtypes.EthereumTxMsg) sdk.Result {
func validateIntrinsicGas(ethTxMsg *evmtypes.EthereumTxMsg) error {
gas, err := ethcore.IntrinsicGas(ethTxMsg.Data.Payload, ethTxMsg.To() == nil, true)
if err != nil {
return sdk.ErrInternal(fmt.Sprintf("failed to compute intrinsic gas cost: %s", err)).Result()
return sdk.ErrInternal(fmt.Sprintf("failed to compute intrinsic gas cost: %s", err))
}
if ethTxMsg.Data.GasLimit < gas {
return sdk.ErrInternal(
fmt.Sprintf("intrinsic gas too low; %d < %d", ethTxMsg.Data.GasLimit, gas),
).Result()
)
}
return sdk.Result{}
return nil
}
// validateAccount validates the account nonce and that the account has enough
// funds to cover the tx cost.
func validateAccount(
ctx sdk.Context, ak auth.AccountKeeper, ethTxMsg *evmtypes.EthereumTxMsg, signer sdk.AccAddress,
) sdk.Result {
) error {
acc := ak.GetAccount(ctx, signer)
@@ -340,12 +234,12 @@ func validateAccount(
return sdk.ErrInternal(
fmt.Sprintf(
"invalid account number for height zero; got %d, expected 0", acc.GetAccountNumber(),
)).Result()
))
}
// Validate nonce is correct
if res := checkNonce(ctx, ak, ethTxMsg, signer); !res.IsOK() {
return res
if err := checkNonce(ctx, ak, ethTxMsg, signer); err != nil {
return err
}
// validate sender has enough funds
@@ -353,25 +247,25 @@ func validateAccount(
if balance.BigInt().Cmp(ethTxMsg.Cost()) < 0 {
return sdk.ErrInsufficientFunds(
fmt.Sprintf("insufficient funds: %s < %s", balance, ethTxMsg.Cost()),
).Result()
)
}
return sdk.Result{}
return nil
}
func checkNonce(
ctx sdk.Context, ak auth.AccountKeeper, ethTxMsg *evmtypes.EthereumTxMsg, signer sdk.AccAddress,
) sdk.Result {
) error {
acc := ak.GetAccount(ctx, signer)
// Validate the transaction nonce is valid (equivalent to the sender accounts
// current nonce).
seq := acc.GetSequence()
if ethTxMsg.Data.AccountNonce != seq {
return sdk.ErrInvalidSequence(
fmt.Sprintf("invalid nonce; got %d, expected %d", ethTxMsg.Data.AccountNonce, seq)).Result()
fmt.Sprintf("invalid nonce; got %d, expected %d", ethTxMsg.Data.AccountNonce, seq))
}
return sdk.Result{}
return nil
}
// ensureSufficientMempoolFees verifies that enough fees have been provided by the
@@ -379,7 +273,7 @@ func checkNonce(
// proposer.
//
// NOTE: This should only be ran during a CheckTx mode.
func ensureSufficientMempoolFees(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxMsg) sdk.Result {
func ensureSufficientMempoolFees(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxMsg) error {
// fee = GP * GL
fee := sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(emint.DenomDefault, ethTxMsg.Fee().Int64()))
@@ -396,8 +290,8 @@ func ensureSufficientMempoolFees(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxM
// reject the transaction that does not meet the minimum fee
return sdk.ErrInsufficientFee(
fmt.Sprintf("insufficient fee, got: %q required: %q", fee, ctx.MinGasPrices()),
).Result()
)
}
return sdk.Result{}
return nil
}
+7 -23
View File
@@ -1,7 +1,6 @@
package app
import (
"fmt"
"math/big"
"testing"
@@ -18,11 +17,8 @@ import (
func requireValidTx(
t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, sim bool,
) {
_, result, abort := anteHandler(ctx, tx, sim)
require.Equal(t, sdk.CodeOK, result.Code, result.Log)
require.False(t, abort)
require.True(t, result.IsOK())
_, err := anteHandler(ctx, tx, sim)
require.True(t, err == nil)
}
func requireInvalidTx(
@@ -30,20 +26,13 @@ func requireInvalidTx(
tx sdk.Tx, sim bool, code sdk.CodeType,
) {
newCtx, result, abort := anteHandler(ctx, tx, sim)
require.True(t, abort)
require.Equal(t, code, result.Code, fmt.Sprintf("invalid result: %v", result))
_, err := anteHandler(ctx, tx, sim)
// require.Equal(t, code, err, fmt.Sprintf("invalid result: %v", err))
require.Error(t, err)
if code == sdk.CodeOutOfGas {
stdTx, ok := tx.(auth.StdTx)
_, ok := tx.(auth.StdTx)
require.True(t, ok, "tx must be in form auth.StdTx")
// require GasWanted is set correctly
require.Equal(t, stdTx.Fee.Gas, result.GasWanted, "'GasWanted' wanted not set correctly")
require.True(t, result.GasUsed > result.GasWanted, "'GasUsed' not greater than GasWanted")
// require that context is set correctly
require.Equal(t, result.GasUsed, newCtx.GasMeter().GasConsumed(), "Context not updated correctly")
}
}
@@ -101,13 +90,8 @@ func TestValidTx(t *testing.T) {
accSeqs := []uint64{acc1.GetSequence(), acc2.GetSequence()}
tx := newTestSDKTx(input.ctx, msgs, privKeys, accNums, accSeqs, fee)
requireValidTx(t, input.anteHandler, input.ctx, tx, false)
// require accounts to update
acc1 = input.accKeeper.GetAccount(input.ctx, addr1)
acc2 = input.accKeeper.GetAccount(input.ctx, addr2)
require.Equal(t, accSeqs[0]+1, acc1.GetSequence())
require.Equal(t, accSeqs[1]+1, acc2.GetSequence())
requireValidTx(t, input.anteHandler, input.ctx, tx, false)
}
func TestSDKInvalidSigs(t *testing.T) {
+5 -8
View File
@@ -15,7 +15,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/crisis"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/genaccounts"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/mint"
@@ -47,7 +46,6 @@ var (
// non-dependant module elements, such as codec registration
// and genesis verification.
ModuleBasics = module.NewBasicManager(
genaccounts.AppModuleBasic{},
genutil.AppModuleBasic{},
auth.AppModuleBasic{},
bank.AppModuleBasic{},
@@ -151,14 +149,14 @@ func NewEthermintApp(
mintSubspace := app.paramsKeeper.Subspace(mint.DefaultParamspace)
distrSubspace := app.paramsKeeper.Subspace(distr.DefaultParamspace)
slashingSubspace := app.paramsKeeper.Subspace(slashing.DefaultParamspace)
govSubspace := app.paramsKeeper.Subspace(gov.DefaultParamspace)
govSubspace := app.paramsKeeper.Subspace(gov.DefaultParamspace).WithKeyTable(gov.ParamKeyTable())
crisisSubspace := app.paramsKeeper.Subspace(crisis.DefaultParamspace)
// add keepers
app.accountKeeper = auth.NewAccountKeeper(app.cdc, keys[auth.StoreKey], authSubspace, eminttypes.ProtoBaseAccount)
app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper, bankSubspace, bank.DefaultCodespace, app.ModuleAccountAddrs())
app.supplyKeeper = supply.NewKeeper(app.cdc, keys[supply.StoreKey], app.accountKeeper, app.bankKeeper, maccPerms)
stakingKeeper := staking.NewKeeper(app.cdc, keys[staking.StoreKey], tkeys[staking.TStoreKey],
stakingKeeper := staking.NewKeeper(app.cdc, keys[staking.StoreKey],
app.supplyKeeper, stakingSubspace, staking.DefaultCodespace)
app.mintKeeper = mint.NewKeeper(app.cdc, keys[mint.StoreKey], mintSubspace, &stakingKeeper, app.supplyKeeper, auth.FeeCollectorName)
app.distrKeeper = distr.NewKeeper(app.cdc, keys[distr.StoreKey], distrSubspace, &stakingKeeper,
@@ -173,7 +171,7 @@ func NewEthermintApp(
govRouter.AddRoute(gov.RouterKey, gov.ProposalHandler).
AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)).
AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper))
app.govKeeper = gov.NewKeeper(app.cdc, keys[gov.StoreKey], app.paramsKeeper, govSubspace,
app.govKeeper = gov.NewKeeper(app.cdc, keys[gov.StoreKey], govSubspace,
app.supplyKeeper, &stakingKeeper, gov.DefaultCodespace, govRouter)
// register the staking hooks
@@ -183,7 +181,6 @@ func NewEthermintApp(
)
app.mm = module.NewManager(
genaccounts.NewAppModule(app.accountKeeper),
genutil.NewAppModule(app.accountKeeper, app.stakingKeeper, app.BaseApp.DeliverTx),
auth.NewAppModule(app.accountKeeper),
bank.NewAppModule(app.bankKeeper, app.accountKeeper),
@@ -193,7 +190,7 @@ func NewEthermintApp(
gov.NewAppModule(app.govKeeper, app.supplyKeeper),
mint.NewAppModule(app.mintKeeper),
slashing.NewAppModule(app.slashingKeeper, app.stakingKeeper),
staking.NewAppModule(app.stakingKeeper, app.distrKeeper, app.accountKeeper, app.supplyKeeper),
staking.NewAppModule(app.stakingKeeper, app.accountKeeper, app.supplyKeeper),
evm.NewAppModule(app.evmKeeper),
)
@@ -207,7 +204,7 @@ func NewEthermintApp(
// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
app.mm.SetOrderInitGenesis(
genaccounts.ModuleName, distr.ModuleName, staking.ModuleName,
distr.ModuleName, staking.ModuleName,
auth.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName,
mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName, evmtypes.ModuleName,
)
+7 -5
View File
@@ -10,6 +10,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/mock"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/ethermint/crypto"
@@ -56,11 +57,6 @@ func newTestSetup() testSetup {
paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams, params.DefaultCodespace)
authSubspace := paramsKeeper.Subspace(auth.DefaultParamspace)
// Add keepers
accKeeper := auth.NewAccountKeeper(cdc, authCapKey, authSubspace, auth.ProtoBaseAccount)
supplyKeeper := auth.NewDummySupplyKeeper(accKeeper)
anteHandler := NewAnteHandler(accKeeper, supplyKeeper)
ctx := sdk.NewContext(
ms,
abci.Header{ChainID: "3", Time: time.Now().UTC()},
@@ -68,6 +64,12 @@ func newTestSetup() testSetup {
log.NewNopLogger(),
)
// Add keepers
accKeeper := auth.NewAccountKeeper(cdc, authCapKey, authSubspace, auth.ProtoBaseAccount)
accKeeper.SetParams(ctx, types.DefaultParams())
supplyKeeper := mock.NewDummySupplyKeeper(accKeeper)
anteHandler := NewAnteHandler(accKeeper, supplyKeeper)
return testSetup{
ctx: ctx,
cdc: cdc,