amaru-relay-bootstrap: the long-lived Antithesis relay entrypoint.
bootstrap-producer: the one-shot producer primitive called by the
relay wrapper and by local checks.
The critical code boundary is still the release-pinned ledger-state
format: the whole toolset (the pinned stock db-analyser, the
db-analyser engine that amaru create-snapshots drives) targets one
cardano-node release at a time. This branch targets cardano-node 10.7.1.
The relay writes the startup marker before bootstrap work. That lets the
Antithesis setup phase complete while the bootstrap itself continues in
the test phase. The marker is not an Amaru-sync proof; it is a container
startup contract.
There is no downstream Compose service waiting on
service_completed_successfully in relay mode. The relay container does
not stop after bootstrap; it execs amaru run.
In standalone mode the producer writes <bundle>/<network>. In relay
mode it writes to scratch, and the wrapper promotes the contents of
<scratch-out>/<network> into /srv/amaru so amaru run can open:
Nonces and bootstrap headers are baked into chain.<network>.db by
amaru bootstrap; they are no longer separate bundle artefacts. The
snapshots/<network>/ directory keeps the materialized epoch snapshots
and their era-history sidecars for re-bootstrap; era-history.json at
the bundle root is passed to amaru node bootstrap --era-history and
is the consume-time override for amaru run --era-history.
Live ChainDB Contract
flowchart LR
writer["cardano-node\nlive writer"] --> state["state volume\nChainDB"]
state --> imm["immutable chunks\nread by tools"]
state --> ledger["ledger DB\ncopied but not mutated"]
state --> vol["volatile DB\ncopied for ChainDB shape"]
imm --> tip["db-analyser\ntip poll + target trace"]
state -. "mounted read-only in relay\ncopied to writable scratch" .-> relay["amaru-relay-bootstrap"]
relay --> scratch["scratch ChainDB\nopened read-write by producer tools"]
The one-shot bootstrap-producer still needs a writable ChainDB path
because node-10.7.1's consensus ImmutableDB validation path opens chunk
files through APIs that reject a read-only filesystem. The relay wrapper
therefore copies the paired cardano-node /live state into private
writable scratch before invoking the producer. The producer behavior is
immutable-only: readiness comes from immutable chunks, and
amaru create-snapshots is given an isolated --cardano-db-dir view in
which the immutable chunks are symlinked from the source ChainDB while
the ledger snapshots its db-analyser engine materializes land in
producer-owned writable directories. The producer never mutates the
source ChainDB, so concurrent producers can run against the same chain.
The retry loop belongs in the relay entrypoint, not in Compose
dependency semantics. This matters under Antithesis faults: a short,
failed producer attempt should refresh from a newer /live snapshot
instead of blocking the whole setup behind a one-shot service.
Any other uncaught failure exits with 64 + rc via the internal-error
trap. The relay wrapper treats exit codes 1, 2, 5, 6, 7, and 8 as
transient and retries; 0 promotes; anything else is fatal.
Runtime Parameters
The relay passes deployment-provided runtime JSON to amaru run:
--era-history /amaru-runtime/era-history.json
# global-parameters.json is exported as AMARU_GLOBAL_* (amaru run --help-global-parameters)
These files must match the custom testnet genesis/config used by the
paired cardano-node. The producer also passes its staged bundle
era-history.json to amaru node bootstrap --era-history. The
history.<slot>.<hash>.json sidecars next to each snapshot remain for
re-bootstrap. All three documents are built from the same genesis
epochLength.
Retargeting to another node release is an explicit project task. It is
not just a Cabal compile check: the ledger-state CBOR that the pinned
tools read and that Amaru imports has to match for that release.
CI Startup Proof
sequenceDiagram
participant Check as amaru-run-bootstrap
participant Producer as bootstrap-producer
participant Bundle as Bundle
participant Amaru as amaru run
Check->>Producer: synthesize chain DB, produce bundle
Producer->>Bundle: create-snapshots + bootstrap stores
Check->>Bundle: copy to writable test directory
Check->>Amaru: run with ledger-dir and chain-dir
Amaru-->>Check: build_ledger trace
Check-->>Check: timeout is expected, early bootstrap failure is not
The CI proof is deliberately peer-free: it does not prove live chain
synchronisation. It proves the produced stores are sufficient for Amaru
to open its ledger and chain state and enter node startup.