From 67e4ec590d0db5291da1bc4df1e846e295788748 Mon Sep 17 00:00:00 2001 From: zakir <80246097+zakir-code@users.noreply.github.com> Date: Mon, 28 Oct 2024 16:05:05 +0800 Subject: [PATCH] refactor: skip 'from' account verification during contract query --- contract/contract.go | 6 ++--- x/crosschain/keeper/bridge_call_in.go | 2 +- x/crosschain/mock/expected_keepers_mocks.go | 12 ++++----- x/crosschain/types/expected_keepers.go | 2 +- x/evm/keeper/contract_code.go | 15 +++++++---- x/evm/keeper/keeper.go | 28 +++++++++++++-------- x/evm/keeper/msg_server.go | 6 ++++- x/evm/testutil/evm.go | 2 +- x/ibc/middleware/keeper/ibc_call.go | 4 +-- x/ibc/middleware/types/expected_keepers.go | 2 +- 10 files changed, 47 insertions(+), 32 deletions(-) diff --git a/contract/contract.go b/contract/contract.go index a2e2cdc3..d4c10b44 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -1,10 +1,10 @@ package contract import ( + "context" "math/big" "strings" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -48,8 +48,8 @@ var ( ) type Caller interface { - QueryContract(ctx sdk.Context, from, contract common.Address, abi abi.ABI, method string, res interface{}, args ...interface{}) error - ApplyContract(ctx sdk.Context, from, contract common.Address, value *big.Int, abi abi.ABI, method string, constructorData ...interface{}) (*evmtypes.MsgEthereumTxResponse, error) + QueryContract(ctx context.Context, from, contract common.Address, abi abi.ABI, method string, res interface{}, args ...interface{}) error + ApplyContract(ctx context.Context, from, contract common.Address, value *big.Int, abi abi.ABI, method string, constructorData ...interface{}) (*evmtypes.MsgEthereumTxResponse, error) } type Contract struct { diff --git a/x/crosschain/keeper/bridge_call_in.go b/x/crosschain/keeper/bridge_call_in.go index c457dcad..f80fe816 100644 --- a/x/crosschain/keeper/bridge_call_in.go +++ b/x/crosschain/keeper/bridge_call_in.go @@ -105,7 +105,7 @@ func (k Keeper) BridgeCallEvm(ctx sdk.Context, sender, refundAddr, to, receiverA } gasLimit := k.GetBridgeCallMaxGasLimit(ctx) - txResp, err := k.evmKeeper.CallEVM(ctx, callEvmSender, &to, value.BigInt(), gasLimit, args, true) + txResp, err := k.evmKeeper.ExecuteEVM(ctx, callEvmSender, &to, value.BigInt(), gasLimit, args) if err != nil { return err } diff --git a/x/crosschain/mock/expected_keepers_mocks.go b/x/crosschain/mock/expected_keepers_mocks.go index a823c729..0dc2d573 100644 --- a/x/crosschain/mock/expected_keepers_mocks.go +++ b/x/crosschain/mock/expected_keepers_mocks.go @@ -530,19 +530,19 @@ func (m *MockEVMKeeper) EXPECT() *MockEVMKeeperMockRecorder { return m.recorder } -// CallEVM mocks base method. -func (m *MockEVMKeeper) CallEVM(ctx types.Context, from common.Address, contract *common.Address, value *big.Int, gasLimit uint64, data []byte, commit bool) (*types3.MsgEthereumTxResponse, error) { +// ExecuteEVM mocks base method. +func (m *MockEVMKeeper) ExecuteEVM(ctx types.Context, from common.Address, contract *common.Address, value *big.Int, gasLimit uint64, data []byte) (*types3.MsgEthereumTxResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CallEVM", ctx, from, contract, value, gasLimit, data, commit) + ret := m.ctrl.Call(m, "ExecuteEVM", ctx, from, contract, value, gasLimit, data) ret0, _ := ret[0].(*types3.MsgEthereumTxResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// CallEVM indicates an expected call of CallEVM. -func (mr *MockEVMKeeperMockRecorder) CallEVM(ctx, from, contract, value, gasLimit, data, commit any) *gomock.Call { +// ExecuteEVM indicates an expected call of ExecuteEVM. +func (mr *MockEVMKeeperMockRecorder) ExecuteEVM(ctx, from, contract, value, gasLimit, data any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallEVM", reflect.TypeOf((*MockEVMKeeper)(nil).CallEVM), ctx, from, contract, value, gasLimit, data, commit) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecuteEVM", reflect.TypeOf((*MockEVMKeeper)(nil).ExecuteEVM), ctx, from, contract, value, gasLimit, data) } // IsContract mocks base method. diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index ea3a2828..b295fbc9 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -64,7 +64,7 @@ type Erc20Keeper interface { // EVMKeeper defines the expected EVM keeper interface used on crosschain type EVMKeeper interface { - CallEVM(ctx sdk.Context, from common.Address, contract *common.Address, value *big.Int, gasLimit uint64, data []byte, commit bool) (*types.MsgEthereumTxResponse, error) + ExecuteEVM(ctx sdk.Context, from common.Address, contract *common.Address, value *big.Int, gasLimit uint64, data []byte) (*types.MsgEthereumTxResponse, error) IsContract(ctx sdk.Context, account common.Address) bool } diff --git a/x/evm/keeper/contract_code.go b/x/evm/keeper/contract_code.go index 6b70dc9e..a055bc3a 100644 --- a/x/evm/keeper/contract_code.go +++ b/x/evm/keeper/contract_code.go @@ -2,6 +2,7 @@ package keeper import ( "bytes" + "context" "encoding/hex" "math/big" @@ -79,7 +80,7 @@ func (k *Keeper) DeployContract(ctx sdk.Context, from common.Address, abi abi.AB return common.Address{}, err } - _, err = k.CallEVMWithoutGas(ctx, from, nil, nil, data, true) + _, err = k.callEvm(ctx, from, nil, nil, nonce, data, true) if err != nil { return common.Address{}, err } @@ -110,12 +111,12 @@ func (k *Keeper) DeployUpgradableContract(ctx sdk.Context, from, logic common.Ad } // QueryContract query contract with args and res -func (k *Keeper) QueryContract(ctx sdk.Context, from, contract common.Address, abi abi.ABI, method string, res interface{}, args ...interface{}) error { +func (k *Keeper) QueryContract(ctx context.Context, from, contract common.Address, abi abi.ABI, method string, res interface{}, args ...interface{}) error { data, err := abi.Pack(method, args...) if err != nil { return types.ErrABIPack.Wrap(err.Error()) } - resp, err := k.CallEVMWithoutGas(ctx, from, &contract, nil, data, false) + resp, err := k.callEvm(sdk.UnwrapSDKContext(ctx), from, &contract, nil, 0, data, false) if err != nil { return err } @@ -126,12 +127,16 @@ func (k *Keeper) QueryContract(ctx sdk.Context, from, contract common.Address, a } // ApplyContract apply contract with args -func (k *Keeper) ApplyContract(ctx sdk.Context, from, contract common.Address, value *big.Int, abi abi.ABI, method string, constructorData ...interface{}) (*evmtypes.MsgEthereumTxResponse, error) { +func (k *Keeper) ApplyContract(ctx context.Context, from, contract common.Address, value *big.Int, abi abi.ABI, method string, constructorData ...interface{}) (*evmtypes.MsgEthereumTxResponse, error) { args, err := abi.Pack(method, constructorData...) if err != nil { return nil, types.ErrABIPack.Wrap(err.Error()) } - resp, err := k.CallEVMWithoutGas(ctx, from, &contract, value, args, true) + nonce, err := k.accountKeeper.GetSequence(ctx, from.Bytes()) + if err != nil { + return nil, err + } + resp, err := k.callEvm(sdk.UnwrapSDKContext(ctx), from, &contract, value, nonce, args, true) if err != nil { return nil, err } diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index ab7fbf06..fbbd2193 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -43,7 +43,7 @@ func NewKeeper(ek *evmkeeper.Keeper, ak fxevmtypes.AccountKeeper) *Keeper { } } -// CallEVMWithoutGas performs a smart contract method call using contract data without gas +// Deprecated: please use callEvm todo: remove this func (k *Keeper) CallEVMWithoutGas( ctx sdk.Context, from common.Address, @@ -52,13 +52,24 @@ func (k *Keeper) CallEVMWithoutGas( data []byte, commit bool, ) (*types.MsgEthereumTxResponse, error) { - gasMeter := ctx.GasMeter() - ctx = ctx.WithGasMeter(storetypes.NewInfiniteGasMeter()) - nonce, err := k.accountKeeper.GetSequence(ctx, from.Bytes()) if err != nil { return nil, err } + return k.callEvm(ctx, from, contract, value, nonce, data, commit) +} + +func (k *Keeper) callEvm( + ctx sdk.Context, + from common.Address, + contract *common.Address, + value *big.Int, + nonce uint64, + data []byte, + commit bool, +) (*types.MsgEthereumTxResponse, error) { + gasMeter := ctx.GasMeter() + ctx = ctx.WithGasMeter(storetypes.NewInfiniteGasMeter()) gasLimit := fxcontract.DefaultGasCap params := ctx.ConsensusParams() @@ -103,14 +114,13 @@ func (k *Keeper) CallEVMWithoutGas( return res, nil } -func (k *Keeper) CallEVM( +func (k *Keeper) ExecuteEVM( ctx sdk.Context, from common.Address, contract *common.Address, value *big.Int, gasLimit uint64, data []byte, - commit bool, ) (*types.MsgEthereumTxResponse, error) { gasMeter := ctx.GasMeter() ctx = ctx.WithGasMeter(storetypes.NewInfiniteGasMeter()) @@ -119,10 +129,6 @@ func (k *Keeper) CallEVM( if err != nil { return nil, err } - params := ctx.ConsensusParams() - if params.Block != nil && params.Block.MaxGas > 0 { - gasLimit = uint64(params.Block.MaxGas) - } if value == nil { value = big.NewInt(0) @@ -141,7 +147,7 @@ func (k *Keeper) CallEVM( SkipAccountChecks: false, } - res, err := k.ApplyMessage(ctx, msg, types.NewNoOpTracer(), commit) + res, err := k.ApplyMessage(ctx, msg, types.NewNoOpTracer(), true) if err != nil { return nil, err } diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index 7b3dbd36..f73b9642 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -24,7 +24,11 @@ func (k *Keeper) CallContract(goCtx context.Context, msg *fxevmtypes.MsgCallCont if account == nil || !account.IsContract() { return nil, govtypes.ErrInvalidProposalMsg.Wrapf("contract %s not found", contract.Hex()) } - _, err := k.CallEVMWithoutGas(ctx, k.module, &contract, nil, common.Hex2Bytes(msg.Data), true) + nonce, err := k.accountKeeper.GetSequence(ctx, k.module.Bytes()) + if err != nil { + return nil, err + } + _, err = k.callEvm(ctx, k.module, &contract, nil, nonce, common.Hex2Bytes(msg.Data), true) if err != nil { return nil, err } diff --git a/x/evm/testutil/evm.go b/x/evm/testutil/evm.go index 1b53b637..f98258ff 100644 --- a/x/evm/testutil/evm.go +++ b/x/evm/testutil/evm.go @@ -80,7 +80,7 @@ func (s *EVMSuite) Call(abi abi.ABI, method string, res interface{}, args ...int } func (s *EVMSuite) CallEVM(data []byte, gasLimit uint64) *evmtypes.MsgEthereumTxResponse { - tx, err := s.evmKeeper.CallEVM(s.ctx, s.GetFrom(), &s.contractAddr, nil, gasLimit, data, false) + tx, err := s.evmKeeper.ExecuteEVM(s.ctx, s.GetFrom(), &s.contractAddr, nil, gasLimit, data) s.NoError(err) return tx } diff --git a/x/ibc/middleware/keeper/ibc_call.go b/x/ibc/middleware/keeper/ibc_call.go index e5857513..71cfc6d3 100644 --- a/x/ibc/middleware/keeper/ibc_call.go +++ b/x/ibc/middleware/keeper/ibc_call.go @@ -45,8 +45,8 @@ func (k Keeper) HandlerIbcCallEvm(ctx sdk.Context, sender common.Address, evmPac } ctx.EventManager().EmitEvent(sdk.NewEvent(types.EventTypeIBCCall, attrs...)) }() - txResp, err := k.evmKeeper.CallEVM(ctx, sender, - evmPacket.GetToAddress(), evmPacket.Value.BigInt(), uint64(limit), evmPacket.MustGetData(), true) + txResp, err := k.evmKeeper.ExecuteEVM(ctx, sender, + evmPacket.GetToAddress(), evmPacket.Value.BigInt(), uint64(limit), evmPacket.MustGetData()) if err != nil { evmErrCause = err.Error() return err diff --git a/x/ibc/middleware/types/expected_keepers.go b/x/ibc/middleware/types/expected_keepers.go index 4dc8b584..92b4372f 100644 --- a/x/ibc/middleware/types/expected_keepers.go +++ b/x/ibc/middleware/types/expected_keepers.go @@ -9,7 +9,7 @@ import ( ) type EvmKeeper interface { - CallEVM(ctx sdk.Context, from common.Address, contract *common.Address, value *big.Int, gasLimit uint64, data []byte, commit bool) (*evmtypes.MsgEthereumTxResponse, error) + ExecuteEVM(ctx sdk.Context, from common.Address, contract *common.Address, value *big.Int, gasLimit uint64, data []byte) (*evmtypes.MsgEthereumTxResponse, error) } type CrosschainKeeper interface {