forked from cerc-io/laconicd-deprecated
ante: check EnableCreate
/EnableCall
in ante handler (#1060)
* Check EnableCreate/EnableCall in ante handler WIP: #1045 Reject tx early in ante handler, avoid deduct user fee for vain. * add unit tests * update changelog Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <federico.kunze94@gmail.com>
This commit is contained in:
parent
6b1b936c64
commit
93d15db4d0
@ -38,6 +38,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### State Machine Breaking
|
||||||
|
|
||||||
|
* (ante) [tharsis#1060](https://github.com/tharsis/ethermint/pull/1060) Check `EnableCreate`/`EnableCall` in `AnteHandler` to short-circuit EVM transactions.
|
||||||
|
|
||||||
### API Breaking
|
### API Breaking
|
||||||
|
|
||||||
* (rpc) [tharsis#1070](https://github.com/tharsis/ethermint/pull/1070) Refactor `rpc/` package:
|
* (rpc) [tharsis#1070](https://github.com/tharsis/ethermint/pull/1070) Refactor `rpc/` package:
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package ante_test
|
package ante_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
@ -685,3 +687,136 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
|
|||||||
suite.enableFeemarket = false
|
suite.enableFeemarket = false
|
||||||
suite.enableLondonHF = true
|
suite.enableLondonHF = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite AnteTestSuite) TestAnteHandlerWithParams() {
|
||||||
|
addr, privKey := tests.NewAddrKey()
|
||||||
|
to := tests.GenerateAddress()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
txFn func() sdk.Tx
|
||||||
|
enableCall bool
|
||||||
|
enableCreate bool
|
||||||
|
expErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"fail - Contract Creation Disabled",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedContractTx :=
|
||||||
|
evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedContractTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true, false,
|
||||||
|
evmtypes.ErrCreateDisabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - Contract Creation Enabled",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedContractTx :=
|
||||||
|
evmtypes.NewTxContract(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedContractTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedContractTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true, true,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail - EVM Call Disabled",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedTx :=
|
||||||
|
evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
false, true,
|
||||||
|
evmtypes.ErrCallDisabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"success - EVM Call Enabled",
|
||||||
|
func() sdk.Tx {
|
||||||
|
signedTx :=
|
||||||
|
evmtypes.NewTx(
|
||||||
|
suite.app.EvmKeeper.ChainID(),
|
||||||
|
1,
|
||||||
|
&to,
|
||||||
|
big.NewInt(10),
|
||||||
|
100000,
|
||||||
|
nil,
|
||||||
|
big.NewInt(ethparams.InitialBaseFee+1),
|
||||||
|
big.NewInt(1),
|
||||||
|
nil,
|
||||||
|
&types.AccessList{},
|
||||||
|
)
|
||||||
|
signedTx.From = addr.Hex()
|
||||||
|
|
||||||
|
tx := suite.CreateTestTx(signedTx, privKey, 1, false)
|
||||||
|
return tx
|
||||||
|
},
|
||||||
|
true, true,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
suite.Run(tc.name, func() {
|
||||||
|
suite.evmParamsOption = func(params *evmtypes.Params) {
|
||||||
|
params.EnableCall = tc.enableCall
|
||||||
|
params.EnableCreate = tc.enableCreate
|
||||||
|
}
|
||||||
|
suite.SetupTest() // reset
|
||||||
|
|
||||||
|
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
|
||||||
|
suite.Require().NoError(acc.SetSequence(1))
|
||||||
|
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
||||||
|
|
||||||
|
suite.ctx = suite.ctx.WithIsCheckTx(true)
|
||||||
|
suite.app.EvmKeeper.SetBalance(suite.ctx, addr, big.NewInt((ethparams.InitialBaseFee+10)*100000))
|
||||||
|
_, err := suite.anteHandler(suite.ctx, tc.txFn(), false)
|
||||||
|
if tc.expErr == nil {
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
} else {
|
||||||
|
suite.Require().Error(err)
|
||||||
|
suite.Require().True(errors.Is(err, tc.expErr))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
suite.evmParamsOption = nil
|
||||||
|
}
|
||||||
|
@ -410,11 +410,17 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
|
|||||||
txFee := sdk.Coins{}
|
txFee := sdk.Coins{}
|
||||||
txGasLimit := uint64(0)
|
txGasLimit := uint64(0)
|
||||||
|
|
||||||
|
params := vbd.evmKeeper.GetParams(ctx)
|
||||||
|
chainID := vbd.evmKeeper.ChainID()
|
||||||
|
ethCfg := params.ChainConfig.EthereumConfig(chainID)
|
||||||
|
baseFee := vbd.evmKeeper.GetBaseFee(ctx, ethCfg)
|
||||||
|
|
||||||
for _, msg := range protoTx.GetMsgs() {
|
for _, msg := range protoTx.GetMsgs() {
|
||||||
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
txGasLimit += msgEthTx.GetGas()
|
txGasLimit += msgEthTx.GetGas()
|
||||||
|
|
||||||
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
|
||||||
@ -422,10 +428,13 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
|
|||||||
return ctx, sdkerrors.Wrap(err, "failed to unpack MsgEthereumTx Data")
|
return ctx, sdkerrors.Wrap(err, "failed to unpack MsgEthereumTx Data")
|
||||||
}
|
}
|
||||||
|
|
||||||
params := vbd.evmKeeper.GetParams(ctx)
|
// return error if contract creation or call are disabled through governance
|
||||||
chainID := vbd.evmKeeper.ChainID()
|
if !params.EnableCreate && txData.GetTo() == nil {
|
||||||
ethCfg := params.ChainConfig.EthereumConfig(chainID)
|
return ctx, sdkerrors.Wrap(evmtypes.ErrCreateDisabled, "failed to create new contract")
|
||||||
baseFee := vbd.evmKeeper.GetBaseFee(ctx, ethCfg)
|
} else if !params.EnableCall && txData.GetTo() != nil {
|
||||||
|
return ctx, sdkerrors.Wrap(evmtypes.ErrCallDisabled, "failed to call contract")
|
||||||
|
}
|
||||||
|
|
||||||
if baseFee == nil && txData.TxType() == ethtypes.DynamicFeeTxType {
|
if baseFee == nil && txData.TxType() == ethtypes.DynamicFeeTxType {
|
||||||
return ctx, sdkerrors.Wrap(ethtypes.ErrTxTypeNotSupported, "dynamic fee tx not supported")
|
return ctx, sdkerrors.Wrap(ethtypes.ErrTxTypeNotSupported, "dynamic fee tx not supported")
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ type AnteTestSuite struct {
|
|||||||
ethSigner ethtypes.Signer
|
ethSigner ethtypes.Signer
|
||||||
enableFeemarket bool
|
enableFeemarket bool
|
||||||
enableLondonHF bool
|
enableLondonHF bool
|
||||||
|
evmParamsOption func(*evmtypes.Params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *AnteTestSuite) StateDB() *statedb.StateDB {
|
func (suite *AnteTestSuite) StateDB() *statedb.StateDB {
|
||||||
@ -71,14 +72,17 @@ func (suite *AnteTestSuite) SetupTest() {
|
|||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
genesis[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
|
genesis[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
|
||||||
}
|
}
|
||||||
|
evmGenesis := evmtypes.DefaultGenesisState()
|
||||||
if !suite.enableLondonHF {
|
if !suite.enableLondonHF {
|
||||||
evmGenesis := evmtypes.DefaultGenesisState()
|
|
||||||
maxInt := sdk.NewInt(math.MaxInt64)
|
maxInt := sdk.NewInt(math.MaxInt64)
|
||||||
evmGenesis.Params.ChainConfig.LondonBlock = &maxInt
|
evmGenesis.Params.ChainConfig.LondonBlock = &maxInt
|
||||||
evmGenesis.Params.ChainConfig.ArrowGlacierBlock = &maxInt
|
evmGenesis.Params.ChainConfig.ArrowGlacierBlock = &maxInt
|
||||||
evmGenesis.Params.ChainConfig.MergeForkBlock = &maxInt
|
evmGenesis.Params.ChainConfig.MergeForkBlock = &maxInt
|
||||||
genesis[evmtypes.ModuleName] = app.AppCodec().MustMarshalJSON(evmGenesis)
|
|
||||||
}
|
}
|
||||||
|
if suite.evmParamsOption != nil {
|
||||||
|
suite.evmParamsOption(&evmGenesis.Params)
|
||||||
|
}
|
||||||
|
genesis[evmtypes.ModuleName] = app.AppCodec().MustMarshalJSON(evmGenesis)
|
||||||
return genesis
|
return genesis
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user