imp(evm): improve performance of EstimateGas (#1444)
* imp(evm): improve performance of EstimateGas * changelog
This commit is contained in:
parent
b820ff7a2c
commit
89fdd19848
@ -52,6 +52,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
|
* (evm) [#1444](https://github.com/evmos/ethermint/pull/1444) Improve performance of `eth_estimateGas`
|
||||||
* (ante) [\#1388](https://github.com/evmos/ethermint/pull/1388) Optimize AnteHandler gas consumption
|
* (ante) [\#1388](https://github.com/evmos/ethermint/pull/1388) Optimize AnteHandler gas consumption
|
||||||
* (lint) [#1298](https://github.com/evmos/ethermint/pull/1298) 150 character line length limit, `gofumpt`, and linting
|
* (lint) [#1298](https://github.com/evmos/ethermint/pull/1298) 150 character line length limit, `gofumpt`, and linting
|
||||||
* (feemarket) [\#1165](https://github.com/evmos/ethermint/pull/1165) Add hint in specs about different gas terminology in Cosmos and Ethereum.
|
* (feemarket) [\#1165](https://github.com/evmos/ethermint/pull/1165) Add hint in specs about different gas terminology in Cosmos and Ethereum.
|
||||||
|
@ -305,14 +305,31 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
|
|||||||
|
|
||||||
txConfig := statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes()))
|
txConfig := statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes()))
|
||||||
|
|
||||||
// Create a helper to check if a gas allowance results in an executable transaction
|
// convert the tx args to an ethereum message
|
||||||
executable := func(gas uint64) (vmerror bool, rsp *types.MsgEthereumTxResponse, err error) {
|
msg, err := args.ToMessage(req.GasCap, cfg.BaseFee)
|
||||||
args.Gas = (*hexutil.Uint64)(&gas)
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
msg, err := args.ToMessage(req.GasCap, cfg.BaseFee)
|
// NOTE: the errors from the executable below should be consistent with go-ethereum,
|
||||||
if err != nil {
|
// so we don't wrap them with the gRPC status code
|
||||||
return false, nil, err
|
|
||||||
}
|
// Create a helper to check if a gas allowance results in an executable transaction
|
||||||
|
executable := func(gas uint64) (vmError bool, rsp *types.MsgEthereumTxResponse, err error) {
|
||||||
|
// update the message with the new gas value
|
||||||
|
msg = ethtypes.NewMessage(
|
||||||
|
msg.From(),
|
||||||
|
msg.To(),
|
||||||
|
msg.Nonce(),
|
||||||
|
msg.Value(),
|
||||||
|
gas,
|
||||||
|
msg.GasPrice(),
|
||||||
|
msg.GasFeeCap(),
|
||||||
|
msg.GasTipCap(),
|
||||||
|
msg.Data(),
|
||||||
|
msg.AccessList(),
|
||||||
|
msg.IsFake(),
|
||||||
|
)
|
||||||
|
|
||||||
// pass false to not commit StateDB
|
// pass false to not commit StateDB
|
||||||
rsp, err = k.ApplyMessageWithConfig(ctx, msg, nil, false, cfg, txConfig)
|
rsp, err = k.ApplyMessageWithConfig(ctx, msg, nil, false, cfg, txConfig)
|
||||||
@ -328,24 +345,25 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
|
|||||||
// Execute the binary search and hone in on an executable gas limit
|
// Execute the binary search and hone in on an executable gas limit
|
||||||
hi, err = types.BinSearch(lo, hi, executable)
|
hi, err = types.BinSearch(lo, hi, executable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reject the transaction as invalid if it still fails at the highest allowance
|
// Reject the transaction as invalid if it still fails at the highest allowance
|
||||||
if hi == cap {
|
if hi == cap {
|
||||||
failed, result, err := executable(hi)
|
failed, result, err := executable(hi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if failed {
|
if failed {
|
||||||
if result != nil && result.VmError != vm.ErrOutOfGas.Error() {
|
if result != nil && result.VmError != vm.ErrOutOfGas.Error() {
|
||||||
if result.VmError == vm.ErrExecutionReverted.Error() {
|
if result.VmError == vm.ErrExecutionReverted.Error() {
|
||||||
return nil, types.NewExecErrorWithReason(result.Ret)
|
return nil, types.NewExecErrorWithReason(result.Ret)
|
||||||
}
|
}
|
||||||
return nil, status.Error(codes.Internal, result.VmError)
|
return nil, errors.New(result.VmError)
|
||||||
}
|
}
|
||||||
// Otherwise, the specified gas cap is too low
|
// Otherwise, the specified gas cap is too low
|
||||||
return nil, status.Error(codes.Internal, fmt.Sprintf("gas required exceeds allowance (%d)", cap))
|
return nil, fmt.Errorf("gas required exceeds allowance (%d)", cap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &types.EstimateGasResponse{Gas: hi}, nil
|
return &types.EstimateGasResponse{Gas: hi}, nil
|
||||||
|
Loading…
Reference in New Issue
Block a user