Mar 23, 9-10 PM (19)
Mar 23, 10-11 PM (36)
Mar 23, 11-12 AM (31)
Mar 24, 12-1 AM (1)
Mar 24, 1-2 AM (3)
Mar 24, 2-3 AM (15)
Mar 24, 3-4 AM (5)
Mar 24, 4-5 AM (3)
Mar 24, 5-6 AM (4)
Mar 24, 6-7 AM (3)
Mar 24, 7-8 AM (102)
Mar 24, 8-9 AM (40)
Mar 24, 9-10 AM (30)
Mar 24, 10-11 AM (167)
Mar 24, 11-12 PM (26)
Mar 24, 12-1 PM (42)
Mar 24, 1-2 PM (129)
Mar 24, 2-3 PM (13)
Mar 24, 3-4 PM (41)
Mar 24, 4-5 PM (47)
Mar 24, 5-6 PM (111)
Mar 24, 6-7 PM (17)
Mar 24, 7-8 PM (9)
Mar 24, 8-9 PM (15)
Mar 24, 9-10 PM (16)
Mar 24, 10-11 PM (28)
Mar 24, 11-12 AM (14)
Mar 25, 12-1 AM (1)
Mar 25, 1-2 AM (2)
Mar 25, 2-3 AM (14)
Mar 25, 3-4 AM (2)
Mar 25, 4-5 AM (10)
Mar 25, 5-6 AM (5)
Mar 25, 6-7 AM (7)
Mar 25, 7-8 AM (14)
Mar 25, 8-9 AM (22)
Mar 25, 9-10 AM (48)
Mar 25, 10-11 AM (28)
Mar 25, 11-12 PM (36)
Mar 25, 12-1 PM (86)
Mar 25, 1-2 PM (29)
Mar 25, 2-3 PM (28)
Mar 25, 3-4 PM (65)
Mar 25, 4-5 PM (30)
Mar 25, 5-6 PM (16)
Mar 25, 6-7 PM (37)
Mar 25, 7-8 PM (10)
Mar 25, 8-9 PM (9)
Mar 25, 9-10 PM (6)
Mar 25, 10-11 PM (25)
Mar 25, 11-12 AM (16)
Mar 26, 12-1 AM (3)
Mar 26, 1-2 AM (9)
Mar 26, 2-3 AM (21)
Mar 26, 3-4 AM (10)
Mar 26, 4-5 AM (1)
Mar 26, 5-6 AM (14)
Mar 26, 6-7 AM (4)
Mar 26, 7-8 AM (8)
Mar 26, 8-9 AM (18)
Mar 26, 9-10 AM (33)
Mar 26, 10-11 AM (21)
Mar 26, 11-12 PM (34)
Mar 26, 12-1 PM (33)
Mar 26, 1-2 PM (77)
Mar 26, 2-3 PM (46)
Mar 26, 3-4 PM (51)
Mar 26, 4-5 PM (40)
Mar 26, 5-6 PM (19)
Mar 26, 6-7 PM (19)
Mar 26, 7-8 PM (15)
Mar 26, 8-9 PM (9)
Mar 26, 9-10 PM (17)
Mar 26, 10-11 PM (38)
Mar 26, 11-12 AM (11)
Mar 27, 12-1 AM (3)
Mar 27, 1-2 AM (1)
Mar 27, 2-3 AM (26)
Mar 27, 3-4 AM (12)
Mar 27, 4-5 AM (6)
Mar 27, 5-6 AM (3)
Mar 27, 6-7 AM (10)
Mar 27, 7-8 AM (18)
Mar 27, 8-9 AM (32)
Mar 27, 9-10 AM (26)
Mar 27, 10-11 AM (38)
Mar 27, 11-12 PM (26)
Mar 27, 12-1 PM (57)
Mar 27, 1-2 PM (31)
Mar 27, 2-3 PM (60)
Mar 27, 3-4 PM (40)
Mar 27, 4-5 PM (20)
Mar 27, 5-6 PM (29)
Mar 27, 6-7 PM (29)
Mar 27, 7-8 PM (13)
Mar 27, 8-9 PM (15)
Mar 27, 9-10 PM (13)
Mar 27, 10-11 PM (23)
Mar 27, 11-12 AM (15)
Mar 28, 12-1 AM (1)
Mar 28, 1-2 AM (1)
Mar 28, 2-3 AM (12)
Mar 28, 3-4 AM (1)
Mar 28, 4-5 AM (2)
Mar 28, 5-6 AM (1)
Mar 28, 6-7 AM (0)
Mar 28, 7-8 AM (2)
Mar 28, 8-9 AM (7)
Mar 28, 9-10 AM (7)
Mar 28, 10-11 AM (7)
Mar 28, 11-12 PM (7)
Mar 28, 12-1 PM (3)
Mar 28, 1-2 PM (4)
Mar 28, 2-3 PM (10)
Mar 28, 3-4 PM (2)
Mar 28, 4-5 PM (4)
Mar 28, 5-6 PM (5)
Mar 28, 6-7 PM (0)
Mar 28, 7-8 PM (0)
Mar 28, 8-9 PM (0)
Mar 28, 9-10 PM (1)
Mar 28, 10-11 PM (20)
Mar 28, 11-12 AM (20)
Mar 29, 12-1 AM (1)
Mar 29, 1-2 AM (6)
Mar 29, 2-3 AM (5)
Mar 29, 3-4 AM (6)
Mar 29, 4-5 AM (3)
Mar 29, 5-6 AM (5)
Mar 29, 6-7 AM (0)
Mar 29, 7-8 AM (0)
Mar 29, 8-9 AM (13)
Mar 29, 9-10 AM (0)
Mar 29, 10-11 AM (0)
Mar 29, 11-12 PM (2)
Mar 29, 12-1 PM (13)
Mar 29, 1-2 PM (0)
Mar 29, 2-3 PM (0)
Mar 29, 3-4 PM (1)
Mar 29, 4-5 PM (3)
Mar 29, 5-6 PM (4)
Mar 29, 6-7 PM (8)
Mar 29, 7-8 PM (5)
Mar 29, 8-9 PM (0)
Mar 29, 9-10 PM (8)
Mar 29, 10-11 PM (24)
Mar 29, 11-12 AM (17)
Mar 30, 12-1 AM (5)
Mar 30, 1-2 AM (5)
Mar 30, 2-3 AM (7)
Mar 30, 3-4 AM (7)
Mar 30, 4-5 AM (3)
Mar 30, 5-6 AM (12)
Mar 30, 6-7 AM (3)
Mar 30, 7-8 AM (36)
Mar 30, 8-9 AM (27)
Mar 30, 9-10 AM (10)
Mar 30, 10-11 AM (67)
Mar 30, 11-12 PM (47)
Mar 30, 12-1 PM (30)
Mar 30, 1-2 PM (38)
Mar 30, 2-3 PM (61)
Mar 30, 3-4 PM (31)
Mar 30, 4-5 PM (18)
Mar 30, 5-6 PM (38)
Mar 30, 6-7 PM (14)
Mar 30, 7-8 PM (13)
Mar 30, 8-9 PM (13)
Mar 30, 9-10 PM (1)
3,328 commits this week Mar 23, 2026 - Mar 30, 2026
fix(ledger): resolve post-Mithril leader election failures
After Mithril bootstrap, two bugs prevent block production:

1. EpochNonce() returns nil when the in-memory nonce is empty for the
   current epoch, even though the DB has the correct value. Fall through
   to DB lookup instead of returning nil early.

2. CaptureGenesisSnapshot() queries slot 0 for pool registrations, but
   after Mithril import epochs start at a much later slot. Fall back to
   the latest epoch's start slot when slot 0 yields no pools.

Signed-off-by: wcatz <[email protected]>
Signed-off-by: Chris Gianelloni <[email protected]>
fix(chainselection): prefer observed frontier and keep quiet local roots hot
Prefer the actually-delivered chainsync tip over the advertised remote
tip for chain selection decisions. New peers are checked against the
best known peer tip to prevent spoofed block numbers.

Simplify TouchPeerActivity to use defer-based locking and direct
best-peer assignment. Revert stale tip threshold to 60s and remove
the PeerActivityEvent subscription from the constructor. When two
peers have delivered the same observed frontier, keep following the
incumbent to avoid churn near tip.

Co-authored-by: Chris Gianelloni <[email protected]>
Signed-off-by: wcatz <[email protected]>
Signed-off-by: Chris Gianelloni <[email protected]>
feat(metrics): add network-labelled prometheus metrics and build info
Wrap the prometheus registry with a constant "network" label so every
metric carries the network name automatically. Move event bus creation
after registry wrapping so event bus metrics also receive the label.

Add dingo_build_info gauge (version, commit, goversion labels) and
three node-level gauges for dashboard sync tracking:
  - dingo_tip_gap_slots: wall-clock slot minus chain tip
  - dingo_shelley_start_time: Shelley genesis start as unix timestamp
  - dingo_epoch_length_slots: slots per epoch

Signed-off-by: wcatz <[email protected]>
Signed-off-by: Chris Gianelloni <[email protected]>
fix(chainselection): prefer observed frontier and keep quiet local roots hot
Prefer the actually-delivered chainsync tip over the advertised remote
tip for chain selection decisions. New peers are checked against the
best known peer tip to prevent spoofed block numbers.

Simplify TouchPeerActivity to use defer-based locking and direct
best-peer assignment. Revert stale tip threshold to 60s and remove
the PeerActivityEvent subscription from the constructor. When two
peers have delivered the same observed frontier, keep following the
incumbent to avoid churn near tip.

Co-authored-by: Chris Gianelloni <[email protected]>
Signed-off-by: wcatz <[email protected]>
Signed-off-by: Chris Gianelloni <[email protected]>
fix(ledger): exempt forged-block rollbacks from loop detector
The rollback loop detector (2 rollbacks to same slot within 5 min)
blocks all further rollbacks at that slot. This is correct for
pathological post-Mithril cascade loops but wrong for block production:
when a peer's fork wins over our forged block, rolling back through our
slot is normal Ouroboros fork resolution (slot battle).

Check ForgedBlockChecker before suppressing the rollback. If we forged
a block at the contested slot, allow the rollback so the node can follow
the canonical chain.

Signed-off-by: wcatz <[email protected]>
Signed-off-by: Chris Gianelloni <[email protected]>
fix(ledger): resolve post-Mithril leader election failures
After Mithril bootstrap, two bugs prevent block production:

1. EpochNonce() returns nil when the in-memory nonce is empty for the
   current epoch, even though the DB has the correct value. Fall through
   to DB lookup instead of returning nil early.

2. CaptureGenesisSnapshot() queries slot 0 for pool registrations, but
   after Mithril import epochs start at a much later slot. Fall back to
   the latest epoch's start slot when slot 0 yields no pools.

Signed-off-by: wcatz <[email protected]>
Signed-off-by: Chris Gianelloni <[email protected]>