Jun 03, 12-1 PM (93)
Jun 03, 1-2 PM (28)
Jun 03, 2-3 PM (77)
Jun 03, 3-4 PM (26)
Jun 03, 4-5 PM (24)
Jun 03, 5-6 PM (23)
Jun 03, 6-7 PM (15)
Jun 03, 7-8 PM (17)
Jun 03, 8-9 PM (19)
Jun 03, 9-10 PM (9)
Jun 03, 10-11 PM (31)
Jun 03, 11-12 AM (14)
Jun 04, 12-1 AM (12)
Jun 04, 1-2 AM (4)
Jun 04, 2-3 AM (1)
Jun 04, 3-4 AM (5)
Jun 04, 4-5 AM (1)
Jun 04, 5-6 AM (0)
Jun 04, 6-7 AM (14)
Jun 04, 7-8 AM (10)
Jun 04, 8-9 AM (11)
Jun 04, 9-10 AM (19)
Jun 04, 10-11 AM (11)
Jun 04, 11-12 PM (14)
Jun 04, 12-1 PM (53)
Jun 04, 1-2 PM (39)
Jun 04, 2-3 PM (60)
Jun 04, 3-4 PM (12)
Jun 04, 4-5 PM (4)
Jun 04, 5-6 PM (7)
Jun 04, 6-7 PM (46)
Jun 04, 7-8 PM (27)
Jun 04, 8-9 PM (4)
Jun 04, 9-10 PM (2)
Jun 04, 10-11 PM (24)
Jun 04, 11-12 AM (7)
Jun 05, 12-1 AM (6)
Jun 05, 1-2 AM (8)
Jun 05, 2-3 AM (1)
Jun 05, 3-4 AM (1)
Jun 05, 4-5 AM (1)
Jun 05, 5-6 AM (5)
Jun 05, 6-7 AM (9)
Jun 05, 7-8 AM (12)
Jun 05, 8-9 AM (8)
Jun 05, 9-10 AM (11)
Jun 05, 10-11 AM (12)
Jun 05, 11-12 PM (8)
Jun 05, 12-1 PM (52)
Jun 05, 1-2 PM (61)
Jun 05, 2-3 PM (26)
Jun 05, 3-4 PM (24)
Jun 05, 4-5 PM (17)
Jun 05, 5-6 PM (7)
Jun 05, 6-7 PM (14)
Jun 05, 7-8 PM (12)
Jun 05, 8-9 PM (6)
Jun 05, 9-10 PM (2)
Jun 05, 10-11 PM (20)
Jun 05, 11-12 AM (9)
Jun 06, 12-1 AM (6)
Jun 06, 1-2 AM (0)
Jun 06, 2-3 AM (3)
Jun 06, 3-4 AM (4)
Jun 06, 4-5 AM (0)
Jun 06, 5-6 AM (24)
Jun 06, 6-7 AM (1)
Jun 06, 7-8 AM (2)
Jun 06, 8-9 AM (3)
Jun 06, 9-10 AM (0)
Jun 06, 10-11 AM (3)
Jun 06, 11-12 PM (6)
Jun 06, 12-1 PM (2)
Jun 06, 1-2 PM (2)
Jun 06, 2-3 PM (2)
Jun 06, 3-4 PM (18)
Jun 06, 4-5 PM (1)
Jun 06, 5-6 PM (6)
Jun 06, 6-7 PM (0)
Jun 06, 7-8 PM (6)
Jun 06, 8-9 PM (0)
Jun 06, 9-10 PM (1)
Jun 06, 10-11 PM (27)
Jun 06, 11-12 AM (9)
Jun 07, 12-1 AM (14)
Jun 07, 1-2 AM (2)
Jun 07, 2-3 AM (0)
Jun 07, 3-4 AM (0)
Jun 07, 4-5 AM (1)
Jun 07, 5-6 AM (1)
Jun 07, 6-7 AM (3)
Jun 07, 7-8 AM (0)
Jun 07, 8-9 AM (0)
Jun 07, 9-10 AM (1)
Jun 07, 10-11 AM (2)
Jun 07, 11-12 PM (2)
Jun 07, 12-1 PM (5)
Jun 07, 1-2 PM (35)
Jun 07, 2-3 PM (2)
Jun 07, 3-4 PM (4)
Jun 07, 4-5 PM (2)
Jun 07, 5-6 PM (4)
Jun 07, 6-7 PM (0)
Jun 07, 7-8 PM (0)
Jun 07, 8-9 PM (17)
Jun 07, 9-10 PM (1)
Jun 07, 10-11 PM (21)
Jun 07, 11-12 AM (9)
Jun 08, 12-1 AM (9)
Jun 08, 1-2 AM (5)
Jun 08, 2-3 AM (3)
Jun 08, 3-4 AM (4)
Jun 08, 4-5 AM (2)
Jun 08, 5-6 AM (9)
Jun 08, 6-7 AM (5)
Jun 08, 7-8 AM (25)
Jun 08, 8-9 AM (36)
Jun 08, 9-10 AM (40)
Jun 08, 10-11 AM (24)
Jun 08, 11-12 PM (22)
Jun 08, 12-1 PM (40)
Jun 08, 1-2 PM (48)
Jun 08, 2-3 PM (33)
Jun 08, 3-4 PM (27)
Jun 08, 4-5 PM (12)
Jun 08, 5-6 PM (23)
Jun 08, 6-7 PM (14)
Jun 08, 7-8 PM (3)
Jun 08, 8-9 PM (6)
Jun 08, 9-10 PM (19)
Jun 08, 10-11 PM (29)
Jun 08, 11-12 AM (8)
Jun 09, 12-1 AM (5)
Jun 09, 1-2 AM (3)
Jun 09, 2-3 AM (1)
Jun 09, 3-4 AM (3)
Jun 09, 4-5 AM (26)
Jun 09, 5-6 AM (5)
Jun 09, 6-7 AM (23)
Jun 09, 7-8 AM (50)
Jun 09, 8-9 AM (35)
Jun 09, 9-10 AM (45)
Jun 09, 10-11 AM (51)
Jun 09, 11-12 PM (46)
Jun 09, 12-1 PM (86)
Jun 09, 1-2 PM (84)
Jun 09, 2-3 PM (36)
Jun 09, 3-4 PM (38)
Jun 09, 4-5 PM (16)
Jun 09, 5-6 PM (18)
Jun 09, 6-7 PM (18)
Jun 09, 7-8 PM (19)
Jun 09, 8-9 PM (16)
Jun 09, 9-10 PM (16)
Jun 09, 10-11 PM (28)
Jun 09, 11-12 AM (10)
Jun 10, 12-1 AM (11)
Jun 10, 1-2 AM (16)
Jun 10, 2-3 AM (11)
Jun 10, 3-4 AM (7)
Jun 10, 4-5 AM (5)
Jun 10, 5-6 AM (2)
Jun 10, 6-7 AM (46)
Jun 10, 7-8 AM (82)
Jun 10, 8-9 AM (18)
Jun 10, 9-10 AM (59)
Jun 10, 10-11 AM (46)
Jun 10, 11-12 PM (90)
Jun 10, 12-1 PM (10)
2,810 commits this week Jun 03, 2026 - Jun 10, 2026
Fix partial fanout StaleChainState when decommit applied before close
  When a DecrementTx was applied on-chain before the head was closed
  (snapshotVersion != openVersion), partialFanout passed fullUTxO to
  buildAndVerifyAccumulator. But the closed datum's accumulatorCommitment
  was built from utxoForProof (snapshot UTxO including the decommit set),
  so the check always failed with StaleChainState, leaving the head stuck.

  Separate the accumulator proof input from the distribution set by adding
  a proofUTxO parameter to partialFanout and findFittingFanoutTx. The
  FanoutTx call site now passes utxoForProof as proofUTxO so it matches
  what the closed datum was committed to, while fullUTxO (the actual
  distribution set) is used unchanged for fanout outputs.

Signed-off-by: Sasha Bogicevic <[email protected]>
net-core: encode LeiosFetch bitmaps as indefinite-length
The leios-prototype CDDL defines `bitmaps` as

    ; indefinite-length map from 64-tx window index to 64-bit presence
    bitmaps = { * base.word16 => base.word64 }

and the reference relay's parser enforces the indefinite-length form:
sending the definite-length variant triggers an immediate TCP RST
within ~25–45 ms of `MsgLeiosBlockTxsRequest`, which we'd been
working around in our dev-relay configs with
`fetch_policy.eb_txs = "no_fetch"`.

Switch `encode_bitmap` from `e.map(len)` (definite-length) to
`e.begin_map()` + `e.end()` (indefinite-length).  Same pattern as
TxSubmission's indefinite-length inner lists.

Verified against the live Leios dev relay (magic 164,
`leios-node.play.dev.cardano.org`): with the fix in, the relay
accepts `MsgLeiosBlockTxsRequest` and streams back the EB-tx list
without RSTing.  First test: `count=512` transactions delivered for
one EB, zero connection resets.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
praos: surface upstream gappy ChainSync via two complementary WARNs
Diagnosing a wedged catch-up against the public Leios dev relay
required grepping across the orphan / fork-mismatch INFO traffic and
inferring the cause from cache state.  Two new WARNs hand the
diagnosis directly to an operator skimming logs:

- **ChainSync ingress contiguity check** in `record_peer_tip`: when an
  arriving header's `prev_hash` doesn't match the previously-announced
  one's hash, log the (block_no, hash) pair on each side and the
  implied skipped-block count.  Throttled per peer
  (`GAP_WARNING_INTERVAL = 10 s`) so a sustained non-contiguous forward
  doesn't flood the log.  This is the direct signal — the WARN fires
  the moment upstream commits the offence.

- **Stuck-validation rollup** in `retry_select_chain`: when validation
  has been frozen for `STUCK_THRESHOLD = 30 s` and some peer offers a
  strictly-better tip, emit one rollup line summarising stuck duration,
  adopted vs best-peer block_no, the count of entries in that peer's
  replay whose parent_hash we don't have locally, and the peer-chain
  size.  Throttled to one fire per `STUCK_WARNING_INTERVAL = 60 s`.
  This covers the general "stuck for any reason" case and stays
  informative when the ingress check has gone quiet under its
  per-peer cooldown.

Both lines were verified against the dev relay: ingress fires within
~30 s of catch-up reaching the wedge boundary (with the exact missing
block hash prefix in the message), and the rollup fires 30 s later
with `unreachable_parent_hashes > 0`, both throttled correctly under
sustained wedge load.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>