laconicd-deprecated/x/evm/keeper/utils.go
Federico Kunze Küllmer a8722655bb
all: bump go-ethereum to v1.10.9 (#231)
* all: bump go-ethereum to v1.10.4

* build

* state transition and rpc

* wip rpc changes

* fix refund

* fixes

* no base fee param

* ante handler

* undo change

* fix test

* bump deps

* calculate base fee

* gRPC base fee query

* update RPC

* fix

* update'

* go.mod

* fix build

* fix panic

* rm changes in third_party

* json rpc changes

* reserved fields

* fixes fixes fixes

* rm no stringer

* fixes 2

* tests wip

* bump geth version

* update

* grpc traceTx

* rm fee market from ante

* fix TransactionArgs

* lint

* update proto

* update tx args

* changelog
2021-10-05 15:38:20 +00:00

117 lines
3.5 KiB
Go

package keeper
import (
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/palantir/stacktrace"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
cmath "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
// DeductTxCostsFromUserBalance it calculates the tx costs and deducts the fees
func (k Keeper) DeductTxCostsFromUserBalance(
ctx sdk.Context,
msgEthTx evmtypes.MsgEthereumTx,
txData evmtypes.TxData,
denom string,
homestead, istanbul, london bool,
) (sdk.Coins, error) {
isContractCreation := txData.GetTo() == nil
// fetch sender account from signature
signerAcc, err := authante.GetSignerAcc(ctx, k.accountKeeper, msgEthTx.GetFrom())
if err != nil {
return nil, 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 nil, 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 nil, sdkerrors.Wrapf(
sdkerrors.ErrOutOfGas,
"gas limit too low: %d (gas limit) < %d (intrinsic gas)", gasLimit, intrinsicGas,
)
}
// calculate the fees paid to validators based on the effective tip and price
effectiveTip := txData.GetGasPrice()
feeMktParams := k.feeMarketKeeper.GetParams(ctx)
if london && !feeMktParams.NoBaseFee && txData.TxType() == ethtypes.DynamicFeeTxType {
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
effectiveTip = cmath.BigMin(txData.GetGasTipCap(), new(big.Int).Sub(txData.GetGasFeeCap(), baseFee))
}
gasUsed := new(big.Int).SetUint64(txData.GetGas())
feeAmt := new(big.Int).Mul(gasUsed, effectiveTip)
fees := sdk.Coins{sdk.NewCoin(denom, sdk.NewIntFromBigInt(feeAmt))}
// deduct the full gas cost from the user balance
if err := authante.DeductFees(k.bankKeeper, ctx, signerAcc, fees); err != nil {
return nil, stacktrace.Propagate(
err,
"failed to deduct full gas cost %s from the user %s balance",
fees, msgEthTx.From,
)
}
return fees, nil
}
// CheckSenderBalance validates that the tx cost value is positive and that the
// sender has enough funds to pay for the fees and value of the transaction.
func CheckSenderBalance(
ctx sdk.Context,
bankKeeper evmtypes.BankKeeper,
sender sdk.AccAddress,
txData evmtypes.TxData,
denom string,
) error {
balance := bankKeeper.GetBalance(ctx, sender, denom)
cost := txData.Cost()
if cost.Sign() < 0 {
return stacktrace.Propagate(
sdkerrors.Wrapf(
sdkerrors.ErrInvalidCoins,
"tx cost (%s%s) is negative and invalid", cost, denom,
),
"tx cost amount should never be negative")
}
if balance.IsNegative() || balance.Amount.BigInt().Cmp(cost) < 0 {
return stacktrace.Propagate(
sdkerrors.Wrapf(
sdkerrors.ErrInsufficientFunds,
"sender balance < tx cost (%s < %s%s)", balance, txData.Cost(), denom,
),
"sender should have had enough funds to pay for tx cost = fee + amount (%s = %s + %s)",
cost, txData.Fee(), txData.GetValue(),
)
}
return nil
}