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 (19)
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 (134)
Jun 10, 12-1 PM (48)
Jun 10, 1-2 PM (33)
Jun 10, 2-3 PM (32)
Jun 10, 3-4 PM (28)
Jun 10, 4-5 PM (35)
Jun 10, 5-6 PM (12)
Jun 10, 6-7 PM (12)
Jun 10, 7-8 PM (38)
Jun 10, 8-9 PM (11)
Jun 10, 9-10 PM (9)
Jun 10, 10-11 PM (20)
Jun 10, 11-12 AM (7)
Jun 11, 12-1 AM (10)
Jun 11, 1-2 AM (2)
Jun 11, 2-3 AM (0)
Jun 11, 3-4 AM (2)
Jun 11, 4-5 AM (7)
Jun 11, 5-6 AM (12)
Jun 11, 6-7 AM (34)
Jun 11, 7-8 AM (100)
Jun 11, 8-9 AM (8)
2,946 commits this week Jun 04, 2026 - Jun 11, 2026
Efficient common case for setCurrentTime
KnownPeers.setCurrentTime and EstablishedPeers.setCurrentTime run on
every governor loop iteration. Add a fast path to KnownPeers for the
common case where nothing is scheduled or the earliest scheduled time
is still in the future; previously it always ran the general path,
rebuilding the record and (with +asserts) checking the invariant.

In EstablishedPeers use findMin instead of minView in the existing
fast-path guard: an O(1) peek that avoids allocating the deletion of
the minimum. The fast path now also covers the empty-queue case, which
previously fell through to the general path.
chore: update Docker configurations and wallet handling
- Added build arguments for Blockfrost API keys in docker-compose files to ensure consistent client bundle paths.
- Updated Dockerfile to handle Blockfrost API keys as environment variables for production builds.
- Modified CI workflow to allow insecure cookies for wallet sessions during testing.
- Refactored wallet handling in various components to use the new useMeshWallet hook, ensuring compatibility with the latest wallet API.
- Enhanced error handling in wallet session management to prevent issues with unconnected wallets.
Fix headAdaOverhead griefing: lock value in OpenDatum at init time
    A malicious participant could set an arbitrary headAdaOverhead in the
    output ClosedDatum at close time. Since mustPreserveHeadAdaOverhead in
    checkContest locks this value permanently after Close, a wrong value
    makes fanout impossible and freezes all head funds.

    Fix: store headAdaOverhead in OpenDatum at init time (where it equals
    worstCaseMinLovelace, the pre-funded overhead with no L2 UTxOs) and
    verify it is unchanged in checkClose, checkIncrement, and checkDecrement.
    The invariant headAdaOverhead = headLovelace - utxoLovelace holds across
    the head lifetime because Increment and Decrement both change headLovelace
    and utxoLovelace by the same deposit/decommit amount.

    Also fix worstCaseClosedDatum used to compute the pre-funded ADA at
    initTx: variable-size integer fields (version, snapshotNumber,
    contestationDeadline, headAdaOverhead) previously used small constants
    (0 or 2 trillion) that produce 1-9 CBOR bytes less than the true
    maximum. Using maxBound @Word64 for all of them ensures the datum size
    estimate is a genuine upper bound, preventing potential ledger min-UTxO
    rejections on close for long-running or high-throughput heads.

Signed-off-by: Sasha Bogicevic <[email protected]>
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]>
Add regression test for FinalPartialFanoutTx with pending deposit UTxO
  When snapshotVersion < version (an IncrementTx confirmed on L1 after the
  last snapshot), computeFullFanoutUTxO includes utxoToCommit in the full
  fanout set. After a PartialFanoutTx distributes all other outputs, a
  FinalPartialFanoutTx must distribute the pending deposit UTxO alone.

  Adds genClosedStateWithPendingCommit to the testlib and a property test
  that verifies finalPartialFanout succeeds in this scenario — guarding
  against the StaleChainState failure observed in practice when the
  in-memory deposit UTxO accumulator element diverges from the on-chain
  commitment.

Signed-off-by: Sasha Bogicevic <[email protected]>
Fix genCloseTx head value mismatch in close property tests
  genStOpen inflates the head UTxO by u0Value but leaves headAdaOverhead
  in the open datum unchanged. genCloseTx now adjusts the head UTxO value
  to headAdaOverhead + confirmedUTxOValue + decommitValue before building
  the close tx, so closeTx computes the correct headAdaOverhead' for the
  closed datum (fixes H65).

  forAllClose was discarding the adjusted UTxO returned by genCloseTx and
  recomputing it from the original inflated OpenState, causing the
  evaluator to see a different input value than what the tx was built
  against (fixes H4/HeadValueIsNotPreserved).

Signed-off-by: Sasha Bogicevic <[email protected]>
Fix genCloseTx head UTxO value for strict mustPreserveHeadValue
  genStOpen inflates the head UTxO by u0Value but genCloseTx was not
  adjusting it before calling unsafeClose. With mustPreserveHeadValue
  now using strict equality (instead of geq), the head value must be
  exactly headAdaOverhead + confirmedUTxO + decommit at close time,
  or the Plutus script fires H65. Adjust the UTxO in genCloseTx the
  same way genClosedStateForFanout and genFanoutTx already do.

Signed-off-by: Sasha Bogicevic <[email protected]>