May 13, 5-6 PM (30)
May 13, 6-7 PM (51)
May 13, 7-8 PM (33)
May 13, 8-9 PM (9)
May 13, 9-10 PM (24)
May 13, 10-11 PM (30)
May 13, 11-12 AM (11)
May 14, 12-1 AM (18)
May 14, 1-2 AM (3)
May 14, 2-3 AM (4)
May 14, 3-4 AM (21)
May 14, 4-5 AM (11)
May 14, 5-6 AM (18)
May 14, 6-7 AM (18)
May 14, 7-8 AM (47)
May 14, 8-9 AM (53)
May 14, 9-10 AM (35)
May 14, 10-11 AM (20)
May 14, 11-12 PM (114)
May 14, 12-1 PM (54)
May 14, 1-2 PM (151)
May 14, 2-3 PM (32)
May 14, 3-4 PM (17)
May 14, 4-5 PM (14)
May 14, 5-6 PM (38)
May 14, 6-7 PM (12)
May 14, 7-8 PM (22)
May 14, 8-9 PM (37)
May 14, 9-10 PM (35)
May 14, 10-11 PM (27)
May 14, 11-12 AM (14)
May 15, 12-1 AM (18)
May 15, 1-2 AM (15)
May 15, 2-3 AM (5)
May 15, 3-4 AM (3)
May 15, 4-5 AM (13)
May 15, 5-6 AM (14)
May 15, 6-7 AM (10)
May 15, 7-8 AM (31)
May 15, 8-9 AM (23)
May 15, 9-10 AM (52)
May 15, 10-11 AM (71)
May 15, 11-12 PM (70)
May 15, 12-1 PM (73)
May 15, 1-2 PM (73)
May 15, 2-3 PM (66)
May 15, 3-4 PM (26)
May 15, 4-5 PM (13)
May 15, 5-6 PM (30)
May 15, 6-7 PM (29)
May 15, 7-8 PM (25)
May 15, 8-9 PM (8)
May 15, 9-10 PM (34)
May 15, 10-11 PM (34)
May 15, 11-12 AM (25)
May 16, 12-1 AM (2)
May 16, 1-2 AM (2)
May 16, 2-3 AM (3)
May 16, 3-4 AM (3)
May 16, 4-5 AM (0)
May 16, 5-6 AM (6)
May 16, 6-7 AM (2)
May 16, 7-8 AM (10)
May 16, 8-9 AM (1)
May 16, 9-10 AM (2)
May 16, 10-11 AM (1)
May 16, 11-12 PM (13)
May 16, 12-1 PM (11)
May 16, 1-2 PM (8)
May 16, 2-3 PM (15)
May 16, 3-4 PM (10)
May 16, 4-5 PM (2)
May 16, 5-6 PM (2)
May 16, 6-7 PM (2)
May 16, 7-8 PM (10)
May 16, 8-9 PM (6)
May 16, 9-10 PM (9)
May 16, 10-11 PM (29)
May 16, 11-12 AM (42)
May 17, 12-1 AM (9)
May 17, 1-2 AM (1)
May 17, 2-3 AM (0)
May 17, 3-4 AM (1)
May 17, 4-5 AM (0)
May 17, 5-6 AM (3)
May 17, 6-7 AM (2)
May 17, 7-8 AM (1)
May 17, 8-9 AM (1)
May 17, 9-10 AM (1)
May 17, 10-11 AM (6)
May 17, 11-12 PM (6)
May 17, 12-1 PM (4)
May 17, 1-2 PM (5)
May 17, 2-3 PM (9)
May 17, 3-4 PM (4)
May 17, 4-5 PM (8)
May 17, 5-6 PM (14)
May 17, 6-7 PM (10)
May 17, 7-8 PM (2)
May 17, 8-9 PM (4)
May 17, 9-10 PM (2)
May 17, 10-11 PM (20)
May 17, 11-12 AM (13)
May 18, 12-1 AM (10)
May 18, 1-2 AM (4)
May 18, 2-3 AM (5)
May 18, 3-4 AM (9)
May 18, 4-5 AM (14)
May 18, 5-6 AM (2)
May 18, 6-7 AM (37)
May 18, 7-8 AM (28)
May 18, 8-9 AM (35)
May 18, 9-10 AM (41)
May 18, 10-11 AM (43)
May 18, 11-12 PM (29)
May 18, 12-1 PM (136)
May 18, 1-2 PM (34)
May 18, 2-3 PM (89)
May 18, 3-4 PM (33)
May 18, 4-5 PM (45)
May 18, 5-6 PM (21)
May 18, 6-7 PM (16)
May 18, 7-8 PM (13)
May 18, 8-9 PM (23)
May 18, 9-10 PM (4)
May 18, 10-11 PM (25)
May 18, 11-12 AM (12)
May 19, 12-1 AM (7)
May 19, 1-2 AM (2)
May 19, 2-3 AM (9)
May 19, 3-4 AM (5)
May 19, 4-5 AM (10)
May 19, 5-6 AM (3)
May 19, 6-7 AM (53)
May 19, 7-8 AM (23)
May 19, 8-9 AM (46)
May 19, 9-10 AM (66)
May 19, 10-11 AM (30)
May 19, 11-12 PM (48)
May 19, 12-1 PM (81)
May 19, 1-2 PM (71)
May 19, 2-3 PM (41)
May 19, 3-4 PM (51)
May 19, 4-5 PM (15)
May 19, 5-6 PM (20)
May 19, 6-7 PM (18)
May 19, 7-8 PM (9)
May 19, 8-9 PM (21)
May 19, 9-10 PM (10)
May 19, 10-11 PM (28)
May 19, 11-12 AM (13)
May 20, 12-1 AM (21)
May 20, 1-2 AM (9)
May 20, 2-3 AM (4)
May 20, 3-4 AM (5)
May 20, 4-5 AM (9)
May 20, 5-6 AM (37)
May 20, 6-7 AM (47)
May 20, 7-8 AM (53)
May 20, 8-9 AM (50)
May 20, 9-10 AM (16)
May 20, 10-11 AM (40)
May 20, 11-12 PM (28)
May 20, 12-1 PM (50)
May 20, 1-2 PM (92)
May 20, 2-3 PM (17)
May 20, 3-4 PM (317)
May 20, 4-5 PM (18)
May 20, 5-6 PM (4)
4,261 commits this week May 13, 2026 - May 20, 2026
Add ToJSON/FromJSON instances for EraTxAuxData
* Add ToJSON/FromJSON and NFData as EraTxAuxData superclass constraints
* Add ToJSON/FromJSON for Metadatum
* Add ToJSON/FromJSON for Data era and PlutusBinary
* Add FromJSON for PoolCert, ConwayGovCert, DijkstraDelegCert, DijkstraTxCert era
* Add ToJSON/FromJSON for ShelleyTxAuxData, AllegraTxAuxData, AlonzoTxAuxData
* Add round-trip JSON property test for TxAuxData era
Add ToJSON/FromJSON instances for EraScript
* Add ToJSON/FromJSON as superclass constraints to EraScript
* Add ToJSON/FromJSON instances for MultiSig, Timelock and DijkstraNativeScript
* Add structured JSON serialisation for native scripts across all eras (Shelley, Allegra, Dijkstra)
* Add FromJSON instance for AlonzoScript (hex-encoded CBOR roundtrip)
* Add EncCBOR/ToCBOR instances for PlutusScript era
* Rename kindObject (returning Value) to kindObjectValue; add new kindObject returning Aeson.Object
  * Add new kindObject returning Aeson.Object
* Fix shelleyBasedEraNativeScriptToJSON and sizedNativeScriptGens to accept a child continuation to correctly handle nested scripts across eras
* Add round-trip JSON property tests for NativeScript and Script to the shared era spec
Fix tx-cost bench: drop fanoutChunkSize, widen FinalPartialFanout range
  computeFinalPartialFanOutCost was capped at 7 (fanoutChunkSize), hiding
  the real tx-size limit for the terminal fanout step. Now it sweeps a wide
  range and searches for the actual maximum, using a single preceding output
  as minimal setup to reach FanoutProgress.

  computePartialFanOutMixedCost also dropped its fanoutChunkSize cap and
  now distributes all-but-one outputs, consistent with the nominal benchmark.
  The stale description mentioning fanoutChunkSize is corrected accordingly.

Signed-off-by: Sasha Bogicevic <[email protected]>
tcp-model: single envelope per link with retrigger semantics
TCP has one cwnd per connection, so a new event (loss or idle reset)
should *replace* the per-link envelope rather than overlay onto a
stack. Adds `bw_start` to `Envelope` so the new envelope picks up at
whatever multiplier the link was already at, then dips to `bw_depth`
through the onset and recovers to 1.0 through the release.

LinkState.active (SmallVec) becomes LinkState.current (Option). bw_mult
and delivery_floor query the single envelope; bytes_deliverable
sub-divides at its phase transitions only. Loss retrigger:
  bw_start    = current_mult
  bw_depth    = current_mult * loss_bw_depth (= cwnd halved from current)
  lat_stall   = max(existing_stall_remaining, rto)
so back-to-back losses correctly extend the stall (instead of shortening
it under naive replacement) and the AIMD halving compounds from the
current cwnd-like state instead of always halving from 1.0.

Without this, the multiplicative composition of overlapping envelopes
drove bw_mult to ~0 at high loss probabilities, throttling the sim to
a crawl. The single-envelope model is both physically correct and far
cheaper to evaluate.

27 unit tests (was 25), including loss-replaces-from-current-mult and
back-to-back-stall-extension. sim-core regression suite unchanged (65
tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Consolidate fanout test constants and fix uncaught exception in postTx
  fanoutChunkSize and fanoutOutputThreshold are now defined once in
  Test.Hydra.Tx.Fixture and imported wherever needed, removing the
  per-file duplicates.

  prepareTxToPost gains explicit FanoutTx/FinalPartialFanoutTx branches
  (error) so GHC's exhaustiveness checker catches any future unhandled
  constructor, instead of silently falling through a wildcard.

  The two deadline-slot conversions in mkChain.postTx now throw
  FailedToConstructFanoutTx (a PostTxError Tx) instead of userError,
  so the exception is caught by Node.hs's PostTxError handler rather
  than propagating uncaught and crashing the node.
Remove hardcoded fanout chunk/threshold constants; make fanout sizing fully dynamic
  HeadLogic no longer uses fanoutChunkSize or fanoutOutputThreshold to decide
  which tx type to emit. For a fresh fanout it always emits FanoutTx; for an
  in-progress fanout it always emits FinalPartialFanoutTx. Handlers now owns the
  sizing decision: it tries the preferred tx first, then falls back to
  PartialFanoutTx with a decreasing chunk size (starting at N-1) until one fits
  within the execution budget, using a single shared findFittingFanoutTx helper.

  PartialFanoutTx is removed from PostChainTx — it is now an internal Handlers
  detail, never emitted by HeadLogic. fanoutChunkSize and fanoutOutputThreshold
  are removed from KZGTrustedSetup and all call sites.
sim-core: expose every tcp-envelope knob as a YAML override
RawTcpEnvelope now exposes the full LinkEnvelopeCfg surface as
optional fields (mss-bytes, initial-cwnd-segments, idle-reset-
threshold-ms, rto-ms, loss-bw-depth, cold-bw-depth, cold-release-ms,
cold-release-shape, loss-release-ms, loss-release-shape). Any field
left unset falls through to the physics-derived default from
LinkEnvelopeCfg::defaults_for. Unknown fields are rejected.

Adds kebab-case serde rename on tcp_model::Curve so the YAML enum
values are spelt "step" / "linear" / "geometric" rather than the
PascalCase Rust variants.

Four new parsing tests cover empty blocks, the full override schema,
the deny-unknown-fields guard, and the layered-defaults semantics.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
sim-core: wire tcp-model envelope into Connection (opt-in per link)
Each directed Connection optionally carries a tcp_model::LinkState plus
the (from, to) link identity and the stateless Rng oracle used to seed
per-message loss draws. Behaviour with no envelope configured is
byte-identical to today; the regression suite is unchanged.

When an envelope is attached:

- send() calls LinkState::on_send with a loss outcome drawn from the
  oracle under context ("tcp_loss", from, to, send_time, message_id).
- update_bandwidth_queues() integrates `bps * bw_mult(t)` to find the
  total bytes deliverable over [last_event, now], then fair-shares them
  among miniprotocols exactly as before. Per-message arrival timestamps
  are computed by inverting bytes_deliverable so the slow-start ramp is
  reflected in arrivals (not averaged out over the update window).
- All arrivals are clamped to LinkState::delivery_floor, modelling
  cross-protocol HoL blocking during a loss-induced RTO stall.

Topology YAML grows an optional per-link `tcp-envelope` block; for now
only `loss-prob-per-segment` is exposed, with all other params derived
from the link's latency and bandwidth via LinkEnvelopeCfg::defaults_for.

Three new connection.rs tests cover: cold-start delaying a 1 MB transfer,
loss-induced delivery floor, and envelope-disabled byte-identical
matching against the no-envelope path.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
sim-core: thread tcp-envelope through the sequential/turbo engine
sequential.rs builds Connections directly (it doesn't route through
NetworkCoordinator), so the envelope wiring added earlier was only
reaching the actor engine. Fix: construct an EnvelopeWiring at link-
build time whenever `LinkConfiguration.tcp_envelope` is `Some`, using
the same `Rng::new(config.seed)` stateless oracle already used by other
sequential-engine machinery.

Caught by a NA,0.200 / top-stake-fraction / 750n sanity run with
loss-prob-per-segment 0.01: the turbo-engine output was byte-identical
to baseline because the envelope cfg was being discarded at the
Connection::new call site.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
tcp-model: caller-supplied loss draw; add inversion helper
Drops the internal RNG: on_send now takes a pre-drawn `loss_drawn`
boolean, and LinkEnvelopeCfg gains `msg_loss_prob(bytes)` for the
caller to sample from any deterministic oracle. This keeps tcp-model
purely deterministic state with no rand dependency.

Adds `invert_bytes_deliverable(bps, target, t0, upper)` — binary
search for when a cumulative byte count crosses a threshold, used by
consumers to compute envelope-aware per-message arrival times.

Adds `has_active_envelopes()` so consumers can fast-path the unperturbed
case, and stops retaining envelopes that fire immediately expired (e.g.
under `LinkEnvelopeCfg::disabled`), guaranteeing byte-identical behaviour
when envelopes are turned off.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
tcp-model: per-link envelope model with cold/idle/loss events
LinkState carries a small stack of active envelopes, queried as a
bandwidth multiplier and a delivery floor at message-send time:

- Cold/idle: instantaneous depth + geometric recovery over log2(BDP/IW)
  RTTs. Re-fires after a configurable idle gap (default RFC-6298-ish
  max(1s, 2L)).
- Loss: Bernoulli draw per send (p scales with segment count); stall
  window = 1 RTO; bandwidth halves at the moment of recovery and
  recovers linearly over (BDP/2)/MSS RTTs.

bytes_deliverable integrates bps · bw_mult(t) over arbitrary intervals,
sub-dividing at envelope phase transitions and applying a fine-grained
trapezoid rule so geometric ramps integrate cleanly. delivery_floor
takes the max stall-end over active envelopes — exact HoL semantics.

24 unit tests including an analytic slow-start cross-check (300ms /
1 MiB/s, 1 MB cold message → ~3.4s transfer time).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
sim-rs: pass header issuer to PraosState::on_tip_advanced
shared-consensus's `on_tip_advanced` grew an `&[u8]` `header_issuer`
argument in 7920317e4 (RB-header equivocation detection on tip
announce); the sim-rs adapter was still calling the old 8-arg
signature, which CI surfaced after the prc/con-rs branch was rebased
onto a main that includes the equivocation-detection commit.

Sim's notion of an issuer is the producing `NodeId`; feed it in as
its little-endian byte representation.  Honest-only sims never
produce two distinct headers at the same `(slot, issuer)` pair so
the new equivocation predicate stays dormant, but the wiring is now
ready for behaviour-driven adversarial runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Subsume `RuleListEra` into `EraTest`:
There is no need to have a separate type class for a common concept that
we aready have for all eras that is provided by `EraTest`. This commit
also hides unnecessary for public view implementation detail:
`EraRuleProof` and `UnliftRules`.

Thanks to `EraRulesWithFailures` type family and relocation of predicate
failure CBOR roundtrip tests into `ledgerTestMain` we are guaranteed
that these tests will run for all eras. Moreover, this changes is in
line with overall tests hierarchy that we are converging onto.