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

Commit

Permalink
tests: add testutils for integration testing (#132)
Browse files Browse the repository at this point in the history
* tests: add testutils for integration testing

* update util

* fix config

* more updates

* rand chain-id

* add rpc client integration test example

* makefile

* rename

* updates to makefile
  • Loading branch information
fedekunze authored Jun 25, 2021
1 parent 61260df commit 459a290
Show file tree
Hide file tree
Showing 21 changed files with 1,938 additions and 2,428 deletions.
313 changes: 168 additions & 145 deletions Makefile

Large diffs are not rendered by default.

File renamed without changes.
2 changes: 1 addition & 1 deletion client/docs/statik/statik.go

Large diffs are not rendered by default.

2,328 changes: 485 additions & 1,843 deletions client/docs/swagger-ui/swagger.yaml

Large diffs are not rendered by default.

184 changes: 30 additions & 154 deletions cmd/ethermintd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ import (

"github.com/cosmos/cosmos-sdk/telemetry"

serverconfig "github.com/cosmos/cosmos-sdk/server/config"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/server/config"
sdk "github.com/cosmos/cosmos-sdk/types"
)

const (
defaultMinGasPrices = ""

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

Expand All @@ -26,67 +23,6 @@ const (
DefaultEVMWSAddress = "0.0.0.0:1318"
)

// BaseConfig defines the server's basic configuration
type BaseConfig struct {
// The minimum gas prices a validator is willing to accept for processing a
// transaction. A transaction's fees must meet the minimum of any denomination
// specified in this config (e.g. 0.25token1;0.0001token2).
MinGasPrices string `mapstructure:"minimum-gas-prices"`

Pruning string `mapstructure:"pruning"`
PruningKeepRecent string `mapstructure:"pruning-keep-recent"`
PruningKeepEvery string `mapstructure:"pruning-keep-every"`
PruningInterval string `mapstructure:"pruning-interval"`

// HaltHeight contains a non-zero block height at which a node will gracefully
// halt and shutdown that can be used to assist upgrades and testing.
//
// Note: Commitment of state will be attempted on the corresponding block.
HaltHeight uint64 `mapstructure:"halt-height"`

// HaltTime contains a non-zero minimum block time (in Unix seconds) at which
// a node will gracefully halt and shutdown that can be used to assist
// upgrades and testing.
//
// Note: Commitment of state will be attempted on the corresponding block.
HaltTime uint64 `mapstructure:"halt-time"`

// MinRetainBlocks defines the minimum block height offset from the current
// block being committed, such that blocks past this offset may be pruned
// from Tendermint. It is used as part of the process of determining the
// ResponseCommit.RetainHeight value during ABCI Commit. A value of 0 indicates
// that no blocks should be pruned.
//
// This configuration value is only responsible for pruning Tendermint blocks.
// It has no bearing on application state pruning which is determined by the
// "pruning-*" configurations.
//
// Note: Tendermint block pruning is dependant on this parameter in conunction
// with the unbonding (safety threshold) period, state pruning and state sync
// snapshot parameters to determine the correct minimum value of
// ResponseCommit.RetainHeight.
MinRetainBlocks uint64 `mapstructure:"min-retain-blocks"`

// InterBlockCache enables inter-block caching.
InterBlockCache bool `mapstructure:"inter-block-cache"`

// IndexEvents defines the set of events in the form {eventType}.{attributeKey},
// which informs Tendermint what to index. If empty, all events will be indexed.
IndexEvents []string `mapstructure:"index-events"`
}

// APIConfig defines the API listener configuration.
type APIConfig = serverconfig.APIConfig

// GRPCConfig defines configuration for the gRPC server.
type GRPCConfig struct {
// Enable defines if the gRPC server should be enabled.
Enable bool `mapstructure:"enable"`

// Address defines the API server to listen on
Address string `mapstructure:"address"`
}

// EVMRPCConfig defines configuration for the EVM RPC server.
type EVMRPCConfig struct {
// Enable defines if the EVM RPC server should be enabled.
Expand All @@ -97,27 +33,26 @@ type EVMRPCConfig struct {
WsAddress string `mapstructure:"ws-address"`
}

// StateSyncConfig defines the state sync snapshot configuration.
type StateSyncConfig struct {
// SnapshotInterval sets the interval at which state sync snapshots are taken.
// 0 disables snapshots. Must be a multiple of PruningKeepEvery.
SnapshotInterval uint64 `mapstructure:"snapshot-interval"`

// SnapshotKeepRecent sets the number of recent state sync snapshots to keep.
// 0 keeps all snapshots.
SnapshotKeepRecent uint32 `mapstructure:"snapshot-keep-recent"`
}

// Config defines the server's top level configuration
type Config struct {
BaseConfig `mapstructure:",squash"`
config.BaseConfig `mapstructure:",squash"`

// Telemetry defines the application telemetry configuration
Telemetry telemetry.Config `mapstructure:"telemetry"`
API APIConfig `mapstructure:"api"`
GRPC GRPCConfig `mapstructure:"grpc"`
EVMRPC EVMRPCConfig `mapstructure:"evm-rpc"`
StateSync StateSyncConfig `mapstructure:"state-sync"`
Telemetry telemetry.Config `mapstructure:"telemetry"`
API config.APIConfig `mapstructure:"api"`
GRPC config.GRPCConfig `mapstructure:"grpc"`
EVMRPC EVMRPCConfig `mapstructure:"evm-rpc"`
StateSync config.StateSyncConfig `mapstructure:"state-sync"`
}

func (c *Config) ToSDKConfig() *config.Config {
return &config.Config{
BaseConfig: c.BaseConfig,
Telemetry: c.Telemetry,
API: c.API,
GRPC: c.GRPC,
StateSync: c.StateSync,
}
}

// SetMinGasPrices sets the validator's minimum gas prices.
Expand Down Expand Up @@ -149,95 +84,36 @@ func (c *Config) GetMinGasPrices() sdk.DecCoins {

// DefaultConfig returns server's default configuration.
func DefaultConfig() *Config {

cfg := config.DefaultConfig()
return &Config{
BaseConfig: BaseConfig{
MinGasPrices: defaultMinGasPrices,
InterBlockCache: true,
Pruning: storetypes.PruningOptionNothing,
PruningKeepRecent: "0",
PruningKeepEvery: "0",
PruningInterval: "0",
MinRetainBlocks: 0,
IndexEvents: make([]string, 0),
},
Telemetry: telemetry.Config{
Enabled: false,
GlobalLabels: [][]string{},
},
API: APIConfig{
Enable: true,
Swagger: true,
Address: "tcp://0.0.0.0:10337",
MaxOpenConnections: 1000,
RPCReadTimeout: 10,
RPCMaxBodyBytes: 1000000,
},
GRPC: GRPCConfig{
Enable: true,
Address: DefaultGRPCAddress,
},
BaseConfig: cfg.BaseConfig,
Telemetry: cfg.Telemetry,
API: cfg.API,
GRPC: cfg.GRPC,
EVMRPC: EVMRPCConfig{
Enable: true,
RPCAddress: DefaultEVMAddress,
WsAddress: DefaultEVMWSAddress,
},
StateSync: StateSyncConfig{
SnapshotInterval: 0,
SnapshotKeepRecent: 2,
},
StateSync: cfg.StateSync,
}
}

// GetConfig returns a fully parsed Config object.
func GetConfig(v *viper.Viper) Config {
globalLabelsRaw := v.Get("telemetry.global-labels").([]interface{})
globalLabels := make([][]string, 0, len(globalLabelsRaw))

cfg := config.GetConfig(v)

return Config{
BaseConfig: BaseConfig{
MinGasPrices: v.GetString("minimum-gas-prices"),
InterBlockCache: v.GetBool("inter-block-cache"),
Pruning: v.GetString("pruning"),
PruningKeepRecent: v.GetString("pruning-keep-recent"),
PruningKeepEvery: v.GetString("pruning-keep-every"),
PruningInterval: v.GetString("pruning-interval"),
HaltHeight: v.GetUint64("halt-height"),
HaltTime: v.GetUint64("halt-time"),
IndexEvents: v.GetStringSlice("index-events"),
MinRetainBlocks: v.GetUint64("min-retain-blocks"),
},
Telemetry: telemetry.Config{
ServiceName: v.GetString("telemetry.service-name"),
Enabled: v.GetBool("telemetry.enabled"),
EnableHostname: v.GetBool("telemetry.enable-hostname"),
EnableHostnameLabel: v.GetBool("telemetry.enable-hostname-label"),
EnableServiceLabel: v.GetBool("telemetry.enable-service-label"),
PrometheusRetentionTime: v.GetInt64("telemetry.prometheus-retention-time"),
GlobalLabels: globalLabels,
},
API: APIConfig{
Enable: v.GetBool("api.enable"),
Swagger: v.GetBool("api.swagger"),
Address: v.GetString("api.address"),
MaxOpenConnections: v.GetUint("api.max-open-connections"),
RPCReadTimeout: v.GetUint("api.rpc-read-timeout"),
RPCWriteTimeout: v.GetUint("api.rpc-write-timeout"),
RPCMaxBodyBytes: v.GetUint("api.rpc-max-body-bytes"),
EnableUnsafeCORS: v.GetBool("api.enabled-unsafe-cors"),
},
GRPC: GRPCConfig{
Enable: v.GetBool("grpc.enable"),
Address: v.GetString("grpc.address"),
},
BaseConfig: cfg.BaseConfig,
Telemetry: cfg.Telemetry,
API: cfg.API,
GRPC: cfg.GRPC,
EVMRPC: EVMRPCConfig{
Enable: v.GetBool("evm-rpc.enable"),
RPCAddress: v.GetString("evm-rpc.address"),
WsAddress: v.GetString("evm-rpc.ws-address"),
},
StateSync: StateSyncConfig{
SnapshotInterval: v.GetUint64("state-sync.snapshot-interval"),
SnapshotKeepRecent: v.GetUint32("state-sync.snapshot-keep-recent"),
},
StateSync: cfg.StateSync,
}
}
54 changes: 6 additions & 48 deletions cmd/ethermintd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
pvm "github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/rpc/client/local"
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/client"
Expand All @@ -42,6 +41,7 @@ import (

"github.com/tharsis/ethermint/cmd/ethermintd/config"
"github.com/tharsis/ethermint/ethereum/rpc"
ethsrv "github.com/tharsis/ethermint/server"
)

// Tendermint full-node start flags
Expand Down Expand Up @@ -230,6 +230,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
grpcSrv, err = servergrpc.StartGRPCServer(clientCtx, app, config.GRPC.Address)
if err != nil {
log.WithError(err).Errorln("failed to boot GRPC server")
return err
}
}

Expand All @@ -242,7 +243,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
tmEndpoint := "/websocket"
tmRPCAddr := cfg.RPC.ListenAddress
log.Infoln("EVM RPC Connecting to Tendermint WebSocket at", tmRPCAddr+tmEndpoint)
tmWsClient := connectTmWS(tmRPCAddr, tmEndpoint)
tmWsClient := ethsrv.ConnectTmWS(tmRPCAddr, tmEndpoint)

rpcServer := ethrpc.NewServer()
apis := rpc.GetRPCAPIs(clientCtx, tmWsClient)
Expand All @@ -253,14 +254,15 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
"namespace": api.Namespace,
"service": api.Service,
}).WithError(err).Fatalln("failed to register service in EVM RPC namespace")
return err
}
}

r := mux.NewRouter()
r.HandleFunc("/", rpcServer.ServeHTTP).Methods("POST")
if grpcSrv != nil {
grpcWeb := grpcweb.WrapServer(grpcSrv)
mountGrpcWebServices(r, grpcWeb, grpcweb.ListGRPCResources(grpcSrv))
ethsrv.MountGRPCWebServices(r, grpcWeb, grpcweb.ListGRPCResources(grpcSrv))
}

handlerWithCors := cors.New(cors.Options{
Expand Down Expand Up @@ -308,7 +310,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
_, port, _ := net.SplitHostPort(config.EVMRPC.RPCAddress)

// allocate separate WS connection to Tendermint
tmWsClient = connectTmWS(tmRPCAddr, tmEndpoint)
tmWsClient = ethsrv.ConnectTmWS(tmRPCAddr, tmEndpoint)
wsSrv = rpc.NewWebsocketsServer(tmWsClient, "localhost:"+port, config.EVMRPC.WsAddress)
go wsSrv.Start()
}
Expand Down Expand Up @@ -391,50 +393,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
return nil
}

func connectTmWS(tmRPCAddr, tmEndpoint string) *rpcclient.WSClient {
tmWsClient, err := rpcclient.NewWS(tmRPCAddr, tmEndpoint,
rpcclient.MaxReconnectAttempts(256),
rpcclient.ReadWait(120*time.Second),
rpcclient.WriteWait(120*time.Second),
rpcclient.PingPeriod(50*time.Second),
rpcclient.OnReconnect(func() {
log.WithField("tendermint_rpc", tmRPCAddr+tmEndpoint).
Debugln("EVM RPC reconnects to Tendermint WS")
}),
)

if err != nil {
log.WithError(err).Fatalln("Tendermint WS client could not be created for ", tmRPCAddr+tmEndpoint)
} else if err := tmWsClient.OnStart(); err != nil {
log.WithError(err).Fatalln("Tendermint WS client could not start for ", tmRPCAddr+tmEndpoint)
}

return tmWsClient
}

func mountGrpcWebServices(
router *mux.Router,
grpcWeb *grpcweb.WrappedGrpcServer,
grpcResources []string,
) {
for _, res := range grpcResources {
log.Printf("[GRPC Web] HTTP POST mounted on %s", res)

s := router.Methods("POST").Subrouter()
s.HandleFunc(res, func(resp http.ResponseWriter, req *http.Request) {
if grpcWeb.IsGrpcWebSocketRequest(req) {
grpcWeb.HandleGrpcWebsocketRequest(resp, req)
return
}

if grpcWeb.IsGrpcWebRequest(req) {
grpcWeb.HandleGrpcWebRequest(resp, req)
return
}
})
}
}

func openDB(rootDir string) (dbm.DB, error) {
dataDir := filepath.Join(rootDir, "data")
return sdk.NewLevelDB("application", dataDir)
Expand Down
12 changes: 6 additions & 6 deletions crypto/ethsecp256k1/keys.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion encoding/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)

// MakeEncodingConfig creates an EncodingConfig for testing
// MakeConfig creates an EncodingConfig for testing
func MakeConfig(mb module.BasicManager) params.EncodingConfig {
cdc := amino.NewLegacyAmino()
interfaceRegistry := types.NewInterfaceRegistry()
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ require (
github.com/tyler-smith/go-bip39 v1.1.0
github.com/xlab/closer v0.0.0-20190328110542-03326addb7c2
github.com/xlab/suplog v1.3.0
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
google.golang.org/genproto v0.0.0-20210607140030-00d4fb20b1ae
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84
google.golang.org/grpc v1.38.0
gopkg.in/yaml.v2 v2.4.0
nhooyr.io/websocket v1.8.7 // indirect
Expand Down
Loading

0 comments on commit 459a290

Please sign in to comment.