chore(tx-generator): pin to upstream supervisor branch + Antithesis re-run#98
Draft
chore(tx-generator): pin to upstream supervisor branch + Antithesis re-run#98
Conversation
|
🚀 Documentation preview Preview: https://cf-cna-pr-98.surge.sh Built from |
5 tasks
paolino
added a commit
that referenced
this pull request
Apr 30, 2026
PR 1 of 2 toward the real asteria workload. Scope-limited to the rename + Haskell source lift + nix scaffolding so the binaries build alongside the existing utxo-indexer. Bootstrap is iteration 5b — *not safe for repeat invocation* — that gap is explicitly the subject of PR 2. Rename: components/asteria-stub/ → components/asteria-game/ service asteria-stub → asteria-game volume asteria-stub-db → asteria-game-db Lift from #67 (asteria-spawn-v2): components/asteria-game/aiken/ (validators + apply-params) components/asteria-game/src/Asteria/ (game state, datums, validators, wallet, providers, RNG, SDK) components/asteria-game/app/{BootstrapMain.hs, PlayerMain.hs} components/asteria-game/asteria-game.cabal (renamed package) components/asteria-game/cabal.project (cardano-node-clients SRP bumped to PR #98 head 5707836b) Build infra: flake.nix — extends prior asteria-stub flake with haskell.nix / iohk-nix overlays so local Haskell packages compile, while keeping the upstream cardano-node-clients flake input that supplies the prebuilt utxo-indexer (PR #98 supervisor). nix/project.nix — lifted from PR #67, package renamed. nix/docker-image.nix — bundles utxo-indexer + asteria-bootstrap + asteria-game (player) execs + composer scripts + bash/jq/ socat; entrypoint stays utxo-indexer. KNOWN GAP — admin_mint validator is the always-true placeholder PR #67 ships. Without an on-chain one-shot guarantee, every container restart could mint another admin NFT. Bootstrap is *not* wired into compose in this PR for that reason. PR 2 patches the Aiken admin_mint to take an OutputReference parameter, runs apply-params at bootstrap-time, and adds defence-in-depth detection in Bootstrap.hs. Composer scripts (composer/stub/{parallel_driver_heartbeat, eventually_alive, finally_alive, helper_sdk}.sh) unchanged from the green stub baseline so this PR stays bisect-safe and in property terms identical to commit 3b6fb0e (PR #74's merged head).
paolino
added a commit
that referenced
this pull request
Apr 30, 2026
PR 1 of 2 toward the real asteria workload. Scope-limited to the rename + Haskell source lift + nix scaffolding so the binaries build alongside the existing utxo-indexer. Bootstrap is iteration 5b — *not safe for repeat invocation* — that gap is explicitly the subject of PR 2. Rename: components/asteria-stub/ → components/asteria-game/ service asteria-stub → asteria-game volume asteria-stub-db → asteria-game-db Lift from #67 (asteria-spawn-v2): components/asteria-game/aiken/ (validators + apply-params) components/asteria-game/src/Asteria/ (game state, datums, validators, wallet, providers, RNG, SDK) components/asteria-game/app/{BootstrapMain.hs, PlayerMain.hs} components/asteria-game/asteria-game.cabal (renamed package) components/asteria-game/cabal.project (cardano-node-clients SRP bumped to PR #98 head 5707836b) Build infra: flake.nix — extends prior asteria-stub flake with haskell.nix / iohk-nix overlays so local Haskell packages compile, while keeping the upstream cardano-node-clients flake input that supplies the prebuilt utxo-indexer (PR #98 supervisor). nix/project.nix — lifted from PR #67, package renamed. nix/docker-image.nix — bundles utxo-indexer + asteria-bootstrap + asteria-game (player) execs + composer scripts + bash/jq/ socat; entrypoint stays utxo-indexer. KNOWN GAP — admin_mint validator is the always-true placeholder PR #67 ships. Without an on-chain one-shot guarantee, every container restart could mint another admin NFT. Bootstrap is *not* wired into compose in this PR for that reason. PR 2 patches the Aiken admin_mint to take an OutputReference parameter, runs apply-params at bootstrap-time, and adds defence-in-depth detection in Bootstrap.hs. Composer scripts (composer/stub/{parallel_driver_heartbeat, eventually_alive, finally_alive, helper_sdk}.sh) unchanged from the green stub baseline so this PR stays bisect-safe and in property terms identical to commit 3b6fb0e (PR #74's merged head).
paolino
added a commit
that referenced
this pull request
Apr 30, 2026
PR 1 of 2 toward the real asteria workload. Scope-limited to the rename + Haskell source lift + nix scaffolding so the binaries build alongside the existing utxo-indexer. Bootstrap is iteration 5b — *not safe for repeat invocation* — that gap is explicitly the subject of PR 2. Rename: components/asteria-stub/ → components/asteria-game/ service asteria-stub → asteria-game volume asteria-stub-db → asteria-game-db Lift from #67 (asteria-spawn-v2): components/asteria-game/aiken/ (validators + apply-params) components/asteria-game/src/Asteria/ (game state, datums, validators, wallet, providers, RNG, SDK) components/asteria-game/app/{BootstrapMain.hs, PlayerMain.hs} components/asteria-game/asteria-game.cabal (renamed package) components/asteria-game/cabal.project (cardano-node-clients SRP bumped to PR #98 head 5707836b) Build infra: flake.nix — extends prior asteria-stub flake with haskell.nix / iohk-nix overlays so local Haskell packages compile, while keeping the upstream cardano-node-clients flake input that supplies the prebuilt utxo-indexer (PR #98 supervisor). nix/project.nix — lifted from PR #67, package renamed. nix/docker-image.nix — bundles utxo-indexer + asteria-bootstrap + asteria-game (player) execs + composer scripts + bash/jq/ socat; entrypoint stays utxo-indexer. KNOWN GAP — admin_mint validator is the always-true placeholder PR #67 ships. Without an on-chain one-shot guarantee, every container restart could mint another admin NFT. Bootstrap is *not* wired into compose in this PR for that reason. PR 2 patches the Aiken admin_mint to take an OutputReference parameter, runs apply-params at bootstrap-time, and adds defence-in-depth detection in Bootstrap.hs. Composer scripts (composer/stub/{parallel_driver_heartbeat, eventually_alive, finally_alive, helper_sdk}.sh) unchanged from the green stub baseline so this PR stays bisect-safe and in property terms identical to commit 3b6fb0e (PR #74's merged head).
paolino
added a commit
that referenced
this pull request
May 1, 2026
PR 1 of 2 toward the real asteria workload. Scope-limited to the rename + Haskell source lift + nix scaffolding so the binaries build alongside the existing utxo-indexer. Bootstrap is iteration 5b — *not safe for repeat invocation* — that gap is explicitly the subject of PR 2. Rename: components/asteria-stub/ → components/asteria-game/ service asteria-stub → asteria-game volume asteria-stub-db → asteria-game-db Lift from #67 (asteria-spawn-v2): components/asteria-game/aiken/ (validators + apply-params) components/asteria-game/src/Asteria/ (game state, datums, validators, wallet, providers, RNG, SDK) components/asteria-game/app/{BootstrapMain.hs, PlayerMain.hs} components/asteria-game/asteria-game.cabal (renamed package) components/asteria-game/cabal.project (cardano-node-clients SRP bumped to PR #98 head 5707836b) Build infra: flake.nix — extends prior asteria-stub flake with haskell.nix / iohk-nix overlays so local Haskell packages compile, while keeping the upstream cardano-node-clients flake input that supplies the prebuilt utxo-indexer (PR #98 supervisor). nix/project.nix — lifted from PR #67, package renamed. nix/docker-image.nix — bundles utxo-indexer + asteria-bootstrap + asteria-game (player) execs + composer scripts + bash/jq/ socat; entrypoint stays utxo-indexer. KNOWN GAP — admin_mint validator is the always-true placeholder PR #67 ships. Without an on-chain one-shot guarantee, every container restart could mint another admin NFT. Bootstrap is *not* wired into compose in this PR for that reason. PR 2 patches the Aiken admin_mint to take an OutputReference parameter, runs apply-params at bootstrap-time, and adds defence-in-depth detection in Bootstrap.hs. Composer scripts (composer/stub/{parallel_driver_heartbeat, eventually_alive, finally_alive, helper_sdk}.sh) unchanged from the green stub baseline so this PR stays bisect-safe and in property terms identical to commit 3b6fb0e (PR #74's merged head).
Picks up the full reconnect-resilience stack on upstream main: * #105 — N2C reconnect supervisor + BlockedIndefinitely catch * #110 — post-reconnect indexer freshness gate (rsIndexFresh) The freshness gate closes the stale-UTxO window between bearer reconnect and chain-sync re-sync that produced the residual tx_generator_*_submit_rejected and tx_generator_population_did_not_grow Always-assertion failures on the previous Antithesis run (329a599).
Three composer-side fixes for findings carried over on the previous Antithesis run (329a599 — see issues #105, #106, #107): 1. (B / #105) The not-applicable case in parallel_driver_transact.sh and parallel_driver_refill.sh was emitting `sdk_sometimes false ...`. Antithesis grades a Sometimes assertion as PASSING when at least one sample has condition=true; we always emitted condition=false, so this assertion could never satisfy and was always failed. Switch to `sdk_reachable` — accumulates samples without a pass/fail grade, the right type for "documented not-applicable response". 2. (C / #106) The composer scripts intentionally exited 1 on not-applicable to mark the tick as "skipped". Antithesis's built-in 'Always: Commands finish with zero exit code' property has no opt-out and grades every non-zero exit as a failure. Switch to the asteria-stub convention: always exit 0, encode tick state purely via SDK assertions (parallel_driver_heartbeat.sh and eventually_alive.sh in components/asteria-stub/composer/stub/ do this). Same in eventually_population_grew.sh — fire the unreachability on did-not-grow and exit 0. 3. (D-adjacent / #107) Add 'index-not-ready' to the refill driver's not-applicable case set. After cardano-node-clients#110 the daemon's freshness gate returns IndexNotReady for refills during the post- reconnect stale-UTxO window; the composer should treat this as a documented not-applicable, not an unknown failure. The submit-rejected paths keep their `sdk_unreachable` (strict) framing — the daemon-side freshness gate (#110) is the actual fix, and we want any leftover submit-rejecteds to surface as findings, not be silenced. Verification gate: a fresh 1h Antithesis run on this branch should show 0 failures from these three findings, plus the supervisor still triggering its full reconnect load.
329a599 to
685fa5e
Compare
paolino
added a commit
that referenced
this pull request
May 1, 2026
Renames components/asteria-player/ → components/asteria-game/ and upgrades the lifted PR #67 sources so the bootstrap is safe to re-run on container restart. - cabal package + executable renamed asteria-player → asteria-game. - cabal.project SRP pinned to cardano-node-clients PR #98 head 5707836b (utxo-indexer supervisor + N2C reconnect). - flake.nix pulls cardano-node-clients utxo-indexer as a flake input so dockerTools bundles the prebuilt binary. - nix/docker-image.nix bundles utxo-indexer + asteria-bootstrap + asteria-game (player) execs + composer/stub scripts; entrypoint is the indexer, the bootstrap runs as a serial driver. - composer/stub/ shape replaces composer/asteria/: green-baseline heartbeat / eventually_alive / finally_alive plus a new serial_driver_asteria_bootstrap that execs /bin/asteria-bootstrap. - app/BootstrapMain.hs gains Asteria.Bootstrap.isAlreadyDeployed: queries Provider for UTxOs at the asteria spend address and short-circuits if any UTxO carries the @"asteriaAdmin"@ token. Antithesis can restart the asteria-game container at will and bootstrap exits 0 quickly on subsequent invocations. The asteria_game testnet that wires this image into Antithesis is added in the next commit. KNOWN GAP — admin_mint validator is the always-true placeholder PR #67 ships. The Haskell-side detection plus Antithesis's @serial_driver_@ scheduling are the contract until a follow-up PR replaces admin_mint with a one-shot policy parameterised on a seed @OutputReference@. Tracks: #67 (asteria-spawn-v2), #98 (utxo-indexer supervisor). Closes companion: #108 (idempotent bootstrap, content folded here).
Antithesis run on 685fa5e (https://cardano.antithesis.com/report/tilehuSggX4cnuy5qyXfwpqI/CVALsMOlHQdIyvQsc0sKyxZ79mapUIksHP-v0XZcVds.html) still flagged tx-generator/parallel_driver_*.sh against the "Always: Commands finish with zero exit code" property. Example log lines show command_return_code=1 with a runtime of ~30-60ms and an empty additional_stderr — i.e. the script never reached any of our 'exit 0' lines. Root cause: 'set -euo pipefail' + 'nc -U -q 1 $sock' fails the assignment when the daemon's control socket isn't yet bound (early boot, supervisor mid-cycle), and 'set -e' kills the script before any 'exit 0' branch runs. Same shape applies to eventually_population_grew.sh: an empty RSP made jq emit 0, and we then incorrectly fired the 'tx_generator_population_did_not_grow' Always assertion against a daemon we never successfully queried. Fix: - Replace 'set -euo pipefail' with 'set -u' (matches components/asteria-stub/composer/stub/parallel_driver_heartbeat.sh). - Wrap nc in '|| true', check for empty RSP, and if empty emit a 'tx_generator_*_daemon_unreachable' reachability event then exit 0. Composer's "Always exit 0" property holds; assertion ingestion still records the path was taken; daemon is retried on the next tick. - eventually_population_grew.sh: distinguish "daemon unreachable" from "daemon says populationSize=0". Fire did_not_grow only when the snapshot RSP is non-empty AND parses as JSON. The remaining tx_generator_*_submit_rejected Always failures from the 685fa5e run are a separate duplicate-submit-after-reconnect race tracked at lambdasistemi/cardano-node-clients#111.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps cardano-node-clients pin to upstream main
d0928a6,which now carries:
Plus three composer-side fixes folded into one commit:
tx_generator_*_not_applicablefromsdk_sometimes falsetosdk_reachable(closes fix(composer): tx_generator_*_not_applicable should be Reachability, not Sometimes-false #105).index-not-readyto the refill driver's not-applicable case set so the daemon's new freshness gate is treated as a documented response, not unknown failure.The submit-rejected paths keep their
sdk_unreachableframing — the daemon's freshness gate is the actual fix, and any leftover submit-rejecteds should still surface as findings.Verification
Image at
tx-generator:8325fc2is pre-pushed to GHCR (digestsha256:aeb64083316d4b88a2f2803be2a60ae61e40d2639ff543fe37f566ea78ea1ee1);publish-imageswill skip the rebuild.The 1h
cardano-node.yamlworkflow_dispatch on this branch is the gate. Expectation:tx-generator container exitfindings (the reconnect supervisor + BlockedIndefinitely catch landed already on the previous run — see https://cardano.antithesis.com/report/sgGPKwEUgpMFBkdN3QMH1MDn for the precedent).tx_generator_refill_submit_rejectedand 0tx_generator_population_did_not_grow(the freshness gate prevents stale-UTxO submissions; closes fix(composer): tx_generator_*_submit_rejected too strict during fault-injection reconnect window #107).parallel_driver_*.shandeventually_population_grew.sh"Always exit 0" failures (the always-exit-0 convention).tx_generator_*_not_applicablereported as Reachability with a positive sample count, not as a failed Sometimes.If all of those hold the PR is mergeable; per the pins-main-only rule the upstream pin is already at
d0928a6on main so no repoint is needed.Related