Home / Input Output / hydra-poc
May 29, 8-9 PM (0)
May 29, 9-10 PM (0)
May 29, 10-11 PM (0)
May 29, 11-12 AM (0)
May 30, 12-1 AM (0)
May 30, 1-2 AM (0)
May 30, 2-3 AM (0)
May 30, 3-4 AM (0)
May 30, 4-5 AM (0)
May 30, 5-6 AM (0)
May 30, 6-7 AM (0)
May 30, 7-8 AM (1)
May 30, 8-9 AM (0)
May 30, 9-10 AM (1)
May 30, 10-11 AM (1)
May 30, 11-12 PM (1)
May 30, 12-1 PM (2)
May 30, 1-2 PM (1)
May 30, 2-3 PM (1)
May 30, 3-4 PM (0)
May 30, 4-5 PM (0)
May 30, 5-6 PM (0)
May 30, 6-7 PM (1)
May 30, 7-8 PM (0)
May 30, 8-9 PM (0)
May 30, 9-10 PM (0)
May 30, 10-11 PM (0)
May 30, 11-12 AM (0)
May 31, 12-1 AM (0)
May 31, 1-2 AM (0)
May 31, 2-3 AM (0)
May 31, 3-4 AM (0)
May 31, 4-5 AM (0)
May 31, 5-6 AM (0)
May 31, 6-7 AM (0)
May 31, 7-8 AM (0)
May 31, 8-9 AM (0)
May 31, 9-10 AM (0)
May 31, 10-11 AM (0)
May 31, 11-12 PM (0)
May 31, 12-1 PM (0)
May 31, 1-2 PM (0)
May 31, 2-3 PM (0)
May 31, 3-4 PM (0)
May 31, 4-5 PM (0)
May 31, 5-6 PM (0)
May 31, 6-7 PM (0)
May 31, 7-8 PM (0)
May 31, 8-9 PM (0)
May 31, 9-10 PM (0)
May 31, 10-11 PM (0)
May 31, 11-12 AM (0)
Jun 01, 12-1 AM (0)
Jun 01, 1-2 AM (0)
Jun 01, 2-3 AM (0)
Jun 01, 3-4 AM (0)
Jun 01, 4-5 AM (0)
Jun 01, 5-6 AM (0)
Jun 01, 6-7 AM (0)
Jun 01, 7-8 AM (4)
Jun 01, 8-9 AM (8)
Jun 01, 9-10 AM (32)
Jun 01, 10-11 AM (2)
Jun 01, 11-12 PM (9)
Jun 01, 12-1 PM (1)
Jun 01, 1-2 PM (2)
Jun 01, 2-3 PM (2)
Jun 01, 3-4 PM (0)
Jun 01, 4-5 PM (0)
Jun 01, 5-6 PM (0)
Jun 01, 6-7 PM (0)
Jun 01, 7-8 PM (15)
Jun 01, 8-9 PM (0)
Jun 01, 9-10 PM (0)
Jun 01, 10-11 PM (0)
Jun 01, 11-12 AM (0)
Jun 02, 12-1 AM (0)
Jun 02, 1-2 AM (0)
Jun 02, 2-3 AM (0)
Jun 02, 3-4 AM (0)
Jun 02, 4-5 AM (0)
Jun 02, 5-6 AM (0)
Jun 02, 6-7 AM (7)
Jun 02, 7-8 AM (7)
Jun 02, 8-9 AM (18)
Jun 02, 9-10 AM (2)
Jun 02, 10-11 AM (10)
Jun 02, 11-12 PM (2)
Jun 02, 12-1 PM (1)
Jun 02, 1-2 PM (1)
Jun 02, 2-3 PM (5)
Jun 02, 3-4 PM (2)
Jun 02, 4-5 PM (1)
Jun 02, 5-6 PM (0)
Jun 02, 6-7 PM (0)
Jun 02, 7-8 PM (0)
Jun 02, 8-9 PM (0)
Jun 02, 9-10 PM (0)
Jun 02, 10-11 PM (0)
Jun 02, 11-12 AM (0)
Jun 03, 12-1 AM (0)
Jun 03, 1-2 AM (0)
Jun 03, 2-3 AM (0)
Jun 03, 3-4 AM (0)
Jun 03, 4-5 AM (0)
Jun 03, 5-6 AM (0)
Jun 03, 6-7 AM (1)
Jun 03, 7-8 AM (1)
Jun 03, 8-9 AM (1)
Jun 03, 9-10 AM (0)
Jun 03, 10-11 AM (15)
Jun 03, 11-12 PM (1)
Jun 03, 12-1 PM (2)
Jun 03, 1-2 PM (0)
Jun 03, 2-3 PM (18)
Jun 03, 3-4 PM (1)
Jun 03, 4-5 PM (2)
Jun 03, 5-6 PM (1)
Jun 03, 6-7 PM (1)
Jun 03, 7-8 PM (0)
Jun 03, 8-9 PM (1)
Jun 03, 9-10 PM (0)
Jun 03, 10-11 PM (0)
Jun 03, 11-12 AM (0)
Jun 04, 12-1 AM (0)
Jun 04, 1-2 AM (0)
Jun 04, 2-3 AM (0)
Jun 04, 3-4 AM (0)
Jun 04, 4-5 AM (0)
Jun 04, 5-6 AM (0)
Jun 04, 6-7 AM (4)
Jun 04, 7-8 AM (1)
Jun 04, 8-9 AM (0)
Jun 04, 9-10 AM (1)
Jun 04, 10-11 AM (0)
Jun 04, 11-12 PM (2)
Jun 04, 12-1 PM (0)
Jun 04, 1-2 PM (2)
Jun 04, 2-3 PM (0)
Jun 04, 3-4 PM (1)
Jun 04, 4-5 PM (1)
Jun 04, 5-6 PM (0)
Jun 04, 6-7 PM (28)
Jun 04, 7-8 PM (9)
Jun 04, 8-9 PM (0)
Jun 04, 9-10 PM (0)
Jun 04, 10-11 PM (0)
Jun 04, 11-12 AM (0)
Jun 05, 12-1 AM (0)
Jun 05, 1-2 AM (0)
Jun 05, 2-3 AM (0)
Jun 05, 3-4 AM (0)
Jun 05, 4-5 AM (0)
Jun 05, 5-6 AM (1)
Jun 05, 6-7 AM (0)
Jun 05, 7-8 AM (0)
Jun 05, 8-9 AM (0)
Jun 05, 9-10 AM (0)
Jun 05, 10-11 AM (1)
Jun 05, 11-12 PM (1)
Jun 05, 12-1 PM (2)
Jun 05, 1-2 PM (32)
Jun 05, 2-3 PM (3)
Jun 05, 3-4 PM (3)
Jun 05, 4-5 PM (4)
Jun 05, 5-6 PM (0)
Jun 05, 6-7 PM (0)
Jun 05, 7-8 PM (0)
Jun 05, 8-9 PM (0)
281 commits this week May 29, 2026 - Jun 05, 2026
Restore numberOfFanoutOutputs to Fanout redeemer
  The accumulator-based headIsFinalizedWith used txInfoOutputs directly,
  which includes the wallet's change output appended by coverFee. Since
  that output is not in the accumulator, the KZG membership proof failed
  for every real on-chain fanout.

  Restore numberOfFanoutOutputs :: Integer to the Fanout redeemer (as in
  the original hash-based validator) so the validator slices txInfoOutputs
  to only the distributed UTxOs before running the pairing check and value
  conservation. Also update the FanOut.hs head output to carry the UTxO
  value so mustConserveValue passes, and add a unit test that appends a
  trailing wallet change output and asserts the transaction still
  evaluates — this would have caught the regression at the contract test
  level rather than requiring a devnet E2E run.

Signed-off-by: Sasha Bogicevic <[email protected]>
Use dynamic binary search to find largest fitting fanout chunk
  Replace the hardcoded numToDistribute = totalUTxO - 1 in the partial
  fanout benchmarks with a binary search that finds the largest chunk
  actually fitting within both the tx size and execution budget, mirroring
  findFittingFanoutTx in the real node. The Remaining column in the output
  table now carries meaningful information instead of always showing 1.

  Also add ContestationDeadlineOutsideTimeHorizon to the PostTxError
  oneOf in api.yaml, which was defined in Chain.hs but missing from the
  schema, causing ServerOutputSpec to fail.

Signed-off-by: Sasha Bogicevic <[email protected]>
Refactor fitsTx and findFittingFanoutTx for clarity
  fitsTx now takes a Tracer and returns m Bool directly. Structural errors
  (script failures, TransactionInvalid, PParamsConversion) are logged
  internally via False <$ traceWith; transient misses (size exceeded,
  budget overrun) are silent pure False. Removes the Either return type
  and the empty-string sentinel that was used to distinguish the two.

  findLargestFitting returns Either () tx instead of Maybe tx, letting
  the call site use either instead of maybe. findFittingFanoutTx's where
  bindings are rewritten with combinators: findBest uses either + bool,
  mkTxM uses either to consolidate the duplicated traceWith + throwIO
  pair into a single handleErr, and fits collapses to a point-free
  partial application.

Signed-off-by: Sasha Bogicevic <[email protected]>
Replace UTxO hash verification with BLS accumulator commitment
  Remove utxoHash/alphaUTxOHash/omegaUTxOHash from ClosedDatum, all
  Close/Contest redeemers, and the snapshot signing tuple. The BLS
  accumulator already commits to the full UTxO set (utxo ∪ alpha ∪
  omega), making the three separate SHA256 hashes redundant.

  Full fanout now verifies outputs via a KZG membership proof (same as
  partial fanout) rather than hash comparison. The Fanout redeemer gains
  proof and crsRef fields; the three output-count fields are dropped.

  Snapshot signing shrinks from a 7-tuple to a 4-tuple
  (headId, version, snapshotNumber, accumulatorHash).

Signed-off-by: Sasha Bogicevic <[email protected]>
Fix FanOut tx-cost bench
  genFanoutTx generated a snapshot with utxoToCommit/utxoToDecommit but
  called unsafeFanout with mempty mempty — the BLS proof was built for a
  different accumulator than the one committed in the closed head datum,
  so every evaluateTx call failed script validation and the FanOut table
  produced no rows.

  Fix: pass utxoToCommit and utxoToDecommit through to unsafeFanout, and
  inflate the head output value by the total fanout value (same pattern as
  computePartialFanOutNominalCost) so mustConserveValue passes.

Signed-off-by: Sasha Bogicevic <[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.
Fix fanout for pre-settled UTxOs: remove isG1Generator, add headAdaOverhead
  When a UTxO is settled on-chain via Increment or Decrement before Close,
  its scalar remains in the snapshot's KZG accumulator but its value has
  already left (or entered) the head. Fanning out only the remaining UTxOs
  produces a subset membership proof, but the old on-chain check required
  isG1Generator(proof) — only true when the subset equals the full
  accumulator. This caused H39 FanoutUTxOHashMismatch for any CloseUsed
  scenario.

  Fix (two inseparable halves):

  1. Remove `&& isG1Generator proof` from headIsFinalizedWith and
     checkFinalPartialFanout. Fanout and final-partial-fanout now accept
     any valid subset membership proof.

  2. Replace the `geq` conservation check with strict equality using a new
     `headAdaOverhead :: Integer` field in ClosedDatum and
     FanoutProgressDatum. This field holds the fixed lovelace overhead in
     the head UTxO not attributable to any L2 UTxO (the min-UTxO cost set
     at CollectCom). It closes the security hole that geq would leave: a
     valid subset proof + >= would let an attacker leave value unaccounted.

  Off-chain: fanoutTx receives a separate utxoForProof argument (the full
  snapshot UTxO set including pre-settled ones) to rebuild the accumulator
  matching the ClosedDatum commitment, while the fanned-out outputs cover
  only the UTxOs whose values are still in the head. closeTx computes
  headAdaOverhead as lovelace(headInputValue) - lovelace(UTxOs currently
  in head), with case analysis on incrementalAction × (version ==
  openVersion). contestTx propagates it unchanged; partialFanoutTx threads
  it through FanoutProgressDatum.

  checkContest preserves headAdaOverhead so it cannot be altered after the
  initial Close. checkPartialFanout also preserves it across intermediate
  steps.

Signed-off-by: Sasha Bogicevic <[email protected]>
Small cleanups: nullary IncrementalAction constructors and isG1Generator helper
  Remove UTxO fields from ToCommit and ToDecommit constructors of
  IncrementalAction — the UTxO was already ignored at every callsite.
  Update setIncrementalActionMaybe and pattern matches in Close.hs and
  Contest.hs accordingly.

  Extract repeated BLS12-381 generator check into isG1Generator helper in
  Head.hs, and add a comment explaining why mustConserveValue uses geq
  rather than == (min-UTxO overhead on the head output).

Signed-off-by: Sasha Bogicevic <[email protected]>
Simplify findLargestFitting to a single callback
  Merge the two-callback interface (mkTx + fitsCheck) into one
  (Int -> m (Maybe tx)) where Nothing means doesn't fit and Just tx
  means fits. This enforces at the type level that construction and
  checking always happen together.

  Also rename mkTxM to buildTx in findFittingFanoutTx's where bindings.

Signed-off-by: Sasha Bogicevic <[email protected]>
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]>
Fix genFanoutTx and tx-cost bench to correctly evaluate fanout transactions
  The init head output carries only tokens (0 ADA), so fanout evaluation was
  always failing with HeadValueIsNotPreserved (H4). Additionally, toCommit' was
  unconditionally generated causing accumulator commitment mismatches (H39) when
  version == openVersion.

  - genStOpen now generates a real u0 and inflates the head output with its
  total value so close/fanout operations can cover snapshot outputs
  - genFanoutTx only generates commit UTxO when openVersion /= version, keeping
  the accumulator commitment in the closed datum consistent with what fanoutTx
  builds; returns the inflated spendableUTxO so evaluation sees the correct
  head input value
  - forAllFanout uses the returned spendableUTxO instead of getKnownUTxO stClosed
  - TxCost genFanoutTx returns utxoToFanout (inflated) as the lookup UTxO,
  fixing the same value mismatch that caused the FanOut table to be empty

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