grpc: add eth_call query command (#236)

* add eth_call query command

Implement EthCall grpc query api

Closes #229

add eth_call query command

fix codec issue

use query client

use grpc status error and codes

validate address length in grpc handler

* Update x/evm/types/callargs.go

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
yihuang
2021-07-09 09:04:46 +00:00
committed by GitHub
co-authored by Federico Kunze Küllmer
parent 7951852bb0
commit 0020e4f2cd
13 changed files with 3332 additions and 521 deletions
+32
View File
@@ -2,6 +2,7 @@ package keeper
import (
"context"
"encoding/json"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -364,3 +365,34 @@ func (k Keeper) StaticCall(c context.Context, req *types.QueryStaticCallRequest)
return nil, nil
}
// EthCall implements eth_call rpc api.
func (k Keeper) EthCall(c context.Context, req *types.EthCallRequest) (*types.MsgEthereumTxResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
k.WithContext(ctx)
var args types.CallArgs
err := json.Unmarshal(req.Args, &args)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
msg := args.ToMessage(uint64(ethermint.DefaultRPCGasLimit))
cfg, found := k.GetChainConfig(ctx)
if !found {
return nil, status.Error(codes.Internal, types.ErrChainConfigNotFound.Error())
}
ethCfg := cfg.EthereumConfig(k.eip155ChainID)
evm := k.NewEVM(msg, ethCfg)
res, err := k.ApplyMessage(evm, msg, ethCfg)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
// ApplyMessage don't handle gas refund, let's do it here
refund := k.GasToRefund(res.GasUsed)
res.GasUsed -= refund
return res, nil
}
+12 -7
View File
@@ -258,6 +258,17 @@ func (k *Keeper) GetEthIntrinsicGas(msg core.Message, cfg *params.ChainConfig, i
return core.IntrinsicGas(msg.Data(), msg.AccessList(), isContractCreation, homestead, istanbul)
}
// GasToRefund calculate the amount of gas should refund to sender
func (k *Keeper) GasToRefund(gasConsumed uint64) uint64 {
// Apply refund counter, capped to half of the used gas.
refund := gasConsumed / 2
availableRefund := k.GetRefund()
if refund > availableRefund {
return availableRefund
}
return refund
}
// RefundGas transfers the leftover gas to the sender of the message, caped to half of the total gas
// consumed in the transaction. Additionally, the function sets the total gas consumed to the value
// returned by the EVM execution, thus ignoring the previous intrinsic gas consumed during in the
@@ -271,13 +282,7 @@ func (k *Keeper) RefundGas(msg core.Message, leftoverGas uint64) (uint64, error)
}
gasConsumed := msg.Gas() - leftoverGas
// Apply refund counter, capped to half of the used gas.
refund := gasConsumed / 2
availableRefund := k.GetRefund()
if refund > availableRefund {
refund = availableRefund
}
refund := k.GasToRefund(gasConsumed)
leftoverGas += refund