Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

server: configurable tracer #434

Merged
merged 9 commits into from
Aug 16, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### API Breaking

* (server) [tharsis#434](https://github.com/tharsis/ethermint/pull/434) `evm-rpc` flags and app config have been renamed to `json-rpc`.
* (proto, evm) [tharsis#207](https://github.com/tharsis/ethermint/issues/207) Replace `big.Int` in favor of `sdk.Int` for `TxData` fields
* (proto, evm) [tharsis#81](https://github.com/tharsis/ethermint/pull/81) gRPC Query and Tx service changes:
* The `TxReceipt`, `TxReceiptsByBlockHeight` endpoints have been removed from the Query service.
Expand All @@ -65,6 +66,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Improvements

* (evm) [tharsis#434](https://github.com/tharsis/ethermint/pull/434) Support different `Tracer` types for the EVM.
* (deps) [tharsis#427](https://github.com/tharsis/ethermint/pull/427) Bump ibc-go to [`v1.0.0`](https://github.com/cosmos/ibc-go/releases/tag/v1.0.0)
* (gRPC) [tharsis#239](https://github.com/tharsis/ethermint/pull/239) Query `ChainConfig` via gRPC.
* (rpc) [tharsis#181](https://github.com/tharsis/ethermint/pull/181) Use evm denomination for params on tx fee.
Expand Down
6 changes: 3 additions & 3 deletions app/ante/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type EVMKeeper interface {
WithContext(ctx sdk.Context)
ResetRefundTransient(ctx sdk.Context)
GetCoinbaseAddress() (common.Address, error)
NewEVM(msg core.Message, config *params.ChainConfig, params evmtypes.Params, coinbase common.Address) *vm.EVM
NewEVM(msg core.Message, config *params.ChainConfig, params evmtypes.Params, coinbase common.Address, tracer string) *vm.EVM
GetCodeHash(addr common.Address) common.Hash
}

Expand Down Expand Up @@ -389,8 +389,8 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
)
}

// NOTE: pass in an empty coinbase address as we don't need it for the check below
evm := ctd.evmKeeper.NewEVM(coreMsg, ethCfg, params, common.Address{})
// NOTE: pass in an empty coinbase address and tracer as we don't need them for the check below
evm := ctd.evmKeeper.NewEVM(coreMsg, ethCfg, params, common.Address{}, "")

// check that caller has enough balance to cover asset transfer for **topmost** call
// NOTE: here the gas consumed is from the context with the infinite gas meter
Expand Down
7 changes: 5 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ import (
_ "github.com/tharsis/ethermint/client/docs/statik"

"github.com/tharsis/ethermint/app/ante"
srvflags "github.com/tharsis/ethermint/server/flags"
ethermint "github.com/tharsis/ethermint/types"
"github.com/tharsis/ethermint/x/evm"
evmrest "github.com/tharsis/ethermint/x/evm/client/rest"
Expand Down Expand Up @@ -333,11 +334,13 @@ func NewEthermintApp(

app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.BaseApp.MsgServiceRouter())

tracer := cast.ToString(appOpts.Get(srvflags.EVMTracer))

// Create Ethermint keepers
app.EvmKeeper = evmkeeper.NewKeeper(
appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], app.GetSubspace(evmtypes.ModuleName),
app.AccountKeeper, app.BankKeeper, app.StakingKeeper,
bApp.Trace(), // debug EVM based on Baseapp options
tracer, bApp.Trace(), // debug EVM based on Baseapp options
)

// Create IBC Keeper
Expand Down Expand Up @@ -388,7 +391,7 @@ func NewEthermintApp(

// NOTE: we may consider parsing `appOpts` inside module constructors. For the moment
// we prefer to be more strict in what arguments the modules expect.
var skipGenesisInvariants = cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants))
skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants))

// NOTE: Any module instantiated in the module manager that is later modified
// must be passed by reference here.
Expand Down
3 changes: 2 additions & 1 deletion cmd/ethermintd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"github.com/tharsis/ethermint/encoding"
"github.com/tharsis/ethermint/server"
servercfg "github.com/tharsis/ethermint/server/config"
srvflags "github.com/tharsis/ethermint/server/flags"
ethermint "github.com/tharsis/ethermint/types"
)

Expand Down Expand Up @@ -115,7 +116,7 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
txCommand(),
ethermintclient.KeyCommands(app.DefaultNodeHome),
)
rootCmd = server.AddTxFlags(rootCmd)
rootCmd = srvflags.AddTxFlags(rootCmd)

// add rosetta
rootCmd.AddCommand(sdkserver.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Marshaler))
Expand Down
2 changes: 1 addition & 1 deletion config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ build:
init:
home: "$HOME/.ethermintd"
app:
evm-rpc:
json-rpc:
address: "0.0.0.0:8545" # change the JSON-RPC address and port
ws-address: "0.0.0.0:8546" # change the JSON-RPC websocket address and port
genesis:
Expand Down
4 changes: 2 additions & 2 deletions docs/api/json-rpc/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ compatibility for websockets of the [Ethereum's
PubSubAPI](https://geth.ethereum.org/docs/rpc/pubsub), Ethermint needs to cast the Tendermint
responses retreived into the Ethereum types.

You can start a connection with the Ethereum websocket using the `--evm-rpc.ws-address` flag when starting
You can start a connection with the Ethereum websocket using the `--json-rpc.ws-address` flag when starting
the node (default `"0.0.0.0:8546"`):

```bash
ethermintd start --evm-rpc.address"0.0.0.0:8545" --evm-rpc.ws-address="0.0.0.0:8546" --evm.rpc.api="eth,web3,net,txpool,debug" --evm-rpc.enable
ethermintd start --json-rpc.address"0.0.0.0:8545" --json-rpc.ws-address="0.0.0.0:8546" --evm.rpc.api="eth,web3,net,txpool,debug" --json-rpc.enable
```

Then, start a websocket subscription with [`ws`](https://github.com/hashrocket/ws)
Expand Down
8 changes: 4 additions & 4 deletions docs/api/json-rpc/running_server.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ Learn how to run and setup the JSON-RPC server on Ethermint. {synopsis}
To enable RPC server use the following flag (set to true by default).

```bash
ethermintd start --evm-rpc.enable
ethermintd start --json-rpc.enable
```

## Defining Namespaces

`Eth`,`Net` and `Web3` [namespaces](./namespaces) are enabled by default. In order to enable other namespaces use flag `--evm-rpc.api`.
`Eth`,`Net` and `Web3` [namespaces](./namespaces) are enabled by default. In order to enable other namespaces use flag `--json-rpc.api`.

```bash
ethermintd start --evm-rpc.api eth,txpool,personal,net,debug,web3,miner
ethermintd start --json-rpc.api eth,txpool,personal,net,debug,web3,miner
```

### CORS

If accessing the RPC from a browser, CORS will need to be enabled with the appropriate domain set. Otherwise, JavaScript calls are limit by the same-origin policy and requests will fail:

```bash
ethermintd start --evm-rpc.enable-unsafe-cors
ethermintd start --json-rpc.enable-unsafe-cors
```
2 changes: 1 addition & 1 deletion docs/intro/clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ APIs](./../api/JSON-RPC/running_server) to connect with existing web3 tooling.
See the list of supported JSON-RPC API [endpoints](./../api/JSON-RPC/endpoints) and [namespaces](./../api/JSON-RPC/namespaces).
:::

To connect to the JSON-PRC server, start the node with the `--evm-rpc.enable=true` flag and define the namespaces that you would like to run using the `--evm.rpc.api` flag (e.g. `"txpool,eth,web3,net,personal"`. Then, you can point any Ethereum development tooling to `http://localhost:8545` or whatever port you choose with the listen address flag (`--evm-rpc.address`).
To connect to the JSON-PRC server, start the node with the `--json-rpc.enable=true` flag and define the namespaces that you would like to run using the `--evm.rpc.api` flag (e.g. `"txpool,eth,web3,net,personal"`. Then, you can point any Ethereum development tooling to `http://localhost:8545` or whatever port you choose with the listen address flag (`--json-rpc.address`).

<!-- TODO: add Rosetta -->
2 changes: 1 addition & 1 deletion docs/quickstart/run_node.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The instructions for setting up a brand new full node from scratch are the the s
To start your node, just type:

```bash
ethermintd start --evm-rpc.enable=true --evm-rpc.api="eth,web3,net,txpool,debug"
ethermintd start --json-rpc.enable=true --json-rpc.api="eth,web3,net,txpool,debug"
```

## Key Management
Expand Down
2 changes: 1 addition & 1 deletion init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,4 @@ if [[ $1 == "pending" ]]; then
fi

# Start the node (remove the --pruning=nothing flag if historical queries are not needed)
ethermintd start --pruning=nothing $TRACE --log_level $LOGLEVEL --minimum-gas-prices=0.0001aphoton --evm-rpc.api eth,txpool,personal,net,debug,web3,miner
ethermintd start --pruning=nothing $TRACE --log_level $LOGLEVEL --minimum-gas-prices=0.0001aphoton --json-rpc.api eth,txpool,personal,net,debug,web3,miner
2 changes: 1 addition & 1 deletion scripts/contract-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ cat $HOME/.ethermint/config/genesis.json | jq '.app_state["mint"]["params"]["min
"$PWD"/build/ethermintd validate-genesis

# Start the node (remove the --pruning=nothing flag if historical queries are not needed) in background and log to file
"$PWD"/build/ethermintd start --pruning=nothing --rpc.unsafe --evm-rpc.address="0.0.0.0:8545" --keyring-backend test > ethermintd.log 2>&1 &
"$PWD"/build/ethermintd start --pruning=nothing --rpc.unsafe --json-rpc.address="0.0.0.0:8545" --keyring-backend test > ethermintd.log 2>&1 &

# Give ethermintd node enough time to launch
sleep 5
Expand Down
2 changes: 1 addition & 1 deletion scripts/integration-test-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ start_func() {
echo "starting ethermint node $i in background ..."
"$PWD"/build/ethermintd start --pruning=nothing --rpc.unsafe \
--p2p.laddr tcp://$IP_ADDR:$NODE_P2P_PORT"$i" --address tcp://$IP_ADDR:$NODE_PORT"$i" --rpc.laddr tcp://$IP_ADDR:$NODE_RPC_PORT"$i" \
--evm-rpc.address=$IP_ADDR:$RPC_PORT"$i" \
--json-rpc.address=$IP_ADDR:$RPC_PORT"$i" \
--keyring-backend test --home "$DATA_DIR$i" \
>"$DATA_DIR"/node"$i".log 2>&1 & disown

Expand Down
2 changes: 1 addition & 1 deletion scripts/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ start_func() {
echo "starting ethermint node $i in background ..."
"$PWD"/build/ethermintd start --pruning=nothing --rpc.unsafe \
--p2p.laddr tcp://$IP_ADDR:$NODE_P2P_PORT"$i" --address tcp://$IP_ADDR:$NODE_PORT"$i" --rpc.laddr tcp://$IP_ADDR:$NODE_RPC_PORT"$i" \
--evm-rpc.address=$IP_ADDR:$RPC_PORT"$i" \
--json-rpc.address=$IP_ADDR:$RPC_PORT"$i" \
--keyring-backend test --home "$DATA_DIR$i" \
>"$DATA_DIR"/node"$i".log 2>&1 & disown

Expand Down
104 changes: 79 additions & 25 deletions server/config/config.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
package config

import (
"github.com/cosmos/cosmos-sdk/server/config"
"fmt"

"github.com/spf13/viper"

"github.com/tendermint/tendermint/libs/strings"

"github.com/cosmos/cosmos-sdk/server/config"

sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

const (
// DefaultGRPCAddress is the default address the gRPC server binds to.
DefaultGRPCAddress = "0.0.0.0:9900"

// DefaultEVMAddress is the default address the EVM JSON-RPC server binds to.
DefaultEVMAddress = "0.0.0.0:8545"
// DefaultJSONRPCAddress is the default address the JSON-RPC server binds to.
DefaultJSONRPCAddress = "0.0.0.0:8545"

// DefaultEVMWSAddress is the default address the EVM WebSocket server binds to.
DefaultEVMWSAddress = "0.0.0.0:8546"
// DefaultJSONRPCWsAddress is the default address the JSON-RPC WebSocket server binds to.
DefaultJSONRPCWsAddress = "0.0.0.0:8546"

// DefaultEVMTracer is the default vm.Tracer type
DefaultEVMTracer = "json"
)

var (
evmTracers = []string{DefaultEVMTracer, "markdown", "struct", "access_list"}
)

// GetDefaultAPINamespaces returns the default list of JSON-RPC namespaces that should be enabled
Expand Down Expand Up @@ -45,8 +59,9 @@ func AppConfig(denom string) (string, interface{}) {
}

customAppConfig := Config{
Config: *srvCfg,
EVMRPC: *DefaultEVMConfig(),
Config: *srvCfg,
EVM: *DefaultEVMConfig(),
JSONRPC: *DefaultJSONRPCConfig(),
}

customAppTemplate := config.DefaultConfigTemplate + DefaultConfigTemplate
Expand All @@ -57,15 +72,39 @@ func AppConfig(denom string) (string, interface{}) {
// DefaultConfig returns server's default configuration.
func DefaultConfig() *Config {
return &Config{
Config: *config.DefaultConfig(),
EVMRPC: *DefaultEVMConfig(),
Config: *config.DefaultConfig(),
EVM: *DefaultEVMConfig(),
JSONRPC: *DefaultJSONRPCConfig(),
}
}

// EVMConfig defines the application configuration values for the EVM.
type EVMConfig struct {
// Tracer defines vm.Tracer type that the EVM will use if the node is run in
// trace mode. Default: 'json'.
Tracer string `mapstructure:"tracer"`
}

// DefaultEVMConfig returns the default EVM configuration
func DefaultEVMConfig() *EVMConfig {
return &EVMConfig{
Tracer: DefaultEVMTracer,
}
}

// Validate returns an error if the tracer type is invalid.
func (c EVMConfig) Validate() error {
if !strings.StringInSlice(c.Tracer, evmTracers) {
return fmt.Errorf("invalid tracer type %s, available types: %v", c.Tracer, evmTracers)
}

return nil
}

// EVMRPCConfig defines configuration for the EVM RPC server.
type EVMRPCConfig struct {
// RPCAddress defines the HTTP server to listen on
RPCAddress string `mapstructure:"address"`
// JSONRPCConfig defines configuration for the EVM RPC server.
type JSONRPCConfig struct {
// Address defines the HTTP server to listen on
Address string `mapstructure:"address"`
// WsAddress defines the WebSocket server to listen on
WsAddress string `mapstructure:"ws-address"`
// API defines a list of JSON-RPC namespaces that should be enabled
Expand All @@ -76,13 +115,13 @@ type EVMRPCConfig struct {
EnableUnsafeCORS bool `mapstructure:"enable-unsafe-cors"`
}

// DefaultEVMConfig returns an EVM config with the JSON-RPC API enabled by default
func DefaultEVMConfig() *EVMRPCConfig {
return &EVMRPCConfig{
// DefaultJSONRPCConfig returns an EVM config with the JSON-RPC API enabled by default
func DefaultJSONRPCConfig() *JSONRPCConfig {
return &JSONRPCConfig{
Enable: true,
API: GetDefaultAPINamespaces(),
RPCAddress: DefaultEVMAddress,
WsAddress: DefaultEVMWSAddress,
Address: DefaultJSONRPCAddress,
WsAddress: DefaultJSONRPCWsAddress,
EnableUnsafeCORS: false,
}
}
Expand All @@ -92,7 +131,8 @@ func DefaultEVMConfig() *EVMRPCConfig {
type Config struct {
config.Config

EVMRPC EVMRPCConfig `mapstructure:"evm-rpc"`
EVM EVMConfig `mapstructure:"evm"`
JSONRPC JSONRPCConfig `mapstructure:"json-rpc"`
}

// GetConfig returns a fully parsed Config object.
Expand All @@ -101,12 +141,26 @@ func GetConfig(v *viper.Viper) Config {

return Config{
Config: cfg,
EVMRPC: EVMRPCConfig{
Enable: v.GetBool("evm-rpc.enable"),
API: v.GetStringSlice("evm-rpc.api"),
RPCAddress: v.GetString("evm-rpc.address"),
WsAddress: v.GetString("evm-rpc.ws-address"),
EnableUnsafeCORS: v.GetBool("evm-rpc.enable-unsafe-cors"),
EVM: EVMConfig{
Tracer: v.GetString("evm.tracer"),
},
JSONRPC: JSONRPCConfig{
Enable: v.GetBool("json-rpc.enable"),
API: v.GetStringSlice("json-rpc.api"),
Address: v.GetString("json-rpc.address"),
WsAddress: v.GetString("json-rpc.ws-address"),
EnableUnsafeCORS: v.GetBool("json-rpc.enable-unsafe-cors"),
},
}
}

// ValidateBasic returns an error any of the application configuration fields are invalid
func (c Config) ValidateBasic() error {
if err := c.EVM.Validate(); err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrAppConfig, "invalid evm config value: %s", err.Error())
}

// TODO: validate JSON-RPC APIs

return c.Config.ValidateBasic()
}
8 changes: 4 additions & 4 deletions server/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

func TestDefaultConfig(t *testing.T) {
cfg := DefaultEVMConfig()
require.True(t, cfg.Enable)
require.Equal(t, cfg.RPCAddress, DefaultEVMAddress)
require.Equal(t, cfg.WsAddress, DefaultEVMWSAddress)
cfg := DefaultConfig()
require.True(t, cfg.JSONRPC.Enable)
require.Equal(t, cfg.JSONRPC.Address, DefaultJSONRPCAddress)
require.Equal(t, cfg.JSONRPC.WsAddress, DefaultJSONRPCWsAddress)
}
25 changes: 18 additions & 7 deletions server/config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,35 @@ package config
// DefaultConfigTemplate defines the configuration template for the EVM RPC configuration
const DefaultConfigTemplate = `
###############################################################################
### EVM RPC Configuration ###
### EVM Configuration ###
###############################################################################

[evm-rpc]
[evm]

# Tracer defines the 'vm.Tracer' type that the EVM will use when the node is run in
# debug mode. To enable tracing use the '--trace' flag when starting your node.
# Valid types are: json|struct|access_list|markdown
tracer = "{{ .EVM.Tracer }}"

###############################################################################
### JSON RPC Configuration ###
###############################################################################

[json-rpc]

# Enable defines if the gRPC server should be enabled.
enable = {{ .EVMRPC.Enable }}
enable = {{ .JSONRPC.Enable }}

# Address defines the EVM RPC HTTP server address to bind to.
address = "{{ .EVMRPC.RPCAddress }}"
address = "{{ .JSONRPC.Address }}"

# Address defines the EVM WebSocket server address to bind to.
ws-address = "{{ .EVMRPC.WsAddress }}"
ws-address = "{{ .JSONRPC.WsAddress }}"

# API defines a list of JSON-RPC namespaces that should be enabled
# Example: "eth,txpool,personal,net,debug,web3"
api = "{{range $index, $elmt := .EVMRPC.API}}{{if $index}},{{$elmt}}{{else}}{{$elmt}}{{end}}{{end}}"
api = "{{range $index, $elmt := .JSONRPC.API}}{{if $index}},{{$elmt}}{{else}}{{$elmt}}{{end}}{{end}}"

# EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk)
enable-unsafe-cors = "{{ .EVMRPC.EnableUnsafeCORS }}"
enable-unsafe-cors = "{{ .JSONRPC.EnableUnsafeCORS }}"
`
Loading