feat: mid-epoch transition stability
Signed-off-by: Chris Guiney <[email protected]>
Signed-off-by: Chris Guiney <[email protected]>
Signed-off-by: yHSJ <[email protected]>
The `crates/cardano/src/ashard/` module was merged into `crates/cardano/src/ewrap/` (it became EWRAP's per-shard leg) and the `EpochEndAccumulate` delta was renamed to `EWrapProgress`. The debug guide's tables, narrative, file-path references, and instrumentation hints still pointed at the old names and paths. Updates the Step 3 classification table, Step 5 work-unit narrative + source-file map, and Step 6 instrumentation table to: - talk about EWRAP/ESTART each having a per-shard leg + finalize, not a separate ASHARD work unit; - point at `ewrap/rewards.rs`, `crates/cardano/src/shard.rs`, and the per-unit `work_unit.rs` files; - reference `EWrapProgress` (not `EpochEndAccumulate`) and the `EpochWrapUpV2` / `EpochTransitionV2` deltas where boundary close / open is described. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- shard.rs: const-context divisibility check now uses `u32::is_multiple_of` (stable-const since Rust 1.87) per `clippy::manual_is_multiple_of`. - model/epochs.rs: replace `let mut x = T::default(); x.f = ...; x` with a struct-literal `..Default::default()` form per `clippy::field_reassign_with_default`; also demote a doc comment attached to a `prop_compose!` invocation to a regular `//` comment (rustdoc can't attach docs to macro invocations). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- genesis/mod.rs: fix copy/paste typo "Ewrap (which now runs before Ewrap)" → "per-shard Ewrap pass (which runs before the global Ewrap finalize)" (PR #978 comment 3154574432). - work_units.md: add `text` language to fenced sequence diagram block for markdownlint MD040 (3153861508); fix stale loader name `BoundaryWork::load_ewrap` → `load_finalize` (3153861515). - tests/memory.rs: sample heap allocation across full iteration as well as iterator construction, so a backend that buffers the shard on first `next()` no longer slips through (3153861530). - model/epochs.rs: hoist `#[allow(deprecated)]` from per-item attributes on the prop_compose!/test items (where the macro hides the lint site) to the whole `prop_tests` module — silences the test-build deprecation warnings introduced by the V1/V2 split. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
`shard_key_ranges` previously guarded `total_shards` and `shard_index` with `debug_assert!`, which compiles to nothing in release. A `0` would divide by zero in `variant_range`, and a non-divisor of 256 would silently produce broken partitions. Since `total_shards` can come from persisted `ShardProgress.total` (not just the compile-time `ACCOUNT_SHARDS` constant), the invariants must hold at runtime in all profiles. Promotes the validation to unconditional `assert!` / `panic!` with informative messages. Addresses PR #978 review comment 3153861503. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
`commit_finalize` was archiving `self.ending_state()` at the epoch-start temporal key, but `stream_and_apply_namespace::<D, EpochState>` only applied the boundary-closing deltas (PParamsUpdate, TreasuryWithdrawal, EpochWrapUp) to the writer — `ending_state` itself was never refreshed. The archived row therefore carried the pre-commit snapshot (stale rolling/pparams, populated `ewrap_progress`). Adds an EpochState-specific variant of the streaming helper that returns the post-apply singleton; `commit_finalize` swaps the result into `self.ending_state` before the archive write, so the archived EpochState matches what's about to be committed to the live state store. Addresses PR #978 review comment 3153861497. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Previously, `EwrapWorkUnit` / `EstartWorkUnit` / `RupdWorkUnit::initialize` read only `*_progress.total` from persisted state and the core lifecycle loop iterated `0..total_shards` unconditionally, so a crash mid-boundary replayed shards `0..k-1` on restart. That is unsafe: `AccountTransition` deltas (Estart) are non-idempotent — replaying a committed shard would double-rotate every account in it. Adds `WorkUnit::start_shard()` (defaulting to `0`); `run_lifecycle` now loops `start_shard..total_shards`. The three sharded work units cache the committed cursor in `initialize` from `*_progress.committed`, and their `start_shard()` returns it. `CardanoWorkUnit` delegates the new method to its variants. The bootstrap test harness mirrors the real runner. Also propagates `load_epoch` failures via `?` instead of the previous `Err(_) => ACCOUNT_SHARDS` swallow, so a state-read failure can no longer silently repartition an in-flight boundary. Addresses PR #978 review comments 3153861491 (restart cursor) and 3154574387 (propagate load_epoch failures). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
New `components/asteria-stub/` ships a tiny Debian image with
cardano-cli (+ liblmdb0 runtime), jq, and bash. Its only job is to
host composer scripts at `/opt/antithesis/test/v1/stub/`:
- parallel_driver_heartbeat.sh — short tick, emits Sometimes
- eventually_alive.sh — post-fault: pings p1/p2/p3, Always
- finally_alive.sh — post-workload: pings p1/p2/p3, Always
The container itself just `sleep infinity`s. This is intentional:
the stub is the experimentation harness for evolving property checks
before touching the real asteria-player. Real game logic stays in
PR #67's `components/asteria-player/`.
Conventions adopted from the working sidecar template:
- cardano-cli ping uses `-j --magic 42 --host X --port Y --tip
--quiet -c1`. Without `-j --tip` the cli has no query target and
exits non-zero.
- SDK output goes to /tmp/sdk.jsonl (default path) on a tmpfs
mount; Antithesis introspects that path. A named-volume
convention (e.g. ANTITHESIS_OUTPUT_DIR=/sdk) is not picked up.
- liblmdb0 must be apt-installed; cardano-cli loads liblmdb.so.0
at start regardless of subcommand.
On failure, eventually_alive / finally_alive emit a self-classifying
JSON detail with the failing host, exit code, and the cardano-cli
stderr — so the next failure self-diagnoses without another round
trip.
Image referenced by content digest in
testnets/cardano_node_master/docker-compose.yaml; the publish-images
workflow builds and pushes both `:asteria-stub-v3` and
`:<full-commit>` on PR. Bootstrap relied on a paired git tag so the
script could resolve the friendly name back to a commit; once
merged, the digest pin is the only contract.
Signed-off-by: Chris Gianelloni <[email protected]>
Release 13.7.0.4
Bincode encodes CardanoDelta variants by positional index and structs by positional fields, so this branch's three new variants (EWrapProgress, EStartProgress, RupdProgress) inserted mid-enum and the appended `prev_*_progress` fields on EpochWrapUp / EpochTransition would have made pre-upgrade WAL rows undecodable. Freezes CardanoDelta indices 0..=38 to match pre-PR `main`, restores the legacy struct shapes verbatim under `#[deprecated]`, and introduces EpochWrapUpV2 / EpochTransitionV2 carrying the new undo state. The three sharded-progress variants plus the V2 variants are appended at the end of the enum. New commit paths in estart/reset.rs and ewrap/wrapup.rs emit V2; the legacy types remain solely for replay of older WAL rows and carry TODO(wal-compat) cleanup notes. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Signed-off-by: Allain Magyar <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: Roland Kuhn <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: yHSJ <[email protected]>
Signed-off-by: yHSJ <[email protected]>