@blinklabs/dingo 0.46.4 → 0.81.0

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 DELETED
@@ -1,1157 +0,0 @@
1
- # Architecture
2
-
3
- Dingo is a high-performance Cardano blockchain node implementation in Go. This document describes its architecture, core components, and design patterns.
4
-
5
- ## Table of Contents
6
-
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)
14
- - [Directory Structure](#directory-structure)
15
- - [Core Node Structure](#core-node-structure)
16
- - [Event-Driven Communication](#event-driven-communication)
17
- - [Storage Architecture](#storage-architecture)
18
- - [Blockchain State Management](#blockchain-state-management)
19
- - [Chain Management](#chain-management)
20
- - [Network and Protocol Handling](#network-and-protocol-handling)
21
- - [Peer Governance](#peer-governance)
22
- - [Transaction Mempool](#transaction-mempool)
23
- - [Block Production](#block-production)
24
- - [Mithril Bootstrap](#mithril-bootstrap)
25
- - [External Interfaces](#external-interfaces)
26
- - [Design Patterns](#design-patterns)
27
- - [Threading and Concurrency](#threading-and-concurrency)
28
- - [Configuration](#configuration)
29
- - [Stake Snapshots](#stake-snapshots)
30
-
31
- ## Overview
32
-
33
- Dingo's architecture is built on several key principles:
34
-
35
- 1. Modular component design using dependency injection and composition
36
- 2. Event-driven communication via EventBus rather than direct coupling
37
- 3. Pluggable storage backends with a dual-layer database architecture (blob + metadata)
38
- 4. Full Ouroboros protocol support for Node-to-Node and Node-to-Client
39
- 5. Multi-peer chain synchronization with Ouroboros Praos chain selection
40
- 6. Block production with VRF leader election and stake snapshots
41
- 7. Graceful shutdown with phased resource cleanup
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 "External Interfaces"
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
-
355
- ## Directory Structure
356
-
357
- ```
358
- dingo/
359
- ├── cmd/dingo/ # CLI entry points
360
- │ ├── main.go # Cobra CLI setup, plugin management
361
- │ ├── serve.go # Node server command
362
- │ ├── load.go # Block loading from ImmutableDB/Mithril
363
- │ ├── mithril.go # Mithril bootstrap subcommand
364
- │ └── version.go # Version information
365
- ├── chain/ # Blockchain state and validation
366
- │ ├── chain.go # Chain struct, block management
367
- │ ├── manager.go # ChainManager, fork handling
368
- │ ├── event.go # Chain events (update, fork)
369
- │ ├── iter.go # ChainIterator for sequential block access
370
- │ └── errors.go # Chain-specific errors
371
- ├── chainselection/ # Multi-peer chain comparison
372
- │ ├── selector.go # ChainSelector struct
373
- │ ├── comparison.go # Ouroboros Praos chain selection rules
374
- │ ├── event.go # Selection events
375
- │ ├── peer_tip.go # Peer tip tracking
376
- │ └── vrf.go # VRF verification
377
- ├── chainsync/ # Block synchronization protocol state
378
- │ └── chainsync.go # Multi-client sync state, stall detection
379
- ├── connmanager/ # Network connection lifecycle
380
- │ ├── connection_manager.go
381
- │ └── event.go # Connection events
382
- ├── database/ # Storage abstraction layer
383
- │ ├── database.go # Database struct, dual-layer design
384
- │ ├── cbor_cache.go # TieredCborCache implementation
385
- │ ├── cbor_offset.go # Offset-based CBOR references
386
- │ ├── hot_cache.go # Hot cache for frequently accessed data
387
- │ ├── block_lru_cache.go # Block-level LRU cache
388
- │ ├── immutable/ # ImmutableDB chunk reader
389
- │ ├── models/ # Database models
390
- │ ├── types/ # Database types
391
- │ ├── sops/ # Storage operations
392
- │ └── plugin/ # Storage plugin system
393
- │ ├── plugin.go # Plugin registry and interfaces
394
- │ ├── blob/ # Blob storage plugins
395
- │ │ ├── badger/ # Badger (default local storage)
396
- │ │ ├── aws/ # AWS S3
397
- │ │ └── gcs/ # Google Cloud Storage
398
- │ └── metadata/ # Metadata plugins
399
- │ ├── sqlite/ # SQLite (default)
400
- │ ├── postgres/# PostgreSQL
401
- │ └── mysql/ # MySQL
402
- ├── event/ # Event bus for decoupled communication
403
- │ ├── event.go # EventBus, async delivery
404
- │ ├── epoch.go # Epoch transition events
405
- │ └── metrics.go # Event metrics
406
- ├── ledger/ # Ledger state, validation, block production
407
- │ ├── state.go # LedgerState, UTXO tracking
408
- │ ├── view.go # Ledger view queries
409
- │ ├── queries.go # State queries
410
- │ ├── validation.go # Transaction validation (Phase 1 UTXO rules)
411
- │ ├── verify_header.go # Block header validation (VRF/KES/OpCert)
412
- │ ├── chainsync.go # Epoch nonce calculation, rollback handling
413
- │ ├── candidate_nonce.go # Candidate nonce computation
414
- │ ├── certs.go # Certificate processing
415
- │ ├── governance.go # Governance action processing
416
- │ ├── delta.go # State delta tracking
417
- │ ├── block_event.go # Block event processing
418
- │ ├── slot_clock.go # Wall-clock slot timing
419
- │ ├── metrics.go # Ledger metrics
420
- │ ├── peer_provider.go # Ledger-based peer discovery
421
- │ ├── era_summary.go # Era transition handling
422
- │ ├── eras/ # Era-specific validation rules
423
- │ │ ├── byron.go # Byron era
424
- │ │ ├── shelley.go # Shelley era
425
- │ │ ├── allegra.go # Allegra era
426
- │ │ ├── mary.go # Mary era
427
- │ │ ├── alonzo.go # Alonzo era
428
- │ │ ├── babbage.go # Babbage era
429
- │ │ └── conway.go # Conway era
430
- │ ├── forging/ # Block production
431
- │ │ ├── forger.go # BlockForger, slot-based forging loop
432
- │ │ ├── builder.go # DefaultBlockBuilder, block assembly
433
- │ │ ├── keys.go # PoolCredentials (VRF/KES/OpCert)
434
- │ │ ├── slot_tracker.go # Slot battle detection
435
- │ │ ├── events.go # Forging events
436
- │ │ └── metrics.go # Forging metrics
437
- │ ├── leader/ # Leader election
438
- │ │ ├── election.go # Ouroboros Praos leader checks
439
- │ │ └── schedule.go # Epoch leader schedule computation
440
- │ └── snapshot/ # Stake snapshot management
441
- │ ├── manager.go # Snapshot manager, event-driven capture
442
- │ ├── calculator.go# Stake distribution calculation
443
- │ └── rotation.go # Mark/Set/Go rotation
444
- ├── ledgerstate/ # Low-level ledger state import
445
- │ ├── cbor_decode.go # CBOR decoding for large structures
446
- │ ├── mempack.go # Memory-packed state representation
447
- │ ├── snapshot.go # Snapshot parsing
448
- │ ├── import.go # Ledger state import
449
- │ ├── utxo.go # UTXO state handling
450
- │ └── certstate.go # Certificate state handling
451
- ├── mempool/ # Transaction pool
452
- │ ├── mempool.go # Mempool, validation, capacity
453
- │ └── consumer.go # Per-consumer transaction tracking
454
- ├── ouroboros/ # Ouroboros protocol handlers
455
- │ ├── ouroboros.go # N2N and N2C protocol management
456
- │ ├── chainsync.go # Chain synchronization
457
- │ ├── blockfetch.go # Block fetching
458
- │ ├── txsubmission.go # TX submission (N2N)
459
- │ ├── localtxsubmission.go # TX submission (N2C)
460
- │ ├── localtxmonitor.go # Mempool monitoring
461
- │ ├── localstatequery.go # Ledger queries
462
- │ └── peersharing.go # Peer discovery
463
- ├── peergov/ # Peer selection and governance
464
- │ ├── peergov.go # PeerGovernor
465
- │ ├── churn.go # Peer rotation
466
- │ ├── quotas.go # Per-source quotas
467
- │ ├── score.go # Peer scoring
468
- │ ├── ledger.go # Ledger-based peer discovery
469
- │ └── event.go # Peer events
470
- ├── topology/ # Network topology handling
471
- │ └── topology.go # Topology configuration
472
- ├── blockfrost/ # Blockfrost-compatible REST API
473
- │ ├── blockfrost.go # Server lifecycle
474
- │ ├── adapter.go # Node state adapter
475
- │ ├── handlers.go # HTTP handlers
476
- │ ├── pagination.go # Cursor-based pagination
477
- │ └── types.go # API response types
478
- ├── mesh/ # Mesh (Rosetta) API
479
- │ ├── mesh.go # Server lifecycle
480
- │ ├── network.go # /network/* endpoints
481
- │ ├── account.go # /account/* endpoints
482
- │ ├── block.go # /block/* endpoints
483
- │ ├── construction.go # /construction/* endpoints
484
- │ ├── mempool_api.go # /mempool/* endpoints
485
- │ ├── operations.go # Cardano operation mapping
486
- │ └── convert.go # Type conversion utilities
487
- ├── utxorpc/ # UTxO RPC gRPC server
488
- │ ├── utxorpc.go # Server setup
489
- │ ├── query.go # Query service
490
- │ ├── submit.go # Submit service
491
- │ ├── sync.go # Sync service
492
- │ └── watch.go # Watch service
493
- ├── bark/ # Bark Dingo-to-Dingo C2 and archive protocol
494
- │ ├── bark.go # Bark server lifecycle and transport setup
495
- │ ├── archive.go # Archive service interface
496
- │ └── blob.go # Remote archive blob adapter with security window
497
- ├── mithril/ # Mithril snapshot bootstrap
498
- │ ├── bootstrap.go # Bootstrap orchestration
499
- │ ├── client.go # Mithril aggregator client
500
- │ └── download.go # Snapshot download and extraction
501
- ├── keystore/ # Key management
502
- │ ├── keystore.go # Key store interface
503
- │ ├── keyfile.go # Key file parsing
504
- │ ├── keyfile_unix.go # Unix file permissions
505
- │ ├── keyfile_windows.go # Windows ACL permissions
506
- │ └── evolution.go # KES key evolution
507
- ├── config/cardano/ # Embedded Cardano network configurations
508
- ├── internal/
509
- │ ├── config/ # Configuration parsing
510
- │ ├── integration/ # Integration tests
511
- │ ├── node/ # Node orchestration (CLI wiring)
512
- │ │ ├── node.go # Run(), signal handling, metrics server
513
- │ │ └── load.go # Block loading implementation
514
- │ ├── test/ # Test utilities
515
- │ │ ├── conformance/ # Amaru conformance tests
516
- │ │ ├── devnet/ # DevNet end-to-end tests
517
- │ │ └── testutil/ # Shared test helpers
518
- │ └── version/ # Version information
519
- ├── node.go # Node struct definition, Run(), shutdown
520
- ├── config.go # Configuration management (functional options)
521
- └── tracing.go # OpenTelemetry tracing
522
- ```
523
-
524
- ## Core Node Structure
525
-
526
- The `Node` struct (defined in `node.go`) orchestrates all major components:
527
-
528
- ```go
529
- type Node struct {
530
- connManager *connmanager.ConnectionManager // Network connections
531
- peerGov *peergov.PeerGovernor // Peer selection/governance
532
- chainsyncState *chainsync.State // Multi-peer sync state
533
- chainSelector *chainselection.ChainSelector // Chain comparison
534
- eventBus *event.EventBus // Event routing
535
- mempool *mempool.Mempool // Transaction pool
536
- chainManager *chain.ChainManager // Blockchain state
537
- db *database.Database // Storage layer
538
- ledgerState *ledger.LedgerState // UTXO/state tracking
539
- snapshotMgr *snapshot.Manager // Stake snapshot capture
540
- utxorpc *utxorpc.Utxorpc // UTxO RPC server
541
- bark *bark.Bark // Bark C2/archive server
542
- blockfrostAPI *blockfrost.Blockfrost // Blockfrost REST API
543
- meshAPI *mesh.Server // Mesh (Rosetta) API
544
- ouroboros *ouroboros.Ouroboros // Protocol handlers
545
- blockForger *forging.BlockForger // Block production
546
- leaderElection *leader.Election // Slot leader checks
547
- }
548
- ```
549
-
550
- ### Initialization Flow
551
-
552
- When `Node.Run()` is called, components are initialized in this order:
553
-
554
- ```
555
- 1. EventBus creation
556
- 2. Database loading (blob + metadata plugins)
557
- 3. ChainManager initialization
558
- 4. Ouroboros protocol handler creation
559
- 5. LedgerState creation (UTXO tracking, validation)
560
- 6. Bark remote archive adapter (if configured)
561
- 7. LedgerState start
562
- 8. Snapshot manager start (captures genesis snapshot)
563
- 9. Mempool setup
564
- 10. ChainsyncState (multi-client tracking, stall detection)
565
- 11. ChainSelector (Ouroboros Praos chain comparison)
566
- 12. ConnectionManager (listeners)
567
- 13. Stalled client recycler (background goroutine)
568
- 14. PeerGovernor (topology + churn + ledger peers)
569
- 15. UTxO RPC server (if port configured)
570
- 16. Bark C2/archive server (if port configured)
571
- 17. Blockfrost API (if port configured)
572
- 18. Mesh API (if port configured)
573
- 19. Block forger + leader election (if block producer mode)
574
- 20. Wait for shutdown signal
575
- ```
576
-
577
- ### Shutdown Flow
578
-
579
- Graceful shutdown proceeds in phases:
580
-
581
- ```
582
- Phase 1: Stop accepting new work
583
- Block forger, leader election, chain selector,
584
- peer governor, snapshot manager, UTxO RPC,
585
- Bark C2/archive server, Blockfrost API, Mesh API
586
-
587
- Phase 2: Drain and close connections
588
- Mempool, ConnectionManager
589
-
590
- Phase 3: Flush state and close database
591
- LedgerState, Database
592
-
593
- Phase 4: Cleanup resources
594
- Registered shutdown functions, EventBus
595
- ```
596
-
597
- ## Event-Driven Communication
598
-
599
- Components communicate via the `EventBus` (`event/event.go`) rather than direct coupling:
600
-
601
- ```
602
- Publisher ---publish---> EventBus ---deliver---> Subscribers
603
- |
604
- | async
605
- v
606
- Worker Pool
607
- (4 workers)
608
- ```
609
-
610
- ### Key Event Types
611
-
612
- All event types follow the `subsystem.snake_case_name` convention.
613
-
614
- | Event | Source | Purpose |
615
- |-------|--------|---------|
616
- | `chain.update` | ChainManager | Block added to chain |
617
- | `chain.fork_detected` | ChainManager | Fork detected |
618
- | `chainselection.peer_tip_update` | ChainSelector | Peer tip updated |
619
- | `chainselection.chain_switch` | ChainSelector | Active peer changed |
620
- | `chainselection.selection` | ChainSelector | Chain selection made |
621
- | `chainselection.peer_evicted` | ChainSelector | Peer evicted |
622
- | `chainsync.client_added` | ChainsyncState | Client tracking added |
623
- | `chainsync.client_removed` | ChainsyncState | Client tracking removed |
624
- | `chainsync.client_synced` | ChainsyncState | Client caught up |
625
- | `chainsync.client_stalled` | ChainsyncState | Client stall detected |
626
- | `chainsync.fork_detected` | ChainsyncState | Chainsync fork detected |
627
- | `chainsync.client_remove_requested` | Node | Stalled client removal |
628
- | `chainsync.resync` | LedgerState | Chainsync resync request |
629
- | `connmanager.inbound_conn` | ConnManager | Inbound connection |
630
- | `connmanager.conn_closed` | ConnManager | Connection closed |
631
- | `connmanager.connection_recycle_requested` | ConnManager | Connection recycling |
632
- | `mempool.add_tx` | Mempool | Transaction added |
633
- | `mempool.remove_tx` | Mempool | Transaction removed |
634
- | `ledger.block` | LedgerState | Block applied or rolled back |
635
- | `ledger.tx` | LedgerState | Transaction processed |
636
- | `ledger.error` | LedgerState | Ledger error occurred |
637
- | `ledger.blockfetch` | Ouroboros | Block fetch event received |
638
- | `ledger.chainsync` | Ouroboros | Chainsync event received |
639
- | `ledger.pool_restored` | LedgerState | Pool state restored after rollback |
640
- | `epoch.transition` | LedgerState | Epoch boundary crossed |
641
- | `hardfork.transition` | LedgerState | Hard fork transition |
642
- | `block.forged` | BlockForger | Block successfully forged |
643
- | `forging.slot_battle` | SlotTracker | Competing blocks at same slot |
644
- | `peergov.outbound_conn` | PeerGov | Outbound connection initiated |
645
- | `peergov.peer_demoted` | PeerGov | Peer demoted |
646
- | `peergov.peer_promoted` | PeerGov | Peer promoted |
647
- | `peergov.peer_removed` | PeerGov | Peer removed |
648
- | `peergov.peer_added` | PeerGov | Peer added |
649
- | `peergov.peer_churn` | PeerGov | Peer rotation event |
650
- | `peergov.quota_status` | PeerGov | Quota status update |
651
- | `peergov.bootstrap_exited` | PeerGov | Exited bootstrap mode |
652
- | `peergov.bootstrap_recovery` | PeerGov | Bootstrap recovery |
653
-
654
- ### EventBus Features
655
-
656
- - Asynchronous delivery via worker pool (4 workers, 1000-entry queue)
657
- - Buffered channels with timeout protection to prevent blocking
658
- - Prometheus metrics for event delivery tracking and latency
659
-
660
- ## Storage Architecture
661
-
662
- Dingo uses a dual-layer storage architecture with pluggable backends:
663
-
664
- ```
665
- Database
666
- -------------------------------------------------
667
- | Blob Store | Metadata Store |
668
- | (blocks, UTxOs, txs) | (indexes, state)|
669
- -------------------------------------------------
670
- | Plugins: | Plugins: |
671
- | - Badger (default) | - SQLite (default)|
672
- | - AWS S3 | - PostgreSQL |
673
- | - Google Cloud Storage | - MySQL |
674
- -------------------------------------------------
675
- ```
676
-
677
- ### Storage Modes
678
-
679
- Dingo supports two storage modes, configured via `storageMode`:
680
-
681
- - `core` (default): Minimal storage for chain following and block production.
682
- - `api`: Extended storage with transaction indexes, address lookups, and asset tracking. Required when any client-facing API server (Blockfrost, Mesh, UTxO RPC) is enabled. Bark is a separate Dingo-to-Dingo protocol and is not part of that API surface.
683
-
684
- ### Tiered CBOR Cache
685
-
686
- Instead of storing full CBOR data redundantly, Dingo uses offset-based references with a tiered cache:
687
-
688
- ```
689
- CBOR Data Request
690
- |
691
- v
692
- Tier 1: Hot Cache (in-memory)
693
- - UTxO entries: configurable count (HotUtxoEntries)
694
- - Transaction entries: configurable count + byte limit
695
- - O(1) access, LRU eviction
696
- | miss
697
- v
698
- Tier 2: Block LRU Cache
699
- - Recently accessed blocks with pre-computed indexes
700
- - Fast extraction without blob store access
701
- | miss
702
- v
703
- Tier 3: Cold Extraction
704
- - Fetch block from blob store
705
- - Extract CBOR at stored offset
706
- ```
707
-
708
- ### CborOffset Structure
709
-
710
- Each CBOR reference is a fixed 52-byte `CborOffset` struct with magic prefix:
711
-
712
- | Field | Size | Purpose |
713
- |-------|------|---------|
714
- | Magic | 4 bytes | "DOFF" prefix to identify offset storage |
715
- | BlockSlot | 8 bytes | Block slot number |
716
- | BlockHash | 32 bytes | Block hash |
717
- | ByteOffset | 4 bytes | Offset within block CBOR |
718
- | ByteLength | 4 bytes | Length of CBOR data |
719
-
720
- ### Plugin System
721
-
722
- Plugins are registered via a global registry (`database/plugin/plugin.go`):
723
-
724
- ```go
725
- plugin.SetPluginOption() -> plugin.GetPlugin() -> plugin.Start() -> Use interface
726
- ```
727
-
728
- Interfaces:
729
- - `BlobStore` - Block/transaction storage operations
730
- - `MetadataStore` - Index and query operations
731
-
732
- ### Database Models
733
-
734
- Key models in `database/models/`:
735
-
736
- | Model | Purpose |
737
- |-------|---------|
738
- | `Block` | Block metadata (slot, hash, height, era) |
739
- | `Transaction` | Transaction records |
740
- | `Utxo` | UTXO set entries |
741
- | `Account` | Stake account registrations and delegations |
742
- | `Pool` | Stake pool registrations |
743
- | `Drep` | DRep registrations |
744
- | `Epoch` | Epoch metadata and nonces |
745
- | `PoolStakeSnapshot` | Per-pool stake at epoch boundary |
746
- | `EpochSummary` | Network-wide aggregates per epoch |
747
- | `BackfillCheckpoint` | Mithril backfill progress tracking |
748
- | `NetworkState` | Network-wide state tracking |
749
- | `GovernanceAction` | Governance proposals |
750
- | `CommitteeMember` | Constitutional committee members |
751
-
752
- ## Blockchain State Management
753
-
754
- The `LedgerState` (`ledger/state.go`) manages UTXO tracking and validation:
755
-
756
- ```
757
- LedgerState
758
- -------------------------------------------------
759
- | - UTXO tracking and lookup |
760
- | - Protocol parameter management |
761
- | - Certificate processing (pools, stakes, DReps)|
762
- | - Transaction validation (Phase 1: UTXO rules) |
763
- | - Plutus script execution (Phase 2) |
764
- | - Block header validation (VRF/KES/OpCert) |
765
- | - Epoch nonce computation |
766
- | - Governance action processing |
767
- | - State restoration on rollback |
768
- | - Ledger-based peer discovery |
769
- -------------------------------------------------
770
- | Database Worker Pool |
771
- | - Async database operations |
772
- | - Configurable pool size (default: 5 workers) |
773
- | - Fire-and-forget or result-waiting |
774
- -------------------------------------------------
775
- ```
776
-
777
- ### Era-Specific Validation
778
-
779
- The `ledger/eras/` package provides era-specific validation rules for each Cardano era (Byron through Conway). Each era implements protocol parameter extraction, fee calculation, and era-specific transaction rules.
780
-
781
- ### Block Header Validation
782
-
783
- `ledger/verify_header.go` performs cryptographic validation of block headers:
784
- - VRF proof verification against the epoch nonce
785
- - KES signature verification with period checks
786
- - Operational certificate chain validation
787
- - Slot leader eligibility checking
788
-
789
- ### Epoch Nonce Computation
790
-
791
- `ledger/chainsync.go` and `ledger/candidate_nonce.go` implement the Ouroboros Praos nonce evolution:
792
- - Evolving nonce: accumulated from each block's VRF output
793
- - Candidate nonce: frozen at the stability window cutoff
794
- - Epoch nonce: derived from candidate nonce and previous epoch's last block hash
795
-
796
- ### Ledger View
797
-
798
- The `LedgerView` interface provides query access to ledger state:
799
- - UTXO lookups by address or output reference
800
- - Protocol parameter queries
801
- - Stake distribution queries
802
- - Account registration checks
803
-
804
- ## Chain Management
805
-
806
- The `ChainManager` (`chain/manager.go`) manages multiple chains:
807
-
808
- ```
809
- ChainManager
810
- -------------------------------------------------
811
- | Primary Chain |
812
- | Persistent chain loaded from database |
813
- | |
814
- | Fork Chains |
815
- | Temporary chains for peer synchronization |
816
- | |
817
- | Block Cache |
818
- | In-memory cache for quick access |
819
- | |
820
- | Rollback Support |
821
- | Reverts chain to previous point (up to K |
822
- | blocks), emits rollback events, restores |
823
- | account/pool/DRep state |
824
- -------------------------------------------------
825
- ```
826
-
827
- ### Chain Selection (Ouroboros Praos)
828
-
829
- The `ChainSelector` (`chainselection/`) implements Ouroboros Praos rules:
830
-
831
- 1. Higher block number wins (longer chain)
832
- 2. At equal block number, lower slot wins (denser chain)
833
-
834
- The selector tracks tips from all connected peers and switches the active chainsync connection when a better chain is found.
835
-
836
- ## Network and Protocol Handling
837
-
838
- ### Ouroboros Protocol Stack
839
-
840
- The `Ouroboros` struct (`ouroboros/ouroboros.go`) manages all protocol handlers:
841
-
842
- ```
843
- Ouroboros Protocols
844
- -------------------------------------------
845
- | Node-to-Node (N2N) | Node-to-Client (N2C)|
846
- |---------------------|---------------------|
847
- | ChainSync | ChainSync |
848
- | Block sync | Wallet sync |
849
- | | |
850
- | BlockFetch | LocalTxMonitor |
851
- | Block retrieval | Mempool queries |
852
- | | |
853
- | TxSubmission2 | LocalTxSubmission |
854
- | Transaction share | Transaction submit|
855
- | | |
856
- | PeerSharing | LocalStateQuery |
857
- | Peer discovery | Ledger queries |
858
- -------------------------------------------
859
- ```
860
-
861
- ### Connection Management
862
-
863
- The `ConnectionManager` (`connmanager/connection_manager.go`) handles connection lifecycle:
864
-
865
- ```
866
- ConnectionManager
867
- -------------------------------------------------
868
- | Inbound Listeners |
869
- | TCP N2N (default: 3001) |
870
- | TCP N2C (configurable) |
871
- | Unix socket N2C |
872
- | |
873
- | Outbound Clients |
874
- | Source port selection |
875
- | |
876
- | Connection Tracking |
877
- | Per-peer connection state |
878
- | Duplex detection (bidirectional connections) |
879
- | Stalled connection recycling |
880
- -------------------------------------------------
881
- ```
882
-
883
- ### Multi-Client Chainsync
884
-
885
- The `chainsync.State` tracks multiple concurrent chainsync clients:
886
- - Configurable max client count
887
- - Stall detection with configurable timeout
888
- - Grace period before recycling stalled connections
889
- - Cooldown to prevent rapid reconnection flapping
890
- - Plateau detection: if the local tip stops advancing while peers are ahead, the active chainsync connection is recycled
891
-
892
- ## Peer Governance
893
-
894
- The `PeerGovernor` (`peergov/peergov.go`) manages peer selection and topology:
895
-
896
- ```
897
- PeerGovernor
898
- -------------------------------------------------
899
- | Peer Targets |
900
- | Known peers: 150 |
901
- | Established peers: 50 |
902
- | Active peers: 20 |
903
- | |
904
- | Per-Source Quotas |
905
- | Topology quota: 3 peers |
906
- | Gossip quota: 12 peers |
907
- | Ledger quota: 5 peers |
908
- | |
909
- | Peer Churn |
910
- | Gossip churn: 5 min interval, 20% |
911
- | Public root churn: 30 min interval, 20% |
912
- | |
913
- | Peer Scoring |
914
- | Performance-based peer ranking |
915
- | |
916
- | Ledger Peer Discovery |
917
- | Discovers peers from stake pool relays |
918
- | Activated after UseLedgerAfterSlot |
919
- | |
920
- | Denied List |
921
- | Prevents reconnection to bad peers |
922
- | (30 min timeout) |
923
- -------------------------------------------------
924
- ```
925
-
926
- ## Transaction Mempool
927
-
928
- The `Mempool` (`mempool/mempool.go`) manages pending transactions:
929
-
930
- ```
931
- Mempool
932
- -------------------------------------------------
933
- | Transaction Management |
934
- | Validation on add (Phase 1 + Phase 2) |
935
- | Capacity limits (configurable) |
936
- | Watermark-based eviction and rejection |
937
- | Automatic purging on chain updates |
938
- | |
939
- | Consumer Tracking |
940
- | Per-consumer state for TX distribution |
941
- | |
942
- | Metrics |
943
- | Transaction count, total size, |
944
- | validation statistics |
945
- -------------------------------------------------
946
- ```
947
-
948
- ## Block Production
949
-
950
- When running as a stake pool operator, Dingo can produce blocks. This involves three subsystems under `ledger/`:
951
-
952
- ### Leader Election (`ledger/leader/`)
953
-
954
- `Election` subscribes to epoch transition events and pre-computes a leader schedule for each epoch. For each slot, it checks whether the pool's VRF output meets the threshold determined by the pool's relative stake (from the "go" snapshot, 2 epochs old).
955
-
956
- ### Block Forging (`ledger/forging/`)
957
-
958
- `BlockForger` runs a slot-based loop that:
959
- 1. Waits for the next slot boundary using the wall-clock slot timer
960
- 2. Checks leader eligibility via the `Election`
961
- 3. Assembles a block from mempool transactions using `DefaultBlockBuilder`
962
- 4. Broadcasts the forged block through the chain manager
963
-
964
- The forger tracks slot battles (competing blocks at the same slot) and skips forging when the node is not sufficiently synced, controlled by `forgeSyncToleranceSlots` and `forgeStaleGapThresholdSlots`.
965
-
966
- ### Pool Credentials (`ledger/forging/keys.go`, `keystore/`)
967
-
968
- VRF signing keys, KES signing keys, and operational certificates are loaded from files at startup. The `keystore` package handles platform-specific file permission checks (Unix file modes, Windows ACLs) and KES key evolution.
969
-
970
- ## Mithril Bootstrap
971
-
972
- The `mithril/` package enables fast initial sync by downloading and importing a Mithril snapshot rather than syncing from genesis:
973
-
974
- 1. `client.go` queries the Mithril aggregator for the latest certified snapshot
975
- 2. `download.go` downloads and extracts the snapshot archive
976
- 3. `bootstrap.go` orchestrates the import into Dingo's database
977
-
978
- This is exposed via the `dingo mithril` CLI subcommand and the `dingo load` command.
979
-
980
- ## External Interfaces
981
-
982
- Dingo provides three client-facing APIs plus Bark. All are optional and gated by port configuration. UTxO RPC, Blockfrost, and Mesh are general-purpose external APIs and require `storageMode: api`. Bark is different: it is Dingo's own protocol for Dingo-to-Dingo C2/archive services, not a general-purpose application API.
983
-
984
- ### Blockfrost API (`blockfrost/`)
985
-
986
- A Blockfrost-compatible REST API that provides read access to chain data. The current implementation exposes the latest, epoch, network, and pool subset. It uses an adapter pattern to translate between Dingo's internal state and Blockfrost response types and supports cursor-based pagination.
987
-
988
- ### Mesh API (`mesh/`)
989
-
990
- Implements the Mesh (formerly Rosetta) API specification for wallet integration and chain analysis. Provides endpoints for network status, account balances, block queries, transaction construction, and mempool access.
991
-
992
- ### UTxO RPC (`utxorpc/`)
993
-
994
- A gRPC server implementing the UTxO RPC specification with query, submit, sync, and watch services. Supports optional TLS.
995
-
996
- ### Bark (`bark/`)
997
-
998
- Bark is Dingo's own protocol for Dingo-to-Dingo control-plane and archive services. It exposes archive access over Connect/gRPC and also supplies a remote archive adapter with a configurable security window, allowing Dingo to fetch historical blocks from a remote Bark instance instead of storing them locally.
999
-
1000
- ## Design Patterns
1001
-
1002
- ### Dependency Injection
1003
-
1004
- The `Node` creates and injects dependencies into components during initialization. Components receive their dependencies through constructors rather than creating them internally.
1005
-
1006
- ### Interface Segregation
1007
-
1008
- Small, focused interfaces allow swapping implementations:
1009
- - `BlobStore` for blob storage
1010
- - `MetadataStore` for metadata storage
1011
- - Protocol handler interfaces for Ouroboros
1012
- - `forging.LeaderChecker`, `forging.BlockBroadcaster`, `forging.SlotClockProvider` for block production
1013
-
1014
- ### Plugin Architecture
1015
-
1016
- Storage backends are loaded dynamically through a plugin registry, allowing extension without modifying core code.
1017
-
1018
- ### Adapter Pattern
1019
-
1020
- The block production system uses adapters (`mempoolAdapter`, `stakeDistributionAdapter`, `epochInfoAdapter`, `slotClockAdapter`) to decouple forging interfaces from concrete implementations.
1021
-
1022
- ### Observer Pattern
1023
-
1024
- The `EventBus` implements publisher/subscriber communication, decoupling components that produce events from those that consume them.
1025
-
1026
- ### Iterator Pattern
1027
-
1028
- `ChainIterator` provides sequential access to blocks without exposing internal chain structure.
1029
-
1030
- ### Manager Pattern
1031
-
1032
- `ChainManager`, `PeerGovernor`, and `snapshot.Manager` orchestrate related operations and maintain consistent state across multiple entities.
1033
-
1034
- ### Worker Pool Pattern
1035
-
1036
- Database operations and event delivery use worker pools for controlled concurrency and backpressure.
1037
-
1038
- ## Threading and Concurrency
1039
-
1040
- | Pattern | Usage |
1041
- |---------|-------|
1042
- | Goroutine Management | Tracked WaitGroups for clean shutdown |
1043
- | Mutex Protection | RWMutex for read-heavy operations |
1044
- | Atomic Operations | Atomic types for metrics counters |
1045
- | Channel Communication | EventBus async delivery |
1046
- | Context Cancellation | Graceful shutdown signals |
1047
- | Worker Pools | Database operations and event delivery |
1048
- | sync.Once | Ensure single shutdown execution |
1049
-
1050
- ## Configuration
1051
-
1052
- Configuration priority (highest to lowest):
1053
-
1054
- 1. CLI flags
1055
- 2. Environment variables
1056
- 3. YAML config file (`dingo.yaml`)
1057
- 4. Hardcoded defaults
1058
-
1059
- Key configuration areas:
1060
- - Network selection (preview, preprod, mainnet)
1061
- - Storage mode (`core` or `api`)
1062
- - Database path and plugins
1063
- - Listen addresses and ports
1064
- - Mempool capacity and watermarks
1065
- - Peer targets and quotas
1066
- - CBOR cache sizing (hot entries, block LRU)
1067
- - Chainsync client limits and stall timeout
1068
- - Block producer credentials (VRF key, KES key, operational certificate)
1069
- - External interface ports (Blockfrost, Mesh, UTxO RPC, Bark)
1070
-
1071
- ## Stake Snapshots
1072
-
1073
- Stake snapshots capture the stake distribution at epoch boundaries for use in Ouroboros Praos leader election. The block producer must know the stake distribution from 2 epochs ago to determine if it is the slot leader.
1074
-
1075
- ### Ouroboros Praos Snapshot Model
1076
-
1077
- ```
1078
- Epoch N-2 Epoch N-1 Epoch N (current)
1079
- | | |
1080
- v v v
1081
- [Go Snapshot] <- [Set Snapshot] <- [Mark Snapshot]
1082
- | |
1083
- Used for leader election Captured at
1084
- in current epoch epoch boundary
1085
- ```
1086
-
1087
- - Mark Snapshot: Captured at the end of epoch N, becomes Set at epoch N+1
1088
- - Set Snapshot: Previous Mark, becomes Go at epoch N+1
1089
- - Go Snapshot: Active snapshot used for leader election (2 epochs old)
1090
-
1091
- ### Stake Snapshot Components
1092
-
1093
- ```
1094
- Block Processing
1095
- |
1096
- v
1097
- LedgerState --> Epoch Transition --> EventBus (EpochTransitionEvent)
1098
- Detection |
1099
- v
1100
- SnapshotManager
1101
- (Subscribe)
1102
- |
1103
- -----------------------------------+------
1104
- | | |
1105
- v v v
1106
- Calculate Stake Rotate Snapshots Cleanup
1107
- Distribution Mark -> Set -> Go
1108
- | |
1109
- v v
1110
- Database
1111
- PoolStakeSnapshot EpochSummary
1112
- ```
1113
-
1114
- ### Database Models
1115
-
1116
- | Model | Purpose |
1117
- |-------|---------|
1118
- | `PoolStakeSnapshot` | Per-pool stake at epoch boundary (epoch, type, pool hash, stake, delegator count) |
1119
- | `EpochSummary` | Network-wide aggregates (total stake, pool count, delegator count, epoch nonce) |
1120
-
1121
- Snapshot types: `"mark"`, `"set"`, `"go"`
1122
-
1123
- ### Query Interface
1124
-
1125
- The `LedgerView` provides stake distribution queries:
1126
-
1127
- ```go
1128
- // Get full stake distribution for leader election
1129
- dist, err := ledgerView.GetStakeDistribution(epoch)
1130
-
1131
- // Get stake for a specific pool
1132
- poolStake, err := ledgerView.GetPoolStake(epoch, poolKeyHash)
1133
-
1134
- // Get total active stake
1135
- totalStake, err := ledgerView.GetTotalActiveStake(epoch)
1136
- ```
1137
-
1138
- ### Event-Driven Capture
1139
-
1140
- `EpochTransitionEvent` triggers snapshot capture:
1141
-
1142
- ```go
1143
- type EpochTransitionEvent struct {
1144
- PreviousEpoch uint64
1145
- NewEpoch uint64
1146
- BoundarySlot uint64
1147
- EpochNonce []byte
1148
- ProtocolVersion uint
1149
- SnapshotSlot uint64 // Typically boundary - 1
1150
- }
1151
- ```
1152
-
1153
- ### Rollback Support
1154
-
1155
- On chain rollback past an epoch boundary:
1156
- - Delete snapshots for epochs after rollback point
1157
- - Recalculate affected snapshots on forward replay