Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix multiple results returned by eth_estimateGas #3223

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 13 additions & 70 deletions app/rpc/namespaces/eth/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/vm"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/spf13/viper"

Expand All @@ -20,7 +19,6 @@ import (
sdkerror "github.com/okex/exchain/libs/cosmos-sdk/types/errors"
authexported "github.com/okex/exchain/libs/cosmos-sdk/x/auth/exported"
"github.com/okex/exchain/libs/cosmos-sdk/x/supply"
"github.com/okex/exchain/x/evm/types"
"github.com/okex/exchain/x/token"
wasmkeeper "github.com/okex/exchain/x/wasm/keeper"
wasmtypes "github.com/okex/exchain/x/wasm/types"
Expand All @@ -40,7 +38,7 @@ const (
RPCNullData = "null"
)

//gasPrice: to get "minimum-gas-prices" config or to get ethermint.DefaultGasPrice
// gasPrice: to get "minimum-gas-prices" config or to get ethermint.DefaultGasPrice
func ParseGasPrice() *hexutil.Big {
gasPrices, err := sdk.ParseDecCoins(viper.GetString(server.FlagMinGasPrices))
if err == nil && gasPrices != nil && len(gasPrices) > 0 {
Expand Down Expand Up @@ -144,83 +142,28 @@ func TransformDataError(err error, method string) error {
data: RPCNullData,
}
}
m, retErr := preProcessError(realErr, err.Error())
if retErr != nil {
return realErr
}
//if there have multi error type of EVM, this need a reactor mode to process error
revert, f := m[vm.ErrExecutionReverted.Error()]
if !f {
revert = RPCUnknowErr
}
data, f := m[types.ErrorHexData]
if !f {
data = RPCNullData
}
switch method {
case RPCEthEstimateGas:
return DataError{
code: VMExecuteExceptionInEstimate,
Msg: revert,
data: data,
}
case RPCEthCall:
return DataError{
code: VMExecuteException,
Msg: revert,
data: newDataError(revert, data),
}
default:
return DataError{
code: DefaultEVMErrorCode,
Msg: revert,
data: newDataError(revert, data),
}
}
return preProcessError(realErr, err.Error())
}

//Preprocess error string, the string of realErr.Log is most like:
//`["execution reverted","message","HexData","0x00000000000"];some failed information`
//we need marshalled json slice from realErr.Log and using segment tag `[` and `]` to cut it
func preProcessError(realErr *cosmosError, origErrorMsg string) (map[string]string, error) {
var logs []string
lastSeg := strings.LastIndexAny(realErr.Log, "]")
// realErr is a cosmosError, which is formatted from wrappedError. Msgs are concatenated with ':' between each of them
// Main cause always appears in the first place, thus this function only get the first part of the error out of realErr.
func preProcessError(realErr *cosmosError, origErrorMsg string) error {
lastSeg := strings.IndexAny(realErr.Log, ":")
if lastSeg < 0 {
return nil, DataError{
code: DefaultEVMErrorCode,
Msg: origErrorMsg,
data: RPCNullData,
}
}
marshaler := realErr.Log[0 : lastSeg+1]
e := json.Unmarshal([]byte(marshaler), &logs)
if e != nil {
return nil, DataError{
code: DefaultEVMErrorCode,
Msg: origErrorMsg,
data: RPCNullData,
}
}
m := genericStringMap(logs)
if m == nil {
return nil, DataError{
return DataError{
code: DefaultEVMErrorCode,
Msg: origErrorMsg,
data: RPCNullData,
}
}
return m, nil
}

func genericStringMap(s []string) map[string]string {
var ret = make(map[string]string)
if len(s)%2 != 0 {
return nil
}
for i := 0; i < len(s); i += 2 {
ret[s[i]] = s[i+1]
errorSeg := realErr.Log[0:lastSeg]

return DataError{
code: DefaultEVMErrorCode,
Msg: errorSeg,
data: RPCNullData,
}
return ret
}

func CheckError(txRes sdk.TxResponse) (common.Hash, error) {
Expand Down
13 changes: 7 additions & 6 deletions app/rpc/namespaces/eth/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import (

func Test_TransformDataError(t *testing.T) {

sdkerr := newWrappedCosmosError(7, `["execution reverted","message","HexData","0x00000000000"];failed message tail`, evmtypes.ModuleName)
sdkerr := newWrappedCosmosError(7, `["execution reverted","message","HexData","0x00000000000"]:failed message tail`, evmtypes.ModuleName)
err := TransformDataError(sdkerr, "eth_estimateGas").(DataError)
require.NotNil(t, err.ErrorData())
require.Equal(t, err.ErrorData(), "0x00000000000")
require.Equal(t, err.ErrorCode(), VMExecuteExceptionInEstimate)
require.Equal(t, err.Error(), `["execution reverted","message","HexData","0x00000000000"]`)
require.Equal(t, err.ErrorData(), RPCNullData)
require.Equal(t, err.ErrorCode(), DefaultEVMErrorCode)
err = TransformDataError(sdkerr, "eth_call").(DataError)
require.NotNil(t, err.ErrorData())
data, ok := err.ErrorData().(*wrappedEthError)
require.True(t, ok)
require.NotNil(t, data)
require.Equal(t, err.Error(), `["execution reverted","message","HexData","0x00000000000"]`)
require.Equal(t, err.ErrorData(), RPCNullData)
require.Equal(t, err.ErrorCode(), DefaultEVMErrorCode)
}
Loading