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

ci: Add ibc-rs/Hermes integration test #35

Merged
merged 8 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,23 @@ jobs:
with:
command: test
args: --all-features

# TODO: Remove the IBC_COMMITISH env var once the phase 4 work has been merged
# to master in ibc-rs.
ibc-integration:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build Docker image
run: |
docker build \
-f ci/Dockerfile \
-t informaldev/basecoin-rs-ci \
./ci
- name: Run test
run: |
docker run --rm \
--env IBC_COMMITISH=basecoin/phase-4-1 \
-v `pwd`:/src/basecoin-rs \
informaldev/basecoin-rs-ci

45 changes: 45 additions & 0 deletions ci/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
ARG TENDERMINT_VERSION=0.34.9
ARG GAIA_VERSION=4.2.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be better to use Gaiad v5 or v6 (mainnet hub-4 is at v6).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can currently only get this working for Gaiad v5.0.5 (that's the latest image we have from cephalopodequipment in the v5.x series). v6.0.0 fails at the point where I try to add the generated user key to the basecoin-0 chain via Hermes:

Configuring Hermes...
2021-12-23T14:10:10.979891Z TRACE ThreadId(01) deserialized the encoded pub key into a ProtoAny of type '/cosmos.crypto.secp256k1.PubKey'
Success: Added key 'testkey' (cosmos1va7pcr6gt6p8vvyexrmzwrm6k8uuc7rq2z96w0) on chain ibc-0
Generating user key...
{"name":"user","type":"local","address":"cosmos177vu4gpafpzd9f39kwc64m3tevk628dr3xe6d0","pubkey":"{\"@type\":\"/cosmos.crypto.secp256k1.PubKey\",\"key\":\"A1QTDg0L9pZeHs0WHf73tTjyUBa8UI2Z931CHjUCSCVN\"}","mnemonic":"safe defense winter glide ladder belt clip inform they forest utility record feature cannon deliver stomach will mean destroy border matter sleep gospel involve"}
Adding user key to basecoin-0 chain...
Error: error encoding key: EOF while parsing a value at line 1 column 0

I'm assuming the serialization format changed between Gaiad v5 and v6?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tested this and it seems gaiad-v0.6.0 writes the output of the keys add command to stderr instead of stdout, so the user_seed.json file is empty leading to this problem.

ARG RUST_VERSION=1.57

FROM tendermint/tendermint:v${TENDERMINT_VERSION} AS tendermint
FROM cephalopodequipment/gaiad:${GAIA_VERSION} AS gaia
FROM rust:${RUST_VERSION}-slim-bullseye

COPY --from=tendermint /usr/bin/tendermint /usr/bin/tendermint
COPY --from=gaia /usr/bin/gaiad /usr/bin/gaiad

ENV IBC_SRC=/src/ibc-rs
ENV BASECOIN_SRC=/src/basecoin-rs
ENV LOG_DIR=/var/log/basecoin-rs
ENV IBC_COMMITISH=master
adizere marked this conversation as resolved.
Show resolved Hide resolved

COPY entrypoint.sh /usr/bin/entrypoint.sh
COPY tendermint-config/ /basecoin/.tendermint/config
COPY hermes-config.toml /basecoin/.hermes/config.toml
COPY one-chain /basecoin/one-chain
COPY tests/ /basecoin/tests

RUN apt update && \
apt upgrade -y && \
apt install -y curl pkg-config libssl-dev git && \
useradd -U -s /bin/bash -d /basecoin basecoin && \
mkdir -p "${IBC_SRC}" && \
mkdir -p "${BASECOIN_SRC}" && \
mkdir -p "${LOG_DIR}" && \
mkdir -p /basecoin && \
mkdir -p /basecoin/.tendermint/config && \
mkdir -p /basecoin/.hermes && \
chown -R basecoin:basecoin "${IBC_SRC}" && \
chown -R basecoin:basecoin "${LOG_DIR}" && \
chown -R basecoin:basecoin "${BASECOIN_SRC}" && \
chown -R basecoin:basecoin /basecoin

VOLUME "${IBC_SRC}"
VOLUME "${BASECOIN_SRC}"

WORKDIR /basecoin
USER basecoin:basecoin

ENTRYPOINT ["/usr/bin/entrypoint.sh"]
CMD []
77 changes: 77 additions & 0 deletions ci/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# CI-related scripts

This folder contains scripts and configuration relating to integration testing
for basecoin-rs (which could also be modified to act as an integration test for
ibc-rs).

## Docker image

[`Dockerfile`](./Dockerfile) contains the primary script for building a Docker
image to test basecoin-rs.

### Building

From the root of this repository:

```bash
docker build -f ci/Dockerfile -t informaldev/basecoin-rs-ci ./ci
```

### Running

Running the image with appropriate parameters will allow you to test a build of
basecoin-rs with a particular build of ibc-rs (specifically the relayer,
Hermes). At present, by default, this executes the
[`update-channel`](./tests/update-channel.sh) script as a test if no `CMD` is
supplied to the image when running it.

From the root of this repository:

```bash
# Build basecoin-rs (located at `pwd`) and a local version of ibc-rs located at
# `/path/to/local/ibc-rs`.
docker run --rm -it \
-v `pwd`:/src/basecoin-rs \
-v /path/to/local/ibc-rs/:/src/ibc-rs \
informaldev/basecoin-rs-ci

# If no local ibc-rs source volume is mounted, the image will automatically pull
# the latest ibc-rs code on master from the ibc-rs repository on GitHub.
docker run --rm -it \
-v `pwd`:/src/basecoin-rs \
informaldev/basecoin-rs-ci

# If you don't want to execute the tests, and rather want a BASH prompt from
# which you can manually interact with the various running binaries.
docker run --rm -it \
-v `pwd`:/src/basecoin-rs \
informaldev/basecoin-rs-ci \
/bin/bash

```

### What does this image do?

For even more detail, see [`entrypoint.sh`](./entrypoint.sh). In sequence, a
container run from this image will:

1. Clone the [ibc-rs repository][ibc-rs-repo] if no ibc-rs sources have been
mounted into the container.
2. Build the Hermes binary from the ibc-rs sources in the container.
3. Build the basecoin-rs binary from the basecoin-rs source volume mounted into
the container.
4. Set up a single [Gaia] instance to act as a foreign chain for interacting
with basecoin-rs. The ID of this chain will be `ibc-0`.
5. Configure Hermes.
6. Start a [Tendermint] node and the basecoin-rs binary (the Tendermint node
will automatically connect to the basecoin-rs binary, providing a chain with
ID `basecoin-0`).
7. If no `CMD` arguments are provided for the container, it will automatically
execute the [`update-channel.sh`](./tests/update-channel.sh) script, which
creates and updates an IBC channel between `basecoin-0` and `ibc-0`. If `CMD`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the plan is to eventually go all the way up to channels, but at the moment we stop at clients because connection handshake fails (cf. https://github.com/informalsystems/ibc-rs/issues/1710)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point, but ATM we've been pinning ibc deps to specific branches (e.g. basecoin/phase-4-1 or basecoin/phase-5) in Cargo.toml. This was done to account for missing non-SDK chain support in ibc-rs. Now that proof verification and other things like custom proof-spec support have been implemented, we can finally start to depend on ibc-rs releases (once the fix for https://github.com/informalsystems/ibc-rs/issues/1710 is merged).
That said, we still haven't merged #27 yet, so I suggest we only run hermes create connection for now.

arguments are provided for the container, that test will not be executed and
the relevant `CMD` arguments will be executed instead.

[ibc-rs-repo]: https://github.com/informalsystems/ibc-rs
[Gaia]: https://github.com/cosmos/gaia
[Tendermint]: https://github.com/tendermint/tendermint
92 changes: 92 additions & 0 deletions ci/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/bin/bash
set -euo pipefail

IBC_SRC=${IBC_SRC:-/src/ibc-rs}
BASECOIN_SRC=${BASECOIN_SRC:-/src/basecoin-rs}
BUILD_ROOT="${HOME}/build"
IBC_BUILD="${BUILD_ROOT}/ibc-rs"
BASECOIN_BUILD="${BUILD_ROOT}/basecoin-rs"
BASECOIN_BIN="${BASECOIN_BUILD}/debug/tendermint-basecoin"
HERMES_BIN="${IBC_BUILD}/release/hermes"
IBC_REPO=https://github.com/informalsystems/ibc-rs.git
IBC_COMMITISH=${IBC_COMMITISH:-master}
CHAIN_DATA="${HOME}/data"
HERMES_CONFIG="${HOME}/.hermes/config.toml"
LOG_DIR=${LOG_DIR:-/var/log/basecoin-rs}
TESTS_DIR=${TESTS_DIR:-${HOME}/tests}
DEFAULT_TEST=${DEFAULT_TEST:-${TESTS_DIR}/update-channel.sh}

if [ ! -f "${BASECOIN_SRC}/Cargo.toml" ]; then
echo "basecoin-rs sources must be mounted into ${BASECOIN_SRC} for this script to work properly."
exit 1
fi

if [ ! -f "${IBC_SRC}/Cargo.toml" ]; then
echo "No ibc-rs sources detected. Cloning repo..."
git clone "${IBC_REPO}" "${IBC_SRC}"
echo "Checking out ${IBC_COMMITISH}..."
cd "${IBC_SRC}"
git checkout "${IBC_COMMITISH}"
git status
echo ""
fi

cd "${IBC_SRC}"
echo "Building Hermes..."
cargo build --release --bin hermes --target-dir "${IBC_BUILD}/"

cd "${BASECOIN_SRC}"
echo ""
echo "Building basecoin-rs..."
cargo build --target-dir "${BASECOIN_BUILD}"

echo ""
echo "Setting up chain ibc-0..."
mkdir -p "${CHAIN_DATA}"
"${HOME}/one-chain" gaiad ibc-0 "${CHAIN_DATA}" 26657 26656 6060 9090 100000000000

echo ""
echo "Configuring Hermes..."
"${HERMES_BIN}" -c "${HERMES_CONFIG}" \
keys add ibc-0 \
-f "${CHAIN_DATA}/ibc-0/user_seed.json"

gaiad keys add user --keyring-backend="test" --output json > "${HOME}/user_seed.json"
"${HERMES_BIN}" -c "${HERMES_CONFIG}" keys add basecoin-0 -f "${HOME}/user_seed.json"
Copy link
Contributor Author

@thanethomson thanethomson Dec 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command specifically fails for Gaiad v6.0.0, and where I suspect the serialization in ibc-rs may need to be updated. cc @adizere @hu55a1n1


echo ""
echo "Starting Tendermint..."
tendermint unsafe-reset-all
tendermint node > "${LOG_DIR}/tendermint.log" 2>&1 &

echo "Starting basecoin-rs..."
cd "${BASECOIN_SRC}"
"${BASECOIN_BIN}" -p 26358 -v > "${LOG_DIR}/basecoin.log" 2>&1 &

echo "Waiting for Tendermint node to be available..."
set +e
for retry in {1..4}; do
sleep 5
curl "http://127.0.0.1:26357/abci_info"
CURL_STATUS=$?
if [ ${CURL_STATUS} -eq 0 ]; then
break
else
echo "curl exit code status ${CURL_STATUS} (attempt ${retry})"
fi
done
set -e
# Will fail if we still can't reach the Tendermint node
curl "http://127.0.0.1:26357/abci_info" > /dev/null 2>&1

if [ ! -z "$@" ]; then
cd "${HOME}"
exec "$@"
else
echo ""
echo "No parameters supplied. Executing default test: ${DEFAULT_TEST}"
"${DEFAULT_TEST}"
echo ""
echo "Success!"
fi

93 changes: 93 additions & 0 deletions ci/hermes-config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
[global]
log_level = 'trace'

[[chains]]
id = 'ibc-0'
rpc_addr = 'http://127.0.0.1:26657'
grpc_addr = 'http://127.0.0.1:9090'
websocket_addr = 'ws://localhost:26657/websocket'
rpc_timeout = '10s'
account_prefix = 'cosmos'
key_name = 'testkey'
store_prefix = 'ibc'
gas_price = { price = 0.001, denom = 'stake' }
clock_drift = '5s'
trusting_period = '14days'

[chains.trust_threshold]
numerator = '1'
denominator = '3'

[[chains]]
id = 'basecoin-0'
rpc_addr = 'http://127.0.0.1:26357'
grpc_addr = 'http://127.0.0.1:9093'
websocket_addr = 'ws://localhost:26357/websocket'
rpc_timeout = '10s'
account_prefix = 'cosmos'
key_name = 'testkey'
store_prefix = 'ibc'
gas_price = { price = 0.001, denom = 'stake' }
clock_drift = '5s'
trusting_period = '14days'
proof_specs = '''
[
{
"leaf_spec": {
"hash": 1,
"prehash_key": 0,
"prehash_value": 0,
"length": 0,
"prefix": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
},
"inner_spec": {
"child_order": [
0,
1,
2
],
"child_size": 32,
"min_prefix_length": 0,
"max_prefix_length": 64,
"empty_child": [
0,
32
],
"hash": 1
},
"max_depth": 0,
"min_depth": 0
},
{
"leaf_spec": {
"hash": 1,
"prehash_key": 0,
"prehash_value": 0,
"length": 0,
"prefix": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
},
"inner_spec": {
"child_order": [
0,
1,
2
],
"child_size": 32,
"min_prefix_length": 0,
"max_prefix_length": 64,
"empty_child": [
0,
32
],
"hash": 1
},
"max_depth": 0,
"min_depth": 0
}
]
'''

[chains.trust_threshold]
numerator = '1'
denominator = '3'

Loading