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

Feat: Configurable RPC Apis #349

Merged
merged 29 commits into from
Jul 26, 2021
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f65707c
fix confusing name
crypto-facs Jul 22, 2021
84d475d
feat: Enable configurable grpc apis
crypto-facs Jul 23, 2021
6fb66fe
docs: Update docs and changelog
crypto-facs Jul 23, 2021
89416b5
Organized flags order
crypto-facs Jul 23, 2021
e097d36
merge conflicts
crypto-facs Jul 25, 2021
b65d49a
fix linter
crypto-facs Jul 25, 2021
ce5087d
fix linter
crypto-facs Jul 25, 2021
144b388
fix maligned struct
crypto-facs Jul 25, 2021
c131a06
Merge branch 'main' into configurable-rpcs
crypto-facs Jul 25, 2021
073aa9d
fix typo in docs
crypto-facs Jul 26, 2021
2929380
fix unnecesary duplicate
crypto-facs Jul 26, 2021
1c50243
Update cmd/ethermintd/config/config.go
crypto-facs Jul 26, 2021
dcebdc0
Update cmd/ethermintd/config/config.go
crypto-facs Jul 26, 2021
ebfb6de
Update cmd/ethermintd/config/config.go
crypto-facs Jul 26, 2021
2d93d8e
Update docs/basics/json_rpc.md
crypto-facs Jul 26, 2021
960cb40
fix eth to be manage as default
crypto-facs Jul 26, 2021
3010993
Update init.sh
crypto-facs Jul 26, 2021
ac03109
Update tests/solidity/init-test-node.sh
crypto-facs Jul 26, 2021
bb6bfa4
add default case
crypto-facs Jul 26, 2021
6ce870b
Merge branch 'configurable-rpcs' of github.com:crypto-facs/ethermint …
crypto-facs Jul 26, 2021
277bce6
add default enable api namespaces
crypto-facs Jul 26, 2021
5048f20
update changelog
crypto-facs Jul 26, 2021
d9a0ace
fix namespaces array handler
crypto-facs Jul 26, 2021
3c4032a
remove duplicated changelog
crypto-facs Jul 26, 2021
43b0f7b
fix typo
crypto-facs Jul 26, 2021
bb9aa27
remove duplicates namespaces and fix eth namespace issue
crypto-facs Jul 26, 2021
129f154
fix variable name
crypto-facs Jul 26, 2021
4e554bf
break line in docs
crypto-facs Jul 26, 2021
994b817
Merge branch 'main' into configurable-rpcs
fedekunze Jul 26, 2021
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 @@ -71,6 +71,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (rpc) [tharsis#176](https://github.com/tharsis/ethermint/issues/176) Support fetching pending nonce
* (rpc) [tharsis#272](https://github.com/tharsis/ethermint/pull/272) do binary search to estimate gas accurately
* (rpc) [#313](https://github.com/tharsis/ethermint/pull/313) Implement internal debug namespace (Not including logger functions nor traces).
* (rpc) [#313](https://github.com/tharsis/ethermint/pull/313) Implement internal debug namespace (Not including logger functions nor traces).
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
* (rpc) [#349](https://github.com/tharsis/ethermint/pull/349) Implement configurable JSON-RPC APIs to manage enabled namespaces.
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved

### Bug Fixes

Expand Down
27 changes: 18 additions & 9 deletions cmd/ethermintd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import (
ethermint "github.com/tharsis/ethermint/types"
)

// GetDefaultAPINamespaces returns the default list of JSON-RPC namespaces that should be enabled
func GetDefaultAPINamespaces() []string {
return []string{"eth"}
}

const (
// DefaultGRPCAddress is the default address the gRPC server binds to.
DefaultGRPCAddress = "0.0.0.0:9900"
Expand Down Expand Up @@ -57,27 +62,30 @@ func DefaultConfig() *Config {
}
}

// DefaultEVMConfig returns an EVM config with the JSON-RPC API enabled by default
func DefaultEVMConfig() *EVMRPCConfig {
return &EVMRPCConfig{
Enable: true,
RPCAddress: DefaultEVMAddress,
WsAddress: DefaultEVMWSAddress,
}
}

// EVMRPCConfig defines configuration for the EVM RPC server.
type EVMRPCConfig struct {
// RPCAddress defines the HTTP server to listen on
RPCAddress 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
API []string `mapstructure:"api"`
// Enable defines if the EVM RPC server should be enabled.
Enable bool `mapstructure:"enable"`
// EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk)
EnableUnsafeCORS bool `mapstructure:"enable-unsafe-cors"`
}

// DefaultEVMConfig returns an EVM config with the JSON-RPC API enabled by default
func DefaultEVMConfig() *EVMRPCConfig {
return &EVMRPCConfig{
Enable: true,
API: GetDefaultAPINamespaces(),
RPCAddress: DefaultEVMAddress,
WsAddress: DefaultEVMWSAddress,
}
}

// Config defines the server's top level configuration. It includes the default app config
// from the SDK as well as the EVM configuration to enable the JSON-RPC APIs.
type Config struct {
Expand All @@ -95,6 +103,7 @@ func GetConfig(v *viper.Viper) 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"),
},
Expand Down
10 changes: 10 additions & 0 deletions docs/basics/json_rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ Check the JSON-RPC methods and namespaces supported on Ethermint. {synopsis}
- [Ethereum JSON-RPC](https://eth.wiki/json-rpc/API) {prereq}
- [Geth JSON-RPC APIs](https://geth.ethereum.org/docs/rpc/server) {prereq}

## JSON-RPC Server

To enable RPC server use the following flag (set to true by default).

```ethermintd start --evm-rpc.enable```
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved

By default, only `eth` namespace is enabled. In order to enable other namespaces use flag `--evm-rpc.api`.

```ethermintd start --evm-rpc.api eth,txpool,personal,net,debug,web3```
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

## JSON-RPC Methods

| Method | Namespace | Implemented | Notes |
Expand Down
113 changes: 66 additions & 47 deletions ethereum/rpc/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package rpc
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/server"

"github.com/ethereum/go-ethereum/rpc"
"github.com/tharsis/ethermint/ethereum/rpc/backend"
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/debug"
Expand Down Expand Up @@ -33,53 +32,73 @@ const (
)

// GetRPCAPIs returns the list of all APIs
func GetRPCAPIs(ctx *server.Context, clientCtx client.Context, tmWSClient *rpcclient.WSClient) []rpc.API {
func GetRPCAPIs(ctx *server.Context, clientCtx client.Context, tmWSClient *rpcclient.WSClient, selectedAPIs []string) []rpc.API {
nonceLock := new(types.AddrLocker)
backend := backend.NewEVMBackend(ctx.Logger, clientCtx)
ethAPI := eth.NewPublicAPI(ctx.Logger, clientCtx, backend, nonceLock)
evmBackend := backend.NewEVMBackend(ctx.Logger, clientCtx)
ethAPI := eth.NewPublicAPI(ctx.Logger, clientCtx, evmBackend, nonceLock)

var apis []rpc.API

return []rpc.API{
{
Namespace: Web3Namespace,
Version: apiVersion,
Service: web3.NewPublicAPI(),
Public: true,
},
{
Namespace: EthNamespace,
Version: apiVersion,
Service: ethAPI,
Public: true,
},
{
Namespace: EthNamespace,
Version: apiVersion,
Service: filters.NewPublicAPI(ctx.Logger, tmWSClient, backend),
Public: true,
},
{
Namespace: NetNamespace,
Version: apiVersion,
Service: net.NewPublicAPI(clientCtx),
Public: true,
},
{
Namespace: PersonalNamespace,
Version: apiVersion,
Service: personal.NewAPI(ctx.Logger, ethAPI),
Public: true,
},
{
Namespace: TxPoolNamespace,
Version: apiVersion,
Service: txpool.NewPublicAPI(ctx.Logger),
Public: true,
},
{
Namespace: DebugNamespace,
Version: apiVersion,
Service: debug.NewInternalAPI(ctx),
Public: true,
},
for index := range selectedAPIs {
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
switch selectedAPIs[index] {
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
case EthNamespace:
apis = append(apis,
rpc.API{
Namespace: EthNamespace,
Version: apiVersion,
Service: filters.NewPublicAPI(ctx.Logger, tmWSClient, evmBackend),
Public: true,
},
)
case Web3Namespace:
apis = append(apis,
rpc.API{
Namespace: Web3Namespace,
Version: apiVersion,
Service: web3.NewPublicAPI(),
Public: true,
},
)
case NetNamespace:
apis = append(apis,
rpc.API{
Namespace: NetNamespace,
Version: apiVersion,
Service: net.NewPublicAPI(clientCtx),
Public: true,
},
)
case PersonalNamespace:
apis = append(apis,
rpc.API{
Namespace: PersonalNamespace,
Version: apiVersion,
Service: personal.NewAPI(ctx.Logger, ethAPI),
Public: true,
},
)
case TxPoolNamespace:
apis = append(apis,
rpc.API{
Namespace: TxPoolNamespace,
Version: apiVersion,
Service: txpool.NewPublicAPI(ctx.Logger),
Public: true,
},
)
case DebugNamespace:
apis = append(apis,
rpc.API{
Namespace: DebugNamespace,
Version: apiVersion,
Service: debug.NewInternalAPI(ctx),
Public: true,
},
)
default:
ctx.Logger.Error("Invalid namespace value", "namespace", selectedAPIs[index])
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
}
}

return apis
}
2 changes: 1 addition & 1 deletion init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,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
ethermintd start --pruning=nothing $TRACE --log_level $LOGLEVEL --minimum-gas-prices=0.0001aphoton --evm-rpc.api eth,txpool,personal,net,debug,web3
7 changes: 6 additions & 1 deletion server/evmrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package server
import (
"net"
"net/http"
"strings"
"time"

"github.com/gorilla/mux"
Expand All @@ -21,7 +22,11 @@ func StartEVMRPC(ctx *server.Context, clientCtx client.Context, tmRPCAddr string
tmWsClient := ConnectTmWS(tmRPCAddr, tmEndpoint)

rpcServer := ethrpc.NewServer()
apis := rpc.GetRPCAPIs(ctx, clientCtx, tmWsClient)

rpcAPI := config.EVMRPC.API
rpcAPI = strings.ReplaceAll(rpcAPI, " ", "")
rpcAPIArr := strings.Split(rpcAPI, ",")
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
apis := rpc.GetRPCAPIs(ctx, clientCtx, tmWsClient, rpcAPIArr)

for _, api := range apis {
if err := rpcServer.RegisterName(api.Namespace, api.Service); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const (
flagGRPCEnable = "grpc.enable"
flagGRPCAddress = "grpc.address"
flagEVMRPCEnable = "evm-rpc.enable"
flagEVMRPCAPI = "evm-rpc.api"
flagEVMRPCAddress = "evm-rpc.address"
flagEVMWSAddress = "evm-rpc.ws-address"
flagEVMEnableUnsafeCORS = "evm-rpc.enable-unsafe-cors"
Expand Down Expand Up @@ -179,6 +180,7 @@ which accepts a path for the resulting pprof file.
cmd.Flags().String(flagGRPCWebAddress, serverconfig.DefaultGRPCWebAddress, "The gRPC-Web server address to listen on")

cmd.Flags().Bool(flagEVMRPCEnable, true, "Define if the gRPC server should be enabled")
cmd.Flags().StringSlice(flagEVMRPCAPI, config.GetDefaultAPINamespaces(), "Defines a list of JSON-RPC namespaces that should be enabled")
cmd.Flags().String(flagEVMRPCAddress, config.DefaultEVMAddress, "the EVM RPC server address to listen on")
cmd.Flags().String(flagEVMWSAddress, config.DefaultEVMWSAddress, "the EVM WS server address to listen on")
cmd.Flags().Bool(flagEVMEnableUnsafeCORS, false, "Define if the EVM RPC server should enabled CORS (unsafe - use it at your own risk)")
Expand Down
2 changes: 1 addition & 1 deletion tests/solidity/init-test-node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ ethermintd collect-gentxs
ethermintd validate-genesis

# Start the node (remove the --pruning=nothing flag if historical queries are not needed)
ethermintd start --pruning=nothing --rpc.unsafe --keyring-backend test --trace --log_level info
ethermintd start --pruning=nothing --rpc.unsafe --keyring-backend test --trace --log_level info --evm-rpc.api eth,txpool,personal,net,debug,web3
6 changes: 5 additions & 1 deletion testutil/network/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,11 @@ func startInProcess(cfg Config, val *Validator) error {

val.jsonRPC = jsonrpc.NewServer()

apis := rpc.GetRPCAPIs(val.Ctx, val.ClientCtx, tmWsClient)
rpcAPI := val.AppConfig.EVMRPC.API
rpcAPI = strings.ReplaceAll(rpcAPI, " ", "")
rpcAPIArr := strings.Split(rpcAPI, ",")
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved

apis := rpc.GetRPCAPIs(val.Ctx, val.ClientCtx, tmWsClient, rpcAPIArr)
for _, api := range apis {
if err := val.jsonRPC.RegisterName(api.Namespace, api.Service); err != nil {
return fmt.Errorf("failed to register JSON-RPC namespace %s: %w", api.Namespace, err)
Expand Down