evm, server: configurable tracer (#434)

* server: update server and enable configurable tracer

* config validation

* fix import cycle

* fix start

* update fields

* c++

* c++
This commit is contained in:
Federico Kunze Küllmer
2021-08-16 09:45:10 +00:00
committed by GitHub
parent 353455def9
commit cc3b2ff8e9
26 changed files with 292 additions and 168 deletions
+3 -2
View File
@@ -378,7 +378,8 @@ func (k Keeper) EthCall(c context.Context, req *types.EthCallRequest) (*types.Ms
return nil, status.Error(codes.Internal, err.Error())
}
evm := k.NewEVM(msg, ethCfg, params, coinbase)
evm := k.NewEVM(msg, ethCfg, params, coinbase, k.tracer)
// pass true means execute in query mode, which don't do actual gas refund.
res, err := k.ApplyMessage(evm, msg, ethCfg, true)
k.ctxStack.RevertAll()
@@ -448,7 +449,7 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
k.WithContext(ctx)
msg := args.ToMessage(req.GasCap)
evm := k.NewEVM(msg, ethCfg, params, coinbase)
evm := k.NewEVM(msg, ethCfg, params, coinbase, k.tracer)
// pass true means execute in query mode, which don't do actual gas refund.
rsp, err := k.ApplyMessage(evm, msg, ethCfg, true)
+5 -1
View File
@@ -48,6 +48,9 @@ type Keeper struct {
// chain ID number obtained from the context's chain id
eip155ChainID *big.Int
// Tracer used to collect execution traces from the EVM transaction execution
tracer string
// trace EVM state transition execution. This value is obtained from the `--trace` flag.
// For more info check https://geth.ethereum.org/docs/dapp/tracing
debug bool
@@ -58,7 +61,7 @@ func NewKeeper(
cdc codec.BinaryCodec,
storeKey, transientKey sdk.StoreKey, paramSpace paramtypes.Subspace,
ak types.AccountKeeper, bankKeeper types.BankKeeper, sk types.StakingKeeper,
debug bool,
tracer string, debug bool,
) *Keeper {
// ensure evm module account is set
@@ -80,6 +83,7 @@ func NewKeeper(
stakingKeeper: sk,
storeKey: storeKey,
transientKey: transientKey,
tracer: tracer,
debug: debug,
}
}
+14 -7
View File
@@ -2,7 +2,6 @@ package keeper
import (
"math/big"
"os"
"time"
"github.com/palantir/stacktrace"
@@ -28,7 +27,13 @@ import (
// (ChainConfig and module Params). It additionally sets the validator operator address as the
// coinbase address to make it available for the COINBASE opcode, even though there is no
// beneficiary of the coinbase transaction (since we're not mining).
func (k *Keeper) NewEVM(msg core.Message, config *params.ChainConfig, params types.Params, coinbase common.Address) *vm.EVM {
func (k *Keeper) NewEVM(
msg core.Message,
config *params.ChainConfig,
params types.Params,
coinbase common.Address,
tracer string,
) *vm.EVM {
blockCtx := vm.BlockContext{
CanTransfer: core.CanTransfer,
Transfer: core.Transfer,
@@ -41,18 +46,20 @@ func (k *Keeper) NewEVM(msg core.Message, config *params.ChainConfig, params typ
}
txCtx := core.NewEVMTxContext(msg)
vmConfig := k.VMConfig(params)
vmConfig := k.VMConfig(msg, params, tracer)
return vm.NewEVM(blockCtx, txCtx, k, config, vmConfig)
}
// VMConfig creates an EVM configuration from the debug setting and the extra EIPs enabled on the
// module parameters. The config generated uses the default JumpTable from the EVM.
func (k Keeper) VMConfig(params types.Params) vm.Config {
func (k Keeper) VMConfig(msg core.Message, params types.Params, tracer string) vm.Config {
cfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
return vm.Config{
Debug: k.debug,
Tracer: vm.NewJSONLogger(&vm.LogConfig{Debug: k.debug}, os.Stderr), // TODO: consider using the Struct Logger too
NoRecursion: false, // TODO: consider disabling recursion though params
Tracer: types.NewTracer(tracer, msg, cfg, k.Ctx().BlockHeight(), k.debug),
NoRecursion: false, // TODO: consider disabling recursion though params
ExtraEips: params.EIPs(),
}
}
@@ -154,7 +161,7 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT
}
// create an ethereum EVM instance and run the message
evm := k.NewEVM(msg, ethCfg, params, coinbase)
evm := k.NewEVM(msg, ethCfg, params, coinbase, k.tracer)
txHash := tx.Hash()
+40
View File
@@ -0,0 +1,40 @@
package types
import (
"math/big"
"os"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
)
const (
TracerAccessList = "access_list"
TracerJSON = "json"
TracerStruct = "struct"
TracerMarkdown = "markdown"
)
// NewTracer creates a new Logger tracer to collect execution traces from an
// EVM transaction.
func NewTracer(tracer string, msg core.Message, cfg *params.ChainConfig, height int64, debug bool) vm.Tracer {
// TODO: enable additional log configuration
logCfg := &vm.LogConfig{
Debug: debug,
}
switch tracer {
case TracerAccessList:
precompiles := vm.ActivePrecompiles(cfg.Rules(big.NewInt(height)))
return vm.NewAccessListTracer(msg.AccessList(), msg.From(), *msg.To(), precompiles)
case TracerJSON:
return vm.NewJSONLogger(logCfg, os.Stderr)
case TracerMarkdown:
return vm.NewMarkdownLogger(logCfg, os.Stdout) // TODO: Stderr ?
case TracerStruct:
return vm.NewStructLogger(logCfg)
default:
return nil
}
}