Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ jobs:
sleep 5
fi

if go test -short -p 1 -timeout=15m -count=1 -tags=kwiltest ./...; then
if go test -failfast -short -p 1 -timeout=15m -count=1 -tags=kwiltest ./...; then
echo "✅ Tests passed on attempt $attempt"
break
else
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-node-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ permissions:
packages: write

env:
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/tn-db
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/node
Comment thread
outerlook marked this conversation as resolved.

jobs:
build-and-push:
Expand Down
26 changes: 23 additions & 3 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ tasks:
docker:build:local:
desc: Build Docker image for local development (no version args needed)
cmds:
- docker build -f deployments/Dockerfile -t tn-db:local .
- docker build -f deployments/Dockerfile -t ghcr.io/trufnetwork/node:local .

# ─── host ─────────────────────────────────────────────────────────────────────

Expand Down Expand Up @@ -121,6 +121,8 @@ tasks:
desc: Set environment variables for devnet
internal: true
env:
SETUP_DB_OWNER: "{{.DEV_DB_OWNER}}"
SETUP_CHAIN_ID: "{{.DEV_CHAIN_ID}}"
DB_OWNER: "{{.DEV_DB_OWNER}}"
CHAIN_ID: "{{.DEV_CHAIN_ID}}"
requires: { vars: [ DEV_DB_OWNER, DEV_CHAIN_ID ] }
Expand All @@ -129,6 +131,8 @@ tasks:
desc: Run docker-compose locally (single node stack)
deps: [ single:env, build:binaries ]
env:
SETUP_DB_OWNER: "{{.DEV_DB_OWNER}}"
SETUP_CHAIN_ID: "{{.DEV_CHAIN_ID}}"
DB_OWNER: "{{.DEV_DB_OWNER}}"
CHAIN_ID: "{{.DEV_CHAIN_ID}}"
cmds:
Expand All @@ -148,14 +152,23 @@ tasks:
internal: true
env:
BACKENDS: "{{.DEV_NODE_1_ADDRESS}},{{.DEV_NODE_2_ADDRESS}}"
CHAIN_ID: "{{.DEV_CHAIN_ID}}"
NODE_RPC_ENDPOINT: "{{.DEV_NODE_1_RPC_ENDPOINT}}"
SETUP_CHAIN_ID: "{{.DEV_CHAIN_ID}}"
SETUP_DB_OWNER: "{{.DEV_DB_OWNER}}"
CHAIN_ID: "{{.DEV_CHAIN_ID}}"
DB_OWNER: "{{.DEV_DB_OWNER}}"
requires: { vars: [ DEV_NODE_1_ADDRESS, DEV_NODE_2_ADDRESS, DEV_CHAIN_ID, DEV_DB_OWNER ] } # Added requires guard for all used vars

devnet:start:
desc: Run docker-compose locally with dev configuration, 2 nodes, gateway, and indexer services
deps: [ devnet:env, build:binaries ]
env:
SETUP_DB_OWNER: "{{.DEV_DB_OWNER}}"
SETUP_CHAIN_ID: "{{.DEV_CHAIN_ID}}"
DB_OWNER: "{{.DEV_DB_OWNER}}"
CHAIN_ID: "{{.DEV_CHAIN_ID}}"
BACKENDS: "{{.DEV_NODE_1_ADDRESS}},{{.DEV_NODE_2_ADDRESS}}"
NODE_RPC_ENDPOINT: "{{.DEV_NODE_1_RPC_ENDPOINT}}"
cmds:
- task: _compose
vars:
Expand All @@ -165,6 +178,13 @@ tasks:
devnet:stop:
desc: Shutdown dev 2 nodes, gateway, and indexer services
deps: [ devnet:env ]
env:
SETUP_DB_OWNER: "{{.DEV_DB_OWNER}}"
SETUP_CHAIN_ID: "{{.DEV_CHAIN_ID}}"
DB_OWNER: "{{.DEV_DB_OWNER}}"
CHAIN_ID: "{{.DEV_CHAIN_ID}}"
BACKENDS: "{{.DEV_NODE_1_ADDRESS}},{{.DEV_NODE_2_ADDRESS}}"
NODE_RPC_ENDPOINT: "{{.DEV_NODE_1_RPC_ENDPOINT}}"
cmds:
- task: _compose
vars:
Expand Down Expand Up @@ -325,4 +345,4 @@ tasks:
PRIVATE_KEY: "{{.PRIVATE_KEY}}"
PROVIDER: "{{.PROVIDER}}"
ADMIN_WALLET: "{{.DEV_DB_OWNER}}"
- kwil-cli exec-action grant_roles text:system text:network_writer text[]:{{.DEV_DB_OWNER}} --private-key {{.PRIVATE_KEY}} --provider {{.PROVIDER}} --sync
- kwil-cli exec-action grant_roles text:system text:network_writer text[]:{{.DEV_DB_OWNER}} --private-key {{.PRIVATE_KEY}} --provider {{.PROVIDER}} --sync
12 changes: 6 additions & 6 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,18 @@ services:
tn-db:
container_name: tn-db
hostname: tn-db
image: "tn-db:local"
image: "ghcr.io/trufnetwork/node:local"
restart: unless-stopped
build:
context: .
dockerfile: ./deployments/Dockerfile
args:
- CHAIN_ID=${CHAIN_ID:-trufnetwork-dev}
environment:
CONFIG_PATH: /root/.kwild
# app.pg-db-host
KWILD_DB_HOST: kwil-postgres
# DB_OWNER must be provided at runtime
DB_OWNER: ${DB_OWNER:-}
# Optionally supply SETUP_DB_OWNER to override the owner derived from the generated node key
SETUP_DB_OWNER: ${SETUP_DB_OWNER:-}
SETUP_CHAIN_ID: ${SETUP_CHAIN_ID:-trufnetwork-dev}
ports:
- "50051:50051"
- "${TN_RPC_PORT:-8484}:8484"
Expand All @@ -58,6 +57,8 @@ services:
- ${TN_VOLUME:-data-tn-db}:/root/.kwild
networks:
- tn-network
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: "json-file"
options:
Expand All @@ -72,5 +73,4 @@ networks:

volumes:
data-kwil-postgres:

data-tn-db:
2 changes: 1 addition & 1 deletion deployments/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ FROM alpine:latest

ENV SETUP_CHAIN_ID=truflation-dev
ENV SETUP_DB_OWNER=
# DB_OWNER will be provided as an environment variable at runtime
# Provide SETUP_DB_OWNER at runtime to override the derived owner; otherwise kwild derives one from the generated node key
ENV CONFIG_PATH=/root/.kwild

WORKDIR /app
Expand Down
8 changes: 5 additions & 3 deletions deployments/dev-net/devnet-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ services:
- KWILD_DB_HOST=kwil-postgres-1
- KWILD_APP_HOSTNAME=tn-db-1
- KWILD_CHAIN_P2P_EXTERNAL_ADDRESS=http://tn-db-1:26656
- DB_OWNER=${DB_OWNER:-0x4710A8D8F0D845da110086812a32De6d90d7ff5C}
- SETUP_DB_OWNER=${SETUP_DB_OWNER:-0x4710A8D8F0D845da110086812a32De6d90d7ff5C}
- SETUP_CHAIN_ID=${SETUP_CHAIN_ID:-trufnetwork-dev}
ports:
- "50051:50051"
- "8080:8080"
Expand Down Expand Up @@ -106,7 +107,8 @@ services:
- KWILD_DB_HOST=kwil-postgres-2
- KWILD_APP_HOSTNAME=tn-db-2
- KWILD_CHAIN_P2P_EXTERNAL_ADDRESS=http://tn-db-2:26656
- DB_OWNER=${DB_OWNER:-0x4710A8D8F0D845da110086812a32De6d90d7ff5C}
- SETUP_DB_OWNER=${SETUP_DB_OWNER:-0x4710A8D8F0D845da110086812a32De6d90d7ff5C}
- SETUP_CHAIN_ID=${SETUP_CHAIN_ID:-trufnetwork-dev}
ports:
- "8485:8484"
- "26658:26657"
Expand All @@ -132,4 +134,4 @@ networks:
volumes:
data-kwil-postgres-1:
data-kwil-postgres-2:
tn-conf:
tn-conf:
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ for i in {1..5}; do
if aws ecr get-login-password --region {{ .Region }} | docker login --username AWS --password-stdin {{ .RepoURI }} && \
docker pull {{ .ImageURI }}; then
echo "ECR login and pull successful."
# Tag the image as tn-db:local, as the docker-compose file expects that
docker tag {{ .ImageURI }} tn-db:local
# Tag the image as ghcr.io/trufnetwork/node:local, as the docker-compose file expects that
docker tag {{ .ImageURI }} ghcr.io/trufnetwork/node:local
break
fi
if [ $i -eq 5 ]; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ for i in {1..5}; do
if aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-west-2.amazonaws.com/mock-repo && \
docker pull 123456789012.dkr.ecr.us-west-2.amazonaws.com/mock-repo:latest; then
echo "ECR login and pull successful."
# Tag the image as tn-db:local, as the docker-compose file expects that
docker tag 123456789012.dkr.ecr.us-west-2.amazonaws.com/mock-repo:latest tn-db:local
# Tag the image as ghcr.io/trufnetwork/node:local, as the docker-compose file expects that
docker tag 123456789012.dkr.ecr.us-west-2.amazonaws.com/mock-repo:latest ghcr.io/trufnetwork/node:local
break
fi
if [ $i -eq 5 ]; then
Expand Down
118 changes: 118 additions & 0 deletions docs/container-image-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# TN Node Container Quickstart

Run the TRUF.NETWORK node container with Docker Compose while keeping the standard operator layout for data and configuration.

> **Heads up**
> The default quickstart relies on the container’s auto-initialization, which generates a brand-new genesis and starts an isolated network. Follow the optional pre-population section (or mount existing config) before the first run if you need to join an established network instead of bootstrapping a fresh one.

## Prerequisites
- Docker Engine 24+ with the `docker compose` plugin.
- Pull access to `ghcr.io/trufnetwork/node` and `kwildb/postgres`.
- Optional: the [`kwild` CLI](https://github.com/trufnetwork/node/releases) if you want to pre-populate configuration files instead of using the container’s auto-initialization path.

## 1. Prepare the workspace
```bash
mkdir -p ~/truf-node/tn_data
cd ~/truf-node
```
The `tn_data` directory becomes the bind mount that stores keys, logs, and the blockstore on the host so they persist across container rebuilds.

## 2. Save the Compose stack
Create `docker-compose.yml` in `~/truf-node` using the minimal stack below.

<details>
<summary>Minimal docker-compose.yml</summary>

```yaml
services:
postgres:
image: kwildb/postgres:16.8-1
restart: unless-stopped
environment:
POSTGRES_HOST_AUTH_METHOD: trust
volumes:
# this creates a host directory named pg-data in the current workspace
- ./pg-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5

tn-node:
image: ghcr.io/trufnetwork/node:${TN_NODE_TAG:-latest}
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
KWILD_DB_HOST: postgres
KWILD_DB_PORT: 5432
SETUP_CHAIN_ID: ${SETUP_CHAIN_ID:-truflation-dev}
SETUP_DB_OWNER: ${SETUP_DB_OWNER:-}
volumes:
# this creates a host directory named tn_data in the current workspace, or reuses your pre-generated config if it exists
- ./tn_data:/root/.kwild
ports:
- "8484:8484" # JSON-RPC
- "6600:6600" # P2P
```

</details>

Compose automatically loads variables from a `.env` file in the same directory. At a minimum set the node image tag you want to run (for example the latest release) and optionally pre-fill auto-setup values:

```dotenv
TN_NODE_TAG=v0.15.0
SETUP_CHAIN_ID=truflation-dev
# Leave empty to let the container derive the owner from the generated node key
SETUP_DB_OWNER=
```

## 3. Launch the services
```bash
docker compose up -d
docker compose ps
```
The node waits for Postgres to pass its health check before it starts. Use the bind mount (`~/truf-node/tn_data`) to inspect the generated config, keys, and logs.

### Verify the node
```bash
curl http://localhost:8484/api/v1/health
docker compose logs -f tn-node
```

## Optional: Pre-populate the configuration
If you need this container to join an existing network (mainnet/testnet/devnet), generate `config.toml`, `genesis.json`, and keys ahead of time so the container skips auto-initialization.

1. Clone the operator repository (once):
```bash
git clone https://github.com/trufnetwork/truf-node-operator.git ~/truf-node-operator
```
2. Install or download the matching `kwild` release binary and add it to your `PATH`.
3. Generate the config with the official genesis (adjust flags as needed for your environment, just like the [Node Operator Guide](node-operator-guide.md)):
```bash
kwild setup init \
--genesis ~/truf-node-operator/configs/network/v2/genesis.json \
--root ~/truf-node/tn_data \
--p2p.bootnodes "4e0b5c952be7f26698dc1898ff3696ac30e990f25891aeaf88b0285eab4663e1#ed25519@node-1.mainnet.truf.network:26656,0c830b69790eaa09315826403c2008edc65b5c7132be9d4b7b4da825c2a166ae#ed25519@node-2.mainnet.truf.network:26656" \
--state-sync.enable \
--state-sync.trusted-providers "0c830b69790eaa09315826403c2008edc65b5c7132be9d4b7b4da825c2a166ae#ed25519@node-2.mainnet.truf.network:26656" \
--rpc.private
```
4. Update the generated database host so it matches the Compose service name. Open `~/truf-node/tn_data/config.toml` and set:
```toml
[db]
host = 'postgres'
```
(This ensures the node reaches the Postgres container without relying on environment overrides.)

The next `docker compose up -d` start reuses this configuration instead of triggering auto-setup.

### Relying on auto-generation
For throwaway networks you can skip the steps above. Leave `SETUP_DB_OWNER` blank to let the container derive an identifier from the generated node key. Override `SETUP_CHAIN_ID` and `SETUP_DB_OWNER` in `.env` only when you want deterministic values for the generated genesis.

## Maintenance tips
- Back up the `~/truf-node/tn_data` directory; it contains the node identity, admin certificates, and blockstore.
- To rotate configuration, stop the stack, edit files under `~/truf-node/tn_data`, then start the stack again. The entrypoint leaves existing files untouched.
- Testing a new image? Set `TN_NODE_TAG` to the candidate tag and point the compose stack at a fresh host directory so you can diff auto-generated config before promoting it to production.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ require (
github.com/spf13/cobra v1.9.1
github.com/stretchr/testify v1.10.0
github.com/testcontainers/testcontainers-go v0.37.0
github.com/trufnetwork/kwil-db v0.10.3-0.20250915124855-c60f28b113d1
github.com/trufnetwork/kwil-db/core v0.4.3-0.20250915124855-c60f28b113d1
github.com/trufnetwork/kwil-db v0.10.3-0.20250916115210-a6b854684a3e
github.com/trufnetwork/kwil-db/core v0.4.3-0.20250916115210-a6b854684a3e
github.com/trufnetwork/sdk-go v0.3.2-0.20250630062504-841b40cdb709
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1214,8 +1214,12 @@ github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPD
github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI=
github.com/trufnetwork/kwil-db v0.10.3-0.20250915124855-c60f28b113d1 h1:NQ1HD0kf61QtNhcaCJ0jDqTaMw7WipBEZzn7lb0Mios=
github.com/trufnetwork/kwil-db v0.10.3-0.20250915124855-c60f28b113d1/go.mod h1:LiBAC48uZl2B0IiLtD2hpOce7RNfpuDdghVAOc3u1Qo=
github.com/trufnetwork/kwil-db v0.10.3-0.20250916115210-a6b854684a3e h1:1J0GDHNtJqoTLbFyTjGDzSn9u1h3JeeV3E2GL8uUm9k=
github.com/trufnetwork/kwil-db v0.10.3-0.20250916115210-a6b854684a3e/go.mod h1:LiBAC48uZl2B0IiLtD2hpOce7RNfpuDdghVAOc3u1Qo=
github.com/trufnetwork/kwil-db/core v0.4.3-0.20250915124855-c60f28b113d1 h1:FJ/dHHviqqx4wyH5ucA2z2JRmo4+k1eOCy6d9ye5djA=
github.com/trufnetwork/kwil-db/core v0.4.3-0.20250915124855-c60f28b113d1/go.mod h1:HnOsh9+BN13LJCjiH0+XKaJzyjWKf+H9AofFFp90KwQ=
github.com/trufnetwork/kwil-db/core v0.4.3-0.20250916115210-a6b854684a3e h1:IHsL26fvglbJ8t2CVbwPWv1nFD5mIJofwq80tS4Quus=
github.com/trufnetwork/kwil-db/core v0.4.3-0.20250916115210-a6b854684a3e/go.mod h1:HnOsh9+BN13LJCjiH0+XKaJzyjWKf+H9AofFFp90KwQ=
github.com/trufnetwork/openzeppelin-merkle-tree-go v0.0.2 h1:DCq8MzbWH0wZmICNmMVsSzUHUPl+2vqRhluEABjxl88=
github.com/trufnetwork/openzeppelin-merkle-tree-go v0.0.2/go.mod h1:Y0MJpPp9QXU5vC6Gpoilql2NkgmGNcbHm9HYC2v2N8s=
github.com/trufnetwork/sdk-go v0.3.2-0.20250630062504-841b40cdb709 h1:d9EqPXIjbq/atzEncK5dM3Z9oStx1BxCGuL/sjefeCw=
Expand Down
2 changes: 1 addition & 1 deletion internal/migrations/erc20-bridge/000-extension.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- Only necessary to run on leader and validator nodes.
-- This is not meant to be run on tests as the contract address is valid for mainnet only.

USE erc20 {
chain: 'sepolia',
Expand Down
Loading
Loading