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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions