forked from cerc-io/laconicd-deprecated
ante, evm: AnteHandler refactor (#517)
* Refactor fees function * Implement suggestions * wip test * checksenderbalance tests * wip deductcost test * Tests fixes * Merge master and fix conflicts * Merging account and bank interfaces * Update x/evm/keeper/utils.go Co-authored-by: Hanchon <guillermo.paoletti@gmail.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
co-authored by
Hanchon
Federico Kunze Küllmer
parent
8f12b64ea4
commit
3f19217d7f
+3
-15
@@ -19,32 +19,20 @@ import (
|
||||
ibcante "github.com/cosmos/ibc-go/modules/core/ante"
|
||||
|
||||
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
const (
|
||||
secp256k1VerifyCost uint64 = 21000
|
||||
)
|
||||
|
||||
// AccountKeeper defines an expected keeper interface for the auth module's AccountKeeper
|
||||
type AccountKeeper interface {
|
||||
authante.AccountKeeper
|
||||
NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
|
||||
GetSequence(sdk.Context, sdk.AccAddress) (uint64, error)
|
||||
}
|
||||
|
||||
// BankKeeper defines an expected keeper interface for the bank module's Keeper
|
||||
type BankKeeper interface {
|
||||
authtypes.BankKeeper
|
||||
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
|
||||
}
|
||||
|
||||
// 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.
|
||||
func NewAnteHandler(
|
||||
ak AccountKeeper,
|
||||
bankKeeper BankKeeper,
|
||||
ak evmtypes.AccountKeeper,
|
||||
bankKeeper evmtypes.BankKeeper,
|
||||
evmKeeper EVMKeeper,
|
||||
feeGrantKeeper authante.FeegrantKeeper,
|
||||
channelKeeper channelkeeper.Keeper,
|
||||
|
||||
+25
-59
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/palantir/stacktrace"
|
||||
|
||||
ethermint "github.com/tharsis/ethermint/types"
|
||||
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@@ -89,13 +90,13 @@ func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s
|
||||
|
||||
// EthAccountVerificationDecorator validates an account balance checks
|
||||
type EthAccountVerificationDecorator struct {
|
||||
ak AccountKeeper
|
||||
bankKeeper BankKeeper
|
||||
ak evmtypes.AccountKeeper
|
||||
bankKeeper evmtypes.BankKeeper
|
||||
evmKeeper EVMKeeper
|
||||
}
|
||||
|
||||
// NewEthAccountVerificationDecorator creates a new EthAccountVerificationDecorator
|
||||
func NewEthAccountVerificationDecorator(ak AccountKeeper, bankKeeper BankKeeper, ek EVMKeeper) EthAccountVerificationDecorator {
|
||||
func NewEthAccountVerificationDecorator(ak evmtypes.AccountKeeper, bankKeeper evmtypes.BankKeeper, ek EVMKeeper) EthAccountVerificationDecorator {
|
||||
return EthAccountVerificationDecorator{
|
||||
ak: ak,
|
||||
bankKeeper: bankKeeper,
|
||||
@@ -154,18 +155,8 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx
|
||||
avd.ak.SetAccount(ctx, acc)
|
||||
}
|
||||
|
||||
// validate sender has enough funds to pay for tx cost
|
||||
balance := avd.bankKeeper.GetBalance(ctx, from, evmDenom)
|
||||
cost := txData.Cost()
|
||||
|
||||
if balance.Amount.BigInt().Cmp(cost) < 0 {
|
||||
return ctx, stacktrace.Propagate(
|
||||
sdkerrors.Wrapf(
|
||||
sdkerrors.ErrInsufficientFunds,
|
||||
"sender balance < tx cost (%s < %s%s)", balance, txData.Cost(), evmDenom,
|
||||
),
|
||||
"sender should have had enough funds to pay for tx cost = fee + amount (%s = %s + %s)", cost, txData.Fee(), txData.GetValue(),
|
||||
)
|
||||
if err := evmkeeper.CheckSenderBalance(ctx, avd.bankKeeper, from, txData, evmDenom); err != nil {
|
||||
return ctx, stacktrace.Propagate(err, "failed to check sender balance")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -177,11 +168,11 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx
|
||||
// EthNonceVerificationDecorator checks that the account nonce from the transaction matches
|
||||
// the sender account sequence.
|
||||
type EthNonceVerificationDecorator struct {
|
||||
ak AccountKeeper
|
||||
ak evmtypes.AccountKeeper
|
||||
}
|
||||
|
||||
// NewEthNonceVerificationDecorator creates a new EthNonceVerificationDecorator
|
||||
func NewEthNonceVerificationDecorator(ak AccountKeeper) EthNonceVerificationDecorator {
|
||||
func NewEthNonceVerificationDecorator(ak evmtypes.AccountKeeper) EthNonceVerificationDecorator {
|
||||
return EthNonceVerificationDecorator{
|
||||
ak: ak,
|
||||
}
|
||||
@@ -235,13 +226,13 @@ func (nvd EthNonceVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx,
|
||||
// EthGasConsumeDecorator validates enough intrinsic gas for the transaction and
|
||||
// gas consumption.
|
||||
type EthGasConsumeDecorator struct {
|
||||
ak AccountKeeper
|
||||
bankKeeper BankKeeper
|
||||
ak evmtypes.AccountKeeper
|
||||
bankKeeper evmtypes.BankKeeper
|
||||
evmKeeper EVMKeeper
|
||||
}
|
||||
|
||||
// NewEthGasConsumeDecorator creates a new EthGasConsumeDecorator
|
||||
func NewEthGasConsumeDecorator(ak AccountKeeper, bankKeeper BankKeeper, ek EVMKeeper) EthGasConsumeDecorator {
|
||||
func NewEthGasConsumeDecorator(ak evmtypes.AccountKeeper, bankKeeper evmtypes.BankKeeper, ek EVMKeeper) EthGasConsumeDecorator {
|
||||
return EthGasConsumeDecorator{
|
||||
ak: ak,
|
||||
bankKeeper: bankKeeper,
|
||||
@@ -274,6 +265,7 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
||||
blockHeight := big.NewInt(ctx.BlockHeight())
|
||||
homestead := ethCfg.IsHomestead(blockHeight)
|
||||
istanbul := ethCfg.IsIstanbul(blockHeight)
|
||||
evmDenom := params.EvmDenom
|
||||
|
||||
var events sdk.Events
|
||||
|
||||
@@ -291,45 +283,19 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
||||
return ctx, stacktrace.Propagate(err, "failed to unpack tx data")
|
||||
}
|
||||
|
||||
isContractCreation := txData.GetTo() == nil
|
||||
fees, err := evmkeeper.DeductTxCostsFromUserBalance(
|
||||
ctx,
|
||||
egcd.bankKeeper,
|
||||
egcd.ak,
|
||||
*msgEthTx,
|
||||
txData,
|
||||
evmDenom,
|
||||
homestead,
|
||||
istanbul,
|
||||
)
|
||||
|
||||
// fetch sender account from signature
|
||||
signerAcc, err := authante.GetSignerAcc(ctx, egcd.ak, msgEthTx.GetFrom())
|
||||
if err != nil {
|
||||
return ctx, stacktrace.Propagate(err, "account not found for sender %s", msgEthTx.From)
|
||||
}
|
||||
|
||||
gasLimit := txData.GetGas()
|
||||
|
||||
var accessList ethtypes.AccessList
|
||||
if txData.GetAccessList() != nil {
|
||||
accessList = txData.GetAccessList()
|
||||
}
|
||||
|
||||
intrinsicGas, err := core.IntrinsicGas(txData.GetData(), accessList, isContractCreation, homestead, istanbul)
|
||||
if err != nil {
|
||||
return ctx, stacktrace.Propagate(
|
||||
sdkerrors.Wrap(err, "failed to compute intrinsic gas cost"),
|
||||
"failed to retrieve intrinsic gas, contract creation = %t; homestead = %t, istanbul = %t", isContractCreation, homestead, istanbul)
|
||||
}
|
||||
|
||||
// intrinsic gas verification during CheckTx
|
||||
if ctx.IsCheckTx() && gasLimit < intrinsicGas {
|
||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrOutOfGas, "gas limit too low: %d (gas limit) < %d (intrinsic gas)", gasLimit, intrinsicGas)
|
||||
}
|
||||
|
||||
// calculate the fees paid to validators based on gas limit and price
|
||||
feeAmt := txData.Fee() // fee = gas limit * gas price
|
||||
|
||||
evmDenom := egcd.evmKeeper.GetParams(ctx).EvmDenom
|
||||
fees := sdk.Coins{sdk.NewCoin(evmDenom, sdk.NewIntFromBigInt(feeAmt))}
|
||||
|
||||
// deduct the full gas cost from the user balance
|
||||
if err := authante.DeductFees(egcd.bankKeeper, ctx, signerAcc, fees); err != nil {
|
||||
return ctx, stacktrace.Propagate(
|
||||
err,
|
||||
"failed to deduct full gas cost %s from the user %s balance", fees, msgEthTx.From,
|
||||
)
|
||||
return ctx, stacktrace.Propagate(err, "failed to deduct transaction costs from user balance")
|
||||
}
|
||||
|
||||
events = append(events, sdk.NewEvent(sdk.EventTypeTx, sdk.NewAttribute(sdk.AttributeKeyFee, fees.String())))
|
||||
@@ -477,11 +443,11 @@ func (ald AccessListDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b
|
||||
|
||||
// EthIncrementSenderSequenceDecorator increments the sequence of the signers.
|
||||
type EthIncrementSenderSequenceDecorator struct {
|
||||
ak AccountKeeper
|
||||
ak evmtypes.AccountKeeper
|
||||
}
|
||||
|
||||
// NewEthIncrementSenderSequenceDecorator creates a new EthIncrementSenderSequenceDecorator.
|
||||
func NewEthIncrementSenderSequenceDecorator(ak AccountKeeper) EthIncrementSenderSequenceDecorator {
|
||||
func NewEthIncrementSenderSequenceDecorator(ak evmtypes.AccountKeeper) EthIncrementSenderSequenceDecorator {
|
||||
return EthIncrementSenderSequenceDecorator{
|
||||
ak: ak,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user