Skip to content

Refactor entrypoint.sh scripts to use set -- + exec "$@" for safe multi-token flag handling #62

Description

@3alpha

Summary

Both validator/entrypoint.sh and beacon-chain/entrypoint.sh build their argv as a single unquoted string (FLAGS="…" + exec lighthouse $FLAGS). That pattern silently breaks on any flag value that contains whitespace or shell metacharacters, because the shell word-splits the unquoted expansion.

#61 ("Allow graffiti to have spaces") is a localized patch: it pulls --graffiti out of the FLAGS string and passes it separately. That fixes the immediate symptom for --graffiti only and leaves the underlying footgun in place for every other flag (and for any future flag we add) in both entrypoints.

Proposed approach

Replace the FLAGS="…" / exec lighthouse $FLAGS pattern with a set -- based argv builder, then exec with "$@".

validator/entrypoint.sh

set -- \
  --debug-level="$LOG_LEVEL" \
  --network="$NETWORK" \
  validator \
  --init-slashing-protection \
  --datadir="$DATA_DIR" \
  --beacon-nodes="$BEACON_API_URL${BACKUP_BEACON_NODES:+,$BACKUP_BEACON_NODES}" \
  --graffiti="$VALID_GRAFFITI" \
  --http \
  --http-address 0.0.0.0 \
  --http-port="$VALIDATOR_PORT" \
  --http-allow-origin='*' \
  --unencrypted-http-transport \
  --metrics \
  --metrics-address=0.0.0.0 \
  --metrics-port=8008 \
  --metrics-allow-origin='*' \
  --suggested-fee-recipient="$VALID_FEE_RECIPIENT"

# Only intentionally multi-token options remain split:
# shellcheck disable=SC2086
exec lighthouse "$@" $MEVBOOST_FLAG $EXTRA_OPTS

beacon-chain/entrypoint.sh

set -- \
  --debug-level="$LOG_LEVEL" \
  --network="$NETWORK" \
  beacon_node \
  --datadir="$DATA_DIR" \
  --http \
  --http-allow-origin='*' \
  --http-address=0.0.0.0 \
  --http-port="$BEACON_API_PORT" \
  --port="$P2P_PORT" \
  --metrics \
  --metrics-address=0.0.0.0 \
  --metrics-port=8008 \
  --metrics-allow-origin='*' \
  --execution-endpoint="$ENGINE_URL" \
  --execution-jwt="$JWT_FILE_PATH"

# Only intentionally multi-token options remain split:
# shellcheck disable=SC2086
exec lighthouse "$@" $CHECKPOINT_SYNC_FLAG $MEVBOOST_FLAG $EXTRA_OPTS

This:

  • Quotes every flag value, so spaces (graffiti, future text flags) are preserved verbatim.
  • Keeps MEVBOOST_FLAG, CHECKPOINT_SYNC_FLAG, and EXTRA_OPTS intentionally unquoted, matching today's multi-token behavior.
  • Supersedes the local workaround introduced by Allow graffiti to have spaces #61 — the line exec lighthouse $FLAGS --graffiti "$VALID_GRAFFITI" can be reverted once the validator refactor lands.

Cross-client consistency ⚠️

The same FLAGS="…" + exec … $FLAGS anti-pattern exists in every DAppNode consensus client entrypoint — both validator/entrypoint.sh and beacon-chain/entrypoint.sh:

Repo validator/entrypoint.sh beacon-chain/entrypoint.sh
dappnode/DAppNodePackage-lighthouse-generic yes yes
dappnode/DAppNodePackage-prysm-generic yes yes
dappnode/DAppNodePackage-teku-generic yes yes
dappnode/DAppNodePackage-lodestar-generic yes yes
dappnode/DAppNodePackage-nimbus-generic yes yes

To keep operator-facing behavior identical across clients, the same set -- / exec "$@" $EXTRA_OPTS refactor must be replicated in every one of these entrypoints. This issue tracks the lighthouse-side fix (validator + beacon-chain); each sibling repo should get its own linked issue with the same body so the refactor lands consistently.

Scope

In this repo:

In each sibling repo (prysm, teku, lodestar, nimbus):

  • validator/entrypoint.sh
  • beacon-chain/entrypoint.sh

(One PR per repo is fine; the goal is that all five clients ship the same argv-construction pattern.)

Acceptance criteria

  • validator/entrypoint.sh builds its argv via set -- and uses exec lighthouse "$@" $MEVBOOST_FLAG $EXTRA_OPTS.
  • beacon-chain/entrypoint.sh builds its argv via set -- and uses exec lighthouse "$@" $CHECKPOINT_SYNC_FLAG $MEVBOOST_FLAG $EXTRA_OPTS.
  • All flag values are quoted; --graffiti "$VALID_GRAFFITI" round-trips spaces.
  • MEVBOOST_FLAG, CHECKPOINT_SYNC_FLAG, and EXTRA_OPTS remain intentionally unquoted (multi-token, as today) with # shellcheck disable=SC2086.
  • The PR 61 local workaround (exec lighthouse $FLAGS --graffiti "…") is removed since it is no longer needed.
  • sync-test workflow stays green.
  • Echo lines for the launched flags are updated to reflect the new argv builder.
  • The same refactor is mirrored in the validator/entrypoint.sh and beacon-chain/entrypoint.sh of: dappnode/DAppNodePackage-prysm-generic, dappnode/DAppNodePackage-teku-generic, dappnode/DAppNodePackage-lodestar-generic, dappnode/DAppNodePackage-nimbus-generic.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Low priorityenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions