Skip to content
Draft
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
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ validators.yaml
nodes.yaml
genesis.json
genesis.ssz
annotated_validators.yaml

# Hash-sig validator keys (contains sensitive secret keys)
hash-sig-keys/
Expand Down
25 changes: 0 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,31 +298,6 @@ qlean_0:
- 2
```

**Recommended:** `annotated_validators.yaml` is also generated and should be preferred by client software as it includes public keys and private key file references directly, eliminating the need for clients to derive key filenames from validator indices:

```yaml
zeam_0:
- index: 0
pubkey_hex: 4b3c31094bcc9b45446b2028eae5ad192b2df16778837b10230af102255c9c5f72d7ba43eae30b2c6a779f47367ebf5a42f6c959
privkey_file: validator_0_sk.json
- index: 3
pubkey_hex: 8df32a54d2fbdf3a88035b2fe3931320cb900d364d6e7c56b19c0f3c6006ce5b3ebe802a65fe1b420183f62e830a953cb33b7804
privkey_file: validator_3_sk.json

ream_0:
- index: 1
pubkey_hex: 5b15f72f90bd655b039f9839c36951454b89c605f8c334581cfa832bdd0c994a1350094f7e22617d77607b067b0aa2439e0ead7d
privkey_file: validator_1_sk.json
- index: 4
pubkey_hex: 71bf8f73980591574de34a0db471da74f5cfd84d4731d53f47bf3023b26c2638ac5bd24993ea71492fedbd6c4afe5c299213b76b
privkey_file: validator_4_sk.json

qlean_0:
- index: 2
pubkey_hex: b87e69568a347d1aa811cc158634fb1f4e247c5509ad2b1652a8d758ec0ab0796954e307b97dd6284fbb30088c2e595546fdf663
privkey_file: validator_2_sk.json
```

`nodes.yaml` provide enrs of all the nodes so that clients don't have to run a discovery protocol:

```yaml
Expand Down
29 changes: 29 additions & 0 deletions ansible-devnet/genesis/annotated_validators.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
ethlambda_0:
- index: 5
pubkey_hex: 6e01c00e9072c67682a1ef518f13d163925e271bf07fea002339fc0c84a1950d6b273f5731a11632b559a62d0a5e051afde52f2a
privkey_file: validator_5_sk.ssz

grandine_0:
- index: 4
pubkey_hex: 0ef8694be847ec6719fc620ffe81c13a56e37373906ebc613d9eaf4f8b6ed54611120762c62cb803c4941574c6941832424ab70b
privkey_file: validator_4_sk.ssz

lantern_0:
- index: 3
pubkey_hex: 6abd60595707ad6d992b9959737b476aa8d30f16a5129f2c485fcb2b11cfa0637295b7300a4b8e1bbb06777ba188f91c1b90d00f
privkey_file: validator_3_sk.ssz

qlean_0:
- index: 2
pubkey_hex: 23694c4388679e3368cb0a38b8fc5a7406cd9947543d2c6d614af86fdf52e948ac55e63918a8cb40bfd90e2ebccfe55219af1a0e
privkey_file: validator_2_sk.ssz

ream_0:
- index: 1
pubkey_hex: 1ed8fa061a70477c2ef9ca05abcf5533612b6f234a6b982ee3936b0f64e81474b535b90feb9fd271931ad80615588418535ac618
privkey_file: validator_1_sk.ssz

zeam_0:
- index: 0
pubkey_hex: b1b55d559bb8a32549508b381e9ff66fa809b963ee0e6f58c260ac51e4a07b437ab2aa7951f9104aad05e46358a6c83d36b4cd12
privkey_file: validator_0_sk.ssz
84 changes: 84 additions & 0 deletions ansible-devnet/genesis/deploy-validator-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
shuffle: roundrobin
# Deployment mode: 'local' for local deployment, 'ansible' for remote deployment via Ansible
deployment_mode: ansible
config:
activeEpoch: 18
keyType: "hash-sig"
validators:
- name: "zeam_0"
# node id 7d0904dc6d8d7130e0e68d5d3175d0c3cf470f8725f67bd8320882f5b9753cc0
# peer id 16Uiu2HAkvi2sxT75Bpq1c7yV2FjnSQJJ432d6jeshbmfdJss1i6f
image: blockblaz/zeam:latest
privkey: "bdf953adc161873ba026330c56450453f582e3c4ee6cb713644794bcfdd85fe5"
enrFields:
# verify /ip4/127.0.0.1/udp/9000/quic-v1/p2p/16Uiu2HAkvi2sxT75Bpq1c7yV2FjnSQJJ432d6jeshbmfdJss1i6f
ip: "46.224.123.223"
quic: 9001
metricsPort: 9095
count: 1 # number of indices for this node

- name: "ream_0"
# node id bc531fc1a99a896acb45603f28a32f81ae607480af46435009de4609370cb7bb
# peer id 16Uiu2HAmPQhkD6Zg5Co2ee8ShshkiY4tDePKFARPpCS2oKSLj1E1
image: ghcr.io/reamlabs/ream:latest
privkey: "af27950128b49cda7e7bc9fcb7b0270f7a3945aa7543326f3bfdbd57d2a97a32"
enrFields:
#verify /ip4/127.0.0.1/udp/9001/quic-v1/p2p/16Uiu2HAmPQhkD6Zg5Co2ee8ShshkiY4tDePKFARPpCS2oKSLj1E1
ip: "77.42.27.219"
quic: 9001
metricsPort: 9095
devnet: 1
count: 1

- name: "qlean_0"
# TODO: add a third entry in nodes.yaml corresponding to this
image: qdrvm/qlean-mini:latest
privkey: "c2bbdac5e876b3e9d4b8b6b8c2bbdac5e876b3e9d4b8b6b8c2bbdac5e876b3e9"
enrFields:
#verify /ip4/127.0.0.1/udp/9001/quic-v1/p2p/16Uiu2HAmPQhkD6Zg5Co2ee8ShshkiY4tDePKFARPpCS2oKSLj1E1
ip: "46.224.123.220"
quic: 9001
metricsPort: 9095
count: 1

- name: "lantern_0"
# node id a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
# peer id 16Uiu2HAm7TYVs6qvDKnrovd9m4vvRikc4HPXm1WyLumKSe5fHxBv
image: piertwo/lantern:v0.0.2
privkey: "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5"
# verify /ip4/127.0.0.1/udp/9004/quic-v1/p2p/16Uiu2HAm7TYVs6qvDKnrovd9m4vvRikc4HPXm1WyLumKSe5fHxBv
enrFields:
ip: "46.224.135.177"
quic: 9001
metricsPort: 9095
count: 1

# - name: "lighthouse_0"
# # node id a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
# # peer id 16Uiu2HAm7TYVs6qvDKnrovd9m4vvRikc4HPXm1WyLumKSe5fHxBv
# image: hopinheimer/lighthouse:latest
# privkey: "4fd22cf461fbeae4947a3fdaef8d533fc7fd1ef1ce4cd98e993210c18234df3f"
# # verify /ip4/127.0.0.1/udp/9004/quic-v1/p2p/16Uiu2HAm7TYVs6qvDKnrovd9m4vvRikc4HPXm1WyLumKSe5fHxBv
# enrFields:
# ip: "46.224.135.169"
# quic: 9001
# metricsPort: 9095
# count: 1

- name: "grandine_0"
image: sifrai/lean:latest
privkey: "64a7f5ab53907966374ca23af36392910af682eec82c12e3abbb6c2ccdf39a72"
enrFields:
ip: "37.27.250.20"
quic: 9001
metricsPort: 9095
count: 1

- name: "ethlambda_0"
image: ghcr.io/lambdaclass/ethlambda:latest
privkey: "299550529a79bc2dce003747c52fb0639465c893e00b0440ac66144d625e066a"
enrFields:
ip: "78.47.44.215"
quic: 9001
metricsPort: 9095
count: 1
2 changes: 0 additions & 2 deletions ansible/playbooks/copy-genesis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
loop:
- config.yaml
- validators.yaml
- annotated_validators.yaml
- nodes.yaml
- genesis.json
- genesis.ssz
Expand Down Expand Up @@ -137,7 +136,6 @@
loop:
- config.yaml
- validators.yaml
- annotated_validators.yaml
- nodes.yaml
- genesis.json
- genesis.ssz
Expand Down
3 changes: 1 addition & 2 deletions ansible/playbooks/generate-genesis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,13 @@
debug:
msg: |
✅ Genesis generation complete!

Generated files in {{ genesis_dir }}:
- config.yaml (with GENESIS_VALIDATORS)
- validators.yaml
- nodes.yaml
- genesis.json
- genesis.ssz
- annotated_validators.yaml
{% for node in node_names_list %}
- {{ node }}.key
{% endfor %}
97 changes: 0 additions & 97 deletions generate-genesis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -521,103 +521,6 @@ rm -f "$GENESIS_VALIDATORS_TMP"

echo ""

# ========================================
# Generate annotated_validators.yaml with key metadata
# ========================================
echo "🔧 Generating annotated_validators.yaml..."

VALIDATORS_OUTPUT_FILE="$GENESIS_DIR/validators.yaml"
ANNOTATED_VALIDATORS_FILE="$GENESIS_DIR/annotated_validators.yaml"

if [ ! -f "$VALIDATORS_OUTPUT_FILE" ]; then
echo " ❌ Error: validators.yaml not found at $VALIDATORS_OUTPUT_FILE"
exit 1
fi

ASSIGNMENT_HAS_WRAPPER=$(yq eval 'has("validators")' "$VALIDATORS_OUTPUT_FILE" 2>/dev/null)
if [ "$ASSIGNMENT_HAS_WRAPPER" != "true" ]; then
ASSIGNMENT_HAS_WRAPPER="false"
fi

ASSIGNMENT_NODE_NAMES=()
if [ "$ASSIGNMENT_HAS_WRAPPER" = "true" ]; then
while IFS= read -r node_name; do
if [ -n "$node_name" ]; then
ASSIGNMENT_NODE_NAMES+=("$node_name")
fi
done < <(yq eval '.validators | keys | .[]' "$VALIDATORS_OUTPUT_FILE" 2>/dev/null)
else
while IFS= read -r node_name; do
if [ -n "$node_name" ]; then
ASSIGNMENT_NODE_NAMES+=("$node_name")
fi
done < <(yq eval 'keys | .[]' "$VALIDATORS_OUTPUT_FILE" 2>/dev/null)
fi

if [ ${#ASSIGNMENT_NODE_NAMES[@]} -eq 0 ]; then
echo " ❌ Error: No validator assignments found in validators.yaml"
exit 1
fi

NODE_ASSIGNMENTS_TMP=$(mktemp)

for idx in "${!ASSIGNMENT_NODE_NAMES[@]}"; do
node=${ASSIGNMENT_NODE_NAMES[$idx]}

if [ "$ASSIGNMENT_HAS_WRAPPER" = "true" ]; then
INDEX_QUERY=".validators.\"$node\"[]"
else
INDEX_QUERY=".\"$node\"[]"
fi

echo "$node:" >> "$NODE_ASSIGNMENTS_TMP"

ENTRY_FOUND=false

while IFS= read -r raw_index; do
# Trim whitespace using bash parameter expansion (avoids xargs which can fail in sandboxed environments)
raw_index="${raw_index#"${raw_index%%[![:space:]]*}"}"
raw_index="${raw_index%"${raw_index##*[![:space:]]}"}"
if [ -z "$raw_index" ] || [ "$raw_index" == "null" ]; then
continue
fi

ENTRY_FOUND=true

PUBKEY_HEX_VALUE=$(yq eval ".validators[$raw_index].$PUBKEY_FIELD" "$MANIFEST_FILE" 2>/dev/null)

if [ -z "$PUBKEY_HEX_VALUE" ] || [ "$PUBKEY_HEX_VALUE" == "null" ]; then
echo " ❌ Error: Missing pubkey for validator index $raw_index in manifest"
rm -f "$NODE_ASSIGNMENTS_TMP"
exit 1
fi

PUBKEY_HEX_NO_PREFIX="${PUBKEY_HEX_VALUE#0x}"
PRIVKEY_FILENAME="validator_${raw_index}_sk.ssz"

cat << EOF >> "$NODE_ASSIGNMENTS_TMP"
- index: $raw_index
pubkey_hex: $PUBKEY_HEX_NO_PREFIX
privkey_file: $PRIVKEY_FILENAME
EOF
done < <(yq eval "$INDEX_QUERY" "$VALIDATORS_OUTPUT_FILE" 2>/dev/null)

if [ "$ENTRY_FOUND" = false ]; then
echo " []" >> "$NODE_ASSIGNMENTS_TMP"
fi

if [ "$idx" -lt $(( ${#ASSIGNMENT_NODE_NAMES[@]} - 1 )) ]; then
echo "" >> "$NODE_ASSIGNMENTS_TMP"
fi
done

cat "$NODE_ASSIGNMENTS_TMP" > "$ANNOTATED_VALIDATORS_FILE"
rm -f "$NODE_ASSIGNMENTS_TMP"

echo " ✅ Generated annotated_validators.yaml with pubkey and privkey metadata"

echo ""

# ========================================
# Step 4: Generate Private Key Files
# ========================================
Expand Down
87 changes: 87 additions & 0 deletions local-devnet/genesis/deploy-validator-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
shuffle: roundrobin
# Deployment mode: 'local' for local deployment, 'ansible' for remote deployment via Ansible
deployment_mode: local
config:
activeEpoch: 18
keyType: "hash-sig"
validators:
- name: "zeam_0"
# node id 7d0904dc6d8d7130e0e68d5d3175d0c3cf470f8725f67bd8320882f5b9753cc0
# peer id 16Uiu2HAkvi2sxT75Bpq1c7yV2FjnSQJJ432d6jeshbmfdJss1i6f
image: blockblaz/zeam:latest
privkey: "bdf953adc161873ba026330c56450453f582e3c4ee6cb713644794bcfdd85fe5"
enrFields:
# verify /ip4/127.0.0.1/udp/9000/quic-v1/p2p/16Uiu2HAkvi2sxT75Bpq1c7yV2FjnSQJJ432d6jeshbmfdJss1i6f
ip: "127.0.0.1"
quic: 9001
metricsPort: 8081
count: 1 # number of indices for this node

- name: "ream_0"
# node id bc531fc1a99a896acb45603f28a32f81ae607480af46435009de4609370cb7bb
# peer id 16Uiu2HAmPQhkD6Zg5Co2ee8ShshkiY4tDePKFARPpCS2oKSLj1E1
image: ghcr.io/reamlabs/ream:latest
privkey: "af27950128b49cda7e7bc9fcb7b0270f7a3945aa7543326f3bfdbd57d2a97a32"
enrFields:
#verify /ip4/127.0.0.1/udp/9001/quic-v1/p2p/16Uiu2HAmPQhkD6Zg5Co2ee8ShshkiY4tDePKFARPpCS2oKSLj1E1
ip: "127.0.0.1"
quic: 9002
metricsPort: 8082
devnet: 1
count: 1

- name: "qlean_0"
# TODO: add a third entry in nodes.yaml corresponding to this
image: qdrvm/qlean-mini:latest
privkey: "c2bbdac5e876b3e9d4b8b6b8c2bbdac5e876b3e9d4b8b6b8c2bbdac5e876b3e9"
enrFields:
#verify /ip4/127.0.0.1/udp/9001/quic-v1/p2p/16Uiu2HAmPQhkD6Zg5Co2ee8ShshkiY4tDePKFARPpCS2oKSLj1E1
ip: "127.0.0.1"
quic: 9003
metricsPort: 8083
count: 1

- name: "lantern_0"
# node id a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
# peer id 16Uiu2HAm7TYVs6qvDKnrovd9m4vvRikc4HPXm1WyLumKSe5fHxBv
image: piertwo/lantern:v0.0.2
privkey: "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5"
# verify /ip4/127.0.0.1/udp/9004/quic-v1/p2p/16Uiu2HAm7TYVs6qvDKnrovd9m4vvRikc4HPXm1WyLumKSe5fHxBv
enrFields:
ip: "127.0.0.1"
quic: 9004
metricsPort: 8084
count: 1

# - name: "lighthouse_0"
# # node id a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
# # peer id 16Uiu2HAm7TYVs6qvDKnrovd9m4vvRikc4HPXm1WyLumKSe5fHxBv
# image: hopinheimer/lighthouse:latest
# privkey: "4fd22cf461fbeae4947a3fdaef8d533fc7fd1ef1ce4cd98e993210c18234df3f"
# # verify /ip4/127.0.0.1/udp/9004/quic-v1/p2p/16Uiu2HAm7TYVs6qvDKnrovd9m4vvRikc4HPXm1WyLumKSe5fHxBv
# enrFields:
# ip: "127.0.0.1"
# quic: 9005
# metricsPort: 8085
# count: 1

- name: "grandine_0"
image: sifrai/lean:unstable
privkey: "64a7f5ab53907966374ca23af36392910af682eec82c12e3abbb6c2ccdf39a72"
enrFields:
ip: "127.0.0.1"
quic: 9006
metricsPort: 8086
count: 1

- name: "ethlambda_0"
# node id a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
# peer id 16Uiu2HAmPV5jU62WtmDkCEmfq1jzbBDkGbHNsDN78gJyvmv2TuC5
image: ghcr.io/lambdaclass/ethlambda:latest
privkey: "299550529a79bc2dce003747c52fb0639465c893e00b0440ac66144d625e066a"
# verify /ip4/127.0.0.1/udp/9007/quic-v1/p2p/16Uiu2HAmPV5jU62WtmDkCEmfq1jzbBDkGbHNsDN78gJyvmv2TuC5
enrFields:
ip: "127.0.0.1"
quic: 9007
metricsPort: 8087
count: 1
Loading