devnet4: dual hash-sig keys and GENESIS_VALIDATORS format#154
Open
ch4r10t33r wants to merge 50 commits intomainfrom
Open
devnet4: dual hash-sig keys and GENESIS_VALIDATORS format#154ch4r10t33r wants to merge 50 commits intomainfrom
ch4r10t33r wants to merge 50 commits intomainfrom
Conversation
Add support for configuring nodes as aggregators through validator-config.yaml. This allows selective designation of nodes to perform aggregation duties by setting isAggregator: true in the validator configuration. Changes: - Add isAggregator field (default: false) to all validators in both local and ansible configs - Update parse-vc.sh to extract and export isAggregator flag - Modify all client command scripts to pass --is-aggregator flag when enabled - Add isAggregator status to node information output
Resolved conflicts in client-cmds scripts by keeping both: - Aggregator flag support - Checkpoint sync URL support Updated Docker images: - zeam: 0xpartha/zeam:devnet3 - lantern: piertwo/lantern:v0.0.3-test - ethlambda: ghcr.io/lambdaclass/ethlambda:devnet3 Added httpPort support for lantern nodes.
Resolve zeam-cmd.sh: keep single attestation_committee block and zeam_global_flags in node_binary.
- Generate hosts-prepare.yml (one inventory host per remote IP) and use it for prepare.yml so apt/docker run once per machine. - Apply SSH user/key to both hosts.yml and hosts-prepare.yml. - Allow --validatorConfig with --prepare in spin-node.sh. - Ignore hosts-prepare.yml; document behavior in prepare playbook. - Add ansible-devnet/genesis/test-validator-config.yaml for multi-client tests.
ansible-playbook runs from ansible/; lookup('file') resolves relative paths
there, breaking prepare/deploy when --validatorConfig is repo-relative.
…unt check Skip expansion when the file's attestation_committee_count >= --subnets. --subnets takes precedence only when it exceeds the file's value (default 1).
…subnets skip logic
…sent When validators lack an explicit 'subnet' field, compute it as validator_index % attestation_committee_count instead of defaulting to 0. This ensures correct multi-subnet aggregator selection for hand-maintained configs that set attestation_committee_count but omit per-row subnet fields.
…tion Use cumulative count to compute the first validator index per node, matching the assignment from the beacon genesis generator tool.
Let Docker pick the native platform so the correct image is pulled on both amd64 and arm64 servers. Requires a multi-arch zeam image.
Mode selection now uses duplicate client types (not duplicate IPs) to distinguish replicate from shared-host. This lets the local devnet (all clients on 127.0.0.1) use replicate mode correctly. Port stride changes from +i to +(i * num_template_rows) so clones never collide even when all rows share the same IP.
Each of the five active nodes (zeam_0/1/2, ethlambda_0/1) is now on its own server. Ports are normalized to the base values (quic 9001, metrics 9095, api 5055) since there are no collisions. This also makes the config a valid replicate-mode template for --subnets expansion.
Add test-validator-config-subnet2.yaml: 2-subnet layout with 7 nodes per subnet (zeam, gean, ethlambda, qlean, lantern). Update validator-config.yaml to reflect current deployment. Sync validator-config-expanded.yaml.
Switch from new-style flags (--genesis, --bootnodes, --validator-registry-path, --listen-addr) to the flags gean:devnet4 actually accepts: --custom-network-config-dir, --gossipsub-port, --http-address.
KatyaRyazantseva
previously approved these changes
Apr 15, 2026
… snaiyer1/ream:latest
Switch --validator-registry-path from validators.yaml to annotated_validators.yaml in ream, lantern, qlean, and grandine — both in the local client-cmds scripts and the Ansible roles. Update qlean's yq index extraction to use .index since annotated_validators.yaml stores objects instead of bare integers.
… and metrics 9095)
Co-authored-by: Parthasarathy Ramanujam <1627026+ch4r10t33r@users.noreply.github.com>
…tern qlean: use --genesis-dir and build/out/bin; remove deprecated per-file flags, duplicate -ltrace, and xmss path logic; update ansible docker args and defaults. lantern: pass --validator-registry-path to validators.yaml (required separate from annotated_validators); fixes default ./genesis/validators.yaml parse error.
Align the ansible role fallback image with client-cmds/ream-cmd.sh, which is already pinned to snaiyer1/ream:latest (commit da97676). The ghcr.io/reamlabs/ream:latest-devnet4 defaults were leftover from the short-lived devnet4 image switch and would only take effect if extraction from ream-cmd.sh failed, but are worth keeping consistent.
Replace --validator-config with --custom-network-config-dir so checkpoint sync resolves the local genesis time instead of comparing against 0. Also forward --attestation-committee-count (when >1) and --log, matching the local nlean-cmd.sh contract.
…ients
In a multi-subnet deployment an aggregator must subscribe to every
subnet's attestation topics to build aggregates across committees.
Previously only the aggregator's own subnet was subscribed, which
fragmented votes and blocked justification/finalization.
- parse-vc.sh: compute the unique sorted CSV of subnet ids across the
validator config and export it as aggregateSubnetIds.
- client-cmds/*.sh: for every client (ethlambda, gean, grandine,
lantern, lighthouse, nlean, peam, qlean, ream, zeam), pass
--aggregate-subnet-ids <csv> to both the binary and docker forms
when the node is an aggregator and the network has >1 subnet.
- ansible/roles/{zeam,ethlambda}: resolve the full subnet id set from
validator-config.yaml via yq and forward --aggregate-subnet-ids to
the container command for aggregator nodes in multi-subnet networks.
Expand the live devnet layout to 16 nodes spread evenly over two subnets (8 per subnet, one of each client per subnet). Pick zeam_0 as the subnet-0 aggregator and ethlambda_1 as the subnet-1 aggregator so at least two independent clients own aggregation.
# Conflicts: # client-cmds/nlean-cmd.sh
KatyaRyazantseva
approved these changes
Apr 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Draft PR for devnet4 work: dual attester/proposer hash-sig keys, updated
generate-genesis.sh,config.yamlshape (attestation_pubkey/proposal_pubkey),parse-vc.sh/ qlean paths, Ansible genesis task, README and docs.config.yamlunder genesis dirs remains gitignored (generated locally).Multi-subnet aggregator selection (
spin-node.sh)When picking aggregators randomly (default, no
--aggregator), each client type (name prefix before the first_, e.g.zeamfromzeam_0) can be aggregator on at most one subnet. Ifzeam_*is chosen for subnet 0, nozeam_*node is eligible on other subnets. If there are more subnets than distinct clients, the script warns and picks from all nodes in that subnet. Explicit--aggregatorstill fixes that node for its subnet and records its client type so other subnets avoid it when possible. ConflictingisAggregator: trueYAML presets are dropped with a warning in default mode.