Apr 07, 2-3 PM (54)
Apr 07, 3-4 PM (25)
Apr 07, 4-5 PM (36)
Apr 07, 5-6 PM (19)
Apr 07, 6-7 PM (22)
Apr 07, 7-8 PM (21)
Apr 07, 8-9 PM (20)
Apr 07, 9-10 PM (16)
Apr 07, 10-11 PM (41)
Apr 07, 11-12 AM (21)
Apr 08, 12-1 AM (13)
Apr 08, 1-2 AM (6)
Apr 08, 2-3 AM (9)
Apr 08, 3-4 AM (9)
Apr 08, 4-5 AM (4)
Apr 08, 5-6 AM (21)
Apr 08, 6-7 AM (40)
Apr 08, 7-8 AM (72)
Apr 08, 8-9 AM (42)
Apr 08, 9-10 AM (24)
Apr 08, 10-11 AM (56)
Apr 08, 11-12 PM (43)
Apr 08, 12-1 PM (36)
Apr 08, 1-2 PM (64)
Apr 08, 2-3 PM (45)
Apr 08, 3-4 PM (17)
Apr 08, 4-5 PM (16)
Apr 08, 5-6 PM (17)
Apr 08, 6-7 PM (27)
Apr 08, 7-8 PM (12)
Apr 08, 8-9 PM (11)
Apr 08, 9-10 PM (6)
Apr 08, 10-11 PM (50)
Apr 08, 11-12 AM (18)
Apr 09, 12-1 AM (7)
Apr 09, 1-2 AM (5)
Apr 09, 2-3 AM (2)
Apr 09, 3-4 AM (4)
Apr 09, 4-5 AM (6)
Apr 09, 5-6 AM (15)
Apr 09, 6-7 AM (36)
Apr 09, 7-8 AM (22)
Apr 09, 8-9 AM (25)
Apr 09, 9-10 AM (33)
Apr 09, 10-11 AM (20)
Apr 09, 11-12 PM (60)
Apr 09, 12-1 PM (68)
Apr 09, 1-2 PM (43)
Apr 09, 2-3 PM (74)
Apr 09, 3-4 PM (22)
Apr 09, 4-5 PM (51)
Apr 09, 5-6 PM (26)
Apr 09, 6-7 PM (23)
Apr 09, 7-8 PM (21)
Apr 09, 8-9 PM (39)
Apr 09, 9-10 PM (18)
Apr 09, 10-11 PM (29)
Apr 09, 11-12 AM (15)
Apr 10, 12-1 AM (5)
Apr 10, 1-2 AM (4)
Apr 10, 2-3 AM (4)
Apr 10, 3-4 AM (12)
Apr 10, 4-5 AM (3)
Apr 10, 5-6 AM (9)
Apr 10, 6-7 AM (30)
Apr 10, 7-8 AM (45)
Apr 10, 8-9 AM (47)
Apr 10, 9-10 AM (20)
Apr 10, 10-11 AM (61)
Apr 10, 11-12 PM (70)
Apr 10, 12-1 PM (46)
Apr 10, 1-2 PM (23)
Apr 10, 2-3 PM (36)
Apr 10, 3-4 PM (33)
Apr 10, 4-5 PM (38)
Apr 10, 5-6 PM (30)
Apr 10, 6-7 PM (11)
Apr 10, 7-8 PM (13)
Apr 10, 8-9 PM (7)
Apr 10, 9-10 PM (25)
Apr 10, 10-11 PM (47)
Apr 10, 11-12 AM (18)
Apr 11, 12-1 AM (6)
Apr 11, 1-2 AM (4)
Apr 11, 2-3 AM (2)
Apr 11, 3-4 AM (0)
Apr 11, 4-5 AM (8)
Apr 11, 5-6 AM (4)
Apr 11, 6-7 AM (5)
Apr 11, 7-8 AM (7)
Apr 11, 8-9 AM (3)
Apr 11, 9-10 AM (0)
Apr 11, 10-11 AM (10)
Apr 11, 11-12 PM (4)
Apr 11, 12-1 PM (7)
Apr 11, 1-2 PM (3)
Apr 11, 2-3 PM (7)
Apr 11, 3-4 PM (12)
Apr 11, 4-5 PM (18)
Apr 11, 5-6 PM (39)
Apr 11, 6-7 PM (0)
Apr 11, 7-8 PM (0)
Apr 11, 8-9 PM (2)
Apr 11, 9-10 PM (1)
Apr 11, 10-11 PM (19)
Apr 11, 11-12 AM (23)
Apr 12, 12-1 AM (4)
Apr 12, 1-2 AM (1)
Apr 12, 2-3 AM (9)
Apr 12, 3-4 AM (2)
Apr 12, 4-5 AM (0)
Apr 12, 5-6 AM (2)
Apr 12, 6-7 AM (2)
Apr 12, 7-8 AM (1)
Apr 12, 8-9 AM (3)
Apr 12, 9-10 AM (2)
Apr 12, 10-11 AM (11)
Apr 12, 11-12 PM (4)
Apr 12, 12-1 PM (1)
Apr 12, 1-2 PM (10)
Apr 12, 2-3 PM (24)
Apr 12, 3-4 PM (7)
Apr 12, 4-5 PM (7)
Apr 12, 5-6 PM (17)
Apr 12, 6-7 PM (2)
Apr 12, 7-8 PM (1)
Apr 12, 8-9 PM (8)
Apr 12, 9-10 PM (9)
Apr 12, 10-11 PM (38)
Apr 12, 11-12 AM (23)
Apr 13, 12-1 AM (5)
Apr 13, 1-2 AM (6)
Apr 13, 2-3 AM (5)
Apr 13, 3-4 AM (6)
Apr 13, 4-5 AM (2)
Apr 13, 5-6 AM (18)
Apr 13, 6-7 AM (23)
Apr 13, 7-8 AM (39)
Apr 13, 8-9 AM (43)
Apr 13, 9-10 AM (51)
Apr 13, 10-11 AM (75)
Apr 13, 11-12 PM (35)
Apr 13, 12-1 PM (55)
Apr 13, 1-2 PM (80)
Apr 13, 2-3 PM (42)
Apr 13, 3-4 PM (20)
Apr 13, 4-5 PM (31)
Apr 13, 5-6 PM (25)
Apr 13, 6-7 PM (18)
Apr 13, 7-8 PM (13)
Apr 13, 8-9 PM (15)
Apr 13, 9-10 PM (22)
Apr 13, 10-11 PM (29)
Apr 13, 11-12 AM (13)
Apr 14, 12-1 AM (6)
Apr 14, 1-2 AM (8)
Apr 14, 2-3 AM (15)
Apr 14, 3-4 AM (4)
Apr 14, 4-5 AM (4)
Apr 14, 5-6 AM (63)
Apr 14, 6-7 AM (48)
Apr 14, 7-8 AM (100)
Apr 14, 8-9 AM (33)
Apr 14, 9-10 AM (19)
Apr 14, 10-11 AM (34)
Apr 14, 11-12 PM (41)
Apr 14, 12-1 PM (61)
Apr 14, 1-2 PM (67)
Apr 14, 2-3 PM (0)
3,759 commits this week Apr 07, 2026 - Apr 14, 2026
Add async write-behind SQLite persistence with batch inserts
  Move SQLite event writes off the hot path using a bounded TBQueue
  (capacity 1000) and a single background writer thread. Events are
  JSON-encoded eagerly and enqueued; the writer drains the queue and
  batch-inserts via executeMany in a single transaction.

  Key changes:
  - EventSink gains a putEvents field for batch writes; mkEventSink
    provides a default sequential fallback
  - putEventsToSinks switches from event-major to sink-major loop order
  - SQLiteBased uses BLOB storage instead of TEXT, WAL mode with
    synchronous=NORMAL, and 64 MB page cache
  - Flush marker pattern (TMVar) lets rotate and tests block until all
    queued writes hit disk
  - Migration bypasses the async queue and writes directly via executeMany
  - Node replay collects events into a list then calls putEventsToSinks
    once instead of per-event mapM_
  - Rotation module delegates to underlying putEvents for batch support
Remove legacy file-based persistence modules
  Delete `Hydra.Events.FileBased`, `Hydra.Persistence`, and
  `Hydra.PersistenceLog` which are no longer needed now that
  `Hydra.Events.SQLiteBased` is the sole persistence backend.

  Migration logic in `migrateFromFileBased` now reads the legacy
  newline-delimited JSON file directly, removing the dependency on
  `PersistenceIncremental`. The `Persistence` log constructor is removed
  from `HydraLog` along with it. Drop `resourcet` and `unliftio` from
  the library build-depends as they were only pulled in by the deleted
  modules.
Statically link SQLite into hydra-node binary
  Add `static-sqlite` to the static-libs overlay (built with
  `--disable-shared`) and point the `direct-sqlite` pkgconfig at it.
  This embeds libsqlite3 directly into the binary for both native and
  musl64 builds, so Docker images do not need libsqlite3.so at runtime —
  fixing the container crash-loop seen in the network-test CI workflow.
Replace file-based persistence with SQLite event store
  Events are now persisted in a SQLite database (hydra.db) instead of a
  plain append-only JSON file (state). On first startup after upgrade,
  existing state files are automatically migrated into the database and
  renamed to state.migrated.

  Key changes:
  - Add Hydra.Events.SQLiteBased with mkSQLiteEventStore and
    migrateFromFileBased
  - WAL mode, synchronous=NORMAL, 64MB page cache for fast reads/writes
  - rotate uses a single transaction (atomic delete + checkpoint insert)
  - Migration batches all inserts in one transaction
  - Update Run.hs to wire up the SQLite store
  - Update docs to reflect SQLite backend and hydra.db filename
  - Add Hydra.Events.SQLiteBasedSpec mirroring FileBasedSpec
Improve state-machine tests of `ChainDB` to (better) handle `Peras{Cert,Vote}DB`-related actions
Co-authored-by: Agustin Mista <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
Co-authored-by: Nicolas "Niols" Jeannerod <[email protected]>
Rework `PerasCertDB` (+ tests) to be consistent with `PerasVoteDB` API
Co-authored-by: Agustin Mista <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
Co-authored-by: Nicolas "Niols" Jeannerod <[email protected]>
Add explicit handling of `PerasVoteDB` exceptions at the node level
Co-authored-by: Agustin Mista <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
Co-authored-by: Nicolas "Niols" Jeannerod <[email protected]>
Slim down persisted StateChanged events (#2577)
fix #2539 

  Remove redundant fields from three StateChanged constructors:

- SnapshotRequested: drop requestedTxIds (derivable from map txId
snapshot.confirmed)
- SnapshotConfirmed: change snapshot to Maybe (Nothing on normal AckSn
path where the snapshot is already tracked in seenSnapshot; Just only on
side-load path)
- DecommitRecorded: drop utxoToDecommit (derivable from utxoFromTx
decommitTx)
- PartySignedSnapshot: replace snapshot :: Snapshot tx with
snapshotNumber :: SnapshotNumber

The API server reconstructs SnapshotConfirmed outputs by threading the
seenSnapshot through a stateful mapAccum conduit for history replay and
reading nodeStateP before updating for live events.

<!-- Describe your change here -->

---

<!-- Consider each and tick it off one way or the other -->
* [x] CHANGELOG updated or not needed
* [x] Documentation updated or not needed
* [x] Haddocks updated or not needed
* [x] No new TODOs introduced or explained herafter

---------

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