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

rpc: Add probe to capture responses from Tendermint RPC for use in testing #653

Merged
merged 19 commits into from
Nov 18, 2020
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ Cargo.lock

# These are log files emitted by model-based tests
**/*.log

# RPC probe results
/rpc-probe/probe-results/
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@
- `[tendermint]` (Since v0.17.0-rc2) Fix abci::Data serialization to base64-encoded string. ([#667])
- `[tendermint]` (Since v0.17.0-rc2) Simplify abci::Log serialization ([#667])

### IMPROVEMENTS:

- `[rpc]` A new RPC probe (in the `rpc-probe` directory) has been added to
facilitate quick, pre-scripted interactions with a Tendermint node (via its
WebSocket endpoint). This aims to help improve testing and compatibility
between Tendermint in Go and Rust. ([#653])

[#653]: https://github.com/informalsystems/tendermint-rs/pull/653
[#667]: https://github.com/informalsystems/tendermint-rs/issues/667
[#672]: https://github.com/informalsystems/tendermint-rs/pull/672


## v0.17.0-rc2

*Nov 11, 2020*
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"light-node",
"proto",
"rpc",
"rpc-probe",
"tendermint",
"testgen"
]
Expand Down
31 changes: 31 additions & 0 deletions rpc-probe/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "tendermint-rpc-probe"
version = "0.1.0"
authors = ["Thane Thomson <[email protected]>"]
edition = "2018"
license = "Apache-2.0"
homepage = "https://www.tendermint.com/"
repository = "https://github.com/informalsystems/tendermint-rs"
readme = "README.md"

description = """
tendermint-rpc-probe allows us to probe a running Tendermint instance with
a given sequence of requests, capturing those requests and/or responses.
"""

[package.metadata.docs.rs]
all-features = true

[dependencies]
async-tungstenite = { version = "0.10", features = [ "tokio-runtime" ] }
futures = "0.3"
getrandom = "0.1"
log = "0.4"
serde = { version = "1", features = [ "derive" ] }
serde_json = "1"
simple_logger = "1.11"
structopt = "0.3"
subtle-encoding = "0.5.1"
thiserror = "1.0"
tokio = { version = "0.3", features = [ "full" ] }
uuid = "0.8"
95 changes: 95 additions & 0 deletions rpc-probe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Tendermint RPC Probe

The Tendermint RPC probe is an application that assists in testing the various
crates in this repository. It currently allows you to execute a quick probe of
a running [Tendermint] node, where a quick probe executes requests against all
of the [Tendermint RPC] endpoints (including subscriptions for different event
types), and saves all of the responses it gets as JSON files. These JSON files
can be used in testing in other crates.

## Requirements

To run this probe locally, you will need:

* The Rust toolchain (latest stable)
* Docker

## Usage (with Docker)

From the root of the tendermint.rs repository:

```bash
cd rpc-probe
./run-with-docker.sh
```

This will:

1. Build the `tendermint-rpc-probe` executable
2. Pull the latest version of the Tendermint Docker image
3. Initialize and run a Tendermint node with the `kvstore` app in the
background. (This node exposes a WebSocket endpoint at
`ws://127.0.0.1:26657/websocket`)
4. Run `tendermint-rpc-probe` against the running Tendermint node.
5. Terminate the Docker image.

To run a specific version of Tendermint, simply:

```bash
TENDERMINT_TAG="v0.33.8" ./run-with-docker.sh
```

## Usage (without Docker)

Simply run:

```bash
cargo run -- --help
```

to see what options are available to run the probe.

For example:

```bash
# Executes the probe with all default options (i.e. against a Tendermint node
# listening on 127.0.0.1:26657)
cargo run

# Customize the address
cargo run -- --addr ws://192.168.1.15:26657/websocket

# Customize how long to wait before each request (in milliseconds)
# Defaults to 1000ms
cargo run -- --request-wait 100
```

## Output

By default, all request and response JSON-RPC messages will be written into a
folder called `probe-results` in the `rpc-probe` directory.

For example, the `probe-results/incoming/abci_info.json` file (returned by the
[`abci_info`] RPC request) could look something like:

```json
{
"id": "8944f639-7da0-4595-ac5e-3e432079f510",
"jsonrpc": "2.0",
"result": {
"response": {
"app_version": "1",
"data": "{\"size\":0}",
"last_block_app_hash": "AAAAAAAAAAA=",
"last_block_height": "13",
"version": "0.17.0"
}
}
}
```

The full JSON-RPC wrapper is saved to disk.

[Tendermint]: https://github.com/tendermint/tendermint
[Tendermint RPC]: https://docs.tendermint.com/master/rpc/
[`abci_info`]: https://docs.tendermint.com/master/rpc/#/ABCI/abci_info
69 changes: 69 additions & 0 deletions rpc-probe/run-with-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/sh
set -euo pipefail

# run-with-docker.sh is a helper script that sets up a Docker container with a running Tendermint node.
# The scripts input parameters are defined through environment variables. The script also accepts
# regular input parameters that are forwarded to the `rpc-probe` application.
#
# Script input variables examples:
#
# Use specific tag from official DockerHub tendermint repository:
# TENDERMINT_TAG=v0.33.0 ./run-with-docker.sh
#
# Use custom DockerHub image:
# TENDERMINT_IMAGE=informaldev/tendermint:0.34.0-stargate4 ./run-with-docker.sh
#
# Use custom local Docker image:
# DOCKER_PULL=0 TENDERMINT_IMAGE=a1c86c07867e ./run-with-docker.sh
#
# Override local tmp folder (it has to exist):
# TMP_DIR=/tmp/tendermint ./run-with-docker.sh
#
# ###
#
# rpc-probe input parameter examples:
#
# Verbose output:
# ./run-with-docker.sh -v
#
# Override output directory (default: "probe-results"):
# ./run-with-docker.sh --output "my-other-probe-results"
#
# Change request wait times when probing (default: 1000):
# ./run-with-docker.sh --request-wait 2000

DEFAULT_TENDERMINT_IMAGE="tendermint/tendermint:${TENDERMINT_TAG:-latest}"
echo "DOCKER_PULL=${DOCKER_PULL:=1}"
echo "TENDERMINT_IMAGE=${TENDERMINT_IMAGE:=$DEFAULT_TENDERMINT_IMAGE}"
echo "Application input: $@"

cargo build

echo "TMP_DIR=${TMP_DIR:=$(mktemp -d)}"

if [ "${DOCKER_PULL}" -eq "1" ]; then
docker pull "${TENDERMINT_IMAGE}"
else
echo "Skipping pulling of Docker image"
fi

docker run -it --rm -v "${TMP_DIR}:/tendermint" "${TENDERMINT_IMAGE}" init
docker run -d \
--name rpc-probe-tendermint \
--rm \
-v "${TMP_DIR}:/tendermint" \
-p 26657:26657 \
"${TENDERMINT_IMAGE}" node --proxy_app=kvstore

echo "Waiting for local Docker node to come up..."
sleep 5

set +e # Try to clean up even if execution failed.
cargo run -- $@

docker stop rpc-probe-tendermint

echo "DOCKER_PULL=${DOCKER_PULL}"
echo "TENDERMINT_IMAGE=${TENDERMINT_IMAGE}"
echo "Application input: $@"
echo "TMP_DIR=${TMP_DIR}"
Loading