diff --git a/default.env b/default.env index abd4776fc..ebd64ae72 100644 --- a/default.env +++ b/default.env @@ -297,7 +297,7 @@ LOG_LEVEL=info JWT_SECRET= # Authenticated execution client endpoint. This default uses the execution node container. EL_NODE=http://execution:8551 -# Consensus client address. This could be comma-separated for Lighthouse, Nimbus or Teku VC clients, with failover, +# Consensus client address. This could be a comma-separated list with failover, # or could just be a remote consensus client URL for "validator only" setups. CL_NODE=http://consensus:5052 # Used by "ethd keys", adjust this if you have multiple Eth Docker stacks connected to the same Docker bridge network diff --git a/ethdo/Dockerfile b/ethdo/Dockerfile index a6a1fe14e..a25d96082 100644 --- a/ethdo/Dockerfile +++ b/ethdo/Dockerfile @@ -9,6 +9,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install adduser \ bash \ jq \ + curl \ && gosu nobody true \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/ethdo/docker-entrypoint.sh b/ethdo/docker-entrypoint.sh index e8f7fe6ed..431dddbcf 100755 --- a/ethdo/docker-entrypoint.sh +++ b/ethdo/docker-entrypoint.sh @@ -83,8 +83,20 @@ if [[ "$*" =~ "--offline" ]]; then chown ethdo:ethdo /app/offline-preparation.json fi else - # Get just the first CL_NODE - __args=( "${__args[@]:0:1}" "--connection" "$(cut -d, -f1 <<<"${CL_NODE}")" "${__args[@]:1}" ) + nodes=$(echo "${CL_NODE}" | tr ',' ' ') + for node in ${nodes}; do + if curl -s -m 5 -o /dev/null -w "%{http_code}" "${node}" | grep -q "^[23]"; then + node_reachable=1 + break + fi + done + + if [[ "${node_reachable}" -eq 0 ]]; then + echo "No consensus client node is reachable via any URL in ${CL_NODE}" + exit 1 + fi + + __args=( "${__args[@]:0:1}" "--connection" "${node}" "${__args[@]:1}" ) fi set +e diff --git a/lighthouse-vc-only.yml b/lighthouse-vc-only.yml index 8b51ff73c..0724e13e8 100644 --- a/lighthouse-vc-only.yml +++ b/lighthouse-vc-only.yml @@ -93,6 +93,8 @@ services: depends_on: lighthouse-builder: condition: service_completed_successfully + environment: + - CL_NODE=${CL_NODE} volumes: - lhvalidator-data:/var/lib/lighthouse - ./.eth/validator_keys:/validator_keys @@ -103,8 +105,6 @@ services: - account - validator - exit - - --beacon-node - - ${CL_NODE:-http://consensus:5052} - --datadir - /var/lib/lighthouse - --network diff --git a/lighthouse.yml b/lighthouse.yml index bd3a1f483..23a0dd77a 100644 --- a/lighthouse.yml +++ b/lighthouse.yml @@ -177,6 +177,8 @@ services: condition: service_started lighthouse-builder: condition: service_completed_successfully + environment: + - CL_NODE=${CL_NODE} volumes: - lhvalidator-data:/var/lib/lighthouse - ./.eth/validator_keys:/validator_keys @@ -187,8 +189,6 @@ services: - account - validator - exit - - --beacon-node - - http://consensus:5052 - --datadir - /var/lib/lighthouse - --network diff --git a/lighthouse/validator-exit.sh b/lighthouse/validator-exit.sh index 3a5581c96..b23e72465 100755 --- a/lighthouse/validator-exit.sh +++ b/lighthouse/validator-exit.sh @@ -9,4 +9,21 @@ if [[ "$(id -u)" -eq 0 ]]; then exec gosu lhvalidator "${BASH_SOURCE[0]}" "$@" fi +nodes=$(echo "${CL_NODE}" | tr ',' ' ') +for node in ${nodes}; do + if curl -s -m 5 -o /dev/null -w "%{http_code}" "${node}" | grep -q "^[23]"; then + node_reachable=1 + break + fi +done + +if [[ "${node_reachable}" -eq 0 ]]; then + echo "No consensus client node is reachable via any URL in ${CL_NODE}" + sleep 30 + exit 1 +fi + +# Insert the --beacon-node after the 4th position +set -- "${@:1:4}" "--beacon-node" "${node}" "${@:5}" + exec "$@" diff --git a/siren.yml b/siren.yml index 313aad1c9..273d46df0 100644 --- a/siren.yml +++ b/siren.yml @@ -25,7 +25,12 @@ services: - NODE_OPTIONS="--dns-result-order=ipv4first" <<: *logging entrypoint: - - docker-entrypoint.sh + - /bin/bash + - -c + command: + - | + export BEACON_URL="$${BEACON_URL%%,*}" + exec /app/docker-assets/docker-entrypoint.sh labels: - traefik.enable=true - traefik.http.routers.$(SIREN_HOST:-siren}.service=${SIREN_HOST:-siren} diff --git a/teku-vc-only.yml b/teku-vc-only.yml index 029e0041f..95011ac31 100644 --- a/teku-vc-only.yml +++ b/teku-vc-only.yml @@ -97,7 +97,7 @@ services: entrypoint: - /opt/teku/bin/teku - voluntary-exit - - --beacon-node-api-endpoint=${CL_NODE:-http://consensus:5052} + - --beacon-node-api-endpoints=${CL_NODE:-http://consensus:5052} - --validator-keys=/var/lib/teku/validator-keys:/var/lib/teku/validator-passwords - --validator-keys=/var/lib/teku/validator/key-manager/local:/var/lib/teku/validator/key-manager/local-passwords diff --git a/teku.yml b/teku.yml index 0d1c90c96..e3003fd28 100644 --- a/teku.yml +++ b/teku.yml @@ -176,7 +176,7 @@ services: entrypoint: - /opt/teku/bin/teku - voluntary-exit - - --beacon-node-api-endpoint=${CL_NODE:-http://consensus:5052} + - --beacon-node-api-endpoints=${CL_NODE:-http://consensus:5052} - --validator-keys=/var/lib/teku/validator-keys:/var/lib/teku/validator-passwords - --validator-keys=/var/lib/teku/validator/key-manager/local:/var/lib/teku/validator/key-manager/local-passwords diff --git a/vc-utils/keymanager.sh b/vc-utils/keymanager.sh index fc1c87c47..9f8ce3031 100755 --- a/vc-utils/keymanager.sh +++ b/vc-utils/keymanager.sh @@ -96,19 +96,35 @@ else __call_cl_api() { local exitstatus + local nodes + local node + local node_reachable=0 + + nodes=$(echo "${CL_NODE}" | tr ',' ' ') + for node in ${nodes}; do + if curl -s -m 5 -o /dev/null -w "%{http_code}" "${node}" | grep -q "^[23]"; then + node_reachable=1 + break + fi + done + + if [[ "${node_reachable}" -eq 0 ]]; then + echo "No consensus client node is reachable via any URL in ${CL_NODE}" + exit 1 + fi set +e if [[ -z "${__api_data}" ]]; then __code=$(curl -m 60 -s --show-error -o /tmp/result.txt -w "%{http_code}" -X "${__http_method}" -H "Accept: application/json" \ - "${CL_NODE}"/"${__api_path}") + "${node}"/"${__api_path}") else __code=$(curl -m 60 -s --show-error -o /tmp/result.txt -w "%{http_code}" -X "${__http_method}" -H "Accept: application/json" -H "Content-Type: application/json" \ - --data "${__api_data}" "${CL_NODE}"/"${__api_path}") + --data "${__api_data}" "${node}"/"${__api_path}") fi exitstatus=$? if [[ "${exitstatus}" -ne 0 ]]; then echo "Error encountered while trying to call the consensus client REST API via curl." - echo "Please make sure the ${CL_NODE} URL is reachable." + echo "Please make sure the ${node} URL is reachable." echo "Error code ${exitstatus}" exit ${exitstatus} fi @@ -585,6 +601,9 @@ validator-list() { validator-count() { + local nodes + local node + local node_reachable=0 local vc_api_container local vc_service local vc_api_port @@ -635,9 +654,22 @@ validator-count() { fi fi + nodes=$(echo "${CL_NODE}" | tr ',' ' ') + for node in ${nodes}; do + if curl -s -m 5 -o /dev/null -w "%{http_code}" "${node}" | grep -q "^[23]"; then + node_reachable=1 + break + fi + done + + if [[ "${node_reachable}" -eq 0 ]]; then + echo "No consensus client node is reachable via any URL in ${CL_NODE}" + exit 1 + fi + echo "Querying validator state, this may take a minute" for __pubkey in $(echo "${vals}" | jq -r '.data[].validating_pubkey'); do - val_state=$(curl -k -m 60 -s --show-error "${CL_NODE}/eth/v1/beacon/states/head/validators/${__pubkey}" | jq -r .data.status) + val_state=$(curl -k -m 60 -s --show-error "${node}/eth/v1/beacon/states/head/validators/${__pubkey}" | jq -r .data.status) case "${val_state}" in active_ongoing) ((vals_active++));; active_exiting) ((vals_exiting++));;