forked from cerc-io/laconicd-deprecated
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:
+75
-181
@@ -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 account’s
|
||||
// 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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user