Nov 27, 3-4 PM (50)
Nov 27, 4-5 PM (34)
Nov 27, 5-6 PM (31)
Nov 27, 6-7 PM (24)
Nov 27, 7-8 PM (10)
Nov 27, 8-9 PM (3)
Nov 27, 9-10 PM (7)
Nov 27, 10-11 PM (24)
Nov 27, 11-12 AM (21)
Nov 28, 12-1 AM (3)
Nov 28, 1-2 AM (2)
Nov 28, 2-3 AM (3)
Nov 28, 3-4 AM (11)
Nov 28, 4-5 AM (3)
Nov 28, 5-6 AM (30)
Nov 28, 6-7 AM (10)
Nov 28, 7-8 AM (20)
Nov 28, 8-9 AM (53)
Nov 28, 9-10 AM (52)
Nov 28, 10-11 AM (75)
Nov 28, 11-12 PM (49)
Nov 28, 12-1 PM (34)
Nov 28, 1-2 PM (17)
Nov 28, 2-3 PM (102)
Nov 28, 3-4 PM (23)
Nov 28, 4-5 PM (20)
Nov 28, 5-6 PM (8)
Nov 28, 6-7 PM (29)
Nov 28, 7-8 PM (69)
Nov 28, 8-9 PM (2)
Nov 28, 9-10 PM (6)
Nov 28, 10-11 PM (26)
Nov 28, 11-12 AM (12)
Nov 29, 12-1 AM (9)
Nov 29, 1-2 AM (2)
Nov 29, 2-3 AM (0)
Nov 29, 3-4 AM (3)
Nov 29, 4-5 AM (4)
Nov 29, 5-6 AM (0)
Nov 29, 6-7 AM (1)
Nov 29, 7-8 AM (0)
Nov 29, 8-9 AM (2)
Nov 29, 9-10 AM (4)
Nov 29, 10-11 AM (7)
Nov 29, 11-12 PM (0)
Nov 29, 12-1 PM (8)
Nov 29, 1-2 PM (38)
Nov 29, 2-3 PM (14)
Nov 29, 3-4 PM (25)
Nov 29, 4-5 PM (11)
Nov 29, 5-6 PM (11)
Nov 29, 6-7 PM (12)
Nov 29, 7-8 PM (13)
Nov 29, 8-9 PM (7)
Nov 29, 9-10 PM (5)
Nov 29, 10-11 PM (21)
Nov 29, 11-12 AM (25)
Nov 30, 12-1 AM (2)
Nov 30, 1-2 AM (2)
Nov 30, 2-3 AM (4)
Nov 30, 3-4 AM (4)
Nov 30, 4-5 AM (2)
Nov 30, 5-6 AM (1)
Nov 30, 6-7 AM (0)
Nov 30, 7-8 AM (0)
Nov 30, 8-9 AM (2)
Nov 30, 9-10 AM (4)
Nov 30, 10-11 AM (6)
Nov 30, 11-12 PM (6)
Nov 30, 12-1 PM (34)
Nov 30, 1-2 PM (3)
Nov 30, 2-3 PM (7)
Nov 30, 3-4 PM (18)
Nov 30, 4-5 PM (13)
Nov 30, 5-6 PM (13)
Nov 30, 6-7 PM (6)
Nov 30, 7-8 PM (9)
Nov 30, 8-9 PM (31)
Nov 30, 9-10 PM (8)
Nov 30, 10-11 PM (27)
Nov 30, 11-12 AM (24)
Dec 01, 12-1 AM (5)
Dec 01, 1-2 AM (6)
Dec 01, 2-3 AM (6)
Dec 01, 3-4 AM (30)
Dec 01, 4-5 AM (7)
Dec 01, 5-6 AM (8)
Dec 01, 6-7 AM (12)
Dec 01, 7-8 AM (47)
Dec 01, 8-9 AM (27)
Dec 01, 9-10 AM (19)
Dec 01, 10-11 AM (47)
Dec 01, 11-12 PM (48)
Dec 01, 12-1 PM (66)
Dec 01, 1-2 PM (28)
Dec 01, 2-3 PM (28)
Dec 01, 3-4 PM (70)
Dec 01, 4-5 PM (49)
Dec 01, 5-6 PM (23)
Dec 01, 6-7 PM (20)
Dec 01, 7-8 PM (20)
Dec 01, 8-9 PM (8)
Dec 01, 9-10 PM (13)
Dec 01, 10-11 PM (28)
Dec 01, 11-12 AM (28)
Dec 02, 12-1 AM (33)
Dec 02, 1-2 AM (9)
Dec 02, 2-3 AM (10)
Dec 02, 3-4 AM (2)
Dec 02, 4-5 AM (4)
Dec 02, 5-6 AM (4)
Dec 02, 6-7 AM (5)
Dec 02, 7-8 AM (17)
Dec 02, 8-9 AM (67)
Dec 02, 9-10 AM (64)
Dec 02, 10-11 AM (72)
Dec 02, 11-12 PM (58)
Dec 02, 12-1 PM (72)
Dec 02, 1-2 PM (151)
Dec 02, 2-3 PM (113)
Dec 02, 3-4 PM (63)
Dec 02, 4-5 PM (124)
Dec 02, 5-6 PM (22)
Dec 02, 6-7 PM (11)
Dec 02, 7-8 PM (27)
Dec 02, 8-9 PM (19)
Dec 02, 9-10 PM (28)
Dec 02, 10-11 PM (37)
Dec 02, 11-12 AM (32)
Dec 03, 12-1 AM (5)
Dec 03, 1-2 AM (8)
Dec 03, 2-3 AM (39)
Dec 03, 3-4 AM (15)
Dec 03, 4-5 AM (5)
Dec 03, 5-6 AM (3)
Dec 03, 6-7 AM (8)
Dec 03, 7-8 AM (47)
Dec 03, 8-9 AM (39)
Dec 03, 9-10 AM (57)
Dec 03, 10-11 AM (49)
Dec 03, 11-12 PM (42)
Dec 03, 12-1 PM (114)
Dec 03, 1-2 PM (66)
Dec 03, 2-3 PM (72)
Dec 03, 3-4 PM (62)
Dec 03, 4-5 PM (32)
Dec 03, 5-6 PM (28)
Dec 03, 6-7 PM (11)
Dec 03, 7-8 PM (25)
Dec 03, 8-9 PM (13)
Dec 03, 9-10 PM (22)
Dec 03, 10-11 PM (37)
Dec 03, 11-12 AM (23)
Dec 04, 12-1 AM (3)
Dec 04, 1-2 AM (7)
Dec 04, 2-3 AM (16)
Dec 04, 3-4 AM (9)
Dec 04, 4-5 AM (9)
Dec 04, 5-6 AM (2)
Dec 04, 6-7 AM (12)
Dec 04, 7-8 AM (14)
Dec 04, 8-9 AM (78)
Dec 04, 9-10 AM (97)
Dec 04, 10-11 AM (63)
Dec 04, 11-12 PM (74)
Dec 04, 12-1 PM (37)
Dec 04, 1-2 PM (136)
Dec 04, 2-3 PM (26)
Dec 04, 3-4 PM (0)
4,403 commits this week Nov 27, 2025 - Dec 04, 2025
feat(p2p): Add custom bootstrap peers and initialization script
  Enable custom P2P bootstrap configuration for multi-node testing:
  - Add IPFS_BOOTSTRAP_PEERS environment variable support for custom peer lists
  - Update bootstrap() to accept optional custom peers parameter
  - Add initialize-p2p.sh script to extract peer IDs and generate bootstrap config
  - Update hermes-ipfs dependency from 0.0.6 to 0.0.8

  This allows nodes in Docker environments to bootstrap to each other
  instead of public IPFS nodes, enabling isolated P2P testing.
feat(cat-voices): filtering proposals by original author (#3810)
* tables

* wip

* proposals dao tests

* bump db schema

* db index name fix

* migration -> use createAll()

* update migration

* update migration

* chore: remove print

* update ref dto flatten implementation

* migration toFlatten()

* fix: proposals dao

* fix: documents dao and local drafts dao

* chore: clean up TODO

* fix: failing tests

* chore: markdown order

* web: skips for db tests

* fix: db tests on web

* fix: analyzer

* unskip tests

* feat: filtering author on first version

* change filter name from author to originalAuthor

* Adds originalAuthor filter to documentsDao

* authorId -> originalAuthorId

* originalAuthors

* fix: spelling

* use authors from documents for originalAuthors
Prevent insecure l2 interactions until chain sync (#2290)
<!-- Describe your change here -->

🔑 Motivation

> Closes [#2286](https://github.com/cardano-scaling/hydra/issues/2286)

This PR introduces new synchronization tracking (wall-clock time) and
input-handling logic to improve consistency between the chain component
and node state.

---

🔄 Changes

* `NodeState` has been refactored into a sum type with two variants:
`NodeInSync` and `NodeCatchingUp`.

* A new policy based on the configured `ContestationPeriod` has been
introduced, defining the period of time after which the node is
considered out of sync with the chain. Beyond this period, the node will
refuse to process new transactions or sign snapshots.

* The **head logic** now processes inputs only when the node state's
current slot falls within the safe `ContestationPeriod` window relative
to the latest chain time observed by the chain backend and the current
wall-clock time.

+ **NodeState** transitions between `NodeInSync` and `NodeCatchingUp`
according to the above policy.

  + While in `NodeInSync`, the head logic behaves as usual.

  + While in `NodeCatchingUp`:
      - **Client inputs** are **rejected** if outside the window.
      - This is the starting state.

- **Network inputs** are **re-enqueued** (with TTL) until
synchronization is restored.
⚠️ THIS IS PROBLEMATIC: the network component must be aware of the node
state synced status and accept messages only while `NodeInSync`.

* The **API server** now notifies clients via new server outputs when
the node state falls out of sync with the chain backend and when it
becomes synchronized again.

---

📝 Notes

* We use the wall-clock time and not the latest known tip from the
chain, as it is unreliable while the chain backend is still
synchronizing with the Cardano network.

* A party member cannot go offline for longer than the configured
`ContestationPeriod`; otherwise, it would be at risk, as it would be
unable to contest the head closing. This violates the principle of head
safety.

* We decided to move forward with this _alternative_ solution rather
than the _main proposed one_ because it preserves the node architecture
and allows for fast and easy testing of the protocol’s safety without
requiring major hacks during end-to-end tests. This approach also makes
the protocol safe by design and aware of the passage of time relative to
the latest on-chain observations.
---

<!-- 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

---------

Co-authored-by: Sebastian Nagel <[email protected]>
Co-authored-by: Noon <[email protected]>
Add pure Peras Voting rules
With the currently selected generation sizes, we hit the different
voting rules in a somewhat decent proportion, even against randomly
generated functions as part of the PerasVotingView interface.

ouroboros-consensus
  Peras
    Peras voting rules
      isPerasVotingAllowed: OK (1.55s)
        +++ OK, passed 10000 tests.

        Actual result (10000 in total):
        60.29% NoVoteReason(VR-1A or VR-2A)
        20.90% NoVoteReason(VR-1A or VR-2B)
         9.60% VoteReason(VR-2A and VR-2B)
         4.93% VoteReason(VR-1A and VR-1B)
         2.67% NoVoteReason(VR-1B or VR-2A)
         1.61% NoVoteReason(VR-1B or VR-2B)

        Should vote according to model (10000 in total):
        85.47% False
        14.53% True

        VR-(1A|1B|2A|2B) (10000 in total):
        21.30% (False,True,False,False)
        21.24% (False,False,False,False)
        10.63% (False,False,True,False)
        10.27% (False,True,True,False)
         8.99% (False,False,False,True)
         8.76% (False,True,False,True)
         4.67% (False,True,True,True)
         4.26% (False,False,True,True)
         1.93% (True,False,False,False)
         1.77% (True,True,False,False)
         1.71% (True,True,True,False)
         1.61% (True,False,True,False)
         0.75% (True,True,True,True)
         0.74% (True,False,False,True)
         0.70% (True,True,False,True)
         0.67% (True,False,True,True)

        VR-1A (10000 in total):
        90.12% False
         9.88% True

        VR-1B (10000 in total):
        50.07% False
        49.93% True

        VR-2A (10000 in total):
        65.43% False
        34.57% True

        VR-2B (10000 in total):
        70.46% False
        29.54% True