parent
34c2593e43
commit
561d5db985
@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
||||||
|
* (evm) [tharsis#613](https://github.com/tharsis/ethermint/pull/613) Refactor `traceTx`
|
||||||
* (deps) [tharsis#610](https://github.com/tharsis/ethermint/pull/610) Bump Cosmos SDK to [v0.44.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.1).
|
* (deps) [tharsis#610](https://github.com/tharsis/ethermint/pull/610) Bump Cosmos SDK to [v0.44.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.1).
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
@ -208,6 +208,10 @@ func (k Keeper) Params(c context.Context, _ *types.QueryParamsRequest) (*types.Q
|
|||||||
|
|
||||||
// EthCall implements eth_call rpc api.
|
// EthCall implements eth_call rpc api.
|
||||||
func (k Keeper) EthCall(c context.Context, req *types.EthCallRequest) (*types.MsgEthereumTxResponse, error) {
|
func (k Keeper) EthCall(c context.Context, req *types.EthCallRequest) (*types.MsgEthereumTxResponse, error) {
|
||||||
|
if req == nil {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||||
|
}
|
||||||
|
|
||||||
ctx := sdk.UnwrapSDKContext(c)
|
ctx := sdk.UnwrapSDKContext(c)
|
||||||
k.WithContext(ctx)
|
k.WithContext(ctx)
|
||||||
|
|
||||||
@ -242,6 +246,10 @@ func (k Keeper) EthCall(c context.Context, req *types.EthCallRequest) (*types.Ms
|
|||||||
|
|
||||||
// EstimateGas implements eth_estimateGas rpc api.
|
// EstimateGas implements eth_estimateGas rpc api.
|
||||||
func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*types.EstimateGasResponse, error) {
|
func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*types.EstimateGasResponse, error) {
|
||||||
|
if req == nil {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||||
|
}
|
||||||
|
|
||||||
ctx := sdk.UnwrapSDKContext(c)
|
ctx := sdk.UnwrapSDKContext(c)
|
||||||
k.WithContext(ctx)
|
k.WithContext(ctx)
|
||||||
|
|
||||||
@ -275,7 +283,7 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Recap the highest gas limit with account's available balance.
|
// TODO: Recap the highest gas limit with account's available balance.
|
||||||
|
|
||||||
// Recap the highest gas allowance with specified gascap.
|
// Recap the highest gas allowance with specified gascap.
|
||||||
if req.GasCap != 0 && hi > req.GasCap {
|
if req.GasCap != 0 && hi > req.GasCap {
|
||||||
@ -346,20 +354,26 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
|
|||||||
// executes the given message in the provided environment. The return value will
|
// executes the given message in the provided environment. The return value will
|
||||||
// be tracer dependent.
|
// be tracer dependent.
|
||||||
func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*types.QueryTraceTxResponse, error) {
|
func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*types.QueryTraceTxResponse, error) {
|
||||||
|
if req == nil {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||||
|
}
|
||||||
|
|
||||||
ctx := sdk.UnwrapSDKContext(c)
|
ctx := sdk.UnwrapSDKContext(c)
|
||||||
k.WithContext(ctx)
|
k.WithContext(ctx)
|
||||||
params := k.GetParams(ctx)
|
|
||||||
|
|
||||||
coinbase, err := k.GetCoinbaseAddress(ctx)
|
coinbase, err := k.GetCoinbaseAddress(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params := k.GetParams(ctx)
|
||||||
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
||||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
||||||
result, err := k.traceTx(c, coinbase, signer, req.TxIndex, params, ctx, ethCfg, req.Msg, req.TraceConfig)
|
tx := req.Msg.AsTransaction()
|
||||||
|
|
||||||
|
result, err := k.traceTx(ctx, coinbase, signer, req.TxIndex, params, ethCfg, tx, req.TraceConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resultData, err := json.Marshal(result)
|
resultData, err := json.Marshal(result)
|
||||||
@ -372,15 +386,23 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Keeper) traceTx(c context.Context, coinbase common.Address, signer ethtypes.Signer, txIndex uint64,
|
func (k *Keeper) traceTx(
|
||||||
params types.Params, ctx sdk.Context, ethCfg *ethparams.ChainConfig, msg *types.MsgEthereumTx, traceConfig *types.TraceConfig) (*interface{}, error) {
|
ctx sdk.Context,
|
||||||
|
coinbase common.Address,
|
||||||
|
signer ethtypes.Signer,
|
||||||
|
txIndex uint64,
|
||||||
|
params types.Params,
|
||||||
|
ethCfg *ethparams.ChainConfig,
|
||||||
|
tx *ethtypes.Transaction,
|
||||||
|
traceConfig *types.TraceConfig,
|
||||||
|
) (*interface{}, error) {
|
||||||
// Assemble the structured logger or the JavaScript tracer
|
// Assemble the structured logger or the JavaScript tracer
|
||||||
var (
|
var (
|
||||||
tracer vm.Tracer
|
tracer vm.Tracer
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
coreMessage, err := msg.AsMessage(signer)
|
msg, err := tx.AsMessage(signer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
@ -388,29 +410,34 @@ func (k *Keeper) traceTx(c context.Context, coinbase common.Address, signer etht
|
|||||||
switch {
|
switch {
|
||||||
case traceConfig != nil && traceConfig.Tracer != "":
|
case traceConfig != nil && traceConfig.Tracer != "":
|
||||||
timeout := defaultTraceTimeout
|
timeout := defaultTraceTimeout
|
||||||
// TODO change timeout to time.duration
|
// TODO: change timeout to time.duration
|
||||||
// Used string to comply with go ethereum
|
// Used string to comply with go ethereum
|
||||||
if traceConfig.Timeout != "" {
|
if traceConfig.Timeout != "" {
|
||||||
if timeout, err = time.ParseDuration(traceConfig.Timeout); err != nil {
|
timeout, err = time.ParseDuration(traceConfig.Timeout)
|
||||||
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "timeout value: %s", err.Error())
|
return nil, status.Errorf(codes.InvalidArgument, "timeout value: %s", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
txContext := core.NewEVMTxContext(coreMessage)
|
txContext := core.NewEVMTxContext(msg)
|
||||||
|
|
||||||
// Construct the JavaScript tracer to execute with
|
// Construct the JavaScript tracer to execute with
|
||||||
if tracer, err = tracers.New(traceConfig.Tracer, txContext); err != nil {
|
tracer, err = tracers.New(traceConfig.Tracer, txContext)
|
||||||
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle timeouts and RPC cancellations
|
// Handle timeouts and RPC cancellations
|
||||||
deadlineCtx, cancel := context.WithTimeout(c, timeout)
|
deadlineCtx, cancel := context.WithTimeout(ctx.Context(), timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-deadlineCtx.Done()
|
<-deadlineCtx.Done()
|
||||||
if deadlineCtx.Err() == context.DeadlineExceeded {
|
if errors.Is(deadlineCtx.Err(), context.DeadlineExceeded) {
|
||||||
tracer.(*tracers.Tracer).Stop(errors.New("execution timeout"))
|
tracer.(*tracers.Tracer).Stop(errors.New("execution timeout"))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
defer cancel()
|
|
||||||
case traceConfig != nil:
|
case traceConfig != nil:
|
||||||
logConfig := vm.LogConfig{
|
logConfig := vm.LogConfig{
|
||||||
DisableMemory: traceConfig.DisableMemory,
|
DisableMemory: traceConfig.DisableMemory,
|
||||||
@ -420,24 +447,25 @@ func (k *Keeper) traceTx(c context.Context, coinbase common.Address, signer etht
|
|||||||
}
|
}
|
||||||
tracer = vm.NewStructLogger(&logConfig)
|
tracer = vm.NewStructLogger(&logConfig)
|
||||||
default:
|
default:
|
||||||
tracer = types.NewTracer(types.TracerStruct, coreMessage, ethCfg, ctx.BlockHeight(), true)
|
tracer = types.NewTracer(types.TracerStruct, msg, ethCfg, ctx.BlockHeight(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
evm := k.NewEVM(coreMessage, ethCfg, params, coinbase, tracer)
|
evm := k.NewEVM(msg, ethCfg, params, coinbase, tracer)
|
||||||
|
|
||||||
k.SetTxHashTransient(common.HexToHash(msg.Hash))
|
k.SetTxHashTransient(tx.Hash())
|
||||||
k.SetTxIndexTransient(txIndex)
|
k.SetTxIndexTransient(txIndex)
|
||||||
|
|
||||||
res, err := k.ApplyMessage(evm, coreMessage, ethCfg, true)
|
res, err := k.ApplyMessage(evm, msg, ethCfg, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
var result interface{}
|
var result interface{}
|
||||||
|
|
||||||
// Depending on the tracer type, format and return the trace result data.
|
// Depending on the tracer type, format and return the trace result data.
|
||||||
switch tracer := tracer.(type) {
|
switch tracer := tracer.(type) {
|
||||||
case *vm.StructLogger:
|
case *vm.StructLogger:
|
||||||
// TODO Return proper returnValue
|
// TODO: Return proper returnValue
|
||||||
result = types.ExecutionResult{
|
result = types.ExecutionResult{
|
||||||
Gas: res.GasUsed,
|
Gas: res.GasUsed,
|
||||||
Failed: res.Failed(),
|
Failed: res.Failed(),
|
||||||
@ -451,7 +479,7 @@ func (k *Keeper) traceTx(c context.Context, coinbase common.Address, signer etht
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, status.Error(codes.InvalidArgument, "invalid tracer type")
|
return nil, status.Errorf(codes.InvalidArgument, "invalid tracer type %T", tracer)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &result, nil
|
return &result, nil
|
||||||
|
Loading…
Reference in New Issue
Block a user