mirror of
https://github.com/logos-co/nomos.git
synced 2026-08-27 09:31:15 +00:00
feat(devnet): Use volumes in docker compose for setup and run (#2172)
This commit is contained in:
@@ -7,3 +7,4 @@
|
||||
|
||||
ci
|
||||
target
|
||||
tempo-data
|
||||
|
||||
Generated
+1
@@ -4272,6 +4272,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"serde_yaml",
|
||||
"time",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
|
||||
explorer:
|
||||
container_name: explorer
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
depends_on:
|
||||
- logos-blockchain-node-0
|
||||
environment:
|
||||
- NBE_NODE_API_HOST=logos-blockchain-node-0
|
||||
- NBE_NODE_API_PORT=${NODE0_API_PORT}
|
||||
ports:
|
||||
- "8000:8000/tcp"
|
||||
entrypoint: /opt/scripts/run_explorer.sh
|
||||
|
||||
cfgsync:
|
||||
container_name: cfgsync
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
depends_on:
|
||||
- grafana
|
||||
ports:
|
||||
- "4400:4400/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_cfgsync_server.sh
|
||||
|
||||
logos-blockchain-node-0:
|
||||
container_name: logos_blockchain_node_0
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- node-data:/node-data
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
- ./tests/kzgrs/kzgrs_test_params:/kzgrs_test_params:z
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- LB_HOST_IDX=0
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE0_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE0_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE0_API_PORT}
|
||||
- FAUCET_PORT=${NODE0_FAUCET_PORT}
|
||||
ports:
|
||||
- "3000:3000/udp"
|
||||
- "3400:3400/udp"
|
||||
- "18085:18085/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_node.sh
|
||||
|
||||
logos-blockchain-node-1:
|
||||
container_name: logos_blockchain_node_1
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- node-data:/node-data
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
- ./tests/kzgrs/kzgrs_test_params:/kzgrs_test_params:z
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- LB_HOST_IDX=1
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE1_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE1_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE1_API_PORT}
|
||||
- FAUCET_PORT=${NODE1_FAUCET_PORT}
|
||||
ports:
|
||||
- "3001:3001/udp"
|
||||
- "3401:3401/udp"
|
||||
- "18081:18081/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_node.sh
|
||||
|
||||
logos-blockchain-node-2:
|
||||
container_name: logos_blockchain_node_2
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- node-data:/node-data
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
- ./tests/kzgrs/kzgrs_test_params:/kzgrs_test_params:z
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- LB_HOST_IDX=2
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE2_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE2_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE2_API_PORT}
|
||||
- FAUCET_PORT=${NODE2_FAUCET_PORT}
|
||||
ports:
|
||||
- "3002:3002/udp"
|
||||
- "3402:3402/udp"
|
||||
- "18082:18082/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_node.sh
|
||||
|
||||
logos-blockchain-node-3:
|
||||
container_name: logos_blockchain_node_3
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- node-data:/node-data
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
- ./tests/kzgrs/kzgrs_test_params:/kzgrs_test_params:z
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- LB_HOST_IDX=3
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE3_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE3_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE3_API_PORT}
|
||||
- FAUCET_PORT=${NODE3_FAUCET_PORT}
|
||||
ports:
|
||||
- "3003:3003/udp"
|
||||
- "3403:3403/udp"
|
||||
- "18083:18083/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_node.sh
|
||||
|
||||
prometheus:
|
||||
container_name: prometheus
|
||||
image: prom/prometheus:v3.0.1
|
||||
volumes:
|
||||
- ./testnet/monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:z
|
||||
command:
|
||||
- --config.file=/etc/prometheus/prometheus.yml
|
||||
- --storage.tsdb.retention.time=7d
|
||||
- --web.enable-otlp-receiver
|
||||
ports:
|
||||
- 0.0.0.0:9090:9090
|
||||
restart: on-failure
|
||||
|
||||
grafana:
|
||||
container_name: grafana
|
||||
image: grafana/grafana:latest
|
||||
environment:
|
||||
- GF_AUTH_ANONYMOUS_ENABLED=true
|
||||
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
|
||||
- GF_AUTH_DISABLE_LOGIN_FORM=true
|
||||
- GF_FEATURE_TOGGLES_ENABLE=traceqlEditor traceQLStreaming metricsSummary
|
||||
env_file:
|
||||
- ./testnet/monitoring/grafana/plugins.env
|
||||
volumes:
|
||||
- ./testnet/monitoring/grafana/grafana.ini:/etc/grafana/grafana.ini:z
|
||||
- ./testnet/monitoring/grafana/datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml:z
|
||||
- ./testnet/monitoring/grafana/dashboards.yml:/etc/grafana/provisioning/dashboards/dashboards.yml:z
|
||||
- ./testnet/monitoring/grafana/dashboards:/var/lib/grafana/dashboards/:z
|
||||
ports:
|
||||
- 9091:3000
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
- prometheus
|
||||
|
||||
loki:
|
||||
image: grafana/loki:2.9.2
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
|
||||
# Tempo runs as unpriviliged user, volumes need to be chowned before running.
|
||||
tempo-init:
|
||||
image: busybox:latest
|
||||
user: root
|
||||
entrypoint:
|
||||
- "chown"
|
||||
- "10001:10001"
|
||||
- "/var/tempo"
|
||||
volumes:
|
||||
- ./tempo-data:/var/tempo
|
||||
|
||||
tempo:
|
||||
image: grafana/tempo:latest
|
||||
container_name: tempo
|
||||
command: [ "-config.file=/etc/tempo.yaml" ]
|
||||
volumes:
|
||||
- ./testnet/monitoring/tempo.yaml:/etc/tempo.yaml:z
|
||||
- ./tempo-data:/var/tempo
|
||||
ports:
|
||||
- "4317:4317" # otlp grpc
|
||||
depends_on:
|
||||
- tempo-init
|
||||
|
||||
# L2 Sequencer Demo Services
|
||||
l2-nginx:
|
||||
container_name: l2_nginx
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
ports:
|
||||
- "18080:18080"
|
||||
depends_on:
|
||||
- cfgsync
|
||||
- explorer
|
||||
volumes:
|
||||
- ./testnet/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./testnet/static:/usr/share/nginx/html:ro
|
||||
entrypoint: [ "nginx", "-g", "daemon off;" ]
|
||||
|
||||
l2-sequencer:
|
||||
container_name: l2_sequencer
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
environment:
|
||||
- SEQUENCER_LISTEN_ADDR=0.0.0.0:8080
|
||||
- SEQUENCER_NODE_ENDPOINT=http://logos-blockchain-node-0:18081
|
||||
- SEQUENCER_DB_PATH=/data/sequencer.db
|
||||
- SEQUENCER_SIGNING_KEY_PATH=/data/sequencer.key
|
||||
- SEQUENCER_CHANNEL_ID=6d656d636f696e00000000000000000000000000000000000000000000000001
|
||||
- SEQUENCER_INITIAL_BALANCE=1000
|
||||
volumes:
|
||||
- l2-sequencer-data:/data
|
||||
entrypoint: [ "/usr/bin/logos-blockchain-demo-sequencer" ]
|
||||
|
||||
l2-archiver:
|
||||
container_name: l2_archiver
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
environment:
|
||||
- TESTNET_ENDPOINT=http://logos-blockchain-node-1:18081
|
||||
- CHANNEL_ID=6d656d636f696e00000000000000000000000000000000000000000000000001
|
||||
- TOKEN_NAME=MEM
|
||||
entrypoint: [ "/usr/bin/logos-blockchain-demo-archiver" ]
|
||||
|
||||
# Node data volume is marked as external and assumes
|
||||
# that configuration files were placed by compose.setup.yml
|
||||
volumes:
|
||||
l2-sequencer-data:
|
||||
node-data:
|
||||
name: logos-node-data
|
||||
external: true
|
||||
@@ -0,0 +1,81 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
|
||||
cfgsync:
|
||||
container_name: cfgsync
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- node-data:/node-data
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
ports:
|
||||
- "4400:4400/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/setup_cfgsync_server.sh
|
||||
|
||||
client-0:
|
||||
container_name: client_0
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- node-data:/node-data
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- LB_HOST_IDX=0
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE0_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE0_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE0_API_PORT}
|
||||
entrypoint: /etc/logos-blockchain/scripts/setup_cfgsync_client.sh
|
||||
|
||||
client-1:
|
||||
container_name: client_1
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- node-data:/node-data
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- LB_HOST_IDX=1
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE1_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE1_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE1_API_PORT}
|
||||
entrypoint: /etc/logos-blockchain/scripts/setup_cfgsync_client.sh
|
||||
|
||||
client-2:
|
||||
container_name: client_2
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- node-data:/node-data
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- LB_HOST_IDX=2
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE2_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE2_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE2_API_PORT}
|
||||
entrypoint: /etc/logos-blockchain/scripts/setup_cfgsync_client.sh
|
||||
|
||||
client-3:
|
||||
container_name: client_3
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- node-data:/node-data
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- LB_HOST_IDX=3
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE3_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE3_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE3_API_PORT}
|
||||
entrypoint: /etc/logos-blockchain/scripts/setup_cfgsync_client.sh
|
||||
|
||||
volumes:
|
||||
node-data:
|
||||
name: logos-node-data
|
||||
@@ -1,209 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
|
||||
explorer:
|
||||
container_name: explorer
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
depends_on:
|
||||
- logos-blockchain-node-0
|
||||
environment:
|
||||
- NBE_NODE_API_HOST=logos-blockchain-node-0
|
||||
- NBE_NODE_API_PORT=${NODE0_API_PORT}
|
||||
ports:
|
||||
- "8000:8000/tcp"
|
||||
entrypoint: /opt/scripts/run_explorer.sh
|
||||
|
||||
cfgsync:
|
||||
container_name: cfgsync
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
depends_on:
|
||||
- grafana
|
||||
ports:
|
||||
- "4400:4400/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_cfgsync.sh
|
||||
|
||||
logos-blockchain-node-0:
|
||||
container_name: logos_blockchain_node_0
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
- ./tests/kzgrs/kzgrs_test_params:/kzgrs_test_params:z
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE0_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE0_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE0_API_PORT}
|
||||
- FAUCET_PORT=${NODE0_FAUCET_PORT}
|
||||
ports:
|
||||
- "3000:3000/udp"
|
||||
- "3400:3400/udp"
|
||||
- "18085:18085/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_node.sh
|
||||
|
||||
logos-blockchain-node-1:
|
||||
container_name: logos_blockchain_node_1
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
- ./tests/kzgrs/kzgrs_test_params:/kzgrs_test_params:z
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE1_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE1_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE1_API_PORT}
|
||||
- FAUCET_PORT=${NODE1_FAUCET_PORT}
|
||||
ports:
|
||||
- "3001:3001/udp"
|
||||
- "3401:3401/udp"
|
||||
- "18081:18081/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_node.sh
|
||||
|
||||
logos-blockchain-node-2:
|
||||
container_name: logos_blockchain_node_2
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
- ./tests/kzgrs/kzgrs_test_params:/kzgrs_test_params:z
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE2_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE2_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE2_API_PORT}
|
||||
- FAUCET_PORT=${NODE2_FAUCET_PORT}
|
||||
ports:
|
||||
- "3002:3002/udp"
|
||||
- "3402:3402/udp"
|
||||
- "18082:18082/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_node.sh
|
||||
|
||||
logos-blockchain-node-3:
|
||||
container_name: logos_blockchain_node_3
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
volumes:
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
- ./tests/kzgrs/kzgrs_test_params:/kzgrs_test_params:z
|
||||
depends_on:
|
||||
- cfgsync
|
||||
environment:
|
||||
- CFG_HOST_IP=${PUBLIC_IP_ADDR}
|
||||
- CFG_NETWORK_PORT=${NODE3_NET_PORT}
|
||||
- CFG_BLEND_PORT=${NODE3_BLEND_PORT}
|
||||
- CFG_API_PORT=${NODE3_API_PORT}
|
||||
- FAUCET_PORT=${NODE3_FAUCET_PORT}
|
||||
ports:
|
||||
- "3003:3003/udp"
|
||||
- "3403:3403/udp"
|
||||
- "18083:18083/tcp"
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_node.sh
|
||||
|
||||
prometheus:
|
||||
container_name: prometheus
|
||||
image: prom/prometheus:v3.0.1
|
||||
volumes:
|
||||
- ./testnet/monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:z
|
||||
command:
|
||||
- --config.file=/etc/prometheus/prometheus.yml
|
||||
- --storage.tsdb.retention.time=7d
|
||||
- --web.enable-otlp-receiver
|
||||
ports:
|
||||
- 0.0.0.0:9090:9090
|
||||
restart: on-failure
|
||||
|
||||
grafana:
|
||||
container_name: grafana
|
||||
image: grafana/grafana:latest
|
||||
environment:
|
||||
- GF_AUTH_ANONYMOUS_ENABLED=true
|
||||
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
|
||||
- GF_AUTH_DISABLE_LOGIN_FORM=true
|
||||
- GF_FEATURE_TOGGLES_ENABLE=traceqlEditor traceQLStreaming metricsSummary
|
||||
env_file:
|
||||
- ./testnet/monitoring/grafana/plugins.env
|
||||
volumes:
|
||||
- ./testnet/monitoring/grafana/grafana.ini:/etc/grafana/grafana.ini:z
|
||||
- ./testnet/monitoring/grafana/datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml:z
|
||||
- ./testnet/monitoring/grafana/dashboards.yml:/etc/grafana/provisioning/dashboards/dashboards.yml:z
|
||||
- ./testnet/monitoring/grafana/dashboards:/var/lib/grafana/dashboards/:z
|
||||
ports:
|
||||
- 9091:3000
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
- prometheus
|
||||
|
||||
loki:
|
||||
image: grafana/loki:2.9.2
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
|
||||
# Tempo runs as unpriviliged user, volumes need to be chowned before running.
|
||||
tempo-init:
|
||||
image: busybox:latest
|
||||
user: root
|
||||
entrypoint:
|
||||
- "chown"
|
||||
- "10001:10001"
|
||||
- "/var/tempo"
|
||||
volumes:
|
||||
- ./tempo-data:/var/tempo
|
||||
|
||||
tempo:
|
||||
image: grafana/tempo:latest
|
||||
container_name: tempo
|
||||
command: [ "-config.file=/etc/tempo.yaml" ]
|
||||
volumes:
|
||||
- ./testnet/monitoring/tempo.yaml:/etc/tempo.yaml:z
|
||||
- ./tempo-data:/var/tempo
|
||||
ports:
|
||||
- "4317:4317" # otlp grpc
|
||||
depends_on:
|
||||
- tempo-init
|
||||
|
||||
# L2 Sequencer Demo Services
|
||||
l2-nginx:
|
||||
container_name: l2_nginx
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
ports:
|
||||
- "18080:18080"
|
||||
depends_on:
|
||||
- cfgsync
|
||||
- explorer
|
||||
volumes:
|
||||
- ./testnet/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./testnet/static:/usr/share/nginx/html:ro
|
||||
entrypoint: [ "nginx", "-g", "daemon off;" ]
|
||||
|
||||
l2-sequencer:
|
||||
container_name: l2_sequencer
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
environment:
|
||||
- SEQUENCER_LISTEN_ADDR=0.0.0.0:8080
|
||||
- SEQUENCER_NODE_ENDPOINT=http://logos-blockchain-node-0:18081
|
||||
- SEQUENCER_DB_PATH=/data/sequencer.db
|
||||
- SEQUENCER_SIGNING_KEY_PATH=/data/sequencer.key
|
||||
- SEQUENCER_CHANNEL_ID=6d656d636f696e00000000000000000000000000000000000000000000000001
|
||||
- SEQUENCER_INITIAL_BALANCE=1000
|
||||
volumes:
|
||||
- l2-sequencer-data:/data
|
||||
entrypoint: [ "/usr/bin/logos-blockchain-demo-sequencer" ]
|
||||
|
||||
l2-archiver:
|
||||
container_name: l2_archiver
|
||||
image: ghcr.io/logos-blockchain/logos-blockchain:devnet
|
||||
environment:
|
||||
- TESTNET_ENDPOINT=http://logos-blockchain-node-1:18081
|
||||
- CHANNEL_ID=6d656d636f696e00000000000000000000000000000000000000000000000001
|
||||
- TOKEN_NAME=MEM
|
||||
entrypoint: [ "/usr/bin/logos-blockchain-demo-archiver" ]
|
||||
|
||||
volumes:
|
||||
l2-sequencer-data:
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
compose.devnet.run.yml
|
||||
+1
-1
@@ -8,7 +8,7 @@ services:
|
||||
image: logos-blockchain:latest
|
||||
volumes:
|
||||
- ./testnet:/etc/logos-blockchain
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_cfgsync.sh
|
||||
entrypoint: /etc/logos-blockchain/scripts/run_cfgsync_server.sh
|
||||
|
||||
logos-blockchain-node:
|
||||
build:
|
||||
|
||||
@@ -6,6 +6,11 @@ faucet_settings:
|
||||
note_count: 3
|
||||
note_value: 10000000
|
||||
|
||||
deployment_settings_storage_path:
|
||||
deployment-settings.yaml
|
||||
|
||||
mode: Run
|
||||
|
||||
# Tracing
|
||||
tracing_settings:
|
||||
logger: Stdout
|
||||
|
||||
@@ -28,6 +28,7 @@ serde = { workspace = true }
|
||||
serde_json = { default-features = false, version = "1.0" }
|
||||
serde_path_to_error = "0.1"
|
||||
serde_yaml = "0.9"
|
||||
time = { default-features = false, version = "0.3" }
|
||||
tokio = { default-features = false, features = ["macros", "net", "rt-multi-thread"], version = "1" }
|
||||
tracing = { workspace = true }
|
||||
|
||||
|
||||
@@ -1,26 +1,54 @@
|
||||
use std::{path::PathBuf, process};
|
||||
|
||||
use clap::Parser;
|
||||
use logos_blockchain_cfgsync::server::{CfgSyncConfig, cfgsync_app};
|
||||
use logos_blockchain_cfgsync::{
|
||||
CfgsyncMode,
|
||||
server::{CfgSyncConfig, cfgsync_app},
|
||||
};
|
||||
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
fn parse_rfc3339(s: &str) -> Result<OffsetDateTime, String> {
|
||||
OffsetDateTime::parse(s, &Rfc3339)
|
||||
.map_err(|e| format!("Invalid RFC3339 format (2026-02-12T04:45:00Z): {e}"))
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(about = "CfgSync")]
|
||||
struct Args {
|
||||
config: PathBuf,
|
||||
#[arg(short, long, env = "CHAIN_START_TIME", value_parser = parse_rfc3339)]
|
||||
chain_start_time: Option<OffsetDateTime>,
|
||||
#[arg(short, long, env = "CFG_SERVER_MODE")]
|
||||
mode: Option<CfgsyncMode>,
|
||||
#[arg(short, long, env = "CFG_SERVER_STORAGE_PATH")]
|
||||
storage_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let cli = Args::parse();
|
||||
|
||||
let config = CfgSyncConfig::load_from_file(&cli.config).unwrap_or_else(|err| {
|
||||
let mut config = CfgSyncConfig::load_from_file(&cli.config).unwrap_or_else(|err| {
|
||||
eprintln!("{err}");
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
if let Some(chain_start_time) = cli.chain_start_time {
|
||||
config.chain_start_time = Some(chain_start_time);
|
||||
}
|
||||
|
||||
if let Some(storage_path) = cli.storage_path {
|
||||
config.deployment_settings_storage_path = storage_path;
|
||||
}
|
||||
|
||||
if let Some(mode) = cli.mode {
|
||||
config.mode = mode;
|
||||
}
|
||||
|
||||
let port = config.port;
|
||||
let app = cfgsync_app(config.into());
|
||||
let mode = config.mode;
|
||||
let app = cfgsync_app(config.into(), mode);
|
||||
|
||||
println!("Server running on http://0.0.0.0:{port}");
|
||||
let listener = TcpListener::bind(&format!("0.0.0.0:{port}")).await.unwrap();
|
||||
|
||||
@@ -48,6 +48,11 @@ pub fn create_node_configs(
|
||||
ids.push(id_bytes);
|
||||
}
|
||||
|
||||
// Clippy in 1.93.0:
|
||||
// > an unstable sort typically performs faster without any
|
||||
// > observable difference for this data type. [stable_sort_primitive]
|
||||
ids.sort_unstable();
|
||||
|
||||
let (consensus_configs, faucet_note_keys, genesis_tx) =
|
||||
create_consensus_configs(&ids, SHORT_PROLONGED_BOOTSTRAP_PERIOD, faucet_settings);
|
||||
let network_configs = create_network_configs(&ids, &NetworkParams::default());
|
||||
|
||||
@@ -5,6 +5,7 @@ pub mod server;
|
||||
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use clap::ValueEnum;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const DEFAULT_LIBP2P_NETWORK_PORT: u16 = 3000;
|
||||
@@ -68,3 +69,10 @@ pub struct FaucetSettings {
|
||||
pub note_count: usize,
|
||||
pub note_value: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, ValueEnum)]
|
||||
#[clap(rename_all = "kebab-case")]
|
||||
pub enum CfgsyncMode {
|
||||
Setup,
|
||||
Run,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
@@ -9,6 +10,7 @@ use lb_node::config::{
|
||||
deployment::{DeploymentSettings, WellKnownDeployment},
|
||||
};
|
||||
use lb_tests::topology::configs::GeneralConfig;
|
||||
use time::OffsetDateTime;
|
||||
use tokio::{sync::oneshot::Sender, time::timeout};
|
||||
|
||||
use crate::{
|
||||
@@ -26,22 +28,25 @@ pub struct ConfigRepo {
|
||||
waiting_hosts: Mutex<HashMap<Host, Sender<RepoResponse>>>,
|
||||
generated_user_configs: Mutex<HashMap<Host, GeneralConfig>>,
|
||||
deployment_settings: Mutex<Option<DeploymentSettings>>,
|
||||
pub deployment_settings_storage_path: PathBuf,
|
||||
n_hosts: usize,
|
||||
faucet_settings: FaucetSettings,
|
||||
tracing_settings: TracingConfig,
|
||||
chain_start_time: OffsetDateTime,
|
||||
timeout_duration: Duration,
|
||||
}
|
||||
|
||||
impl From<CfgSyncConfig> for Arc<ConfigRepo> {
|
||||
fn from(config: CfgSyncConfig) -> Self {
|
||||
let faucet_settings = config.faucet_settings();
|
||||
let tracing_settings = config.tracing_settings();
|
||||
|
||||
ConfigRepo::new(
|
||||
config.n_hosts,
|
||||
faucet_settings,
|
||||
tracing_settings,
|
||||
config.faucet_settings(),
|
||||
config
|
||||
.chain_start_time
|
||||
.unwrap_or_else(OffsetDateTime::now_utc),
|
||||
config.tracing_settings(),
|
||||
Duration::from_secs(config.timeout),
|
||||
config.deployment_settings_storage_path,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -51,15 +56,19 @@ impl ConfigRepo {
|
||||
pub fn new(
|
||||
n_hosts: usize,
|
||||
faucet_settings: FaucetSettings,
|
||||
chain_start_time: OffsetDateTime,
|
||||
tracing_settings: TracingConfig,
|
||||
timeout_duration: Duration,
|
||||
deployment_settings_storage_path: PathBuf,
|
||||
) -> Arc<Self> {
|
||||
let repo = Arc::new(Self {
|
||||
waiting_hosts: Mutex::new(HashMap::new()),
|
||||
generated_user_configs: Mutex::new(HashMap::new()),
|
||||
deployment_settings: Mutex::new(None),
|
||||
deployment_settings_storage_path,
|
||||
n_hosts,
|
||||
faucet_settings,
|
||||
chain_start_time,
|
||||
tracing_settings,
|
||||
timeout_duration,
|
||||
});
|
||||
@@ -107,6 +116,14 @@ impl ConfigRepo {
|
||||
None
|
||||
}
|
||||
|
||||
fn persist_deployment_settings(&self, settings: &DeploymentSettings) -> Result<(), String> {
|
||||
let yaml = serde_yaml::to_string(settings)
|
||||
.map_err(|e| format!("Error: Failed to serialize deployment settings: {e}"))?;
|
||||
std::fs::write(&self.deployment_settings_storage_path, yaml)
|
||||
.map_err(|err| format!("Failed to write config to file: {err}"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run(&self) {
|
||||
let timeout_duration = self.timeout_duration;
|
||||
|
||||
@@ -121,6 +138,7 @@ impl ConfigRepo {
|
||||
let devnet_settings = {
|
||||
let mut default_settings = DeploymentSettings::from(WellKnownDeployment::Devnet);
|
||||
default_settings.cryptarchia.genesis_state = genesis_tx;
|
||||
default_settings.time.chain_start_time = self.chain_start_time;
|
||||
default_settings
|
||||
};
|
||||
|
||||
@@ -134,6 +152,9 @@ impl ConfigRepo {
|
||||
*deployment_settings = Some(devnet_settings.clone());
|
||||
};
|
||||
|
||||
self.persist_deployment_settings(&devnet_settings)
|
||||
.expect("Settings should be persisted");
|
||||
|
||||
for (host, sender) in waiting_hosts.drain() {
|
||||
let config = configs.get(&host).expect("host should have a config");
|
||||
drop(sender.send(RepoResponse::Config(Box::new((
|
||||
|
||||
@@ -2,8 +2,9 @@ use std::{fs, path::PathBuf, sync::Arc};
|
||||
|
||||
use axum::{
|
||||
Json, Router,
|
||||
body::Body,
|
||||
extract::State,
|
||||
http::StatusCode,
|
||||
http::{Response, StatusCode},
|
||||
response::IntoResponse,
|
||||
routing::{get, post},
|
||||
};
|
||||
@@ -11,10 +12,11 @@ use lb_node::config::TracingConfig;
|
||||
use lb_tests::nodes::create_validator_config;
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
use serde::Deserialize;
|
||||
use time::OffsetDateTime;
|
||||
use tokio::sync::oneshot::channel;
|
||||
|
||||
use crate::{
|
||||
FaucetSettings, Host, RegistrationInfo,
|
||||
CfgsyncMode, FaucetSettings, Host, RegistrationInfo,
|
||||
repo::{ConfigRepo, RepoResponse},
|
||||
};
|
||||
|
||||
@@ -23,6 +25,10 @@ pub struct CfgSyncConfig {
|
||||
pub port: u16,
|
||||
pub n_hosts: usize,
|
||||
pub timeout: u64,
|
||||
pub chain_start_time: Option<OffsetDateTime>,
|
||||
pub deployment_settings_storage_path: PathBuf,
|
||||
|
||||
pub mode: CfgsyncMode,
|
||||
|
||||
pub faucet_settings: FaucetSettings,
|
||||
// Tracing params
|
||||
@@ -68,39 +74,38 @@ async fn init_node(
|
||||
)
|
||||
}
|
||||
|
||||
async fn generate_config(
|
||||
State(repo): State<Arc<ConfigRepo>>,
|
||||
Json(info): Json<RegistrationInfo>,
|
||||
) -> impl IntoResponse {
|
||||
let host = Host::from(info);
|
||||
|
||||
repo.append(host).map_or_else(
|
||||
|| {
|
||||
(
|
||||
StatusCode::BAD_REQUEST,
|
||||
"Network not initialized. Initial nodes must sync first.",
|
||||
)
|
||||
.into_response()
|
||||
},
|
||||
|cfg| {
|
||||
let node_config = create_validator_config(cfg, repo.deployment_settings().unwrap());
|
||||
let yaml = serde_yaml::to_string(&node_config).unwrap_or_default();
|
||||
|
||||
(StatusCode::OK, [(CONTENT_TYPE, "text/yaml")], yaml).into_response()
|
||||
},
|
||||
async fn handle_mode_error() -> (StatusCode, &'static str) {
|
||||
(
|
||||
StatusCode::METHOD_NOT_ALLOWED,
|
||||
"Setup is disabled: Server is in Read-Only mode.",
|
||||
)
|
||||
}
|
||||
|
||||
async fn deployment_settings(State(repo): State<Arc<ConfigRepo>>) -> impl IntoResponse {
|
||||
let deployment_settings = repo.deployment_settings();
|
||||
let yaml = serde_yaml::to_string(&deployment_settings).unwrap_or_default();
|
||||
(StatusCode::OK, [(CONTENT_TYPE, "text/yaml")], yaml).into_response()
|
||||
match tokio::fs::read(&repo.deployment_settings_storage_path).await {
|
||||
Ok(bytes) => Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(CONTENT_TYPE, "text/yaml")
|
||||
.body(Body::from(bytes))
|
||||
.unwrap(),
|
||||
Err(e) => {
|
||||
eprintln!("Failed to read deployment file: {e}");
|
||||
(StatusCode::NOT_FOUND, "Deployment file not found").into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cfgsync_app(config_repo: Arc<ConfigRepo>) -> Router {
|
||||
Router::new()
|
||||
.route("/init-with-node", post(init_node))
|
||||
.route("/generate-config", post(generate_config))
|
||||
.route("/deployment-settings", get(deployment_settings))
|
||||
.with_state(config_repo)
|
||||
pub fn cfgsync_app(config_repo: Arc<ConfigRepo>, mode: CfgsyncMode) -> Router {
|
||||
let mut router = Router::new().route("/deployment-settings", get(deployment_settings));
|
||||
|
||||
match mode {
|
||||
CfgsyncMode::Setup => {
|
||||
router = router.route("/init-with-node", post(init_node));
|
||||
}
|
||||
CfgsyncMode::Run => {
|
||||
router = router.route("/init-with-node", post(handle_mode_error));
|
||||
}
|
||||
}
|
||||
|
||||
router.with_state(config_repo)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,11 @@ faucet_settings:
|
||||
note_count: 3
|
||||
note_value: 10000000
|
||||
|
||||
deployment_settings_storage_path:
|
||||
deployment-settings.yaml
|
||||
|
||||
mode: Run
|
||||
|
||||
# Tracing
|
||||
tracing_settings:
|
||||
logger: !Stdout
|
||||
|
||||
@@ -9,6 +9,8 @@ const SERVER_CFG: &str = "../cfgsync.yaml"; // Use config from "testnet" dir.
|
||||
#[tokio::test]
|
||||
async fn smoke_test_four_clients() {
|
||||
let mut server = std::process::Command::new(SERVER_BIN)
|
||||
.arg("--mode")
|
||||
.arg("setup")
|
||||
.arg(SERVER_CFG)
|
||||
.spawn()
|
||||
.expect("server failed");
|
||||
@@ -38,6 +40,5 @@ async fn smoke_test_four_clients() {
|
||||
fs::remove_file(out).unwrap();
|
||||
}
|
||||
|
||||
sleep(Duration::from_secs(51)).await;
|
||||
server.kill().and_then(|()| server.wait()).unwrap();
|
||||
}
|
||||
|
||||
@@ -14,9 +14,11 @@ const SERVER_CFG: &str = "./tests/cfgsync.yaml";
|
||||
|
||||
#[ignore = "For local debugging"]
|
||||
#[tokio::test]
|
||||
async fn test_spawn_nodes_from_cfgsync_custom_ports() {
|
||||
async fn test_deploy_setup_stage() {
|
||||
// Start the configuration server
|
||||
let mut server = std::process::Command::new(SERVER_BIN)
|
||||
.arg("--mode")
|
||||
.arg("setup")
|
||||
.arg(SERVER_CFG)
|
||||
.spawn()
|
||||
.expect("server failed");
|
||||
@@ -88,3 +90,51 @@ async fn test_spawn_nodes_from_cfgsync_custom_ports() {
|
||||
server.kill().unwrap();
|
||||
server.wait().unwrap();
|
||||
}
|
||||
|
||||
#[ignore = "For local debugging"]
|
||||
#[tokio::test]
|
||||
async fn test_deploy_run_stage() {
|
||||
let server = std::process::Command::new(SERVER_BIN)
|
||||
.arg("--mode")
|
||||
.arg("run")
|
||||
.arg("--storage-path")
|
||||
.arg("cfgsync-deployment-settings.yaml")
|
||||
.arg(SERVER_CFG)
|
||||
.spawn()
|
||||
.expect("server failed to start in run mode");
|
||||
|
||||
sleep(Duration::from_secs(15)).await;
|
||||
|
||||
let response = reqwest::get("http://127.0.0.1:4400/deployment-settings")
|
||||
.await
|
||||
.expect("Failed to hit deployment-settings endpoint");
|
||||
let yaml_bytes = response.bytes().await.unwrap();
|
||||
let deployment: DeploymentSettings = serde_yaml::from_slice(&yaml_bytes).unwrap();
|
||||
|
||||
let mut nodes = Vec::new();
|
||||
|
||||
for i in 0..4 {
|
||||
let node_cfg_path = format!(".tmp_node_{i}.yaml");
|
||||
|
||||
let user_yaml = fs::read_to_string(&node_cfg_path).expect("Node config file missing.");
|
||||
let user_config: UserConfig =
|
||||
serde_yaml::from_str(&user_yaml).expect("Failed to parse user config");
|
||||
|
||||
let run_config = RunConfig {
|
||||
user: user_config,
|
||||
deployment: deployment.clone(),
|
||||
};
|
||||
|
||||
println!(">>>> Spawning Node {i} from disk (.tmp_node_{i}.yaml)");
|
||||
let node = Validator::spawn(run_config)
|
||||
.await
|
||||
.expect("Node spawn failed");
|
||||
nodes.push(node);
|
||||
}
|
||||
|
||||
println!("\nIndependent network spawned from disk. Press Ctrl+C to terminate.\n");
|
||||
|
||||
tokio::signal::ctrl_c().await.unwrap();
|
||||
drop(nodes);
|
||||
drop(server);
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
exec /usr/bin/logos-blockchain-cfgsync-server /etc/logos-blockchain/cfgsync.yaml
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
export CFG_SERVER_MODE="run" \
|
||||
CFG_SERVER_STORAGE_PATH="/node-data/cfgsync/deploymen-settings.yaml"
|
||||
|
||||
exec /usr/bin/logos-blockchain-cfgsync-server /etc/logos-blockchain/cfgsync.yaml
|
||||
@@ -2,20 +2,18 @@
|
||||
|
||||
set -e
|
||||
|
||||
export CFG_FILE_PATH="/config.yaml" \
|
||||
export CFG_FILE_PATH="/node-data/${LB_HOST_IDX}/config.yaml" \
|
||||
CFG_SERVER_ADDR="http://cfgsync:4400" \
|
||||
CFG_HOST_IDENTIFIER="validator-$CFG_API_PORT" \
|
||||
LOG_LEVEL="INFO" \
|
||||
POL_PROOF_DEV_MODE=true
|
||||
|
||||
/usr/bin/logos-blockchain-cfgsync-client
|
||||
CFG_DEPLOYMENT_PATH="/node-data/cfgsync/deployment-settings.yaml" \
|
||||
LOG_LEVEL="INFO"
|
||||
|
||||
echo "Starting Faucet..."
|
||||
/usr/bin/logos-blockchain-faucet \
|
||||
--port $FAUCET_PORT \
|
||||
--node-base-url "http://localhost:$CFG_API_PORT"\
|
||||
--host-identifier $CFG_HOST_IDENTIFIER
|
||||
--host-identifier $CFG_HOST_IDENTIFIER \
|
||||
--drip-amount 1000 &
|
||||
|
||||
echo "Starting Node..."
|
||||
exec /usr/bin/logos-blockchain-node /config.yaml
|
||||
exec /usr/bin/logos-blockchain-node --deployment $CFG_DEPLOYMENT_PATH $CFG_FILE_PATH
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -rf /node-data/${LB_HOST_IDX}
|
||||
|
||||
set -e
|
||||
|
||||
export CFG_FILE_PATH="/node-data/${LB_HOST_IDX}/config.yaml" \
|
||||
CFG_SERVER_ADDR="http://cfgsync:4400" \
|
||||
CFG_HOST_IDENTIFIER="validator-$CFG_NETWORK_PORT"
|
||||
|
||||
mkdir /node-data/${LB_HOST_IDX}
|
||||
|
||||
exec /usr/bin/logos-blockchain-cfgsync-client
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -rf /node-data/cfgsync
|
||||
|
||||
set -e
|
||||
|
||||
export CFG_SERVER_MODE="setup" \
|
||||
CFG_SERVER_STORAGE_PATH="/node-data/cfgsync/deployment-settings.yaml" \
|
||||
CHAIN_START_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
mkdir /node-data/cfgsync
|
||||
|
||||
exec /usr/bin/logos-blockchain-cfgsync-server /etc/logos-blockchain/cfgsync.yaml
|
||||
Reference in New Issue
Block a user