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 all 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

### State Machine Breaking

* (app, evm) [tharsis#434](https://github.com/tharsis/ethermint/pull/434) EVM `Keeper` struct and `NewEVM` function now have a new `trace` field to define
the Tracer type used to collect execution traces from the EVM transaction execution.
* (evm) [tharsis#175](https://github.com/tharsis/ethermint/issues/175) The msg `TxData` field is now represented as a `*proto.Any`.
* (evm) [tharsis#84](https://github.com/tharsis/ethermint/pull/84) Remove `journal`, `CommitStateDB` and `stateObjects`.
* (rpc, evm) [tharsis#81](https://github.com/tharsis/ethermint/pull/81) Remove tx `Receipt` from store and replace it with fields obtained from the Tendermint RPC client.
Expand All @@ -53,6 +55,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 +68,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)
}
Loading