From ce4f461d85cbb1e9807f21ae567dfab4489d34fb Mon Sep 17 00:00:00 2001 From: FlorianJeandenans Date: Fri, 7 Aug 2026 16:29:08 +0200 Subject: [PATCH] fix(blockchain): make dev-up actually start the local chain (3 stacked bugs) `make dev-up` was crash-looping on openinfra-blockchain-node-1. Root cause turned out to be three separate, stacked bugs, all pre-existing (none introduced this session) and apparently never exercised together end to end since the project moved from manual sealing to Aura+GRANDPA (the "local Aura GRANDPA testnet" commit, ADR-009): 1. **deployments/docker-compose.yml still passed `--consensus=manual- seal-3000`** to the node, a flag the CLI no longer accepts at all now that it runs real Aura block production + GRANDPA finality. This was the literal crash: `error: unexpected argument '--consensus' found`. Replaced with `--alice --force-authoring` (openinfra-dev's chain spec has exactly one genesis authority, Alice). 2. **blockchain/Dockerfile's ENTRYPOINT was never wired to docker/authority-entrypoint.sh.** That script already existed and already correctly inserts an authority's Aura (sr25519) and GRANDPA (ed25519) keys via `key insert`, driven by OPENINFRA_DEV_AUTHORITY_SEED -- but the Dockerfile's ENTRYPOINT was still the plain `openinfra-node` binary, so the script was dead code, copied into every image and never executed. Result: even with (1) fixed, the node started as an authority with a permanently empty keystore and sat at block #0 forever -- confirmed directly (`--alice` alone does not populate a usable keystore for this image/polkadot-sdk pinning; only the explicit `key insert` step does). 3. **No network-key auto-generation on a fresh volume.** Unlike a vanilla substrate-node-template, this build does not auto-generate a libp2p identity key on first run with a persistent --base-path (confirmed directly: NetworkKeyNotFound on an empty volume). Added an idempotent `key generate-node-key` step to authority-entrypoint.sh, ahead of the two `key insert` calls -- a no-op on a volume that already has one (so an existing dev deployment's peer ID is unaffected), required for `make dev-clean` (or any first boot) to actually work. docker-compose.yml also gains OPENINFRA_DEV_AUTHORITY_SEED=//Alice, OPENINFRA_NODE_BASE_PATH, and OPENINFRA_NODE_CHAIN -- the entrypoint script's own required inputs, matched exactly to the --base-path/--chain CLI args the node itself runs with (a mismatch here would silently insert keys into a keystore path the running node never reads from). ## Verified - Isolated `docker run` testing at each step (not just the final `docker compose up`): confirmed the exact `--consensus` CLI rejection, confirmed an empty keystore with (1) alone fixed, confirmed real block authoring + GRANDPA finalization (`Imported #1..#5`, `finalized #1`) once (2) was also fixed, confirmed NetworkKeyNotFound on a genuinely fresh volume and its fix. - Full `make dev-clean && make dev-up`: all six containers (blockchain- node, control-plane, provider-agent, postgres, redis, docker-socket- proxy) reach Healthy. `system_health`/`chain_getHeader` over RPC show a live, advancing, finalizing chain (block #0x48 and climbing within a minute of startup). - This is also the first time this session's local dev chain has actually run the current runtime end to end: `state_getMetadata` confirms `NetworkValidator` (pallet-network-validator, merged across ADR-013/014/015 this session) is present -- every prior PR this session could only encoding-verify against this pallet, never dispatch-verify, because the long-running dev chain predated it. That limitation is resolved for local dev going forward (a fresh `make dev-clean && make dev-up` is required to pick this up, since existing substrate-data volumes still hold pre-Aura/GRANDPA genesis state). Co-Authored-By: Claude Sonnet 5 --- blockchain/Dockerfile | 9 +++++++- blockchain/docker/authority-entrypoint.sh | 14 +++++++++++++ deployments/docker-compose.yml | 25 ++++++++++++++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/blockchain/Dockerfile b/blockchain/Dockerfile index b9ec867..1f50e27 100644 --- a/blockchain/Dockerfile +++ b/blockchain/Dockerfile @@ -25,4 +25,11 @@ RUN chmod 0755 /usr/local/bin/openinfra-authority-entrypoint USER 10001:10001 EXPOSE 9944 30333 -ENTRYPOINT ["/usr/local/bin/openinfra-node"] +# docker/authority-entrypoint.sh inserts this authority's Aura/GRANDPA +# keys (via OPENINFRA_DEV_AUTHORITY_SEED) before exec'ing openinfra-node +# with whatever CLI args docker-compose/CMD supplies -- without this, an +# authority's keystore stays empty and it can never author a block or +# vote in GRANDPA, no matter what CLI flags (--alice, etc.) are passed to +# openinfra-node directly. This was previously dead code: the script was +# copied into the image but never made the entrypoint. +ENTRYPOINT ["/usr/local/bin/openinfra-authority-entrypoint"] diff --git a/blockchain/docker/authority-entrypoint.sh b/blockchain/docker/authority-entrypoint.sh index 337e4a4..2760e0e 100644 --- a/blockchain/docker/authority-entrypoint.sh +++ b/blockchain/docker/authority-entrypoint.sh @@ -9,6 +9,20 @@ fi base_path="${OPENINFRA_NODE_BASE_PATH:-/var/lib/openinfra}" chain="${OPENINFRA_NODE_CHAIN:-openinfra-local}" +# This node's libp2p identity key. Unlike a vanilla substrate-node- +# template, this build does not auto-generate one on first run when a +# persistent --base-path is used (observed directly: NetworkKeyNotFound +# on a fresh volume) -- generate it once, idempotently, so a fresh +# volume (first boot, or after `make dev-clean`) starts cleanly instead +# of crash-looping on that error. A subsequent boot with the same +# volume leaves the existing key (and therefore this node's peer ID) +# untouched. +network_key_path="$base_path/chains/$chain/network/secret_ed25519" +if [ ! -f "$network_key_path" ]; then + mkdir -p "$(dirname "$network_key_path")" + openinfra-node key generate-node-key --file "$network_key_path" +fi + openinfra-node key insert \ --base-path "$base_path" \ --chain "$chain" \ diff --git a/deployments/docker-compose.yml b/deployments/docker-compose.yml index b81b7e6..4a88198 100644 --- a/deployments/docker-compose.yml +++ b/deployments/docker-compose.yml @@ -44,7 +44,20 @@ services: command: - --chain=openinfra-dev - --base-path=/var/lib/openinfra/data - - --consensus=manual-seal-3000 + # ADR-009: the dev chain spec (openinfra-dev) has exactly one + # genesis authority, Alice. --consensus=manual-seal-3000 (pre- + # ADR-009) is gone: the node's CLI no longer accepts it at all now + # that it runs real Aura block production + GRANDPA finality + # instead of manual sealing. --alice sets name=Alice and + # role=authority, but does NOT put usable Aura/GRANDPA keys in the + # keystore for this image/polkadot-sdk pinning (confirmed directly: + # an empty keystore, chain stuck at genesis, no block ever + # authored). The actual keys come from OPENINFRA_DEV_AUTHORITY_SEED + # below via docker/authority-entrypoint.sh (this image's + # ENTRYPOINT) -- that explicit `key insert` step is load-bearing + # here, not redundant with --alice. + - --alice + - --force-authoring - --rpc-external - --rpc-port=9944 - --rpc-methods=safe @@ -52,6 +65,16 @@ services: - --prometheus-external environment: OPENINFRA_DEV_SUDO_PUBLIC_KEY_FILE: /run/openinfra-chain/bridge-public.hex + # Consumed by docker/authority-entrypoint.sh (this image's + # ENTRYPOINT), not by openinfra-node directly. //Alice is the + # well-known dev SURI matching openinfra-dev's genesis authority + # (sp_keyring::Sr25519Keyring::Alice / Ed25519Keyring::Alice -- + # blockchain/node/src/chain_spec.rs). base_path/chain must match + # the --base-path/--chain args above exactly, or the script inserts + # keys into a keystore path the running node never reads from. + OPENINFRA_DEV_AUTHORITY_SEED: "//Alice" + OPENINFRA_NODE_BASE_PATH: /var/lib/openinfra/data + OPENINFRA_NODE_CHAIN: openinfra-dev ports: - "127.0.0.1:9944:9944" - "127.0.0.1:30333:30333"