Skip to content
Draft
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
56 changes: 56 additions & 0 deletions .docker/local-network.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
FROM ubuntu:22.04

ARG NODE_VERSION=18.19.1
ARG TARGETARCH
# The server's native dependency tree currently pulls time 0.3.31, which fails
# with rustc >= 1.80. Keep this pin until the server dependencies move forward.
ARG SERVER_RUST_VERSION=1.79.0
ARG PROXY_RUST_VERSION=1.86.0

ENV DEBIAN_FRONTEND=noninteractive
ENV PATH="/opt/node/bin:/root/.cargo/bin:${PATH}"
ENV LIBERDUS_SERVER_RUST_TOOLCHAIN="${SERVER_RUST_VERSION}"
ENV LIBERDUS_PROXY_RUST_TOOLCHAIN="${PROXY_RUST_VERSION}"

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bash \
ca-certificates \
curl \
git \
jq \
libssl-dev \
lsof \
build-essential \
pkg-config \
procps \
python3 \
rsync \
xz-utils \
&& rm -rf /var/lib/apt/lists/*

RUN case "${TARGETARCH:-amd64}" in \
amd64) node_arch="x64" ;; \
arm64) node_arch="arm64" ;; \
*) echo "Unsupported Docker target architecture: ${TARGETARCH}" >&2; exit 1 ;; \
esac \
&& curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" -o /tmp/node.tar.xz \
&& mkdir -p /opt/node \
&& tar -xJf /tmp/node.tar.xz -C /opt/node --strip-components=1 \
&& rm /tmp/node.tar.xz \
&& npm install -g http-server \
&& npm cache clean --force

RUN git config --global url."https://github.com/".insteadOf "ssh://git@github.com/" \
&& git config --global url."https://github.com/".insteadOf "git@github.com:"

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --default-toolchain "${SERVER_RUST_VERSION}" --profile minimal \
&& rustup toolchain install "${PROXY_RUST_VERSION}" --profile minimal

WORKDIR /workspace/client-testing

COPY scripts/local-network /usr/local/bin/liberdus-local-network
RUN chmod +x /usr/local/bin/liberdus-local-network/healthcheck.sh

CMD ["node", "/usr/local/bin/liberdus-local-network/start.js"]
16 changes: 16 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.git
.github
.devcontainer
playwright-tests/node_modules
playwright-tests/playwright-report
playwright-tests/test-results
playwright-tests/.cache
local-network.env
.deps
.artifacts
server
liberdus-proxy
tools-cli-shardus-network
web-client-v2
*.log
*.pid
187 changes: 187 additions & 0 deletions .github/workflows/local-network-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
name: Local Network Smoke

on:
workflow_dispatch:

jobs:
smoke:
runs-on: ubuntu-latest
timeout-minutes: 120
env:
CI: "true"
LIBERDUS_PROXY_REF: new-nodelist-response
PLAYWRIGHT_BASE_URL: http://127.0.0.1:8080/

steps:
- name: Checkout client-testing
uses: actions/checkout@v4

- name: Checkout server
uses: actions/checkout@v4
with:
repository: Liberdus/server
path: .deps/server

- name: Checkout liberdus-proxy
uses: actions/checkout@v4
with:
repository: Liberdus/liberdus-proxy
ref: ${{ env.LIBERDUS_PROXY_REF }}
path: .deps/liberdus-proxy

- name: Checkout web-client-v2
uses: actions/checkout@v4
with:
repository: Liberdus/web-client-v2
path: .deps/web-client-v2

- name: Normalize bind paths for act on Windows
if: ${{ env.ACT == 'true' }}
run: |
set -euo pipefail

case "$GITHUB_WORKSPACE" in
/mnt/[a-zA-Z]/*)
drive="${GITHUB_WORKSPACE#/mnt/}"
drive="${drive%%/*}"
prefix="/mnt/${drive}/"
rest="${GITHUB_WORKSPACE#"$prefix"}"
win_workspace="${drive^^}:\\${rest//\//\\}"

{
echo "LIBERDUS_SERVER_DIR=${win_workspace}\\.deps\\server"
echo "LIBERDUS_PROXY_DIR=${win_workspace}\\.deps\\liberdus-proxy"
echo "LIBERDUS_WEB_CLIENT_DIR=${win_workspace}\\.deps\\web-client-v2"
} >> "$GITHUB_ENV"
;;
esac

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: playwright-tests/package-lock.json

- name: Show Docker versions
run: |
docker --version
docker compose version

- name: Validate local network compose config
run: docker compose -f docker-compose.local.yml config --quiet

- name: Clean previous local network state
run: docker compose -f docker-compose.local.yml down -v --remove-orphans

- name: Install Playwright dependencies
working-directory: playwright-tests
run: |
npm ci
npx playwright install --with-deps chromium

- name: Build local network image
run: docker compose -f docker-compose.local.yml build --progress=plain local-network

- name: Start local network
run: docker compose -f docker-compose.local.yml up -d --no-build local-network

- name: Wait for local network readiness
run: |
set -euo pipefail

previous_health=""
previous_phase=""
previous_healthcheck=""
for attempt in {1..240}; do
cid="$(docker compose -f docker-compose.local.yml ps -q local-network || true)"
if [ -z "$cid" ]; then
echo "local-network container not found"
docker compose -f docker-compose.local.yml ps || true
docker compose -f docker-compose.local.yml logs --no-color --tail=400 local-network || true
exit 1
fi

status="$(docker inspect --format='{{.State.Status}}' "$cid")"
health="$(docker inspect --format='{{if .State.Health}}{{.State.Health.Status}}{{end}}' "$cid")"
phase="$(
docker compose -f docker-compose.local.yml logs --no-color --tail=200 local-network 2>/dev/null \
| awk '/\[liberdus-local\]/ { line=$0 } END { print line }' \
| sed -E 's/^.*\[liberdus-local\] //'
)"
healthcheck="$(
docker inspect "$cid" \
| jq -r '.[0].State.Health.Log[-1].Output // ""' \
| tr '\n' ' ' \
| sed -E 's/[[:space:]]+/ /g; s/^ //; s/ $//'
)"

if [ "$health" != "$previous_health" ] || [ $((attempt % 4)) -eq 1 ]; then
echo "container status=${status} health=${health}"
previous_health="$health"
fi
if [ -n "$phase" ] && [ "$phase" != "$previous_phase" ]; then
echo "startup phase: ${phase}"
previous_phase="$phase"
fi
if [ -n "$healthcheck" ] && [ "$healthcheck" != "$previous_healthcheck" ]; then
echo "${healthcheck}"
previous_healthcheck="$healthcheck"
fi

if [ "$health" = "healthy" ]; then
exit 0
fi

if [ "$status" != "running" ]; then
docker compose -f docker-compose.local.yml logs --no-color --tail=400 local-network
exit 1
fi

sleep 15
done

docker compose -f docker-compose.local.yml logs --no-color --tail=400 local-network
exit 1

- name: Show local network status
run: |
docker compose -f docker-compose.local.yml ps
curl -fsS http://127.0.0.1:4000/cycleinfo/1 | jq '.cycleInfo[0] | {counter, mode, active, standby, syncing, desired, target, networkId}'
curl -fsS http://127.0.0.1:3030/account/0000000000000000000000000000000000000000000000000000000000000000 >/dev/null
curl -fsS http://127.0.0.1:8080/ >/dev/null

- name: Run Playwright smoke
working-directory: playwright-tests
run: npx playwright test --project=chromium --grep '@smoke' --workers=1 --retries=0 --reporter=github,line

- name: Upload Playwright HTML report
if: always()
uses: actions/upload-artifact@v4
with:
name: local-network-playwright-report-${{ github.run_id }}
path: playwright-tests/playwright-report/
if-no-files-found: warn
retention-days: 14

- name: Collect local network logs
if: always()
run: |
mkdir -p .artifacts
docker compose -f docker-compose.local.yml logs --no-color local-network > .artifacts/local-network.log || true
docker compose -f docker-compose.local.yml ps > .artifacts/local-network-ps.txt || true

- name: Upload local network logs
if: always()
uses: actions/upload-artifact@v4
with:
name: local-network-logs-${{ github.run_id }}
path: |
.artifacts/
playwright-tests/test-results/
if-no-files-found: warn
retention-days: 14

- name: Stop local network
if: always()
run: docker compose -f docker-compose.local.yml down -v --remove-orphans
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ xvfb.pid
fluxbox.log
fluxbox.pid
playwright-tests/.cache/network-params.json
playwright-tests/node_modules/
playwright-tests/.env
local-network.env
.deps/
.artifacts/
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

https://drive.google.com/file/d/19oWRpK_AJUo3G3hHYYGN_ZryAT-CSjyd/view?usp=sharing

## Usage
## Legacy Dev Container Usage

This older flow uses the root `liberdus-*.sh` scripts inside the dev container. It is separate from the Docker Compose local-network stack used for CI smoke testing.

1. Make sure you have the dev containers extension for vscode.

Expand All @@ -30,6 +32,19 @@ https://drive.google.com/file/d/19oWRpK_AJUo3G3hHYYGN_ZryAT-CSjyd/view?usp=shari

12. Run `./vnc-stop.sh` in the workspace root directory to stop the VNC server in the container.

## Local Network with Docker Compose

The Playwright tests default to `https://liberdus.com/dev/`, but the Docker Compose stack can run the smoke test against a local network. This is the CI-focused local-network path.

To run the tagged smoke test against the default dev network, leave `PLAYWRIGHT_BASE_URL` unset and run:

```bash
cd playwright-tests
npm run test:smoke
```

See [docs/local-network.md](docs/local-network.md) for the short version of what runs and how to run it locally.

## Manually Setting up a Local Liberdus Network with web-client-v2

1. Setup an environment with the following software:
Expand All @@ -42,9 +57,9 @@ https://drive.google.com/file/d/19oWRpK_AJUo3G3hHYYGN_ZryAT-CSjyd/view?usp=shari

* pkg-config 1.8.0

* Node.js 18.16.1
* Node.js 18.19.1

* Rust 1.74
* Rust 1.79.0 for the server, plus Rust 1.86.0 for `liberdus-proxy`

* Python 3.x

Expand All @@ -54,12 +69,6 @@ https://drive.google.com/file/d/19oWRpK_AJUo3G3hHYYGN_ZryAT-CSjyd/view?usp=shari

* Navigate to the repo's root directory and run `npm install`.

* https://github.com/shardus/tools-cli-shardus-network.git

- Navigate to the repo's root directory and run `npm install`.

- Run `npm link` in the root directory of this repo after installing dependencies to put the `shardus-network` command into the path.

* https://github.com/Liberdus/web-client-v2.git

* No dependencies to install.
Expand All @@ -70,13 +79,13 @@ https://drive.google.com/file/d/19oWRpK_AJUo3G3hHYYGN_ZryAT-CSjyd/view?usp=shari

3. Start a local network of Liberdus nodes.

* Navigate to the `Liberdus/server` repo and run `shardus-network start 10` to start a local network of 10 nodes.
* Navigate to the `Liberdus/server` repo and run `shardus start 5` to start a local network of 5 nodes.

* The minimum number of nodes needed to process transactions is defined by the `minNodes` property in `server/src/config/index.ts`:

```js
...
minNodes: process.env.minNodes ? parseInt(process.env.minNodes) : 10,
minNodes: process.env.minNodes ? parseInt(process.env.minNodes) : 5,
...
```

Expand Down
49 changes: 49 additions & 0 deletions docker-compose.local.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
services:
local-network:
build:
context: .
dockerfile: .docker/local-network.Dockerfile
init: true
environment:
LIBERDUS_SERVER_SOURCE: /sources/server
LIBERDUS_PROXY_SOURCE: /sources/liberdus-proxy
LIBERDUS_WEB_CLIENT_SOURCE: /sources/web-client-v2
LIBERDUS_RUNTIME_ROOT: /workspace/runtime
LIBERDUS_NODE_COUNT: ${LIBERDUS_NODE_COUNT:-10}
LIBERDUS_EXTERNAL_PORT_START: ${LIBERDUS_VALIDATOR_CONTAINER_PORT_START:-9001}
LIBERDUS_INTERNAL_PORT_START: ${LIBERDUS_INTERNAL_PORT_START:-10001}
LIBERDUS_PUBLIC_HOST: ${LIBERDUS_PUBLIC_HOST:-127.0.0.1}
LIBERDUS_MONITOR_PUBLIC_PORT: ${LIBERDUS_MONITOR_HOST_PORT:-3000}
LIBERDUS_PROXY_PUBLIC_PORT: ${LIBERDUS_PROXY_HOST_PORT:-3030}
LIBERDUS_PROXY_WS_PUBLIC_PORT: ${LIBERDUS_PROXY_WS_HOST_PORT:-3031}
LIBERDUS_WEB_PUBLIC_PORT: ${LIBERDUS_WEB_CLIENT_HOST_PORT:-8080}
volumes:
- type: bind
source: ${LIBERDUS_SERVER_DIR:-./.deps/server}
target: /sources/server
read_only: true
- type: bind
source: ${LIBERDUS_PROXY_DIR:-./.deps/liberdus-proxy}
target: /sources/liberdus-proxy
read_only: true
- type: bind
source: ${LIBERDUS_WEB_CLIENT_DIR:-./.deps/web-client-v2}
target: /sources/web-client-v2
read_only: true
- local-network-runtime:/workspace/runtime
ports:
- "${LIBERDUS_MONITOR_HOST_PORT:-3000}:3000"
- "${LIBERDUS_ARCHIVER_HOST_PORT:-4000}:4000"
- "${LIBERDUS_PROXY_HOST_PORT:-3030}:3030"
- "${LIBERDUS_PROXY_WS_HOST_PORT:-3031}:3031"
- "${LIBERDUS_WEB_CLIENT_HOST_PORT:-8080}:8080"
- "${LIBERDUS_VALIDATOR_HOST_PORT_START:-9101}-${LIBERDUS_VALIDATOR_HOST_PORT_END:-9110}:${LIBERDUS_VALIDATOR_CONTAINER_PORT_START:-9001}-${LIBERDUS_VALIDATOR_CONTAINER_PORT_END:-9010}"
healthcheck:
test: ["CMD", "/usr/local/bin/liberdus-local-network/healthcheck.sh"]
interval: 15s
timeout: 10s
retries: 3
start_period: 30m

volumes:
local-network-runtime:
Loading