forked from cerc-io/laconicd-deprecated
rpc, evm: use binary search to estimate gas (#272)
* do binary search to estimate gas Closes #268 - Also refactor ApplyMessage to be more reuseable move binary search to rpc api side to have a clean context each try remove EstimateGas grpc api * extract BinSearch function and add unit test * do estimateGas in grpc query Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
co-authored by
Federico Kunze Küllmer
parent
072f0534db
commit
14b38af8bc
@@ -550,11 +550,21 @@ func (e *PublicAPI) doCall(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := evmtypes.EthCallRequest{Args: bz}
|
||||
req := evmtypes.EthCallRequest{Args: bz, GasCap: ethermint.DefaultRPCGasLimit}
|
||||
|
||||
// From ContextWithHeight: if the provided height is 0,
|
||||
// it will return an empty context and the gRPC query will use
|
||||
// the latest block height for querying.
|
||||
res, err := e.queryClient.EthCall(rpctypes.ContextWithHeight(blockNr.Int64()), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(res.VmError) > 0 {
|
||||
if res.VmError == vm.ErrExecutionReverted.Error() {
|
||||
return nil, evmtypes.NewExecErrorWithReason(res.Ret)
|
||||
}
|
||||
return nil, errors.New(res.VmError)
|
||||
}
|
||||
|
||||
if res.Failed() {
|
||||
if res.VmError == vm.ErrExecutionReverted.Error() {
|
||||
@@ -567,18 +577,28 @@ func (e *PublicAPI) doCall(
|
||||
}
|
||||
|
||||
// EstimateGas returns an estimate of gas usage for the given smart contract call.
|
||||
func (e *PublicAPI) EstimateGas(args evmtypes.CallArgs) (hexutil.Uint64, error) {
|
||||
func (e *PublicAPI) EstimateGas(args evmtypes.CallArgs, blockNrOptional *rpctypes.BlockNumber) (hexutil.Uint64, error) {
|
||||
e.logger.Debug("eth_estimateGas")
|
||||
|
||||
blockNr := rpctypes.EthPendingBlockNumber
|
||||
if blockNrOptional != nil {
|
||||
blockNr = *blockNrOptional
|
||||
}
|
||||
|
||||
bz, err := json.Marshal(&args)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
req := evmtypes.EthCallRequest{Args: bz, GasCap: ethermint.DefaultRPCGasLimit}
|
||||
|
||||
// From ContextWithHeight: if the provided height is 0,
|
||||
// it will return an empty context and the gRPC query will use
|
||||
// the latest block height for querying.
|
||||
data, err := e.doCall(args, 0)
|
||||
res, err := e.queryClient.EstimateGas(rpctypes.ContextWithHeight(blockNr.Int64()), &req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return hexutil.Uint64(data.GasUsed), nil
|
||||
return hexutil.Uint64(res.Gas), nil
|
||||
}
|
||||
|
||||
// GetBlockByHash returns the block identified by hash.
|
||||
@@ -1027,7 +1047,8 @@ func (e *PublicAPI) setTxDefaults(args rpctypes.SendTxArgs) (rpctypes.SendTxArgs
|
||||
Data: input,
|
||||
AccessList: args.AccessList,
|
||||
}
|
||||
estimated, err := e.EstimateGas(callArgs)
|
||||
blockNr := rpctypes.NewBlockNumber(big.NewInt(0))
|
||||
estimated, err := e.EstimateGas(callArgs, &blockNr)
|
||||
if err != nil {
|
||||
return args, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user