forked from cerc-io/laconicd-deprecated
rpc, server: add TLS certificate for websocket (#600)
* rpc, server: add TLS certificate for websocket * changelog
This commit is contained in:
parent
9164eb329d
commit
05d9b290a7
@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
* (rpc, server) [tharsis#600](https://github.com/tharsis/ethermint/pull/600) Add TLS configuration for websocket API
|
||||||
* (rpc) [tharsis#598](https://github.com/tharsis/ethermint/pull/598) Check truncation when creating a `BlockNumber` from `big.Int`
|
* (rpc) [tharsis#598](https://github.com/tharsis/ethermint/pull/598) Check truncation when creating a `BlockNumber` from `big.Int`
|
||||||
* (evm) [tharsis#597](https://github.com/tharsis/ethermint/pull/597) Check for `uint64` -> `int64` block height overflow on `GetHashFn`
|
* (evm) [tharsis#597](https://github.com/tharsis/ethermint/pull/597) Check for `uint64` -> `int64` block height overflow on `GetHashFn`
|
||||||
* (evm) [tharsis#579](https://github.com/tharsis/ethermint/pull/579) Update `DeriveChainID` function to handle `v` signature values `< 35`.
|
* (evm) [tharsis#579](https://github.com/tharsis/ethermint/pull/579) Update `DeriveChainID` function to handle `v` signature values `< 35`.
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ import (
|
|||||||
|
|
||||||
rpcfilters "github.com/tharsis/ethermint/ethereum/rpc/namespaces/eth/filters"
|
rpcfilters "github.com/tharsis/ethermint/ethereum/rpc/namespaces/eth/filters"
|
||||||
"github.com/tharsis/ethermint/ethereum/rpc/types"
|
"github.com/tharsis/ethermint/ethereum/rpc/types"
|
||||||
|
"github.com/tharsis/ethermint/server/config"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -63,15 +65,21 @@ type ErrorMessageJSON struct {
|
|||||||
type websocketsServer struct {
|
type websocketsServer struct {
|
||||||
rpcAddr string // listen address of rest-server
|
rpcAddr string // listen address of rest-server
|
||||||
wsAddr string // listen address of ws server
|
wsAddr string // listen address of ws server
|
||||||
|
certFile string
|
||||||
|
keyFile string
|
||||||
api *pubSubAPI
|
api *pubSubAPI
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWebsocketsServer(logger log.Logger, tmWSClient *rpcclient.WSClient, rpcAddr, wsAddr string) WebsocketsServer {
|
func NewWebsocketsServer(logger log.Logger, tmWSClient *rpcclient.WSClient, cfg config.Config) WebsocketsServer {
|
||||||
logger = logger.With("api", "websocket-server")
|
logger = logger.With("api", "websocket-server")
|
||||||
|
_, port, _ := net.SplitHostPort(cfg.JSONRPC.Address)
|
||||||
|
|
||||||
return &websocketsServer{
|
return &websocketsServer{
|
||||||
rpcAddr: rpcAddr,
|
rpcAddr: "localhost:" + port, // FIXME: this shouldn't be hardcoded to localhost
|
||||||
wsAddr: wsAddr,
|
wsAddr: cfg.JSONRPC.WsAddress,
|
||||||
|
certFile: cfg.TLS.CertificatePath,
|
||||||
|
keyFile: cfg.TLS.KeyPath,
|
||||||
api: newPubSubAPI(logger, tmWSClient),
|
api: newPubSubAPI(logger, tmWSClient),
|
||||||
logger: logger,
|
logger: logger,
|
||||||
}
|
}
|
||||||
@ -82,7 +90,13 @@ func (s *websocketsServer) Start() {
|
|||||||
ws.Handle("/", s)
|
ws.Handle("/", s)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
err := http.ListenAndServe(s.wsAddr, ws)
|
var err error
|
||||||
|
if s.certFile == "" || s.keyFile == "" {
|
||||||
|
err = http.ListenAndServe(s.wsAddr, ws)
|
||||||
|
} else {
|
||||||
|
err = http.ListenAndServeTLS(s.wsAddr, s.certFile, s.keyFile, ws)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == http.ErrServerClosed {
|
if err == http.ErrServerClosed {
|
||||||
return
|
return
|
||||||
|
@ -3,6 +3,7 @@ package config
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
@ -31,9 +32,43 @@ const (
|
|||||||
|
|
||||||
var evmTracers = []string{DefaultEVMTracer, "markdown", "struct", "access_list"}
|
var evmTracers = []string{DefaultEVMTracer, "markdown", "struct", "access_list"}
|
||||||
|
|
||||||
// GetDefaultAPINamespaces returns the default list of JSON-RPC namespaces that should be enabled
|
// Config defines the server's top level configuration. It includes the default app config
|
||||||
func GetDefaultAPINamespaces() []string {
|
// from the SDK as well as the EVM configuration to enable the JSON-RPC APIs.
|
||||||
return []string{"eth", "net", "web3"}
|
type Config struct {
|
||||||
|
config.Config
|
||||||
|
|
||||||
|
EVM EVMConfig `mapstructure:"evm"`
|
||||||
|
JSONRPC JSONRPCConfig `mapstructure:"json-rpc"`
|
||||||
|
TLS TLSConfig `mapstructure:"tls"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
API []string `mapstructure:"api"`
|
||||||
|
// Enable defines if the EVM RPC server should be enabled.
|
||||||
|
Enable bool `mapstructure:"enable"`
|
||||||
|
// GasCap is the global gas cap for eth-call variants.
|
||||||
|
GasCap uint64 `mapstructure:"gas-cap"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLSConfig defines the certificate and matching private key for the server.
|
||||||
|
type TLSConfig struct {
|
||||||
|
// CertificatePath the file path for the certificate .pem file
|
||||||
|
CertificatePath string `mapstructure:"certificate-path"`
|
||||||
|
// KeyPath the file path for the key .pem file
|
||||||
|
KeyPath string `mapstructure:"key-path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppConfig helps to override default appConfig template and configs.
|
// AppConfig helps to override default appConfig template and configs.
|
||||||
@ -63,6 +98,7 @@ func AppConfig(denom string) (string, interface{}) {
|
|||||||
Config: *srvCfg,
|
Config: *srvCfg,
|
||||||
EVM: *DefaultEVMConfig(),
|
EVM: *DefaultEVMConfig(),
|
||||||
JSONRPC: *DefaultJSONRPCConfig(),
|
JSONRPC: *DefaultJSONRPCConfig(),
|
||||||
|
TLS: *DefaultTLSConfig(),
|
||||||
}
|
}
|
||||||
|
|
||||||
customAppTemplate := config.DefaultConfigTemplate + DefaultConfigTemplate
|
customAppTemplate := config.DefaultConfigTemplate + DefaultConfigTemplate
|
||||||
@ -76,16 +112,10 @@ func DefaultConfig() *Config {
|
|||||||
Config: *config.DefaultConfig(),
|
Config: *config.DefaultConfig(),
|
||||||
EVM: *DefaultEVMConfig(),
|
EVM: *DefaultEVMConfig(),
|
||||||
JSONRPC: *DefaultJSONRPCConfig(),
|
JSONRPC: *DefaultJSONRPCConfig(),
|
||||||
|
TLS: *DefaultTLSConfig(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
// DefaultEVMConfig returns the default EVM configuration
|
||||||
func DefaultEVMConfig() *EVMConfig {
|
func DefaultEVMConfig() *EVMConfig {
|
||||||
return &EVMConfig{
|
return &EVMConfig{
|
||||||
@ -102,18 +132,20 @@ func (c EVMConfig) Validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONRPCConfig defines configuration for the EVM RPC server.
|
// GetDefaultAPINamespaces returns the default list of JSON-RPC namespaces that should be enabled
|
||||||
type JSONRPCConfig struct {
|
func GetDefaultAPINamespaces() []string {
|
||||||
// Address defines the HTTP server to listen on
|
return []string{"eth", "net", "web3"}
|
||||||
Address string `mapstructure:"address"`
|
}
|
||||||
// WsAddress defines the WebSocket server to listen on
|
|
||||||
WsAddress string `mapstructure:"ws-address"`
|
// DefaultJSONRPCConfig returns an EVM config with the JSON-RPC API enabled by default
|
||||||
// API defines a list of JSON-RPC namespaces that should be enabled
|
func DefaultJSONRPCConfig() *JSONRPCConfig {
|
||||||
API []string `mapstructure:"api"`
|
return &JSONRPCConfig{
|
||||||
// Enable defines if the EVM RPC server should be enabled.
|
Enable: true,
|
||||||
Enable bool `mapstructure:"enable"`
|
API: GetDefaultAPINamespaces(),
|
||||||
// GasCap is the global gas cap for eth-call variants.
|
Address: DefaultJSONRPCAddress,
|
||||||
GasCap uint64 `mapstructure:"gas-cap"`
|
WsAddress: DefaultJSONRPCWsAddress,
|
||||||
|
GasCap: DefaultGasCap,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate returns an error if the JSON-RPC configuration fields are invalid.
|
// Validate returns an error if the JSON-RPC configuration fields are invalid.
|
||||||
@ -135,24 +167,29 @@ func (c JSONRPCConfig) Validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultJSONRPCConfig returns an EVM config with the JSON-RPC API enabled by default
|
// DefaultTLSConfig returns the default TLS configuration
|
||||||
func DefaultJSONRPCConfig() *JSONRPCConfig {
|
func DefaultTLSConfig() *TLSConfig {
|
||||||
return &JSONRPCConfig{
|
return &TLSConfig{
|
||||||
Enable: true,
|
CertificatePath: "",
|
||||||
API: GetDefaultAPINamespaces(),
|
KeyPath: "",
|
||||||
Address: DefaultJSONRPCAddress,
|
|
||||||
WsAddress: DefaultJSONRPCWsAddress,
|
|
||||||
GasCap: DefaultGasCap,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config defines the server's top level configuration. It includes the default app config
|
// Validate returns an error if the TLS certificate and key file extensions are invalid.
|
||||||
// from the SDK as well as the EVM configuration to enable the JSON-RPC APIs.
|
func (c TLSConfig) Validate() error {
|
||||||
type Config struct {
|
certExt := path.Ext(c.CertificatePath)
|
||||||
config.Config
|
|
||||||
|
|
||||||
EVM EVMConfig `mapstructure:"evm"`
|
if c.CertificatePath != "" && certExt != ".pem" {
|
||||||
JSONRPC JSONRPCConfig `mapstructure:"json-rpc"`
|
return fmt.Errorf("invalid extension %s for certificate path %s, expected '.pem'", certExt, c.CertificatePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyExt := path.Ext(c.KeyPath)
|
||||||
|
|
||||||
|
if c.KeyPath != "" && keyExt != ".pem" {
|
||||||
|
return fmt.Errorf("invalid extension %s for key path %s, expected '.pem'", keyExt, c.KeyPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConfig returns a fully parsed Config object.
|
// GetConfig returns a fully parsed Config object.
|
||||||
@ -171,6 +208,10 @@ func GetConfig(v *viper.Viper) Config {
|
|||||||
WsAddress: v.GetString("json-rpc.ws-address"),
|
WsAddress: v.GetString("json-rpc.ws-address"),
|
||||||
GasCap: v.GetUint64("json-rpc.gas-cap"),
|
GasCap: v.GetUint64("json-rpc.gas-cap"),
|
||||||
},
|
},
|
||||||
|
TLS: TLSConfig{
|
||||||
|
CertificatePath: v.GetString("tls.certificate-path"),
|
||||||
|
KeyPath: v.GetString("tls.key-path"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,5 +234,9 @@ func (c Config) ValidateBasic() error {
|
|||||||
return sdkerrors.Wrapf(sdkerrors.ErrAppConfig, "invalid json-rpc config value: %s", err.Error())
|
return sdkerrors.Wrapf(sdkerrors.ErrAppConfig, "invalid json-rpc config value: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := c.TLS.Validate(); err != nil {
|
||||||
|
return sdkerrors.Wrapf(sdkerrors.ErrAppConfig, "invalid tls config value: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
return c.Config.ValidateBasic()
|
return c.Config.ValidateBasic()
|
||||||
}
|
}
|
||||||
|
@ -34,4 +34,16 @@ api = "{{range $index, $elmt := .JSONRPC.API}}{{if $index}},{{$elmt}}{{else}}{{$
|
|||||||
|
|
||||||
# GasCap sets a cap on gas that can be used in eth_call/estimateGas (0=infinite). Default: 25,000,000.
|
# GasCap sets a cap on gas that can be used in eth_call/estimateGas (0=infinite). Default: 25,000,000.
|
||||||
gas-cap = {{ .JSONRPC.GasCap }}
|
gas-cap = {{ .JSONRPC.GasCap }}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### TLS Configuration ###
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
[tls]
|
||||||
|
|
||||||
|
# Certificate path defines the cert.pem file path for the TLS configuration.
|
||||||
|
certificate-path = "{{ .TLS.CertificatePath }}"
|
||||||
|
|
||||||
|
# Key path defines the key.pem file path for the TLS configuration.
|
||||||
|
key-path = "{{ .TLS.KeyPath }}"
|
||||||
`
|
`
|
||||||
|
@ -38,6 +38,12 @@ const (
|
|||||||
EVMTracer = "evm.tracer"
|
EVMTracer = "evm.tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TLS flags
|
||||||
|
const (
|
||||||
|
TLSCertPath = "tls.certificate-path"
|
||||||
|
TLSKeyPath = "tls.key-path"
|
||||||
|
)
|
||||||
|
|
||||||
// AddTxFlags adds common flags for commands to post tx
|
// AddTxFlags adds common flags for commands to post tx
|
||||||
func AddTxFlags(cmd *cobra.Command) *cobra.Command {
|
func AddTxFlags(cmd *cobra.Command) *cobra.Command {
|
||||||
cmd.PersistentFlags().String(flags.FlagChainID, "testnet", "Specify Chain ID for sending Tx")
|
cmd.PersistentFlags().String(flags.FlagChainID, "testnet", "Specify Chain ID for sending Tx")
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -73,11 +72,10 @@ func StartJSONRPC(ctx *server.Context, clientCtx client.Context, tmRPCAddr, tmEn
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx.Logger.Info("Starting JSON WebSocket server", "address", config.JSONRPC.WsAddress)
|
ctx.Logger.Info("Starting JSON WebSocket server", "address", config.JSONRPC.WsAddress)
|
||||||
_, port, _ := net.SplitHostPort(config.JSONRPC.Address)
|
|
||||||
|
|
||||||
// allocate separate WS connection to Tendermint
|
// allocate separate WS connection to Tendermint
|
||||||
tmWsClient = ConnectTmWS(tmRPCAddr, tmEndpoint, ctx.Logger)
|
tmWsClient = ConnectTmWS(tmRPCAddr, tmEndpoint, ctx.Logger)
|
||||||
wsSrv := rpc.NewWebsocketsServer(ctx.Logger, tmWsClient, "localhost:"+port, config.JSONRPC.WsAddress)
|
wsSrv := rpc.NewWebsocketsServer(ctx.Logger, tmWsClient, config)
|
||||||
wsSrv.Start()
|
wsSrv.Start()
|
||||||
return httpSrv, httpSrvDone, nil
|
return httpSrv, httpSrvDone, nil
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,9 @@ which accepts a path for the resulting pprof file.
|
|||||||
|
|
||||||
cmd.Flags().String(srvflags.EVMTracer, config.DefaultEVMTracer, "the EVM tracer type to collect execution traces from the EVM transaction execution (json|struct|access_list|markdown)")
|
cmd.Flags().String(srvflags.EVMTracer, config.DefaultEVMTracer, "the EVM tracer type to collect execution traces from the EVM transaction execution (json|struct|access_list|markdown)")
|
||||||
|
|
||||||
|
cmd.Flags().String(srvflags.TLSCertPath, "", "the cert.pem file path for the server TLS configuration")
|
||||||
|
cmd.Flags().String(srvflags.TLSKeyPath, "", "the key.pem file path for the server TLS configuration")
|
||||||
|
|
||||||
cmd.Flags().Uint64(server.FlagStateSyncSnapshotInterval, 0, "State sync snapshot interval")
|
cmd.Flags().Uint64(server.FlagStateSyncSnapshotInterval, 0, "State sync snapshot interval")
|
||||||
cmd.Flags().Uint32(server.FlagStateSyncSnapshotKeepRecent, 2, "State sync snapshot to keep")
|
cmd.Flags().Uint32(server.FlagStateSyncSnapshotKeepRecent, 2, "State sync snapshot to keep")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user