fix: use EffectiveGasPrice in ante handler for dynamic fee tx (#817)

* Use effectiveGasPrice in ante handler for dynamic fee tx

Closes: #814

Solution:
- use effectiveGasPrice when check minimal-gas-prices, and deduct fee in ante handler
- implement an EthMempoolFeeDecorator

* add effectiveGasPrice to tx receipt

* changelog

* fix unit test

* fix comments

* add comments

* Apply suggestions from code review

Co-authored-by: Thomas Nguy <81727899+thomas-nguy@users.noreply.github.com>

* review suggestions

Co-authored-by: Thomas Nguy <81727899+thomas-nguy@users.noreply.github.com>
Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
yihuang
2021-12-15 02:17:03 +00:00
committed by GitHub
co-authored by Thomas Nguy Federico Kunze Küllmer
parent 50e463725e
commit ccc6f5b53d
12 changed files with 145 additions and 31 deletions
+5 -11
View File
@@ -9,7 +9,6 @@ import (
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"
)
@@ -54,24 +53,19 @@ func (k Keeper) DeductTxCostsFromUserBalance(
)
}
// calculate the fees paid to validators based on the effective tip and price
effectiveTip := txData.GetGasPrice()
var feeAmt *big.Int
feeMktParams := k.feeMarketKeeper.GetParams(ctx)
if london && !feeMktParams.NoBaseFee && txData.TxType() == ethtypes.DynamicFeeTxType {
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
gasFeeGap := new(big.Int).Sub(txData.GetGasFeeCap(), baseFee)
if gasFeeGap.Sign() == -1 {
if txData.GetGasFeeCap().Cmp(baseFee) < 0 {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "the tx gasfeecap is lower than the tx baseFee: %s (gasfeecap), %s (basefee) ", txData.GetGasFeeCap(), baseFee)
}
effectiveTip = cmath.BigMin(txData.GetGasTipCap(), gasFeeGap)
feeAmt = txData.EffectiveFee(baseFee)
} else {
feeAmt = txData.Fee()
}
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
+8 -11
View File
@@ -5,7 +5,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
cmath "github.com/ethereum/go-ethereum/common/math"
ethtypes "github.com/ethereum/go-ethereum/core/types"
ethparams "github.com/ethereum/go-ethereum/params"
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
@@ -257,7 +256,9 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() {
oneInt := sdk.NewInt(1)
fiveInt := sdk.NewInt(5)
fiftyInt := sdk.NewInt(50)
hundredBaseFeeInt := sdk.NewInt(ethparams.InitialBaseFee * 100)
// should be enough to cover all test cases
initBalance := sdk.NewInt((ethparams.InitialBaseFee + 10) * 105)
testCases := []struct {
name string
@@ -331,15 +332,14 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() {
expectPass: false,
dynamicTxFee: true,
},
// TODO: is this case valid?
{
name: "empty fee failed to deduct",
name: "empty tip fee is valid to deduct",
gasLimit: 10,
gasFeeCap: big.NewInt(ethparams.InitialBaseFee),
gasTipCap: big.NewInt(1),
cost: &oneInt,
accessList: &ethtypes.AccessList{},
expectPass: false,
expectPass: true,
dynamicTxFee: true,
},
{
@@ -382,9 +382,9 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() {
} else {
gasTipCap = tc.gasTipCap
}
suite.app.EvmKeeper.AddBalance(suite.address, hundredBaseFeeInt.BigInt())
suite.app.EvmKeeper.AddBalance(suite.address, initBalance.BigInt())
balance := suite.app.EvmKeeper.GetBalance(suite.address)
suite.Require().Equal(balance, hundredBaseFeeInt.BigInt())
suite.Require().Equal(balance, initBalance.BigInt())
} else {
if tc.gasPrice != nil {
gasPrice = tc.gasPrice.BigInt()
@@ -414,13 +414,10 @@ func (suite *KeeperTestSuite) TestDeductTxCostsFromUserBalance() {
suite.Require().NoError(err, "valid test %d failed", i)
if tc.dynamicTxFee {
baseFee := suite.app.FeeMarketKeeper.GetBaseFee(suite.ctx)
gasFeeGap := new(big.Int).Sub(txData.GetGasFeeCap(), baseFee)
effectiveTip := cmath.BigMin(txData.GetGasTipCap(), gasFeeGap)
suite.Require().Equal(
fees,
sdk.NewCoins(
sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(effectiveTip).Mul(sdk.NewIntFromUint64(tc.gasLimit))),
sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(txData.EffectiveFee(baseFee))),
),
"valid test %d failed, fee value is wrong ", i,
)