Harden smoke.sh and deployment helpers against RPC errors and reformatted JSON
I maintainer di solito rispondono entro 2 giorni
@munathecreator ci sta già lavorando.
Dal 20/10/2026.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 62/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- bash
- Ambito
- tooling
Direzione di ricerca
Start in scripts/_deployment.sh: json_field and the alias lookup in assert_identities_match break on reformatted JSON. Reproduce with the How to verify snippet, using a copy of deployments/testnet.json under a temporary ROOT_DIR, and confirm compact and pretty-printed files give the same output. Then move to scripts/smoke.sh around line 40 (curl timeout) and lines 57-64 (the || true on reexecutor_info). Done when the acceptance checks pass with a fake stellar, and smoke.sh exits without calling register_reexecutor when that read fails.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
scripts/smoke.sh and the shared scripts/_deployment.sh have several fragility problems. The smoke test can hang on a stuck health check, and a transient RPC error while reading the rogue re-executor's state makes it stake another 1,000 XLM on every run. It also never checks that the keystore still matches the deployment record, and the helper that reads deployments/*.json silently stops checking identities if the file is reformatted. No script checks that the tools it needs are installed.
Background
pnpm smoke (README, "Prove it works end to end") plays an agent, a challenger and a rogue re-executor against a local pnpm dev stack and real testnet. scripts/_deployment.sh is sourced by every script and resolves which deployment they act on; its assert_identities_match exists because the stellar-cli keystore is one flat namespace and another project can replace a key under the same alias (CONTRIBUTING, "Things that bite"). EscrowGate.register_reexecutor adds to existing stake rather than replacing it.
Current behaviour
scripts/smoke.sh, line 40:if ! curl -fs "http://127.0.0.1:$API_PORT/health/live" >/dev/null; then.curlhas no--max-time, so a listener that accepts the connection and never answers hangs the script.scripts/smoke.sh, lines 57-64:
ROGUE_INFO="$(stellar contract invoke --id "$GATE_ID" --source "$ROGUE_ALIAS" --network "$NETWORK" \
-- reexecutor_info --reexecutor "$ROGUE_ADDR" 2>/dev/null || true)"
if ! echo "$ROGUE_INFO" | grep -q '"active": *true'; then
echo "==> Staking '$ROGUE_ALIAS' (1,000 XLM)"
If the RPC call fails, || true turns that into an empty string, which is indistinguishable from "not staked", so the script stakes another 1,000 XLM. Repeated flaky runs drain the rogue identity.
3. scripts/smoke.sh never calls assert_identities_match (compare dev.sh, bootstrap_reexecutors.sh and approve_reexecutor.sh, which do), so a replaced deployer key is used to approve voters without warning.
4. scripts/_deployment.sh, line 44 and line 70:
json_field() { grep -o "\"$1\": *\"[^\"]*\"" "$DEPLOY_JSON" | cut -d'"' -f4; }
...
recorded="$(grep -o "{\"alias\":\"$alias\",\"public_key\":\"[^\"]*\"" "$DEPLOY_JSON" | cut -d'"' -f8)"
json_field only matches "key": "value" with at most spaces after the colon; "key" : "value" or any reformatting returns an empty string. The alias lookup only matches the exact compact spelling {"alias":"rex1","public_key":"G..." that deploy_testnet.sh happens to write. If an editor or formatter pretty-prints deployments/<name>.json, recorded is empty and assert_identities_match skips the check without saying so (the [ -n "$recorded" ] guard).
5. No script checks for stellar, curl or openssl; a missing tool shows up as a cryptic command not found partway through.
Expected behaviour
- The health probe times out (a few seconds) and the script says the backend is not answering.
- A failing
reexecutor_infocall aborts the script with aFATAL:message and stakes nothing. Only a successful call that reports "not registered/not active" leads to staking. smoke.shcallsassert_identities_matchright afterrequire_deployment.json_field,deployment_is_publicand the alias lookup inassert_identities_matchreturn the same values for the committed compact file, for the same file pretty-printed withjq .ornode -e 'console.log(JSON.stringify(JSON.parse(require("fs").readFileSync(0,"utf8")),null,2))', and for"key" : "value"spacing. If an alias inBOOTSTRAP_REEXECUTORScannot be found in the record,assert_identities_matchprints aWARN:line instead of silently skipping it._deployment.shprovides a helper, for examplerequire_commands cmd..., that lists every missing tool at once and exits non-zero;smoke.shcalls it forstellar curl nodebefore doing anything else.
Proposed approach
- Rewrite
json_fieldand the alias lookup so they tolerate whitespace and line breaks. Either usenode(already a hard prerequisite for everything these scripts start) to parse the JSON, or keepgrep/sedbut flatten withtr -d '\n'and allow[[:space:]]*around:and,. Keep the function names and output unchanged, because every script calls them. - Add the
WARN:for an alias that has no recorded key. Do not turn it into a failure; older records may not list every alias. - Add
require_commandsto_deployment.sh(it is sourced, so do notexitfrom a subshell; mirror the existingrequire_deploymentstyle). - In
smoke.sh: addrequire_commands, callassert_identities_match, add--max-time 5(and--connect-timeout 2) to thecurl, and replace the|| trueon the rogue read with an explicit exit-status check. Take the "no|| true" fix only for the read ofreexecutor_info; leave the other|| truecalls (funding an already-funded account) alone. - Confirm on your own deployment what
reexecutor_infoprints for an account that was never staked (nullis expected) so that case still leads to staking on a first run.
Pitfall: deployment_is_public uses the same style of grep ("public": *true) and should get the same tolerance, since it protects public deployments from pnpm dev and pnpm smoke.
Files
scripts/smoke.sh: preflight, identity check, curl timeout, no swallowed RPC errors.scripts/_deployment.sh: tolerant JSON helpers, missing-alias warning,require_commands.
Acceptance criteria
- Sourcing
_deployment.shwithROOT_DIRpointing at a temporary tree whosedeployments/x.jsonis (a) the compact committed file, (b) the same file pretty-printed, (c) with"key" : "value"spacing, gives identical output fromjson_field escrow_gate_contract_id, anddeployment_is_publicis correct in all three. -
assert_identities_matchdetects a mismatchedrexNkey in the pretty-printed file (use a fakestellarreturning a different address) and warns when an alias is absent from the record. - With a fake
stellarwhosereexecutor_infocall exits non-zero,smoke.shexits non-zero without callingregister_reexecutor. - A listener that never responds makes the health probe fail within about 5 seconds.
- Running
smoke.shwithcurlhidden fromPATHprints a message naming the missing tool. -
bash -n scripts/smoke.sh scripts/_deployment.shpasses (andshellcheckonsmoke.sh, which sources_deployment.sh, if available).
How to verify
All checks except the last can be done without network or funds, using a temporary ROOT_DIR and a fake stellar script first on PATH:
tmp=$(mktemp -d); mkdir "$tmp/deployments"
cp deployments/testnet.json "$tmp/deployments/testnet.json"
ROOT_DIR="$tmp" bash -c 'source scripts/_deployment.sh; json_field escrow_gate_contract_id'
node -e 'const f=process.argv[1];require("fs").writeFileSync(f,JSON.stringify(JSON.parse(require("fs").readFileSync(f,"utf8")),null,2))' "$tmp/deployments/testnet.json"
ROOT_DIR="$tmp" bash -c 'source scripts/_deployment.sh; json_field escrow_gate_contract_id' # same value
Then, with a local stack from pnpm dev and your own deployment (CONTRIBUTING, "Getting set up"), run pnpm smoke once and confirm it still passes.
Out of scope
- Changing the staking amount, the smoke scenarios, or
backend/src/smoke/run.ts. - Adding preflight checks to scripts other than
smoke.sh(they can adoptrequire_commandslater). - Changing the deployment record format that
deploy_testnet.shwrites.
Notes
Medium: a handful of independent shell fixes. If you prefer to keep the PR small, the JSON helper tolerance and the rogue-stake fix are the most valuable pieces, but the issue is complete only with all of them. Merge-conflict hotspot: scripts/_deployment.sh is also read by the sibling script issues, which do not edit it.
- Lingua principale
- TypeScript
- Stelle
- 0
- Fork
- 1
- Merge medio
- 1g 23h
- PR unite (30g)
- 105
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
awesome-dsh-plugin/awesome-dsh-plugin#9184 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
farion1231/cc-switch#8829 ·
I maintainer di solito rispondono entro 1 giorno
-
[core-client] Remove unused hand-maintained transport helpers after the definition-table cutoverApertadoc-audit enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100