@blinklabs/dingo 0.21.0 → 0.23.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/README.md CHANGED
@@ -9,17 +9,20 @@
9
9
  <a href="https://discord.gg/5fPRZnX4qW"><img src="https://img.shields.io/badge/Discord-7289DA?style=flat&logo=discord&logoColor=white" alt="Discord"></a>
10
10
  </div>
11
11
 
12
- # Dingo
13
-
14
- ⚠️ This is a work in progress and is currently under heavy development
12
+ > ⚠️ **WARNING: Dingo is under heavy active development and is not yet ready for production use. It should only be used on testnets (preview, preprod) and devnets. Do not use Dingo on mainnet with real funds.**
15
13
 
16
14
  A high-performance Cardano blockchain node implementation in Go by Blink Labs. Dingo provides:
17
15
  - Full chain synchronization and validation via Ouroboros consensus protocol
18
- - UTxO tracking with 41 UTXO validation rules and Plutus smart contract execution
16
+ - UTxO tracking with 41 UTXO validation rules and Plutus V1/V2/V3 smart contract execution
17
+ - Block production with VRF leader election and stake snapshots
18
+ - Multi-peer chain selection with density comparison and VRF tie-breaking
19
19
  - Client connectivity for wallets and applications
20
- - Pluggable storage backends (Badger, SQLite, PostgreSQL, GCS, S3)
21
- - Peer governance with dynamic peer selection and topology support
20
+ - Pluggable storage backends (Badger, SQLite, PostgreSQL, MySQL, GCS, S3)
21
+ - Tiered storage modes ("core" for consensus, "api" for full indexing)
22
+ - Peer governance with dynamic peer selection, ledger peers, and topology support
22
23
  - Chain rollback support for handling forks with automatic state restoration
24
+ - Fast bootstrapping via built-in Mithril client
25
+ - Multiple API servers: UTxO RPC, Blockfrost-compatible REST, Mesh (Coinbase Rosetta)
23
26
 
24
27
  Note: On Windows systems, named pipes are used instead of Unix sockets for node-to-client communication.
25
28
 
@@ -29,11 +32,13 @@ Note: On Windows systems, named pipes are used instead of Unix sockets for node-
29
32
 
30
33
  ## Running
31
34
 
32
- Dingo supports configuration via both a YAML config file (`dingo.yaml`) and uses environment
33
- variables to modify its own behavior.
35
+ Dingo supports configuration via a YAML config file (`dingo.yaml`), environment variables, and command-line flags. Priority: CLI flags > environment variables > YAML config > defaults.
36
+
37
+ A sample configuration file is provided at `dingo.yaml.example`. You can copy and edit this file to configure Dingo for your local or production environment.
34
38
 
35
- A sample configuration file is provided at `dingo.yaml.example`.You can copy and edit this file to configure Dingo for your local or production environment:
36
- This behavior can be changed via the following environment variables:
39
+ ### Environment Variables
40
+
41
+ The following environment variables modify Dingo's behavior:
37
42
 
38
43
  - `CARDANO_BIND_ADDR`
39
44
  - IP address to bind for listening (default: `0.0.0.0`)
@@ -66,26 +71,292 @@ This behavior can be changed via the following environment variables:
66
71
  - This socket speaks Ouroboros NtC and is used by client software
67
72
  - `CARDANO_TOPOLOGY`
68
73
  - Full path to the Cardano node topology (default: "")
69
- - `CARDANO_UTXORPC_PORT`
70
- - TCP port to bind for listening for UTxO RPC (default: `9090`)
74
+ - `DINGO_UTXORPC_PORT`
75
+ - TCP port to bind for listening for UTxO RPC (default: `0`, disabled)
76
+ - `DINGO_BLOCKFROST_PORT`
77
+ - TCP port for the Blockfrost-compatible REST API (default: `0`, disabled)
78
+ - `DINGO_MESH_PORT`
79
+ - TCP port for the Mesh (Coinbase Rosetta) API (default: `0`, disabled)
80
+ - `DINGO_BARK_PORT`
81
+ - TCP port for the Bark block archive API (default: `0`, disabled)
82
+ - `DINGO_STORAGE_MODE`
83
+ - Storage mode: `core` (default) or `api`
84
+ - `core` stores only consensus data (UTxOs, certs, pools, protocol params)
85
+ - `api` additionally stores witnesses, scripts, datums, redeemers, and tx metadata
86
+ - API servers (Blockfrost, UTxO RPC, Mesh) require `api` mode
87
+ - `DINGO_RUN_MODE`
88
+ - Run mode: `serve` (full node, default), `load` (batch import), `dev` (development mode), or `leios` (experimental Leios protocol support)
71
89
  - `TLS_CERT_FILE_PATH` - SSL certificate to use, requires `TLS_KEY_FILE_PATH`
72
90
  (default: empty)
73
91
  - `TLS_KEY_FILE_PATH` - SSL certificate key to use (default: empty)
74
92
 
93
+ ### Block Production (SPO Mode)
94
+
95
+ To run Dingo as a stake pool operator producing blocks:
96
+
97
+ - `CARDANO_BLOCK_PRODUCER` - Enable block production (default: `false`)
98
+ - `CARDANO_SHELLEY_VRF_KEY` - Path to VRF signing key file
99
+ - `CARDANO_SHELLEY_KES_KEY` - Path to KES signing key file
100
+ - `CARDANO_SHELLEY_OPERATIONAL_CERTIFICATE` - Path to operational certificate file
101
+
102
+ ### Quick Start
103
+
104
+ ```bash
105
+ # Preview network (default)
106
+ ./dingo
107
+
108
+ # Mainnet
109
+ CARDANO_NETWORK=mainnet ./dingo
110
+
111
+ # Or with explicit config path
112
+ CARDANO_NETWORK=mainnet CARDANO_CONFIG=path/to/mainnet/config.json ./dingo
113
+ ```
114
+
115
+ Dingo creates a `dingo.socket` file that speaks Ouroboros node-to-client and is compatible with `cardano-cli`, `adder`, `kupo`, and other Cardano client tools.
116
+
117
+ Cardano configuration files are bundled in the Docker image. For local builds, you can find them at [docker-cardano-configs](https://github.com/blinklabs-io/docker-cardano-configs/tree/main/config).
118
+
119
+ ## Docker
120
+
121
+ ```bash
122
+ # Run on preview (default)
123
+ docker run -p 3001:3001 ghcr.io/blinklabs-io/dingo
124
+
125
+ # Run on mainnet with persistent storage
126
+ docker run -p 3001:3001 \
127
+ -e CARDANO_NETWORK=mainnet \
128
+ -v dingo-data:/data/db \
129
+ -v dingo-ipc:/ipc \
130
+ ghcr.io/blinklabs-io/dingo
131
+ ```
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.
134
+
135
+ | Port | Service |
136
+ |------|---------|
137
+ | 3001 | Ouroboros NtN (node-to-node) |
138
+ | 3002 | Ouroboros NtC over TCP |
139
+ | 12798 | Prometheus metrics |
140
+
141
+ ## Storage Modes
142
+
143
+ Dingo has two storage modes that control how much data is persisted:
144
+
145
+ | Mode | What's Stored | Use Case |
146
+ |------|---------------|----------|
147
+ | `core` (default) | UTxOs, certificates, pools, protocol parameters | Relays, block producers |
148
+ | `api` | Core data + witnesses, scripts, datums, redeemers, tx metadata | Nodes serving API queries |
149
+
150
+ ```bash
151
+ # Relay or block producer (default)
152
+ ./dingo
153
+
154
+ # API node
155
+ DINGO_STORAGE_MODE=api ./dingo
156
+ ```
157
+
158
+ Or in `dingo.yaml`:
159
+
160
+ ```yaml
161
+ storageMode: "api"
162
+ ```
163
+
164
+ ## API Servers
165
+
166
+ Dingo includes four API servers, all disabled by default. Enable them by setting a non-zero port. All API servers except Bark require `storageMode: "api"`.
167
+
168
+ | API | Port Env Var | Default | Protocol |
169
+ |-----|-------------|---------|----------|
170
+ | UTxO RPC | `DINGO_UTXORPC_PORT` | disabled | gRPC |
171
+ | Blockfrost | `DINGO_BLOCKFROST_PORT` | disabled | REST |
172
+ | Mesh (Rosetta) | `DINGO_MESH_PORT` | disabled | REST |
173
+ | Bark | `DINGO_BARK_PORT` | disabled | RPC |
174
+
175
+ ```bash
176
+ # Enable Blockfrost API on port 3100 and UTxO RPC on port 9090
177
+ DINGO_STORAGE_MODE=api \
178
+ DINGO_BLOCKFROST_PORT=3100 \
179
+ DINGO_UTXORPC_PORT=9090 \
180
+ ./dingo
181
+ ```
182
+
183
+ Or in `dingo.yaml`:
184
+
185
+ ```yaml
186
+ storageMode: "api"
187
+ blockfrostPort: 3100
188
+ utxorpcPort: 9090
189
+ ```
190
+
191
+ ### Deployment Patterns
192
+
193
+ **Relay node** (consensus only, no APIs):
194
+ ```bash
195
+ ./dingo
196
+ ```
197
+
198
+ **API / data node** (full indexing, one or more APIs):
199
+ ```bash
200
+ DINGO_STORAGE_MODE=api DINGO_BLOCKFROST_PORT=3100 ./dingo
201
+ ```
202
+
203
+ **Block producer** (consensus only, with SPO keys):
204
+ ```bash
205
+ CARDANO_BLOCK_PRODUCER=true \
206
+ CARDANO_SHELLEY_VRF_KEY=/keys/vrf.skey \
207
+ CARDANO_SHELLEY_KES_KEY=/keys/kes.skey \
208
+ CARDANO_SHELLEY_OPERATIONAL_CERTIFICATE=/keys/opcert.cert \
209
+ ./dingo
210
+ ```
211
+
212
+ See `dingo.yaml.example` for the full set of configuration options.
213
+
214
+ ## Fast Bootstrapping with Mithril
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.
226
+
227
+ ```bash
228
+ # Bootstrap from Mithril and start syncing
229
+ ./dingo -n preview sync --mithril
230
+
231
+ # Then start the node
232
+ ./dingo -n preview serve
233
+ ```
234
+
235
+ Or use the subcommand form for more control:
236
+
237
+ ```bash
238
+ # List available snapshots
239
+ ./dingo -n preview mithril list
240
+
241
+ # Show snapshot details
242
+ ./dingo -n preview mithril show <digest>
243
+
244
+ # Download and import
245
+ ./dingo -n preview mithril sync
246
+ ```
247
+
248
+ This imports:
249
+ - All blocks from genesis (stored in blob store for serving peers)
250
+ - Current UTxO set, stake accounts, pool registrations, DRep registrations
251
+ - Stake snapshots (mark/set/go) for leader election
252
+ - Protocol parameters, governance state, treasury/reserves
253
+ - Complete epoch history for slot-to-time calculations
254
+
255
+ What is NOT included: Individual transaction records, certificate history, witness/script/datum storage, and governance vote records for blocks before the snapshot. These are not needed for consensus, block production, or serving blocks to peers. New blocks processed after bootstrap will have full metadata.
256
+
257
+ Performance (preview network, ~4M blocks):
258
+
259
+ | Phase | Time |
260
+ |-------|------|
261
+ | Download snapshot (~2.6 GB) | ~1-2 min |
262
+ | Extract + download ancillary | ~1 min |
263
+ | Import ledger state (UTxOs, accounts, pools, DReps, epochs) | ~12 min |
264
+ | Load blocks into blob store | ~36 min |
265
+ | Total | ~50 min |
266
+
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.
332
+
333
+ ### Disk Space Requirements
334
+
335
+ Bootstrapping requires temporary disk space for both the downloaded snapshot and the Dingo database:
336
+
337
+ | Network | Snapshot Size | Dingo DB | Total Needed |
338
+ |---------|--------------|----------|--------------|
339
+ | mainnet | ~180 GB | ~200+ GB | ~400 GB |
340
+ | preprod | ~60 GB | ~80 GB | ~150 GB |
341
+ | preview | ~15 GB | ~25 GB | ~50 GB |
342
+
343
+ These are approximate values that grow over time. The snapshot can be deleted after import, but you need sufficient space for both during the load process.
344
+
75
345
  ## Database Plugins
76
346
 
77
347
  Dingo supports pluggable storage backends for both blob storage (blocks, transactions) and metadata storage. This allows you to choose the best storage solution for your use case.
78
348
 
79
349
  ### Available Plugins
80
350
 
81
- **Blob Storage Plugins:**
351
+ Blob Storage Plugins:
82
352
  - `badger` - BadgerDB local key-value store (default)
83
353
  - `gcs` - Google Cloud Storage blob store
84
354
  - `s3` - AWS S3 blob store
85
355
 
86
- **Metadata Storage Plugins:**
356
+ Metadata Storage Plugins:
87
357
  - `sqlite` - SQLite relational database (default)
88
358
  - `postgres` - PostgreSQL relational database
359
+ - `mysql` - MySQL relational database
89
360
 
90
361
  ### Plugin Selection
91
362
 
@@ -111,34 +382,45 @@ database:
111
382
 
112
383
  Each plugin supports specific configuration options. See `dingo.yaml.example` for detailed configuration examples.
113
384
 
114
- **BadgerDB Options:**
385
+ BadgerDB Options:
115
386
  - `data-dir` - Directory for database files
116
387
  - `block-cache-size` - Block cache size in bytes
117
388
  - `index-cache-size` - Index cache size in bytes
118
389
  - `gc` - Enable garbage collection
119
390
 
120
- **Google Cloud Storage Options:**
391
+ Google Cloud Storage Options:
121
392
  - `bucket` - GCS bucket name
122
393
  - `project-id` - Google Cloud project ID
123
394
  - `prefix` - Path prefix within bucket
124
395
 
125
- **AWS S3 Options:**
396
+ AWS S3 Options:
126
397
  - `bucket` - S3 bucket name
127
398
  - `region` - AWS region
128
399
  - `prefix` - Path prefix within bucket
129
400
  - `access-key-id` - AWS access key ID (optional - uses default credential chain if not provided)
130
401
  - `secret-access-key` - AWS secret access key (optional - uses default credential chain if not provided)
131
402
 
132
- **SQLite Options:**
403
+ SQLite Options:
133
404
  - `data-dir` - Path to SQLite database file
134
405
 
135
- **PostgreSQL Options:**
406
+ PostgreSQL Options:
136
407
  - `host` - PostgreSQL server hostname
137
408
  - `port` - PostgreSQL server port
138
409
  - `username` - Database user
139
410
  - `password` - Database password
140
411
  - `database` - Database name
141
412
 
413
+ MySQL Options:
414
+ - `host` - MySQL server hostname
415
+ - `port` - MySQL server port
416
+ - `user` - Database user
417
+ - `password` - Database password
418
+ - `database` - Database name
419
+ - `ssl-mode` - MySQL TLS mode (mapped to tls= in DSN)
420
+ - `timezone` - MySQL time zone location (default: UTC)
421
+ - `dsn` - Full MySQL DSN (overrides other options when set)
422
+ - `storage-mode` - Storage tier: core or api (default: core)
423
+
142
424
  ### Listing Available Plugins
143
425
 
144
426
  You can see all available plugins and their descriptions:
@@ -151,21 +433,6 @@ You can see all available plugins and their descriptions:
151
433
 
152
434
  For information on developing custom storage plugins, see [PLUGIN_DEVELOPMENT.md](PLUGIN_DEVELOPMENT.md).
153
435
 
154
- ### Example
155
-
156
- Running on mainnet (:sweat_smile:):
157
-
158
- ```bash
159
- CARDANO_NETWORK=mainnet CARDANO_CONFIG=path/to/cardano/configs/mainnet/config.json ./dingo
160
- ```
161
-
162
- Note: you can find cardano configuration files at
163
- <https://github.com/blinklabs-io/docker-cardano-configs/tree/main/config>
164
-
165
- Dingo will drop a `dingo.socket` file which can be used by other clients, such
166
- as `cardano-cli` or software like `adder` or `kupo`. This has only had limited
167
- testing, so success/failure reports are very welcome and encouraged!
168
-
169
436
  ## Features
170
437
 
171
438
  - [x] Network
@@ -200,35 +467,55 @@ testing, so success/failure reports are very welcome and encouraged!
200
467
  - [x] UTxO tracking
201
468
  - [x] Protocol parameters
202
469
  - [x] Genesis validation
470
+ - [x] Block header validation (VRF/KES/OpCert cryptographic verification)
203
471
  - [ ] Certificates
204
472
  - [x] Pool registration
205
473
  - [x] Stake registration/delegation
206
474
  - [x] Account registration checks
475
+ - [x] DRep registration
207
476
  - [ ] Governance
208
477
  - [ ] Transaction validation
209
478
  - [ ] Phase 1 validation
210
479
  - [x] UTxO rules
480
+ - [x] Fee validation (full fee calculation with script costs)
481
+ - [x] Transaction size and ExUnit budget validation
211
482
  - [ ] Witnesses
212
483
  - [ ] Block body
213
484
  - [ ] Certificates
214
485
  - [ ] Delegation/pools
215
486
  - [ ] Governance
216
- - [ ] Phase 2 validation
217
- - [ ] Smart contracts
487
+ - [x] Phase 2 validation
488
+ - [x] Plutus V1 smart contract execution
489
+ - [x] Plutus V2 smart contract execution
490
+ - [x] Plutus V3 smart contract execution
491
+ - [x] Block production
492
+ - [x] VRF leader election with stake snapshots
493
+ - [x] Block forging with KES/OpCert signing
494
+ - [x] Slot battle detection
218
495
  - [x] Mempool
219
496
  - [x] Accept transactions from local clients
220
497
  - [x] Distribute transactions to other nodes
221
498
  - [x] Validation of transaction on add
222
499
  - [x] Consumer tracking
223
500
  - [x] Transaction purging on chain update
501
+ - [x] Watermark-based eviction and rejection
224
502
  - [x] Database Recovery
225
- - [x] Chain rollback support (SQLite and PostgreSQL plugins)
503
+ - [x] Chain rollback support (SQLite, PostgreSQL, and MySQL plugins)
226
504
  - [x] State restoration on rollback
227
505
  - [x] WAL mode for crash recovery
228
506
  - [x] Automatic rollback on transaction error
229
- - [x] Plutus Validation
230
- - [x] Plutus V3 smart contract validation
231
- - [ ] Plutus V1/V2 smart contract validation
507
+ - [x] Stake Snapshots
508
+ - [x] Mark/Set/Go rotation at epoch boundaries
509
+ - [x] Genesis snapshot capture
510
+ - [x] API Servers
511
+ - [x] UTxO RPC (gRPC)
512
+ - [x] Blockfrost-compatible REST API
513
+ - [x] Mesh (Coinbase Rosetta) API
514
+ - [x] Bark block archive API
515
+ - [x] Mithril Bootstrap
516
+ - [x] Built-in Mithril client
517
+ - [x] Ledger state import (UTxOs, accounts, pools, DReps, epochs)
518
+ - [x] Block loading from ImmutableDB
232
519
 
233
520
  Additional planned features can be found in our issue tracker and project boards.
234
521
 
@@ -240,17 +527,117 @@ especially as there is functionality which has not yet been developed.
240
527
 
241
528
  ## Development / Building
242
529
 
243
- This requires Go 1.23 or better is installed. You also need `make`.
530
+ This requires Go 1.24 or later. You also need `make`.
244
531
 
245
532
  ```bash
246
- # Build
533
+ # Format, test, and build (default target)
247
534
  make
535
+
536
+ # Build only
537
+ make build
538
+
248
539
  # Run
249
540
  ./dingo
541
+
542
+ # Run without building a binary
543
+ go run ./cmd/dingo/
250
544
  ```
251
545
 
252
- You can also run the code without building a binary, first
546
+ ### Testing
253
547
 
254
548
  ```bash
255
- go run ./cmd/dingo/
549
+ make test # All tests with race detection
550
+ go test -v -race -run TestName ./package/ # Single test
551
+ make bench # Benchmarks
552
+ ```
553
+
554
+ ### Profiling
555
+
556
+ ```bash
557
+ # Load testdata with CPU and memory profiling
558
+ make test-load-profile
559
+
560
+ # Analyze
561
+ go tool pprof cpu.prof
562
+ go tool pprof mem.prof
563
+ ```
564
+
565
+ ## DevNet
566
+
567
+ The DevNet runs a private Cardano network with Dingo and `cardano-node` producing blocks side by side. It validates that Dingo forges blocks, maintains consensus, and interoperates with the reference node.
568
+
569
+ ### Architecture
570
+
571
+ The DevNet uses Docker Compose to run 3 containers on a bridge network:
572
+
573
+ | Container | Role | Host Port |
574
+ |-----------|------|-----------|
575
+ | `dingo-producer` | Dingo block producer (pool 1) | 3010 |
576
+ | `cardano-producer` | cardano-node block producer (pool 2) | 3011 |
577
+ | `cardano-relay` | Relay node (no block production) | 3012 |
578
+
579
+ A `configurator` init container generates fresh pool keys and genesis files before nodes start.
580
+
581
+ ### Prerequisites
582
+
583
+ - Docker with the Compose plugin (`docker compose`)
584
+ - Go 1.24+
585
+
586
+ ### Running the Automated Tests
587
+
588
+ The test suite builds the Dingo Docker image, starts all containers, waits for health checks, and runs Go integration tests tagged with `//go:build devnet`:
589
+
590
+ ```bash
591
+ cd internal/test/devnet/
592
+
593
+ # Run all devnet tests
594
+ ./run-tests.sh
595
+
596
+ # Run a specific test
597
+ ./run-tests.sh -run TestBasicBlockForging
598
+
599
+ # Keep containers running after tests pass (for inspection)
600
+ ./run-tests.sh --keep-up
601
+ ```
602
+
603
+ Override host ports if needed:
604
+
605
+ ```bash
606
+ DEVNET_DINGO_PORT=4010 DEVNET_CARDANO_PORT=4011 DEVNET_RELAY_PORT=4012 ./run-tests.sh
256
607
  ```
608
+
609
+ ### Running the DevNet Manually
610
+
611
+ For longer-running manual tests (soak testing, observing behavior over multiple epochs, debugging):
612
+
613
+ ```bash
614
+ cd internal/test/devnet/
615
+
616
+ # Start all containers
617
+ ./start.sh
618
+
619
+ # Watch logs
620
+ docker compose -f docker-compose.yml logs -f
621
+
622
+ # Watch a specific node
623
+ docker compose -f docker-compose.yml logs -f dingo-producer
624
+
625
+ # Stop and clean up
626
+ ./stop.sh
627
+ ```
628
+
629
+ Containers remain running until you stop them. The DevNet parameters (in `testnet.yaml`) use 1-second slots and 1500-slot epochs (~25 minutes per epoch), so you can observe epoch transitions, leader election, and stake snapshot rotation relatively quickly.
630
+
631
+ ### Local DevNet (Without Docker)
632
+
633
+ For quick iteration without Docker, `devmode.sh` runs Dingo directly against a local devnet genesis. It resets state and updates genesis timestamps on each run:
634
+
635
+ ```bash
636
+ # Run in devnet mode
637
+ ./devmode.sh
638
+
639
+ # With debug logging
640
+ DEBUG=true ./devmode.sh
641
+ ```
642
+
643
+ This stores state in `.devnet/` and uses genesis configs from `config/cardano/devnet/`. It runs a single Dingo node (no cardano-node counterpart), which is useful for testing startup, epoch transitions, and block production in isolation.
@@ -0,0 +1,91 @@
1
+ # Release Notes
2
+
3
+ ## v0.22.1 (March 8, 2026)
4
+
5
+ **Title:** Stability updates and polish
6
+
7
+ **Date:** March 8, 2026
8
+
9
+ **Version:** v0.22.1
10
+
11
+ Hi folks! Here’s what we shipped in v0.22.1.
12
+
13
+ ### ✨ What's New
14
+
15
+ - **Release notes:** We added v0.22.0 release notes to `RELEASE_NOTES.md` so you can scan changes in one place.
16
+
17
+ ### 💪 Improvements
18
+
19
+ - **Transaction validation:** Transaction validation is more consistent because Conway UTxO validation now runs even when a transaction is marked invalid, while script evaluation is still skipped.
20
+ - **Epoch processing:** Epoch processing recovers more gracefully because nonce recomputation falls back to recomputing from epoch start when an anchor block nonce is missing.
21
+ - **Queue handling:** Queue handling is more solid under load because the main event queue size increased from 1,000 to 10,000 and the header queue size is now clamped to at least the default.
22
+ - **Implausible-tip checks:** Implausible-tip checks are safer across edge cases because the logic now uses peer-based reference blocks with overflow-safe arithmetic.
23
+ - **Publish workflow login:** Publishing is more rock-solid because the publish workflow was tweaked to log in using `docker/login-action@v4`.
24
+ - **Publish workflow runtime:** Automation stays more up to date because Node.js `24.x` was rolled out for the publish workflow.
25
+
26
+ ### 🔧 Fixes
27
+
28
+ - **Epoch cache rollbacks:** Epoch cache handling is safer during concurrent rollbacks because `advanceEpochCache` now guards against empty caches and validates the tail before appending a new epoch.
29
+ - **Test timing:** Tests are less flaky on slower machines because `TestSchedulerRunFailFunc` timing parameters were relaxed.
30
+
31
+ ### 📋 What You Need to Know
32
+
33
+ - **API bind address:** Config validation no longer defaults the API bind address to `0.0.0.0`, so set it explicitly if you need it.
34
+ - **CI and publishing scripts:** If you maintain custom publishing or CI scripts, give them a quick check for compatibility with Node.js `24.x` and `docker/login-action@v4`.
35
+
36
+ ### 🙏 Thank You
37
+
38
+ Thank you for trying!
39
+
40
+ ---
41
+
42
+ ## v0.22.0 (March 7, 2026)
43
+
44
+ **Title:** Mithril bootstrap, built-in APIs, and block production
45
+
46
+ **Date:** March 7, 2026
47
+
48
+ **Version:** v0.22.0
49
+
50
+ Hi folks! Here’s what we shipped in v0.22.0.
51
+
52
+ ### ✨ What's New
53
+
54
+ - **Mithril bootstrap:** Node operators can now bootstrap a Dingo node from a Mithril snapshot and have the ledger state imported automatically (see “Fast Bootstrapping with Mithril” in `README.md`).
55
+ - **Built-in HTTP APIs:** You can run Dingo with built-in, configurable HTTP APIs for common ecosystem compatibility.
56
+ - **Block production:** Block production is now supported with Praos leader election and keystore-backed key management.
57
+ - **Lifecycle events:** The node now emits richer on-chain lifecycle events that applications can subscribe to.
58
+ - **Conway governance metadata:** Governance and Conway-era features are now available in the on-chain metadata pipeline.
59
+ - **Leios mode:** A new “leios” mode is available for early experimentation with Leios protocols.
60
+ - **Stake snapshots:** Stake snapshots and stake distribution are now available with persistence and querying.
61
+
62
+ ### 💪 Improvements
63
+
64
+ - **Faster catch-up validation:** Syncing is now faster and safer by reducing unnecessary validation during initial catch-up.
65
+ - **Tiered storage and caching:** Block and transaction storage can now be tuned for performance and cost with tiered storage and caching options.
66
+ - **Rollback and resync:** Rollback and resync behavior is more robust under forks and stalled peers.
67
+ - **Peer management:** Network and peer management now scales more predictably under load.
68
+ - **Mempool resilience:** Transaction processing is more resilient and configurable under pressure.
69
+ - **Observability:** Observability has been expanded across sync, forging, and storage.
70
+ - **Time and nonce handling:** Epoch, slot, and nonce handling better matches Cardano semantics and edge cases.
71
+ - **Docs:** Developer and operator documentation has been significantly expanded.
72
+
73
+ ### 🔧 Fixes
74
+
75
+ - **Chainsync stability:** Chainsync is more reliable around header/block fetching and coordination.
76
+ - **Concurrency safety:** Several concurrency and event-delivery deadlocks and goroutine leak risks have been eliminated.
77
+ - **Security hardening:** Security hardening has been added for configuration, filesystem usage, and key material.
78
+ - **Protocol validation:** Cryptographic and protocol-validation correctness has been tightened across eras.
79
+ - **Object-store key encoding:** Storage key encoding issues in object stores have been resolved.
80
+
81
+ ### 📋 What You Need to Know
82
+
83
+ - **Event consumers:** If you rely on event type strings, update consumers to match the renamed event type strings.
84
+ - **API storage backfill:** If you enable API storage or new tiered storage modes, run a metadata backfill so queries return complete results.
85
+ - **Forging setup:** If you enable forging, double-check VRF/KES/OpCert key paths and permissions first.
86
+
87
+ ### 🙏 Thank You
88
+
89
+ Thank you for trying!
90
+
91
+ ---