Skip to content
Open
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
34 changes: 34 additions & 0 deletions tools/celestia-node-fiber/testing/docker/Dockerfile.app
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Build a celestia-appd binary with the `fibre` build tag enabled and a
# matching `fibre` server binary. Both go on PATH so the validator
# entrypoint can run them as separate processes.
#
# Pin CELESTIA_APP_REF to a feature/fibre commit; the default tracks
# whatever celestia-app `main` looks like at build time, which is where
# fibre development lives.
ARG GO_VERSION=1.26.1
ARG CELESTIA_APP_REPO=https://github.com/celestiaorg/celestia-app.git
ARG CELESTIA_APP_REF=main

FROM golang:${GO_VERSION}-bookworm AS build
ARG CELESTIA_APP_REPO
ARG CELESTIA_APP_REF
RUN apt-get update \
&& apt-get install -y --no-install-recommends git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /src
RUN git clone --depth 1 --branch "${CELESTIA_APP_REF}" "${CELESTIA_APP_REPO}" celestia-app \
|| git clone "${CELESTIA_APP_REPO}" celestia-app
WORKDIR /src/celestia-app
RUN git checkout "${CELESTIA_APP_REF}" || true
ENV CGO_ENABLED=0 GOFLAGS="-mod=readonly"
RUN go build -tags "ledger,fibre" -o /out/celestia-appd ./cmd/celestia-appd
RUN go build -tags "ledger,fibre" -o /out/fibre ./fibre/cmd

FROM debian:bookworm-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates jq curl \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /out/celestia-appd /usr/local/bin/celestia-appd
COPY --from=build /out/fibre /usr/local/bin/fibre
RUN chmod +x /usr/local/bin/celestia-appd /usr/local/bin/fibre
WORKDIR /home/celestia
28 changes: 28 additions & 0 deletions tools/celestia-node-fiber/testing/docker/Dockerfile.bridge
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Build a celestia-node bridge binary with the `fibre` build tag enabled.
# The bridge is what serves blob.Subscribe over JSON-RPC for the adapter's
# Listen path, and (on the read-only side) the fibre namespace API.
ARG GO_VERSION=1.26.1
ARG CELESTIA_NODE_REPO=https://github.com/celestiaorg/celestia-node.git
ARG CELESTIA_NODE_REF=feature/fibre

FROM golang:${GO_VERSION}-bookworm AS build
ARG CELESTIA_NODE_REPO
ARG CELESTIA_NODE_REF
RUN apt-get update \
&& apt-get install -y --no-install-recommends git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /src
RUN git clone --depth 1 --branch "${CELESTIA_NODE_REF}" "${CELESTIA_NODE_REPO}" celestia-node \
|| git clone "${CELESTIA_NODE_REPO}" celestia-node
WORKDIR /src/celestia-node
RUN git checkout "${CELESTIA_NODE_REF}" || true
ENV CGO_ENABLED=0 GOFLAGS="-mod=readonly"
RUN go build -tags "fibre" -o /out/celestia ./cmd/celestia

FROM debian:bookworm-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates jq curl \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /out/celestia /usr/local/bin/celestia
RUN chmod +x /usr/local/bin/celestia
WORKDIR /home/celestia
118 changes: 118 additions & 0 deletions tools/celestia-node-fiber/testing/docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Fibre 4-validator + bridge docker showcase

A docker-compose stack that brings up four celestia-app validators
(each running a Fibre server), a celestia-node bridge, and a one-shot
init container that registers Fibre Storage Provider hosts and funds an
escrow account. A Go test driver (`docker_test.go`) connects from the
host and exercises the `celestia-node-fiber` adapter end-to-end against
the real 2/3-quorum network.

## Why

The in-process `testing/showcase_test.go` runs against a single
validator inside the test process. That proves the adapter wires
correctly, but it doesn't exercise:

- real consensus 2/3 quorum collection (single validator trivially
satisfies it),
- inter-validator P2P,
- multiple Fibre servers contributing partial signatures,
- the dns:/// host registry resolution path,
- the bridge syncing real headers off a network it doesn't itself drive.

This stack does.

## Architecture

```
+---------- bootstrap (one-shot) ----------+
| init-genesis.sh: 4-val genesis + keys |
+-------+----------------------------------+
| shared volume
+------------+------------+------------+
v v v v
val0 val1 val2 val3
(appd + (appd + (appd + (appd +
fibre) fibre) fibre) fibre)
^
| gRPC :9090, RPC :26657
|
bridge (celestia-node)
^
| JSON-RPC/WebSocket :26658
|
+--------+--------+
| Go test |
| (docker_test.go) |
+-----------------+
```

## Run

```bash
cd tools/celestia-node-fiber/testing/docker

# First boot: builds two images (~5–10 min on a cold cache).
docker compose up -d --build

# Watch the bootstrap + registration progress:
docker compose logs -f bootstrap register

# Once `register` exits 0 and writes /shared/setup.done, the bridge
# connects and the stack is ready.

# From the parent dir, run the Go-side driver:
cd ../..
go test -tags 'fibre fibre_docker' -count=1 -timeout 5m ./testing/docker/...

# Tear down (preserves volumes — add -v to wipe shared genesis state):
docker compose -f testing/docker/compose.yaml down
```

Override endpoints from the host with env vars if your ports collide:

```
FIBRE_BRIDGE_ADDR=ws://127.0.0.1:36658 \
FIBRE_CONSENSUS_ADDR=127.0.0.1:19090 \
go test -tags 'fibre fibre_docker' ...
```

## Build args

Both Dockerfiles accept refs:

| arg | Dockerfile | default | what it does |
|---|---|---|---|
| `CELESTIA_APP_REPO` | `Dockerfile.app` | celestia-app upstream | clone source |
| `CELESTIA_APP_REF` | `Dockerfile.app` | `main` | git ref to build with `-tags fibre,ledger` |
| `CELESTIA_NODE_REPO` | `Dockerfile.bridge` | celestia-node upstream | clone source |
| `CELESTIA_NODE_REF` | `Dockerfile.bridge` | `feature/fibre` | git ref to build with `-tags fibre` |

Example pinning to a specific commit:

```
docker compose build --build-arg CELESTIA_NODE_REF=194cc74c ...
```

## Known TODOs

The scaffold has been validated end-to-end on Apple Silicon
(Docker Desktop 4.70 / linux/arm64). A few rough edges remain that
are worth tightening for CI:

1. **`config.toml` / `app.toml` overrides** in `start-validator.sh`
use `sed` against expected default lines. If the celestia-app
defaults change verb/spacing, the substitutions silently no-op.
Consider a `dasel`/`tomlq` rewrite if it bites.
2. **No healthchecks** on validators. `register` waits on
`service_started`, which is only "container booted", not "RPC
responding". The script polls `celestia-appd status` which
handles that, but a proper healthcheck would let `bridge` start
sooner without polling itself.
3. **No CI integration**. Adding `make docker-test` that wraps
`docker compose up -d --wait`, runs the test, then tears down,
is a sensible follow-up.
4. **Build cache** — every `docker compose up --build` re-clones
celestia-app + celestia-node. To iterate faster, set up a
docker volume cache for `/go/pkg/mod` and `/root/.cache/go-build`,
or build the images once and re-use.
153 changes: 153 additions & 0 deletions tools/celestia-node-fiber/testing/docker/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Local 4-validator + 1-bridge Fibre stack for end-to-end testing of the
# celestia-node-fiber adapter. Designed to be brought up with
# `docker compose up -d` from this directory; the test driver in
# docker_test.go (build tag `fibre_docker`) connects to it from the host.
#
# Services:
# bootstrap one-shot — generates a 4-val genesis under /shared
# val0..val3 validators running celestia-appd + fibre server
# register one-shot — submits MsgSetFibreProviderInfo + escrow
# bridge celestia-node bridge connected to val0
#
# Volumes:
# shared/ genesis, keyrings, peers, JWT — read by every service
#
# Ports exposed to host (override via override file if they collide):
# val0 :26657 (RPC) :9090 (gRPC) :7980 (fibre)
# bridge :26658 (JSON-RPC over WebSocket)
services:
bootstrap:
build:
context: .
dockerfile: Dockerfile.app
entrypoint: ["bash", "/scripts/init-genesis.sh"]
environment:
CHAIN_ID: fibre-docker
NUM_VALIDATORS: "4"
SHARED: /shared
CLIENT_ACCOUNT: default-fibre
volumes:
- shared:/shared
- ./scripts:/scripts:ro
restart: "no"

val0:
build:
context: .
dockerfile: Dockerfile.app
entrypoint: ["bash", "/scripts/start-validator.sh"]
environment:
VAL_INDEX: "0"
SHARED: /shared
CHAIN_ID: fibre-docker
depends_on:
bootstrap:
condition: service_completed_successfully
volumes:
- shared:/shared
- ./scripts:/scripts:ro
ports:
- "26657:26657"
- "9090:9090"
- "7980:7980"

val1:
build:
context: .
dockerfile: Dockerfile.app
entrypoint: ["bash", "/scripts/start-validator.sh"]
environment:
VAL_INDEX: "1"
SHARED: /shared
CHAIN_ID: fibre-docker
depends_on:
bootstrap:
condition: service_completed_successfully
volumes:
- shared:/shared
- ./scripts:/scripts:ro
ports:
- "7981:7980"

val2:
build:
context: .
dockerfile: Dockerfile.app
entrypoint: ["bash", "/scripts/start-validator.sh"]
environment:
VAL_INDEX: "2"
SHARED: /shared
CHAIN_ID: fibre-docker
depends_on:
bootstrap:
condition: service_completed_successfully
volumes:
- shared:/shared
- ./scripts:/scripts:ro
ports:
- "7982:7980"

val3:
build:
context: .
dockerfile: Dockerfile.app
entrypoint: ["bash", "/scripts/start-validator.sh"]
environment:
VAL_INDEX: "3"
SHARED: /shared
CHAIN_ID: fibre-docker
depends_on:
bootstrap:
condition: service_completed_successfully
volumes:
- shared:/shared
- ./scripts:/scripts:ro
ports:
- "7983:7980"

register:
build:
context: .
dockerfile: Dockerfile.app
entrypoint: ["bash", "/scripts/register-fsps.sh"]
environment:
NUM_VALIDATORS: "4"
SHARED: /shared
CHAIN_ID: fibre-docker
CLIENT_ACCOUNT: default-fibre
depends_on:
val0:
condition: service_started
val1:
condition: service_started
val2:
condition: service_started
val3:
condition: service_started
volumes:
- shared:/shared
- ./scripts:/scripts:ro
restart: on-failure

bridge:
build:
context: .
dockerfile: Dockerfile.bridge
entrypoint: ["bash", "/scripts/start-bridge.sh"]
environment:
NETWORK: fibre-docker
SHARED: /shared
CORE_IP: val0
CORE_GRPC_PORT: "9090"
CORE_RPC_PORT: "26657"
depends_on:
register:
condition: service_completed_successfully
volumes:
- shared:/shared
- ./scripts:/scripts:ro
ports:
- "26658:26658"

volumes:
shared:
Loading
Loading