name: dchain # ═══════════════════════════════════════════════════════════════════════════ # DChain — три полноценных ноды, симуляция работы в интернете # # Топология сети: # # ┌──────────────────────────────────────────────────────────────────────┐ # │ internet (172.30.0.0/24) │ # │ │ # │ node1 ── 172.30.0.11 validator + relay :4001 :8081 │ # │ node2 ── 172.30.0.12 validator + relay :4002 :8082 │ # │ node3 ── 172.30.0.13 validator + relay :4003 :8083 │ # │ │ # └──────────────────────────────────────────────────────────────────────┘ # │ │ │ # dc1 (172.31.1.0/24) dc2 (172.31.2.0/24) dc3 (172.31.3.0/24) # internal — только internal — только internal — только # для node1 для node2 для node3 # # Правила: # • Ноды общаются только через backbone «internet» по фиксированным IP. # • Каждая dc-сеть изолирована (internal: true) — имитирует приватную # LAN датацентра, недоступную для других нод напрямую. # • P2P bootstrap — через IP backbone-сети, как в реальном интернете. # • Все три ноды — полноценные валидаторы и relay-провайдеры. # PBFT 3-of-3, fault tolerance f=1: сеть работает при падении одной. # # Идентичности (ключи вшиты в образ из testdata/): # node1 pub: 26018d40e40514f38f799eee403f62da98cb5ac936e29049629f1873cbcb4070 # pid: 12D3KooWCNj2ugnjqoJFPdRuhGZHvGTbEiTMmHDimfsxmGYcjGo9 # # node2 pub: bf3628d1a10fcf5a90d2cb31f387c8d1f2dac6a2c54c736c27d5ea04af9696a2 # pid: 12D3KooWNgmwMbaw5K7vDbGxb9zvcF8gur5GWXGoFEVfKzSNc9bf # # node3 pub: 6316e7427654cd2e300033c5e13b6182d595ec2c63bc8396b74183296112510c # pid: 12D3KooWGVAnaq1EgH1dN49fQWvw1z71R5bZj7UmPkUeQkW4783V # # Быстрый старт: # docker compose up --build -d # docker compose --profile deploy run --rm deploy # open http://localhost:8081 # # Сброс данных: # docker compose down -v && docker compose up --build -d # ═══════════════════════════════════════════════════════════════════════════ # ── Сети ───────────────────────────────────────────────────────────────────── networks: # Общий backbone «интернет» — единственный путь между нодами internet: name: dchain_internet driver: bridge ipam: driver: default config: - subnet: 172.30.0.0/24 gateway: 172.30.0.1 # Изолированные «датацентры» — нет маршрута до других нод и хоста dc1: name: dchain_dc1 driver: bridge internal: true ipam: config: - subnet: 172.31.1.0/24 dc2: name: dchain_dc2 driver: bridge internal: true ipam: config: - subnet: 172.31.2.0/24 dc3: name: dchain_dc3 driver: bridge internal: true ipam: config: - subnet: 172.31.3.0/24 # ── Тома ───────────────────────────────────────────────────────────────────── volumes: node1_data: node2_data: node3_data: # ── Общие якоря ────────────────────────────────────────────────────────────── x-node-base: &node-base build: . restart: unless-stopped # Все три ноды — валидаторы (PBFT 3-of-3) x-validators: &validators VALIDATORS: "26018d40e40514f38f799eee403f62da98cb5ac936e29049629f1873cbcb4070,bf3628d1a10fcf5a90d2cb31f387c8d1f2dac6a2c54c736c27d5ea04af9696a2,6316e7427654cd2e300033c5e13b6182d595ec2c63bc8396b74183296112510c" x-healthcheck: &healthcheck test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8080/api/netstats | grep -q total_blocks"] interval: 5s timeout: 3s retries: 24 start_period: 8s # ════════════════════════════════════════════════════════════════════════════ services: # ── node1 — Лондон / server-1.dchain.local ────────────────────────────── # Роль : genesis · validator · relay provider # Backbone: 172.30.0.11 DC LAN: 172.31.1.10 # Relay fee: 2000 µT # ──────────────────────────────────────────────────────────────────────── node1: <<: *node-base container_name: node1 hostname: server-1.dchain.local networks: internet: ipv4_address: 172.30.0.11 dc1: ipv4_address: 172.31.1.10 ports: - "4001:4001" # libp2p P2P - "8081:8080" # HTTP Explorer / REST API volumes: - node1_data:/data environment: <<: *validators entrypoint: - /bin/sh - -c - | exec /usr/local/bin/node \ --genesis \ --db /data/chain \ --mailbox-db /data/mailbox \ --key /keys/node1.json \ --relay-key /data/relay.json \ --listen /ip4/0.0.0.0/tcp/4001 \ --announce /ip4/172.30.0.11/tcp/4001 \ --stats-addr :8080 \ --validators "$$VALIDATORS" \ --heartbeat=true \ --register-relay \ --relay-fee 2000 healthcheck: *healthcheck # ── node2 — Нью-Йорк / server-2.dchain.local ──────────────────────────── # Роль : validator · relay provider # Backbone: 172.30.0.12 DC LAN: 172.31.2.10 # Bootstrap → node1 (172.30.0.11) по backbone IP # Relay fee: 1500 µT # ──────────────────────────────────────────────────────────────────────── node2: <<: *node-base container_name: node2 hostname: server-2.dchain.local networks: internet: ipv4_address: 172.30.0.12 dc2: ipv4_address: 172.31.2.10 ports: - "4002:4001" - "8082:8080" volumes: - node2_data:/data environment: <<: *validators NODE1_PEER: "/ip4/172.30.0.11/tcp/4001/p2p/12D3KooWCNj2ugnjqoJFPdRuhGZHvGTbEiTMmHDimfsxmGYcjGo9" entrypoint: - /bin/sh - -c - | exec /usr/local/bin/node \ --db /data/chain \ --mailbox-db /data/mailbox \ --key /keys/node2.json \ --relay-key /data/relay.json \ --listen /ip4/0.0.0.0/tcp/4001 \ --announce /ip4/172.30.0.12/tcp/4001 \ --stats-addr :8080 \ --validators "$$VALIDATORS" \ --peers "$$NODE1_PEER" \ --heartbeat=true \ --register-relay \ --relay-fee 1500 depends_on: node1: condition: service_healthy healthcheck: *healthcheck # ── node3 — Токио / server-3.dchain.local ─────────────────────────────── # Роль : validator · relay provider # Backbone: 172.30.0.13 DC LAN: 172.31.3.10 # Bootstrap → node1 + node2 по backbone IP # Relay fee: 1000 µT (самый дешёвый) # ──────────────────────────────────────────────────────────────────────── node3: <<: *node-base container_name: node3 hostname: server-3.dchain.local networks: internet: ipv4_address: 172.30.0.13 dc3: ipv4_address: 172.31.3.10 ports: - "4003:4001" - "8083:8080" volumes: - node3_data:/data environment: <<: *validators NODE1_PEER: "/ip4/172.30.0.11/tcp/4001/p2p/12D3KooWCNj2ugnjqoJFPdRuhGZHvGTbEiTMmHDimfsxmGYcjGo9" NODE2_PEER: "/ip4/172.30.0.12/tcp/4001/p2p/12D3KooWNgmwMbaw5K7vDbGxb9zvcF8gur5GWXGoFEVfKzSNc9bf" entrypoint: - /bin/sh - -c - | exec /usr/local/bin/node \ --db /data/chain \ --mailbox-db /data/mailbox \ --key /keys/node3.json \ --relay-key /data/relay.json \ --listen /ip4/0.0.0.0/tcp/4001 \ --announce /ip4/172.30.0.13/tcp/4001 \ --stats-addr :8080 \ --validators "$$VALIDATORS" \ --peers "$$NODE1_PEER,$$NODE2_PEER" \ --heartbeat=true \ --register-relay \ --relay-fee 1000 depends_on: node1: condition: service_healthy healthcheck: *healthcheck # ── deploy — одноразовый деплой 4 production-контрактов ───────────────── # Запуск: docker compose --profile deploy run --rm deploy # Ждёт готовности всех трёх нод, затем деплоит контракты. # ──────────────────────────────────────────────────────────────────────── deploy: profiles: [deploy] build: . container_name: deploy restart: "no" networks: - internet volumes: - ./scripts/deploy_contracts.sh:/scripts/deploy_contracts.sh:ro entrypoint: ["/bin/sh", "/scripts/deploy_contracts.sh"] environment: # Backbone IP-адреса — без DNS, как будто это разные серверы в интернете NODE1_URL: "http://172.30.0.11:8080" NODE2_URL: "http://172.30.0.12:8080" NODE3_URL: "http://172.30.0.13:8080" depends_on: node1: condition: service_healthy node2: condition: service_healthy node3: condition: service_healthy