Home / Input Output / ouroboros-leios-sim
Apr 07, 8-9 PM (0)
Apr 07, 9-10 PM (0)
Apr 07, 10-11 PM (0)
Apr 07, 11-12 AM (0)
Apr 08, 12-1 AM (0)
Apr 08, 1-2 AM (0)
Apr 08, 2-3 AM (0)
Apr 08, 3-4 AM (0)
Apr 08, 4-5 AM (0)
Apr 08, 5-6 AM (0)
Apr 08, 6-7 AM (0)
Apr 08, 7-8 AM (0)
Apr 08, 8-9 AM (0)
Apr 08, 9-10 AM (0)
Apr 08, 10-11 AM (0)
Apr 08, 11-12 PM (0)
Apr 08, 12-1 PM (1)
Apr 08, 1-2 PM (0)
Apr 08, 2-3 PM (2)
Apr 08, 3-4 PM (1)
Apr 08, 4-5 PM (0)
Apr 08, 5-6 PM (0)
Apr 08, 6-7 PM (0)
Apr 08, 7-8 PM (0)
Apr 08, 8-9 PM (0)
Apr 08, 9-10 PM (0)
Apr 08, 10-11 PM (0)
Apr 08, 11-12 AM (0)
Apr 09, 12-1 AM (0)
Apr 09, 1-2 AM (0)
Apr 09, 2-3 AM (0)
Apr 09, 3-4 AM (0)
Apr 09, 4-5 AM (0)
Apr 09, 5-6 AM (0)
Apr 09, 6-7 AM (0)
Apr 09, 7-8 AM (0)
Apr 09, 8-9 AM (0)
Apr 09, 9-10 AM (0)
Apr 09, 10-11 AM (1)
Apr 09, 11-12 PM (1)
Apr 09, 12-1 PM (0)
Apr 09, 1-2 PM (1)
Apr 09, 2-3 PM (1)
Apr 09, 3-4 PM (1)
Apr 09, 4-5 PM (5)
Apr 09, 5-6 PM (0)
Apr 09, 6-7 PM (0)
Apr 09, 7-8 PM (0)
Apr 09, 8-9 PM (0)
Apr 09, 9-10 PM (0)
Apr 09, 10-11 PM (0)
Apr 09, 11-12 AM (0)
Apr 10, 12-1 AM (0)
Apr 10, 1-2 AM (0)
Apr 10, 2-3 AM (0)
Apr 10, 3-4 AM (0)
Apr 10, 4-5 AM (0)
Apr 10, 5-6 AM (0)
Apr 10, 6-7 AM (0)
Apr 10, 7-8 AM (0)
Apr 10, 8-9 AM (1)
Apr 10, 9-10 AM (2)
Apr 10, 10-11 AM (25)
Apr 10, 11-12 PM (24)
Apr 10, 12-1 PM (2)
Apr 10, 1-2 PM (0)
Apr 10, 2-3 PM (2)
Apr 10, 3-4 PM (2)
Apr 10, 4-5 PM (2)
Apr 10, 5-6 PM (0)
Apr 10, 6-7 PM (0)
Apr 10, 7-8 PM (0)
Apr 10, 8-9 PM (0)
Apr 10, 9-10 PM (0)
Apr 10, 10-11 PM (0)
Apr 10, 11-12 AM (0)
Apr 11, 12-1 AM (0)
Apr 11, 1-2 AM (0)
Apr 11, 2-3 AM (0)
Apr 11, 3-4 AM (0)
Apr 11, 4-5 AM (0)
Apr 11, 5-6 AM (0)
Apr 11, 6-7 AM (0)
Apr 11, 7-8 AM (0)
Apr 11, 8-9 AM (0)
Apr 11, 9-10 AM (0)
Apr 11, 10-11 AM (1)
Apr 11, 11-12 PM (0)
Apr 11, 12-1 PM (0)
Apr 11, 1-2 PM (1)
Apr 11, 2-3 PM (0)
Apr 11, 3-4 PM (0)
Apr 11, 4-5 PM (1)
Apr 11, 5-6 PM (0)
Apr 11, 6-7 PM (0)
Apr 11, 7-8 PM (0)
Apr 11, 8-9 PM (0)
Apr 11, 9-10 PM (0)
Apr 11, 10-11 PM (0)
Apr 11, 11-12 AM (0)
Apr 12, 12-1 AM (0)
Apr 12, 1-2 AM (0)
Apr 12, 2-3 AM (0)
Apr 12, 3-4 AM (0)
Apr 12, 4-5 AM (0)
Apr 12, 5-6 AM (0)
Apr 12, 6-7 AM (0)
Apr 12, 7-8 AM (0)
Apr 12, 8-9 AM (0)
Apr 12, 9-10 AM (0)
Apr 12, 10-11 AM (0)
Apr 12, 11-12 PM (0)
Apr 12, 12-1 PM (0)
Apr 12, 1-2 PM (0)
Apr 12, 2-3 PM (0)
Apr 12, 3-4 PM (0)
Apr 12, 4-5 PM (0)
Apr 12, 5-6 PM (0)
Apr 12, 6-7 PM (0)
Apr 12, 7-8 PM (0)
Apr 12, 8-9 PM (0)
Apr 12, 9-10 PM (0)
Apr 12, 10-11 PM (0)
Apr 12, 11-12 AM (0)
Apr 13, 12-1 AM (0)
Apr 13, 1-2 AM (0)
Apr 13, 2-3 AM (0)
Apr 13, 3-4 AM (0)
Apr 13, 4-5 AM (0)
Apr 13, 5-6 AM (0)
Apr 13, 6-7 AM (0)
Apr 13, 7-8 AM (0)
Apr 13, 8-9 AM (5)
Apr 13, 9-10 AM (3)
Apr 13, 10-11 AM (4)
Apr 13, 11-12 PM (3)
Apr 13, 12-1 PM (0)
Apr 13, 1-2 PM (2)
Apr 13, 2-3 PM (0)
Apr 13, 3-4 PM (0)
Apr 13, 4-5 PM (0)
Apr 13, 5-6 PM (0)
Apr 13, 6-7 PM (0)
Apr 13, 7-8 PM (1)
Apr 13, 8-9 PM (0)
Apr 13, 9-10 PM (0)
Apr 13, 10-11 PM (0)
Apr 13, 11-12 AM (0)
Apr 14, 12-1 AM (0)
Apr 14, 1-2 AM (0)
Apr 14, 2-3 AM (0)
Apr 14, 3-4 AM (0)
Apr 14, 4-5 AM (0)
Apr 14, 5-6 AM (0)
Apr 14, 6-7 AM (0)
Apr 14, 7-8 AM (0)
Apr 14, 8-9 AM (0)
Apr 14, 9-10 AM (0)
Apr 14, 10-11 AM (2)
Apr 14, 11-12 PM (2)
Apr 14, 12-1 PM (1)
Apr 14, 1-2 PM (0)
Apr 14, 2-3 PM (0)
Apr 14, 3-4 PM (0)
Apr 14, 4-5 PM (0)
Apr 14, 5-6 PM (0)
Apr 14, 6-7 PM (0)
Apr 14, 7-8 PM (0)
Apr 14, 8-9 PM (0)
100 commits this week Apr 07, 2026 - Apr 14, 2026
Add configurable committee selection algorithms for linear leios
Add committee-selection-algorithm config with three modes:
- wfa-ls (default): existing VRF lottery matching CIP-0164 wFA+LS
- everyone: every node votes unconditionally (1 vote each)
- top-stake-fraction: nodes covering top N% of cumulative stake vote

This enables traffic analysis comparing the CIP's VRF-based scheme
against simpler alternatives. Vote bundle sizes, CPU times, diffusion,
and threshold checking are unchanged — only the selection mechanism
differs.

Includes benchmark script (scripts/cip-voting-options.sh) that runs
CIP topology under turbo mode across all three committee modes.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
ci(antithesis): poll for test results after submission
Add a two-phase polling script (wait-for-test.sh) that monitors
Antithesis test status via Moog:
- Phase 1: poll every 10s until the test is accepted or rejected
- Phase 2: poll every 60s until the test finishes
- Final check: exit 0 on success, 1 on failure/unknown

Also hoists Moog env vars to job level, auto-increments the try
counter per commit, and caps the job at 180 minutes.

Adapted from cardano-foundation/cardano-node-antithesis.

Signed-off-by: Chris Gianelloni <[email protected]>
net-rs: mempool-driven tx inclusion in RBs and overflow EBs
Add a shared Mempool accumulator that collects transactions from both
local generation and peer receipt. When producing an RB, the mempool
determines the path: if total pending bytes fit within rb_body_max_bytes,
txs go in the RB body directly; otherwise ALL txs drain into an EB
manifest (list of tx hashes) and the RB body is empty with the EB
announced in the header's announced_eb field.

- mempool.rs: Mempool struct with push/drain_all/drain_up_to, shared via
  Arc<Mutex>; tx_from_received_bytes for peer tx accumulation
- config.rs: rb_body_max_bytes (default 64KB), mempool_capacity (10K)
- production.rs: ProducedRb with optional announced_eb, make_fake_block
  encodes txs in CBOR tx_bodies map, make_overflow_eb builds content-
  addressed EB manifests [slot, [tx_hash, ...]]
- main.rs: wire mempool to generator and main loop, replace stage-boundary
  EB production with overflow-triggered path

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
net-rs: produced RBs advertise certified EBs in headers
When an EB election reaches quorum and enters CertEligible phase,
the next RB produced by this node includes certified_eb=true in its
header (CIP-0164 11-field extended header). Receiving nodes parse the
flag via the existing HeaderInfo Leios extension fields.

End of Leios consensus MVP: EB → votes → quorum → cert in RB header.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
net-rs: vote aggregation with per-EB quorum detection
Parse validated vote bodies to extract endorser_block_hash and
voter_id, attribute votes to their EB election, detect quorum (≥3
unique voters for MVP). VotesValidated outcome now carries vote_data.

Verified in 25-node cluster: 75 quorum events across all nodes.
Added scripts/leios-check.sh for Leios cluster diagnostics.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
net-rs: EB-triggered voting with committee selection
When an EB election enters the Voting pipeline phase (3×Δhdr slots
after announcement), committee selection determines whether this node
votes. Structured 130-180B vote bodies are injected into the network
via InjectLeiosVotes. Stage-boundary vote production removed from main.

Verified in 25-node cluster: EBs propagate, elections track pipeline
phases, votes flood the network (~1200 VotesReceived in ~10s run).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
net-rs: contiguity walk falls back to block_cache
select_chain_once's contiguity guard called chain_tree.ancestors(last_hash)
to verify that a peer's replay chain reaches the picked common ancestor.
The walk terminates at the first block whose parent is not in chain_tree.

On_block_received inserts every fetched block into both chain_tree and
block_cache — but the chain_tree insert is skipped when the header has no
parsed info AND chain_tree doesn't already know the block (so block_no=0).
That leaves the block in block_cache without a chain_tree entry, and the
next contiguity walk terminates early, firing `fork mismatch (replay
doesn't reach ancestor)` → OrphanCandidate. With the cooldown cap this no
longer infects other peers, but individual nodes under sustained fork
load can slowly get stuck on this false mismatch.

Fix: add a hybrid walker that follows prev_hash links using chain_tree
first and block_cache as a fallback. The walk terminates at a genuine
gap (neither store has the parent) or at a genesis child (prev_hash=None)
— both distinguished via a new HybridWalk.reached_origin flag so the
genesis-reached check in select_chain_once still works.

The walk is a new private method on PraosConsensus in selection.rs:
walk_ancestors_hybrid(start_hash) -> HybridWalk.

4 new unit tests exercise:
- chain_tree-only case (back-compat with pre-fix behaviour)
- block_cache fallback (tree has tip + anchor, middle only in cache)
- gap termination (parent in neither store → reached_origin=false)
- start_only_in_cache (start block only in block_cache)

Cluster verification at p=0.2: 24/25 nodes stayed healthy for ~55 min
(vs previous build which had 4 stuck by T+60min). The one stuck node
(node-4) hit a separate mux-level ingress-overflow bug during catch-up
fetches, not the contiguity walk — tracked separately.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
net-rs: orphan_cooldown to cap re-intersection cascade rate
evaluate_and_fetch had no persistent skip set — every new event (TipAdvanced,
RolledBack, BlockFetchFailed) re-ran select_chain_once with an empty local
`tried` HashSet, so a peer that failed the contiguity guard would be
re-classified as OrphanCandidate hundreds of times per second, each iteration
clearing its entries and sending another NetworkCommand::ReIntersect. Two
peers on a single node could generate 500k+ orphan log lines per 30 min
and saturate CPU on receiving peers, propagating stuckness.

A naive pending-set guard (clear on IntersectionFound) didn't help on
localhost because re-intersection round-trips complete in 1-3 ms, faster
than TipAdvanced events arrive. The peer ping-pongs between orphan and
re-intersected in a tight loop.

Fix: time-based cooldown instead.

- PraosConsensus.orphan_cooldown: HashMap<PeerId, Instant> holds the
  earliest time each peer can be reconsidered in chain selection.
- ORPHAN_COOLDOWN = 1s — caps orphan/ReIntersect emissions at ≤1/sec/peer.
- evaluate_and_fetch builds `skip` from unexpired cooldown entries (and
  prunes expired ones), inserts new orphans with `now + ORPHAN_COOLDOWN`,
  and gates the log + ReIntersect send on the transition via an
  `already_cooling` check so the rate-limited state is visible exactly
  once per entry.
- IntersectionFound does NOT clear the cooldown — the entry must expire
  naturally so the peer's ChainSync stream has time to rebuild contiguous
  entries under the new anchor before we re-evaluate.
- PeerDisconnected clears the cooldown entry (prevents leaks).

5 new unit tests:
- orphan_first_time_sends_reintersect_and_marks_cooldown
- orphan_while_cooling_does_not_resend_reintersect
- many_tip_advances_while_cooling_do_not_cascade (1000 events → 0 extra)
- intersection_found_does_not_clear_cooldown
- peer_disconnected_clears_cooldown

Cluster verification at p=0.2: fresh run held 21-24/25 nodes healthy for
~2 hours. Orphan-cascade total across all 25 nodes ~5k in that window
(vs 500k+ per-node on the pre-fix build). Stuck count stable at 4/25
in a bounded partition — the remaining stuck nodes fall to a separate
chain_tree contiguity-walk bug (tracked as a follow-up), not the cascade.

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