@blinklabs/dingo 0.25.0 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ARCHITECTURE.md CHANGED
@@ -5,6 +5,12 @@ Dingo is a high-performance Cardano blockchain node implementation in Go. This d
5
5
  ## Table of Contents
6
6
 
7
7
  - [Overview](#overview)
8
+ - [Architecture Diagrams](#architecture-diagrams)
9
+ - [Component Interactions](#component-interactions)
10
+ - [Package Dependency Tree](#package-dependency-tree)
11
+ - [Data Flow](#data-flow)
12
+ - [Peer-to-Peer Networking](#peer-to-peer-networking)
13
+ - [Block Forging](#block-forging)
8
14
  - [Directory Structure](#directory-structure)
9
15
  - [Core Node Structure](#core-node-structure)
10
16
  - [Event-Driven Communication](#event-driven-communication)
@@ -34,6 +40,318 @@ Dingo's architecture is built on several key principles:
34
40
  6. Block production with VRF leader election and stake snapshots
35
41
  7. Graceful shutdown with phased resource cleanup
36
42
 
43
+ ## Architecture Diagrams
44
+
45
+ ### Component Interactions
46
+
47
+ How the Node orchestrator wires components together. Solid arrows are direct method calls; dashed arrows are asynchronous EventBus messages.
48
+
49
+ ```mermaid
50
+ graph TB
51
+ Node["<b>Node</b><br/><i>node.go</i>"]
52
+
53
+ subgraph Networking
54
+ CM["ConnectionManager<br/><i>connmanager/</i>"]
55
+ PG["PeerGovernor<br/><i>peergov/</i>"]
56
+ OB["Ouroboros<br/><i>ouroboros/</i>"]
57
+ end
58
+
59
+ subgraph "Chain State"
60
+ ChM["ChainManager<br/><i>chain/</i>"]
61
+ CS["ChainsyncState<br/><i>chainsync/</i>"]
62
+ CSel["ChainSelector<br/><i>chainselection/</i>"]
63
+ end
64
+
65
+ subgraph "Ledger & Validation"
66
+ LS["LedgerState<br/><i>ledger/</i>"]
67
+ SM["SnapshotManager<br/><i>ledger/snapshot/</i>"]
68
+ MP["Mempool<br/><i>mempool/</i>"]
69
+ end
70
+
71
+ subgraph "Block Production"
72
+ BF["BlockForger<br/><i>ledger/forging/</i>"]
73
+ LE["LeaderElection<br/><i>ledger/leader/</i>"]
74
+ end
75
+
76
+ subgraph Storage
77
+ DB["Database<br/><i>database/</i>"]
78
+ Blob["BlobStore<br/>badger / s3 / gcs"]
79
+ Meta["MetadataStore<br/>sqlite / postgres / mysql"]
80
+ end
81
+
82
+ subgraph "API Servers"
83
+ URPC["UTxO RPC<br/><i>utxorpc/</i>"]
84
+ BFA["Blockfrost API<br/><i>blockfrost/</i>"]
85
+ Mesh["Mesh API<br/><i>mesh/</i>"]
86
+ Bark["Bark<br/><i>bark/</i>"]
87
+ end
88
+
89
+ EB["EventBus<br/><i>event/</i>"]
90
+
91
+ Node --> CM & PG & OB & ChM & LS & MP & DB & EB
92
+ Node -.->|"optional"| BF & LE & URPC & BFA & Mesh & Bark
93
+
94
+ PG -->|"outbound conn requests"| CM
95
+ CM -->|"connections"| OB
96
+ OB -->|"chainsync / blockfetch"| LS
97
+ OB -->|"tx submission"| MP
98
+ LS --> ChM & DB
99
+ LS -->|"validate txs"| MP
100
+ ChM --> DB
101
+ DB --> Blob & Meta
102
+ BF --> LE & MP & ChM
103
+ SM -->|"stake snapshots"| DB
104
+ CSel -->|"switch active peer"| CS
105
+ CS -->|"stall detection"| CM
106
+
107
+ EB -.->|"events"| LS & ChM & CS & CSel & PG & SM & OB & MP
108
+ URPC & BFA & Mesh -.-> LS & DB
109
+ Bark -.-> DB
110
+ ```
111
+
112
+ ### Package Dependency Tree
113
+
114
+ Internal import relationships between dingo packages. External dependencies are omitted.
115
+
116
+ ```mermaid
117
+ graph LR
118
+ root["<b>dingo</b> (root)"]
119
+ cmd["cmd/dingo"]
120
+ chain["chain"]
121
+ chainsync["chainsync"]
122
+ chainsel["chainselection"]
123
+ connmgr["connmanager"]
124
+ db["database"]
125
+ db_models["database/models"]
126
+ db_types["database/types"]
127
+ db_plugin["database/plugin"]
128
+ db_blob["database/plugin/blob/*"]
129
+ db_meta["database/plugin/metadata/*"]
130
+ db_immutable["database/immutable"]
131
+ ev["event"]
132
+ ledger["ledger"]
133
+ ledger_eras["ledger/eras"]
134
+ ledger_forging["ledger/forging"]
135
+ ledger_leader["ledger/leader"]
136
+ ledger_snapshot["ledger/snapshot"]
137
+ ledgerstate["ledgerstate"]
138
+ mempool["mempool"]
139
+ ouroboros["ouroboros"]
140
+ peergov["peergov"]
141
+ topology["topology"]
142
+ intcfg["internal/config"]
143
+ intnode["internal/node"]
144
+ utxorpc["utxorpc"]
145
+ blockfrost["blockfrost"]
146
+ mesh["mesh"]
147
+ bark["bark"]
148
+ mithril["mithril"]
149
+ keystore["keystore"]
150
+
151
+ root --> chain & chainsync & chainsel & connmgr & db & ev
152
+ root --> ledger & ledger_forging & ledger_leader & ledger_snapshot
153
+ root --> mempool & ouroboros & peergov & topology
154
+ root --> utxorpc & blockfrost & mesh & bark
155
+
156
+ cmd --> intcfg & intnode & mithril
157
+
158
+ chain --> db & db_models & ev
159
+ chainsync --> chain & ev & ledger
160
+ chainsel --> ev
161
+ connmgr --> ev
162
+ peergov --> connmgr & ev & topology
163
+
164
+ ouroboros --> chain & chainsel & chainsync & connmgr
165
+ ouroboros --> db_immutable & ev & ledger & mempool & peergov
166
+
167
+ ledger --> chain & db & db_models & db_meta & db_types & ev
168
+ ledger --> ledger_eras & ledger_forging & ledger_leader & ledger_snapshot
169
+ ledger --> mempool & peergov
170
+ ledger_eras --> db_models
171
+ ledger_forging --> chain & ev
172
+ ledger_snapshot --> db & db_models & ev
173
+
174
+ mempool --> chain & ev
175
+
176
+ db --> db_plugin & db_types & db_models
177
+ db_plugin --> db_blob & db_meta & intcfg
178
+ db_blob --> db_plugin & db_types
179
+ db_meta --> db_models & db_types & db_plugin
180
+ db_models --> db_types
181
+
182
+ intnode --> chain & chainsync & db & db_immutable & db_models & db_meta
183
+ intnode --> ledger & ledger_eras & intcfg
184
+
185
+ ledgerstate --> db & db_models & db_types & ledger_eras
186
+ mithril --> db & db_immutable & db_models & ledgerstate & ledger_eras
187
+
188
+ utxorpc --> db & db_models & ev & ledger & ledger_eras & mempool
189
+ mesh --> chain & db & db_models & ev & ledger & mempool
190
+ blockfrost --> ledger
191
+ bark --> db & db_types & ledger
192
+ ```
193
+
194
+ ### Data Flow
195
+
196
+ How blocks flow from the network through validation and into storage.
197
+
198
+ ```mermaid
199
+ sequenceDiagram
200
+ participant Peer
201
+ participant OB as Ouroboros
202
+ participant EB as EventBus
203
+ participant LS as LedgerState
204
+ participant ChM as ChainManager
205
+ participant DB as Database
206
+
207
+ Note over Peer,DB: Stage 1 — Header Discovery (ChainSync)
208
+ Peer->>OB: RollForward(header, tip)
209
+ OB->>EB: publish ChainsyncEvent(header)
210
+ EB->>LS: handleEventChainsyncBlockHeader()
211
+ LS->>LS: verify header crypto (VRF/KES/OpCert)
212
+ LS->>ChM: enqueue header in chain.headers[]
213
+
214
+ Note over Peer,DB: Stage 2 — Full Block Retrieval (BlockFetch)
215
+ LS->>OB: blockfetchClientBlockRange(start, end)
216
+ OB->>Peer: RequestRange(start, end)
217
+ Peer->>OB: Block(type, cbor) × N
218
+ OB->>EB: publish BlockfetchEvent(block)
219
+ EB->>LS: handleEventBlockfetchBlock()
220
+ LS->>LS: decode CBOR, match to queued header
221
+
222
+ Note over Peer,DB: Stage 3 — Block Processing
223
+ OB->>EB: publish BlockfetchEvent(batchDone)
224
+ EB->>LS: handleEventBlockfetchBatchDone()
225
+ LS->>LS: validate transactions (Phase 1 + Phase 2)
226
+ LS->>LS: update UTXO set, process certs & governance
227
+ LS->>LS: compute epoch nonce contributions
228
+
229
+ Note over Peer,DB: Stage 4 — Persistence
230
+ LS->>ChM: chain.AddBlocks(batch) — 50 blocks max
231
+ ChM->>DB: blob.SetBlock(slot, hash, cbor)
232
+ ChM->>DB: metadata: UTxOs, txs, certs, governance
233
+ ChM->>EB: publish ChainUpdateEvent
234
+ LS->>EB: publish BlockEvent, TransactionEvent per tx
235
+
236
+ Note over Peer,DB: Rollback Path
237
+ Peer->>OB: RollBackward(point)
238
+ OB->>EB: publish ChainsyncEvent(rollback)
239
+ EB->>LS: handleEventChainsyncRollback()
240
+ LS->>ChM: chain.Rollback(point)
241
+ ChM->>DB: delete blocks/txs after point
242
+ ChM->>DB: restore account/pool/DRep state
243
+ LS->>EB: publish TransactionEvent(rollback: true) per tx
244
+ ```
245
+
246
+ ### Peer-to-Peer Networking
247
+
248
+ Connection lifecycle, protocol multiplexing, and peer governance.
249
+
250
+ ```mermaid
251
+ graph TB
252
+ subgraph "Peer Governor"
253
+ PG["PeerGovernor"]
254
+ Topo["Topology Config"]
255
+ Gossip["PeerSharing<br/>(gossip)"]
256
+ LedgerPeers["Ledger Peers<br/>(SPO relays)"]
257
+ Score["Peer Scoring"]
258
+ end
259
+
260
+ subgraph "Connection Manager"
261
+ Listeners["TCP Listeners<br/>N2N :3001 / N2C"]
262
+ Outbound["Outbound Dialer"]
263
+ ConnTrack["Connection Tracking<br/>per-IP limits, rate limiting"]
264
+ Recycle["Stall Recycler"]
265
+ end
266
+
267
+ subgraph "Ouroboros Multiplexer"
268
+ direction TB
269
+ subgraph "Node-to-Node (N2N)"
270
+ CSc["ChainSync<br/>client + server"]
271
+ BFc["BlockFetch<br/>client + server"]
272
+ TXs["TxSubmission2<br/>bidirectional"]
273
+ KA["KeepAlive"]
274
+ PS["PeerSharing<br/>client + server"]
275
+ Leios["LeiosFetch / Notify<br/>(experimental)"]
276
+ end
277
+ subgraph "Node-to-Client (N2C)"
278
+ CSn2c["ChainSync<br/>server"]
279
+ LSQ["LocalStateQuery<br/>server"]
280
+ LTM["LocalTxMonitor<br/>server"]
281
+ LTS["LocalTxSubmission<br/>server"]
282
+ end
283
+ end
284
+
285
+ subgraph "Chain Selection"
286
+ CSel["ChainSelector"]
287
+ Tips["Peer Tip Tracker"]
288
+ end
289
+
290
+ Topo --> PG
291
+ Gossip --> PG
292
+ LedgerPeers --> PG
293
+ PG -->|"connect request"| Outbound
294
+ Score -->|"promote / demote"| PG
295
+
296
+ Outbound -->|"TCP dial"| ConnTrack
297
+ Listeners -->|"TCP accept"| ConnTrack
298
+
299
+ ConnTrack -->|"handshake"| CSc & BFc & TXs & KA & PS
300
+ ConnTrack -->|"N2C handshake"| CSn2c & LSQ & LTM & LTS
301
+
302
+ CSc -->|"headers"| CSel
303
+ CSel -->|"best peer"| Tips
304
+ Tips -->|"switch chain"| CSc
305
+
306
+ Recycle -->|"force reconnect"| ConnTrack
307
+ ```
308
+
309
+ ### Block Forging
310
+
311
+ The block production pipeline from leader election through broadcast.
312
+
313
+ ```mermaid
314
+ sequenceDiagram
315
+ participant SC as SlotClock
316
+ participant LE as LeaderElection
317
+ participant BF as BlockForger
318
+ participant BB as BlockBuilder
319
+ participant MP as Mempool
320
+ participant LS as LedgerState
321
+ participant ChM as ChainManager
322
+ participant EB as EventBus
323
+
324
+ Note over SC,EB: Epoch Preparation
325
+ EB->>LE: EpochTransitionEvent(newEpoch)
326
+ LE->>LS: GetStakeDistribution("go" snapshot, epoch-2)
327
+ LE->>LE: compute VRF schedule for new epoch
328
+
329
+ Note over SC,EB: Per-Slot Forging Loop
330
+ SC->>BF: slot tick
331
+ BF->>LE: ShouldProduceBlock(slot)?
332
+ alt not leader
333
+ LE-->>BF: false
334
+ Note over BF: skip slot
335
+ else is leader
336
+ LE-->>BF: true (vrfProof, vrfOutput)
337
+ BF->>BF: check sync tolerance (tip not stale)
338
+ BF->>BB: BuildBlock(slot, kesPeriod)
339
+ BB->>MP: drain eligible transactions
340
+ BB->>LS: validate each tx against current state
341
+ BB->>BB: assemble block body + header
342
+ BB->>BB: sign with KES key, attach VRF proof
343
+ BB-->>BF: block + CBOR
344
+ BF->>ChM: AddBlock(forgedBlock)
345
+ ChM->>EB: publish ChainUpdateEvent
346
+ BF->>EB: publish BlockForgedEvent
347
+ end
348
+
349
+ Note over SC,EB: Slot Battle Detection
350
+ EB->>BF: ChainUpdateEvent(externalBlock at same slot)
351
+ BF->>BF: SlotTracker detects competing block
352
+ BF->>EB: publish SlotBattleEvent
353
+ ```
354
+
37
355
  ## Directory Structure
38
356
 
39
357
  ```
package/README.md CHANGED
@@ -130,7 +130,7 @@ docker run -p 3001:3001 \
130
130
  ghcr.io/blinklabs-io/dingo
131
131
  ```
132
132
 
133
- The image is based on Debian bookworm-slim and includes `cardano-cli`, `mithril-client`, `nview`, and `txtop`. The Dockerfile sets `CARDANO_DATABASE_PATH=/data/db` and `CARDANO_SOCKET_PATH=/ipc/dingo.socket`, overriding the local defaults of `.dingo` and `dingo.socket` — the volume mounts above map to these container paths.
133
+ The image is based on Debian bookworm-slim and includes `cardano-cli`, `nview`, and `txtop`. Mithril snapshot support is built into dingo natively (`dingo mithril sync`). The Dockerfile sets `CARDANO_DATABASE_PATH=/data/db` and `CARDANO_SOCKET_PATH=/ipc/dingo.socket`, overriding the local defaults of `.dingo` and `dingo.socket` — the volume mounts above map to these container paths.
134
134
 
135
135
  | Port | Service |
136
136
  |------|---------|
@@ -213,16 +213,7 @@ See `dingo.yaml.example` for the full set of configuration options.
213
213
 
214
214
  ## Fast Bootstrapping with Mithril
215
215
 
216
- Instead of syncing from genesis (which can take days on mainnet), you can bootstrap Dingo using a [Mithril](https://mithril.network/) snapshot. There are two approaches depending on your use case:
217
-
218
- | Approach | Command | Use Case | Data Available |
219
- |----------|---------|----------|---------------|
220
- | `dingo sync --mithril` | `dingo sync --mithril` | Consensus nodes, relays | Current ledger state + all blocks |
221
- | `mithril-client` + `dingo load` | Manual download + load | Indexers, API nodes | Full historical transaction/certificate data |
222
-
223
- ### Option 1: `dingo sync --mithril` (Recommended for Consensus)
224
-
225
- Dingo has a built-in Mithril client that handles download, extraction, and import automatically. This is the fastest way to get a node running.
216
+ Instead of syncing from genesis (which can take days on mainnet), you can bootstrap Dingo using a [Mithril](https://mithril.network/) snapshot. Dingo has a built-in Mithril client that handles download, extraction, and import automatically. This is the fastest way to get a node running.
226
217
 
227
218
  ```bash
228
219
  # Bootstrap from Mithril and start syncing
@@ -264,71 +255,7 @@ Performance (preview network, ~4M blocks):
264
255
  | Load blocks into blob store | ~36 min |
265
256
  | Total | ~50 min |
266
257
 
267
- ### Option 2: `mithril-client` + `dingo load` (For Indexers/API Nodes)
268
-
269
- If you need full historical data (transaction lookups, certificate queries, datum/script resolution), use the external `mithril-client` to download the snapshot and then load it with `dingo load`, which processes every block through the full indexing pipeline.
270
-
271
- #### Prerequisites
272
-
273
- Install the `mithril-client` CLI from [Mithril releases](https://github.com/input-output-hk/mithril/releases):
274
-
275
- ```bash
276
- # Detect OS and architecture
277
- OS=$(uname -s)
278
- ARCH=$(uname -m)
279
-
280
- case "$OS" in
281
- Linux)
282
- case "$ARCH" in
283
- x86_64) MITHRIL_PLATFORM="x64-linux-musl" ;;
284
- aarch64|arm64) MITHRIL_PLATFORM="arm64-linux-musl" ;;
285
- *) echo "Unsupported architecture: $ARCH"; exit 1 ;;
286
- esac
287
- ;;
288
- Darwin)
289
- case "$ARCH" in
290
- x86_64) MITHRIL_PLATFORM="x64-macos" ;;
291
- arm64) MITHRIL_PLATFORM="arm64-macos" ;;
292
- *) echo "Unsupported architecture: $ARCH"; exit 1 ;;
293
- esac
294
- ;;
295
- *) echo "Unsupported OS: $OS (see Mithril releases for Windows)"; exit 1 ;;
296
- esac
297
-
298
- MITHRIL_VERSION="2506.0"
299
- curl -L "https://github.com/input-output-hk/mithril/releases/download/${MITHRIL_VERSION}/mithril-${MITHRIL_VERSION}-${MITHRIL_PLATFORM}.tar.gz" -o mithril.tar.gz
300
- tar -xzf mithril.tar.gz
301
- sudo mv mithril-client /usr/local/bin/
302
- rm mithril.tar.gz
303
- ```
304
-
305
- For Windows, download the appropriate binary from the [Mithril releases page](https://github.com/input-output-hk/mithril/releases).
306
-
307
- #### Bootstrap Workflow
308
-
309
- ```bash
310
- # Set network (CARDANO_NETWORK is used by dingo, not mithril-client)
311
- export CARDANO_NETWORK=preview
312
- # AGGREGATOR_ENDPOINT is used by mithril-client
313
- export AGGREGATOR_ENDPOINT=https://aggregator.pre-release-preview.api.mithril.network/aggregator
314
-
315
- # For mainnet:
316
- # export AGGREGATOR_ENDPOINT=https://aggregator.release-mainnet.api.mithril.network/aggregator
317
-
318
- # Download snapshot (uses AGGREGATOR_ENDPOINT)
319
- mithril-client cardano-db download --download-dir /tmp/mithril-snapshot
320
-
321
- # Load into Dingo (uses CARDANO_NETWORK for chain config)
322
- ./dingo load /tmp/mithril-snapshot/db/immutable
323
-
324
- # Clean up snapshot
325
- rm -rf /tmp/mithril-snapshot
326
-
327
- # Start Dingo
328
- ./dingo -n preview serve
329
- ```
330
-
331
- This creates full historical data including transaction records, certificate history, witness data, scripts, datums, and governance votes -- everything needed for rich query APIs.
258
+ For indexers and API nodes that need full historical data (transaction lookups, certificate queries, datum/script resolution), configure the storage mode to `api` and `dingo mithril sync` will automatically backfill historical metadata after loading the snapshot.
332
259
 
333
260
  ### Disk Space Requirements
334
261
 
package/RELEASE_NOTES.md CHANGED
@@ -1,6 +1,38 @@
1
1
  # Release Notes
2
2
 
3
3
 
4
+ ## v0.25.0 (March 12, 2026)
5
+
6
+ **Title:** Trusted replay verification and peer counts
7
+
8
+ **Date:** March 12, 2026
9
+
10
+ **Version:** v0.25.0
11
+
12
+ Hi folks! Here’s what we shipped in v0.25.0.
13
+
14
+ ### ✨ What's New
15
+
16
+ - **Trusted chain verification:** Startup and recovery runs are more rock-solid because your node can now verify the chain from a trusted, immutable replay path.
17
+
18
+ ### 💪 Improvements
19
+
20
+ - **Peer metrics accuracy:** Peer limits and metrics are more accurate because local client connections are now tracked separately.
21
+
22
+ ### 🔧 Fixes
23
+
24
+ - **Mithril key defaults (Docker):** Docker deployments are less error-prone because the correct Mithril genesis verification key is now picked up automatically when you don’t provide one.
25
+
26
+ ### 📋 What You Need to Know
27
+
28
+ - **Peer counts:** If you rely on peer-count metrics or peer-limit tuning, expect local client connections to no longer be included in those counts.
29
+
30
+ ### 🙏 Thank You
31
+
32
+ Thank you for trying!
33
+
34
+ ---
35
+
4
36
  ## v0.24.1 (March 12, 2026)
5
37
 
6
38
  **Title:** Stability and polish
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinklabs/dingo",
3
- "version": "0.25.0",
3
+ "version": "0.25.1",
4
4
  "description": "Dingo is a Cardano blockchain data node",
5
5
  "main": "index.js",
6
6
  "bin": {