Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

e2e: allow running of single node using the e2e app #6982

Merged
merged 15 commits into from Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/tendermint/commands/run_node.go
Expand Up @@ -65,7 +65,7 @@ func AddNodeFlags(cmd *cobra.Command) {
"proxy-app",
config.ProxyApp,
"proxy app address, or one of: 'kvstore',"+
" 'persistent_kvstore' or 'noop' for local testing.")
" 'persistent_kvstore', 'test' or 'noop' for local testing.")
cmwaters marked this conversation as resolved.
Show resolved Hide resolved
cmd.Flags().String("abci", config.ABCI, "specify abci transport (socket | grpc)")

// rpc flags
Expand Down
7 changes: 7 additions & 0 deletions internal/proxy/client.go
Expand Up @@ -6,6 +6,7 @@ import (
abciclient "github.com/tendermint/tendermint/abci/client"
"github.com/tendermint/tendermint/abci/example/kvstore"
"github.com/tendermint/tendermint/abci/types"
e2e "github.com/tendermint/tendermint/test/e2e/app"
)

// DefaultClientCreator returns a default ClientCreator, which will create a
Expand All @@ -21,6 +22,12 @@ func DefaultClientCreator(addr, transport, dbDir string) (abciclient.Creator, io
case "persistent_kvstore":
app := kvstore.NewPersistentKVStoreApplication(dbDir)
return abciclient.NewLocalCreator(app), app
case "test":
app, err := e2e.NewApplication(e2e.DefaultConfig(dbDir))
if err != nil {
panic(err)
}
return abciclient.NewLocalCreator(app), noopCloser{}
case "noop":
return abciclient.NewLocalCreator(types.NewBaseApplication()), noopCloser{}
default:
Expand Down
9 changes: 3 additions & 6 deletions test/e2e/Makefile
@@ -1,13 +1,10 @@
all: docker generator runner tests
all: node docker generator runner tests

docker:
docker build --tag tendermint/e2e-node -f docker/Dockerfile ../..

# We need to build support for database backends into the app in
# order to build a binary with a Tendermint node in it (for built-in
# ABCI testing).
app:
go build -o build/app -tags badgerdb,boltdb,cleveldb,rocksdb ./app
node:
go build -o build/node ./node

generator:
go build -o build/generator ./generator
Expand Down
32 changes: 31 additions & 1 deletion test/e2e/README.md
Expand Up @@ -142,10 +142,40 @@ Docker does not enable IPv6 by default. To do so, enter the following in
}
```

## Benchmarking testnets
## Benchmarking Testnets

It is also possible to run a simple benchmark on a testnet. This is done through the `benchmark` command. This manages the entire process: setting up the environment, starting the test net, waiting for a considerable amount of blocks to be used (currently 100), and then returning the following metrics from the sample of the blockchain:

- Average time to produce a block
- Standard deviation of producing a block
- Minimum and maximum time to produce a block

## Running Individual Nodes

The E2E test harness is designed to run several nodes of varying configurations within docker. It is also possible to run a single node in the case of running larger, geographically-dispersed testnets. To run a single node you can either run:

**Built-in**

```bash
make node
tendermint init validator
TMHOME=$HOME/.tendermint ./build/node ./node/built-in.toml
```

To make things simpler the e2e application can also be run in the tendermint binary
by running

```bash
tendermint start --proxy-app test
```

**Socket**

```bash
make node
tendermint init validator
tendermint start
./build/node ./node.socket.toml
```

Check `node/config.go` to see how the settings of the test application can be tweaked.
21 changes: 19 additions & 2 deletions test/e2e/app/app.go
@@ -1,4 +1,4 @@
package main
package app

import (
"bytes"
Expand Down Expand Up @@ -27,6 +27,23 @@ type Application struct {
restoreChunks [][]byte
}

type Config struct {
cmwaters marked this conversation as resolved.
Show resolved Hide resolved
Dir string
SnapshotInterval uint64
cmwaters marked this conversation as resolved.
Show resolved Hide resolved
RetainBlocks uint64
KeyType string
PersistInterval uint64
cmwaters marked this conversation as resolved.
Show resolved Hide resolved
ValidatorUpdates map[string]map[string]uint8 // height <-> pubkey <-> voting power
}

func DefaultConfig(dir string) *Config {
return &Config{
PersistInterval: 1,
SnapshotInterval: 100,
Dir: dir,
}
}

// NewApplication creates the application.
func NewApplication(cfg *Config) (*Application, error) {
state, err := NewState(filepath.Join(cfg.Dir, "state.json"), cfg.PersistInterval)
Expand Down Expand Up @@ -134,7 +151,7 @@ func (app *Application) Commit() abci.ResponseCommit {
if err != nil {
panic(err)
}
logger.Info("Created state sync snapshot", "height", snapshot.Height)
app.logger.Info("Created state sync snapshot", "height", snapshot.Height)
}
retainHeight := int64(0)
if app.cfg.RetainBlocks > 0 {
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/app/snapshots.go
@@ -1,5 +1,5 @@
// nolint: gosec
package main
package app

import (
"encoding/json"
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/app/state.go
@@ -1,5 +1,5 @@
//nolint: gosec
package main
package app

import (
"crypto/sha256"
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/docker/Dockerfile
Expand Up @@ -19,7 +19,7 @@ COPY . .
RUN make build && cp build/tendermint /usr/bin/tendermint
COPY test/e2e/docker/entrypoint* /usr/bin/

RUN cd test/e2e && make app && cp build/app /usr/bin/app
RUN cd test/e2e && make node && cp build/node /usr/bin/app

# Set up runtime directory. We don't use a separate runtime image since we need
# e.g. leveldb and rocksdb which are already installed in the build image.
Expand Down
4 changes: 4 additions & 0 deletions test/e2e/node/built-in.toml
@@ -0,0 +1,4 @@
snapshot_interval = 100
persist_interval = 1
chain_id = "test-chain"
protocol = "builtin"
12 changes: 11 additions & 1 deletion test/e2e/app/config.go → test/e2e/node/config.go
Expand Up @@ -6,6 +6,8 @@ import (
"fmt"

"github.com/BurntSushi/toml"

"github.com/tendermint/tendermint/test/e2e/app"
)

// Config is the application configuration.
Expand All @@ -22,10 +24,18 @@ type Config struct {
PrivValServer string `toml:"privval_server"`
PrivValKey string `toml:"privval_key"`
PrivValState string `toml:"privval_state"`
Misbehaviors map[string]string `toml:"misbehaviors"`
KeyType string `toml:"key_type"`
}

func (cfg *Config) App() *app.Config {
return &app.Config{
SnapshotInterval: cfg.SnapshotInterval,
RetainBlocks: cfg.RetainBlocks,
KeyType: cfg.KeyType,
ValidatorUpdates: cfg.ValidatorUpdates,
}
}

// LoadConfig loads the configuration from disk.
func LoadConfig(file string) (*Config, error) {
cfg := &Config{
Expand Down
5 changes: 3 additions & 2 deletions test/e2e/app/main.go → test/e2e/node/main.go
Expand Up @@ -30,6 +30,7 @@ import (
grpcprivval "github.com/tendermint/tendermint/privval/grpc"
privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval"
rpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
"github.com/tendermint/tendermint/test/e2e/app"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
)

Expand Down Expand Up @@ -97,7 +98,7 @@ func run(configFile string) error {

// startApp starts the application server, listening for connections from Tendermint.
func startApp(cfg *Config) error {
app, err := NewApplication(cfg)
app, err := app.NewApplication(cfg.App())
if err != nil {
return err
}
Expand All @@ -118,7 +119,7 @@ func startApp(cfg *Config) error {
//
// FIXME There is no way to simply load the configuration from a file, so we need to pull in Viper.
func startNode(cfg *Config) error {
app, err := NewApplication(cfg)
app, err := app.NewApplication(cfg.App())
if err != nil {
return err
}
Expand Down
5 changes: 5 additions & 0 deletions test/e2e/node/socket.toml
@@ -0,0 +1,5 @@
snapshot_interval = 100
persist_interval = 1
chain_id = "test-chain"
protocol = "socket"
listen = "tcp://127.0.0.1:26658"
cmwaters marked this conversation as resolved.
Show resolved Hide resolved