Asteria Player
Long-running container that plays the asteria game inside the cardano-node-antithesis cluster. Drives realistic transaction traffic (spend script, mint, reference inputs, validity bounds, inline datums) through the cluster nodes so antithesis can fuzz state-space exploration against contention between players.
This component is part of the phase-1 gatherer feature (#56).
What it does
The container ships two binaries:
asteria-bootstrap— one-shot. Deploys the four asteria validators as inline reference scripts, mints the admin NFT, locks the asteria UTxO at the asteria spend address with inlineAsteriaDatum, and spawns the initial pellet UTxOs at known coordinates.asteria-player— long-running. Reads game state via the N2C local socket, picks an action (mint_ship,move_ship,gather_fuel,mine_asteria,quit) using randomness sourced from the antithesis hypervisor when available, submits the resulting tx, sleeps a randomly-chosen interval, repeats.
Composer scripts under /opt/antithesis/test/v1/asteria/:
parallel_driver_asteria_bootstrap.sh— fires once at start.parallel_driver_asteria_player.sh— long-running player loop, one per replica.eventually_asteria_alive.sh— confirms the bootstrap event landed in the SDK fallback file within a bounded window.helper_sdk_lib.sh— copy of the shared shell SDK helper.
Iterations
- Wiring proof (current). Both binaries emit
sdk_reachableevents to the JSONL fallback file and exit / sleep. No game logic yet; this iteration only proves the Nix → docker image → docker-compose → composer driver → SDK fallback pipeline is wired correctly. See PR #57. cardano-node-clientsintegration. Pincardano-node-clients@f6a31ca(closes the ref-script fee bug that asteria'smove_shipref-input path needs) and transitivesource-repository-packagedependencies. Player connects to N2C and queries protocol parameters.- Real validators. Compile txpipe/asteria's
four Aiken validators (
asteria.spend,spacetime.spend,pellet.spend,deploy.spend) plus the two minting policies (shipyard.mint,fuel.mint) with parameter application. Commit compiled bytes alongside the Aiken sources for reproducibility. - Real bootstrap. Replace the
sdk_reachableplaceholder with the actual deployment tx. - Game loop.
mintShip/moveShip/gatherFuel/mineAsteriadriven by an injectableRandomSource; pure library functions overProvider+Submitterfromcardano-node-clients. - Antithesis randomness. Wire
RandomSourcetoantithesis.random.get_random()(Python subprocess wrapper;System.Randomfallback when the SDK isn't reachable). The hypervisor controls every game decision. - Richer assertions.
eventually_ship_counter_grew,finally_someone_reached_origin,sdk_always(no_double_spend), per-txsdk_sometimesmarkers for unusual states.
Build the image
Nix
cd components/asteria-player
nix build .#docker-image
docker load < result
version=$(nix eval --raw .#version)
docker tag \
ghcr.io/cardano-foundation/cardano-node-antithesis/asteria-player:$version \
ghcr.io/cardano-foundation/cardano-node-antithesis/asteria-player:dev
just load-docker-image wraps the same steps.
Run locally
INTERNAL_NETWORK=false docker compose \
-f testnets/cardano_node_master/docker-compose.yaml up -d
The compose file declares:
asteria-bootstrap— depends onrelay1, exits 0 once the bootstrap event is written.asteria-player-1/asteria-player-2— depend onasteria-bootstrapcompleting successfully; tail forever once started.asteria-sdknamed volume — shared between all three so the JSONL fallback file (/sdk/sdk.jsonl) is observable from any of them.
Inspect the JSONL fallback:
docker run --rm \
-v cardano_node_master_asteria-sdk:/sdk:ro \
--entrypoint /bin/cat \
ghcr.io/cardano-foundation/cardano-node-antithesis/asteria-player:dev \
/sdk/sdk.jsonl
See Also
- License: see LICENSE
- Contributing: see CONTRIBUTING.md
- Other projects by HAL
- Other projects by the Cardano Foundation
- About Cardano