Apr 27, 3-4 PM (42)
Apr 27, 4-5 PM (36)
Apr 27, 5-6 PM (26)
Apr 27, 6-7 PM (13)
Apr 27, 7-8 PM (26)
Apr 27, 8-9 PM (13)
Apr 27, 9-10 PM (16)
Apr 27, 10-11 PM (42)
Apr 27, 11-12 AM (28)
Apr 28, 12-1 AM (17)
Apr 28, 1-2 AM (8)
Apr 28, 2-3 AM (4)
Apr 28, 3-4 AM (5)
Apr 28, 4-5 AM (5)
Apr 28, 5-6 AM (8)
Apr 28, 6-7 AM (8)
Apr 28, 7-8 AM (37)
Apr 28, 8-9 AM (54)
Apr 28, 9-10 AM (59)
Apr 28, 10-11 AM (53)
Apr 28, 11-12 PM (56)
Apr 28, 12-1 PM (49)
Apr 28, 1-2 PM (54)
Apr 28, 2-3 PM (69)
Apr 28, 3-4 PM (31)
Apr 28, 4-5 PM (14)
Apr 28, 5-6 PM (47)
Apr 28, 6-7 PM (9)
Apr 28, 7-8 PM (9)
Apr 28, 8-9 PM (14)
Apr 28, 9-10 PM (20)
Apr 28, 10-11 PM (34)
Apr 28, 11-12 AM (29)
Apr 29, 12-1 AM (13)
Apr 29, 1-2 AM (1)
Apr 29, 2-3 AM (1)
Apr 29, 3-4 AM (6)
Apr 29, 4-5 AM (1)
Apr 29, 5-6 AM (4)
Apr 29, 6-7 AM (12)
Apr 29, 7-8 AM (45)
Apr 29, 8-9 AM (75)
Apr 29, 9-10 AM (49)
Apr 29, 10-11 AM (28)
Apr 29, 11-12 PM (51)
Apr 29, 12-1 PM (39)
Apr 29, 1-2 PM (21)
Apr 29, 2-3 PM (67)
Apr 29, 3-4 PM (25)
Apr 29, 4-5 PM (36)
Apr 29, 5-6 PM (16)
Apr 29, 6-7 PM (10)
Apr 29, 7-8 PM (14)
Apr 29, 8-9 PM (13)
Apr 29, 9-10 PM (17)
Apr 29, 10-11 PM (25)
Apr 29, 11-12 AM (29)
Apr 30, 12-1 AM (6)
Apr 30, 1-2 AM (8)
Apr 30, 2-3 AM (1)
Apr 30, 3-4 AM (6)
Apr 30, 4-5 AM (2)
Apr 30, 5-6 AM (8)
Apr 30, 6-7 AM (15)
Apr 30, 7-8 AM (17)
Apr 30, 8-9 AM (100)
Apr 30, 9-10 AM (19)
Apr 30, 10-11 AM (50)
Apr 30, 11-12 PM (120)
Apr 30, 12-1 PM (69)
Apr 30, 1-2 PM (45)
Apr 30, 2-3 PM (117)
Apr 30, 3-4 PM (29)
Apr 30, 4-5 PM (34)
Apr 30, 5-6 PM (9)
Apr 30, 6-7 PM (20)
Apr 30, 7-8 PM (23)
Apr 30, 8-9 PM (28)
Apr 30, 9-10 PM (13)
Apr 30, 10-11 PM (25)
Apr 30, 11-12 AM (15)
May 01, 12-1 AM (18)
May 01, 1-2 AM (15)
May 01, 2-3 AM (6)
May 01, 3-4 AM (7)
May 01, 4-5 AM (3)
May 01, 5-6 AM (5)
May 01, 6-7 AM (8)
May 01, 7-8 AM (13)
May 01, 8-9 AM (24)
May 01, 9-10 AM (16)
May 01, 10-11 AM (16)
May 01, 11-12 PM (17)
May 01, 12-1 PM (39)
May 01, 1-2 PM (32)
May 01, 2-3 PM (19)
May 01, 3-4 PM (16)
May 01, 4-5 PM (25)
May 01, 5-6 PM (11)
May 01, 6-7 PM (20)
May 01, 7-8 PM (22)
May 01, 8-9 PM (65)
May 01, 9-10 PM (15)
May 01, 10-11 PM (40)
May 01, 11-12 AM (61)
May 02, 12-1 AM (6)
May 02, 1-2 AM (11)
May 02, 2-3 AM (5)
May 02, 3-4 AM (8)
May 02, 4-5 AM (6)
May 02, 5-6 AM (2)
May 02, 6-7 AM (2)
May 02, 7-8 AM (14)
May 02, 8-9 AM (7)
May 02, 9-10 AM (8)
May 02, 10-11 AM (11)
May 02, 11-12 PM (7)
May 02, 12-1 PM (7)
May 02, 1-2 PM (3)
May 02, 2-3 PM (14)
May 02, 3-4 PM (9)
May 02, 4-5 PM (27)
May 02, 5-6 PM (9)
May 02, 6-7 PM (29)
May 02, 7-8 PM (11)
May 02, 8-9 PM (14)
May 02, 9-10 PM (1)
May 02, 10-11 PM (20)
May 02, 11-12 AM (18)
May 03, 12-1 AM (8)
May 03, 1-2 AM (1)
May 03, 2-3 AM (4)
May 03, 3-4 AM (7)
May 03, 4-5 AM (1)
May 03, 5-6 AM (4)
May 03, 6-7 AM (32)
May 03, 7-8 AM (5)
May 03, 8-9 AM (1)
May 03, 9-10 AM (3)
May 03, 10-11 AM (10)
May 03, 11-12 PM (11)
May 03, 12-1 PM (16)
May 03, 1-2 PM (11)
May 03, 2-3 PM (2)
May 03, 3-4 PM (2)
May 03, 4-5 PM (5)
May 03, 5-6 PM (0)
May 03, 6-7 PM (5)
May 03, 7-8 PM (6)
May 03, 8-9 PM (8)
May 03, 9-10 PM (15)
May 03, 10-11 PM (23)
May 03, 11-12 AM (16)
May 04, 12-1 AM (4)
May 04, 1-2 AM (4)
May 04, 2-3 AM (10)
May 04, 3-4 AM (9)
May 04, 4-5 AM (5)
May 04, 5-6 AM (6)
May 04, 6-7 AM (5)
May 04, 7-8 AM (28)
May 04, 8-9 AM (24)
May 04, 9-10 AM (43)
May 04, 10-11 AM (34)
May 04, 11-12 PM (55)
May 04, 12-1 PM (34)
May 04, 1-2 PM (47)
May 04, 2-3 PM (60)
May 04, 3-4 PM (8)
3,605 commits this week Apr 27, 2026 - May 04, 2026
chore(testnet): align cardano_node_adversary pins to origin/main master
Pulls in master's current shared-image versions:
- sidecar:1ff6913       (post legacy-probe delete, #119)
- tracer-sidecar:5271661 (fork-tree probe build)
- configurator + log-tailer + tracer + cardano-node digests already match
- tx-generator from master is intentionally not added — adversary
  testnet runs nodes only

The adversary container itself stays pinned to its own SHA
(adversary:b75cfe3) since master has no adversary equivalent.

Layer 3 of #123 (perturbation metric emit from finally_tips_agree.sh)
is dropped: that script was deleted on main by #119, the cluster-wide
"did the cluster fork" oracle now lives in tracer-sidecar's fork-tree
probe. Re-implementing the perturbation metric on top of that surface
is a follow-up.
feat(adversary): emit Antithesis SDK assertions to prove the attacker fired
Adds Adversary.SDK with Reachable / Sometimes assertion emitters that
write to \$ANTITHESIS_OUTPUT_DIR/sdk.jsonl (default /tmp/sdk.jsonl).
Wires two assertions into app/Main.hs:

  - reachable("adversary_chain_sync_started", {target_host, point, limit})
    fires once per invocation before connectToNode. Antithesis report
    will show, segmented by target_host, "the adversary fired against
    pN at least once". A host that never gets attacked is visible as
    a missing Reachable hit.

  - sometimes(true|false, "adversary_chain_sync_completed",
              {target_host, tip|reason})
    fires once per invocation on completion. true on clean exit,
    false on connect/protocol failure. Sometimes-true vs Sometimes-
    false buckets quantify how often the adversary actually completed
    a full --limit sync vs being cut short by chaos.

Layer 1 of three for issue #123.
asteria-game: widen liveness probe budget to absorb cold-restart
eventually_alive.sh / finally_alive.sh were exiting 1 in timelines
where Antithesis had killed the asteria-game container as a node
fault and the eventually_ check fired ~520ms after the container
respawned. The indexer's first-boot reconnect goes through
node-replaying with exponential backoff (1s, 2s, 4s, 8s, 16s … ≈
13 s by attempt 7) plus the N2C handshake and first-block write —
roughly 30-40s before tipSlot becomes non-null. The old 25 s budget
(15 s settle + 5×2 s retries) collided with that cold-start.

Bump SLEEP_SETTLE 15->30 and MAX_ATTEMPTS 5->15 in both scripts:
60 s budget. The probes still complete in well under the
post-fault window, and the script's contract ("indexer is at chain
tip within budget") is unchanged.

Investigation: see the failing example at vtime 132.9s on
b5698f4 — fault_injector logs show
  93.33  FAULT kill node target=["asteria-game"] dur=12.88
 107.26  containers_meta init+start asteria-game
 107.78  composer fires stub/eventually_alive.sh
 132.89  attempts_exhausted=5 last_reply.tipSlot=null
Implement CBOR instances for EraBasedProtocolParametersUpdate
The ToCBOR/FromCBOR instances for EraBasedProtocolParametersUpdate
were previously stubbed with 'error' calls, which made any code path
using them blow up at runtime. The same problem propagated through
UpdateProposal, whose CBOR instances recurse into a Map containing
EraBasedProtocolParametersUpdate.

Implement them by routing through the ledger's PParamsUpdate encoding:
toCBOR converts via createEraBasedProtocolParamUpdate, fromCBOR
deserialises a PParamsUpdate and projects back via the existing
fromLedgerPParamsUpdate. The instance constraint tightens from
Typeable era to IsShelleyBasedEra era so we can dispatch on the era;
this propagates to UpdateProposal's instances.

Restore the prop_roundtrip_UpdateProposal_CBOR test that was deleted
when the stubs were introduced.
testnet(amaru): rename cardano_amaru_epoch3600 -> cardano_amaru_epoch240
Drops epochLength from 3600 to 240 slots so two full Conway epochs
fit comfortably inside Antithesis's 1-h test phase. The previous
3600-slot variant required ~2 h of vtime growth before the
bootstrap-producer's era-readiness predicate could ever hold,
which cannot be satisfied in a 1-h dispatch (today's 1h6m run
hit predicate satisfaction 0 times, all 39 producer attempts
exited rc=2 chain-not-era-ready).

Directory renamed for clarity. specs/080-amaru-self-bootstrap/
deliberately keeps the old name as historical record of the
original spec.
Sweep dead code and O(n²) anti-patterns in HeadLogic
  Three cleanups spotted while reviewing the newLocalUTxO removal:

  - waitApplyTx and waitOnApplicableDecommit no longer pass the validated
    UTxO to their continuations (the callers stopped using it after the
    newLocalUTxO removal). Validation still happens; only the unused
    continuation arg is dropped.

  - pruneTransactions: rewrite from foldl' with `txs <> [tx]` (O(n^2))
    to guarded recursion with `tx : go u' rest` (O(n)). Threading the
    running UTxO through `go` is still required for validity checks
    on dependent txs.

  - TransactionReceived aggregate: replace `allTxs <> fromList [(k,v)]`
    with `Map.insert k v allTxs`. Same big-O class but eliminates the
    intermediate singleton-Map allocation per ReqTx.

  No behavioural change. Constant-factor wins on the per-ReqTx hot path.

Signed-off-by: Sasha Bogicevic <[email protected]>
testnet(amaru): drop slotLength to 0.36 s for 1-h Antithesis budget
bootstrap-producer's era-readiness predicate requires
`slot >= 2*epochLength = 7,200`. With the default 1-second slot
length, Antithesis vtime under fault injection runs at ~1× wallclock,
so a 1-h budget caps the chain at ~3,600 slots — half the predicate.

Today's run (commit 5de10fff, session bafdf9ed3f06b0b7cbec33a92779d260)
showed exactly that: 39 producer attempts, 0 era-readiness
satisfactions, all transient rc=2 (chain-not-era-ready). amaru never
got past bootstrap.

slotLength: 0.36 s puts 2 epochs at ~43 wallclock minutes, leaving
~17 minutes for bootstrap + amaru run inside a 1-h test phase.
0.24 s would be even faster but starts risking leaders not finishing
block minting before the next slot — keep margin.

epoch length stays at 3,600 slots so the era boundaries the producer
walks remain unchanged.
fix: avoid re-traversal and decoding logic duplication in blocks decode
  Few things:

  1. We were duplicating decoding logic regarding arrays and maps (which
     is particularly tedious) in the minicbor-extra; This is more
     cleanly done with a `WithSize` type wrapper as it allows to
     decouple the decoding logic from measuring the size of the decoded
     object (instead of having to rewrite specialized function for each
     type of structure).

  2. The TransactionBody and AuxiliaryData were already retaining
     information from their decoding, so we needed not the WithSize
     wrapper for them; but it's useful for the witnesses.

  3. All-in-all, the size is better calculated on-the-fly when iterating
     over transactions.

Signed-off-by: KtorZ <[email protected]>