@blinklabs/dingo 0.46.3 → 0.80.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
@@ -4,577 +4,75 @@
4
4
  <img src="./.github/assets/dingo-logo-with-text-horizontal.png" alt="Dingo Logo" width="640">
5
5
  <br>
6
6
  <img alt="GitHub" src="https://img.shields.io/github/license/blinklabs-io/dingo">
7
- <a href="https://goreportcard.com/report/github.com/blinklabs-io/dingo"><img src="https://goreportcard.com/badge/github.com/blinklabs-io/dingo" alt="Go Report Card"></a>
8
7
  <a href="https://pkg.go.dev/github.com/blinklabs-io/dingo"><img src="https://pkg.go.dev/badge/github.com/blinklabs-io/dingo.svg" alt="Go Reference"></a>
9
8
  <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
9
  </div>
11
10
 
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.**
13
-
14
- A high-performance Cardano blockchain node implementation in Go by Blink Labs. Dingo provides:
15
- - Full chain synchronization and validation via Ouroboros consensus protocol
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
- - Client connectivity for wallets and applications
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
23
- - Chain rollback support for handling forks with automatic state restoration
24
- - Fast bootstrapping via built-in Mithril client
25
- - Multiple external interfaces: general-purpose APIs (UTxO RPC, Blockfrost-compatible REST, Mesh/Rosetta) plus Bark for Dingo-to-Dingo C2 and archive services
26
-
27
- Note: On Windows systems, named pipes are used instead of Unix sockets for node-to-client communication.
28
-
29
- <div align="center">
30
- <img src="./.github/dingo-20241210.png" alt="dingo screenshot" width="640">
31
- </div>
32
-
33
- ## Running
34
-
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.
38
-
39
- ### Environment Variables
40
-
41
- The following environment variables modify Dingo's behavior:
42
-
43
- - `CARDANO_BIND_ADDR`
44
- - IP address to bind for listening (default: `0.0.0.0`)
45
- - `CARDANO_CONFIG`
46
- - Full path to the Cardano node configuration (default:
47
- `./config/cardano/preview/config.json`)
48
- - Use your own configuration files for different networks
49
- - Genesis configuration files are read from the same directory by default
50
- - `CARDANO_DATABASE_PATH`
51
- - A directory which contains the ledger database files (default:
52
- `.dingo`)
53
- - This is the location for persistent data storage for the ledger
54
- - `CARDANO_INTERSECT_TIP`
55
- - Ignore prior chain history and start from current position (default:
56
- `false`)
57
- - This is experimental and will likely break... use with caution
58
- - `CARDANO_METRICS_PORT`
59
- - TCP port to bind for listening for Prometheus metrics (default: `12798`)
60
- - `CARDANO_NETWORK`
61
- - Named Cardano network (default: `preview`)
62
- - `CARDANO_PRIVATE_BIND_ADDR`
63
- - IP address to bind for listening for Ouroboros NtC (default:
64
- `127.0.0.1`)
65
- - `CARDANO_PRIVATE_PORT`
66
- - TCP port to bind for listening for Ouroboros NtC (default: `3002`)
67
- - `CARDANO_RELAY_PORT`
68
- - TCP port to bind for listening for Ouroboros NtN (default: `3001`)
69
- - `CARDANO_SOCKET_PATH`
70
- - UNIX socket path for listening (default: `dingo.socket`)
71
- - This socket speaks Ouroboros NtC and is used by client software
72
- - `CARDANO_TOPOLOGY`
73
- - Full path to the Cardano node topology (default: "")
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)
89
- - `TLS_CERT_FILE_PATH` - SSL certificate to use, requires `TLS_KEY_FILE_PATH`
90
- (default: empty)
91
- - `TLS_KEY_FILE_PATH` - SSL certificate key to use (default: empty)
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`, `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
-
135
- | Port | Service | Default |
136
- |------|---------|---------|
137
- | 3001 | Ouroboros NtN (node-to-node) | Enabled |
138
- | 3002 | Ouroboros NtC over TCP | Enabled |
139
- | 12798 | Prometheus metrics | Enabled |
140
- | 3000 | Blockfrost REST API | Disabled |
141
- | 8080 | Mesh (Rosetta) REST API | Disabled |
142
- | 9090 | UTxO RPC (gRPC) | Disabled |
143
- | — | Bark archive (gRPC) | Disabled (example when enabled: 9091) |
144
-
145
- ## Storage Modes
146
-
147
- Dingo has two storage modes that control how much data is persisted:
148
-
149
- | Mode | What's Stored | Use Case |
150
- |------|---------------|----------|
151
- | `core` (default) | UTxOs, certificates, pools, protocol parameters | Relays, block producers |
152
- | `api` | Core data + witnesses, scripts, datums, redeemers, tx metadata | Nodes serving API queries |
153
-
154
- ```bash
155
- # Relay or block producer (default)
156
- ./dingo
157
-
158
- # API node
159
- DINGO_STORAGE_MODE=api ./dingo
160
- ```
161
-
162
- Or in `dingo.yaml`:
163
-
164
- ```yaml
165
- storageMode: "api"
166
- ```
167
-
168
- ## API Servers and Bark
169
-
170
- Dingo includes three general-purpose external APIs plus Bark. UTxO RPC, Blockfrost, and Mesh are client-facing 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. Set an individual port to 0 to disable a specific interface. The Blockfrost server currently exposes the latest, epoch, network, and pool subset.
171
-
172
- | Interface | Port Env Var | Default | Protocol | Role |
173
- |-----------|--------------|---------|----------|------|
174
- | UTxO RPC | `DINGO_UTXORPC_PORT` | disabled | gRPC | General-purpose client API |
175
- | Blockfrost | `DINGO_BLOCKFROST_PORT` | disabled | REST | General-purpose client API |
176
- | Mesh (Rosetta) | `DINGO_MESH_PORT` | disabled | REST | General-purpose client API |
177
- | Bark | `DINGO_BARK_PORT` | disabled | Connect/gRPC | Dingo-to-Dingo C2/archive protocol |
178
-
179
- ```bash
180
- # Enable Blockfrost API on port 3100 and UTxO RPC on port 9090
181
- DINGO_STORAGE_MODE=api \
182
- DINGO_BLOCKFROST_PORT=3100 \
183
- DINGO_UTXORPC_PORT=9090 \
184
- ./dingo
185
- ```
186
-
187
- Or in `dingo.yaml`:
188
-
189
- ```yaml
190
- storageMode: "api"
191
- blockfrostPort: 3100
192
- utxorpcPort: 9090
193
- ```
194
-
195
- ### Deployment Patterns
196
-
197
- **Relay node** (consensus only, no APIs):
198
- ```bash
199
- ./dingo
200
- ```
201
-
202
- **API / data node** (full indexing, one or more APIs):
203
- ```bash
204
- DINGO_STORAGE_MODE=api DINGO_BLOCKFROST_PORT=3100 ./dingo
205
- ```
206
-
207
- **Block producer** (consensus only, with SPO keys):
208
- ```bash
209
- CARDANO_BLOCK_PRODUCER=true \
210
- CARDANO_SHELLEY_VRF_KEY=/keys/vrf.skey \
211
- CARDANO_SHELLEY_KES_KEY=/keys/kes.skey \
212
- CARDANO_SHELLEY_OPERATIONAL_CERTIFICATE=/keys/opcert.cert \
213
- ./dingo
214
- ```
215
-
216
- When `storageMode=core`, the Badger blob store defaults to mmap-only settings: `block-cache-size=0`, `index-cache-size=0`, and `compression=false`. When `storageMode=api`, the default Badger profile is `block-cache-size=268435456`, `index-cache-size=0`, and `compression=true`. YAML, environment variable, and CLI Badger options override those defaults only when explicitly set.
217
-
218
- See `dingo.yaml.example` for the full set of configuration options.
219
-
220
- ## Fast Bootstrapping with Mithril
221
-
222
- 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.
223
-
224
- ```bash
225
- # Bootstrap from Mithril and start syncing
226
- ./dingo -n preview sync --mithril
227
-
228
- # Then start the node
229
- ./dingo -n preview serve
230
- ```
231
-
232
- Or use the subcommand form for more control:
233
-
234
- ```bash
235
- # List available snapshots
236
- ./dingo -n preview mithril list
237
-
238
- # Show snapshot details
239
- ./dingo -n preview mithril show <digest>
240
-
241
- # Download and import
242
- ./dingo -n preview mithril sync
243
- ```
244
-
245
- This imports:
246
- - All blocks from genesis (stored in blob store for serving peers)
247
- - Current UTxO set, stake accounts, pool registrations, DRep registrations
248
- - Stake snapshots (mark/set/go) for leader election
249
- - Protocol parameters, governance state, treasury/reserves
250
- - Complete epoch history for slot-to-time calculations
251
-
252
- Individual transaction records, certificate history, witness/script/datum storage, and governance vote records for blocks before the snapshot are not stored by the snapshot itself. In `core` mode these are not needed — consensus, block production, and serving blocks to peers work without them, and new blocks processed after bootstrap will have full metadata. In `api` mode, `dingo mithril sync` automatically runs a backfill step after loading the snapshot to populate this historical data, so API servers (Blockfrost, UTxO RPC, Mesh) have complete records from genesis.
253
-
254
- Performance (preview network, ~4M blocks):
255
-
256
- | Phase | core mode | api mode |
257
- |-------|-----------|----------|
258
- | Download snapshot (~2.6 GB) | ~1-2 min | ~1-2 min |
259
- | Extract + download ancillary | ~1 min | ~1 min |
260
- | Import ledger state (UTxOs, accounts, pools, DReps, epochs) | ~12 min | ~12 min |
261
- | Load blocks into blob store | ~36 min | ~36 min |
262
- | Backfill historical metadata | — | ~varies |
263
- | Total | ~50 min | ~50 min + backfill |
264
-
265
- ### Disk Space Requirements
266
-
267
- Bootstrapping requires temporary disk space for both the downloaded snapshot and the Dingo database:
268
-
269
- | Network | Snapshot Size | Dingo DB | Total Needed |
270
- |---------|--------------|----------|--------------|
271
- | mainnet | ~180 GB | ~200+ GB | ~400 GB |
272
- | preprod | ~60 GB | ~80 GB | ~150 GB |
273
- | preview | ~15 GB | ~25 GB | ~50 GB |
274
-
275
- 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.
276
-
277
- ## Database Plugins
278
-
279
- 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.
280
-
281
- ### Available Plugins
282
-
283
- Blob Storage Plugins:
284
- - `badger` - BadgerDB local key-value store (default)
285
- - `gcs` - Google Cloud Storage blob store
286
- - `s3` - AWS S3 blob store
287
-
288
- Metadata Storage Plugins:
289
- - `sqlite` - SQLite relational database (default)
290
- - `postgres` - PostgreSQL relational database
291
- - `mysql` - MySQL relational database
292
-
293
- ### Plugin Selection
294
-
295
- Plugins can be selected via command-line flags, environment variables, or configuration file:
296
-
297
- ```bash
298
- # Command line
299
- ./dingo --blob gcs --metadata sqlite
300
-
301
- # Environment variables
302
- DINGO_DATABASE_BLOB_PLUGIN=gcs
303
- DINGO_DATABASE_METADATA_PLUGIN=sqlite
304
-
305
- # Configuration file (dingo.yaml)
306
- database:
307
- blob:
308
- plugin: "gcs"
309
- metadata:
310
- plugin: "sqlite"
311
- ```
312
-
313
- ### Plugin Configuration
314
-
315
- Each plugin supports specific configuration options. See `dingo.yaml.example` for detailed configuration examples.
316
-
317
- BadgerDB Options:
318
- - `data-dir` - Directory for database files
319
- - `block-cache-size` - Block cache size in bytes
320
- - `index-cache-size` - Index cache size in bytes
321
- - `compression` - Enable Snappy compression
322
- - `gc` - Enable garbage collection
323
-
324
- Leave the mode-sensitive Badger settings unset if you want Dingo's storage-mode defaults. `storageMode=core` uses `block-cache-size=0`, `index-cache-size=0`, and `compression=false`; `storageMode=api` uses `block-cache-size=268435456`, `index-cache-size=0`, and `compression=true`.
325
-
326
- Google Cloud Storage Options:
327
- - `bucket` - GCS bucket name
328
- - `project-id` - Google Cloud project ID
329
- - `prefix` - Path prefix within bucket
330
-
331
- AWS S3 Options:
332
- - `bucket` - S3 bucket name
333
- - `region` - AWS region
334
- - `prefix` - Path prefix within bucket
335
- - `access-key-id` - AWS access key ID (optional - uses default credential chain if not provided)
336
- - `secret-access-key` - AWS secret access key (optional - uses default credential chain if not provided)
337
-
338
- SQLite Options:
339
- - `data-dir` - Path to SQLite database file
340
-
341
- PostgreSQL Options:
342
- - `host` - PostgreSQL server hostname
343
- - `port` - PostgreSQL server port
344
- - `username` - Database user
345
- - `password` - Database password
346
- - `database` - Database name
347
-
348
- MySQL Options:
349
- - `host` - MySQL server hostname
350
- - `port` - MySQL server port
351
- - `user` - Database user
352
- - `password` - Database password
353
- - `database` - Database name
354
- - `ssl-mode` - MySQL TLS mode (mapped to tls= in DSN)
355
- - `timezone` - MySQL time zone location (default: UTC)
356
- - `dsn` - Full MySQL DSN (overrides other options when set)
357
- - `storage-mode` - Storage tier: core or api (default: core)
358
-
359
- ### Listing Available Plugins
360
-
361
- You can see all available plugins and their descriptions:
362
-
363
- ```bash
364
- ./dingo list
365
- ```
366
-
367
- ## Plugin Development
368
-
369
- For information on developing custom storage plugins, see [PLUGIN_DEVELOPMENT.md](PLUGIN_DEVELOPMENT.md).
370
-
371
- ## Features
372
-
373
- - [x] Network
374
- - [x] UTxO RPC
375
- - [x] Ouroboros
376
- - [x] Node-to-node
377
- - [x] ChainSync
378
- - [x] BlockFetch
379
- - [x] TxSubmission2
380
- - [x] Node-to-client
381
- - [x] ChainSync
382
- - [x] LocalTxMonitor
383
- - [x] LocalTxSubmission
384
- - [x] LocalStateQuery
385
- - [x] Peer governor
386
- - [x] Topology config
387
- - [x] Peer churn (full PeerChurnEvent with gossip/public root churn, bootstrap events)
388
- - [x] Ledger peers
389
- - [x] Peer sharing
390
- - [x] Denied peers tracking
391
- - [x] Connection manager
392
- - [x] Inbound connections
393
- - [x] Node-to-client over TCP
394
- - [x] Node-to-client over UNIX socket
395
- - [x] Node-to-node over TCP
396
- - [x] Outbound connections
397
- - [x] Node-to-node over TCP
398
- - [ ] Ledger
399
- - [x] Blocks
400
- - [x] Block storage
401
- - [x] Chain selection (density comparison, VRF tie-breaker, ChainForkEvent)
402
- - [x] UTxO tracking
403
- - [x] Protocol parameters
404
- - [x] Genesis validation
405
- - [x] Block header validation (VRF/KES/OpCert cryptographic verification)
406
- - [ ] Certificates
407
- - [x] Pool registration
408
- - [x] Stake registration/delegation
409
- - [x] Account registration checks
410
- - [x] DRep registration
411
- - [ ] Governance
412
- - [ ] Transaction validation
413
- - [ ] Phase 1 validation
414
- - [x] UTxO rules
415
- - [x] Fee validation (full fee calculation with script costs)
416
- - [x] Transaction size and ExUnit budget validation
417
- - [ ] Witnesses
418
- - [ ] Block body
419
- - [ ] Certificates
420
- - [ ] Delegation/pools
421
- - [ ] Governance
422
- - [x] Phase 2 validation
423
- - [x] Plutus V1 smart contract execution
424
- - [x] Plutus V2 smart contract execution
425
- - [x] Plutus V3 smart contract execution
426
- - [x] Block production
427
- - [x] VRF leader election with stake snapshots
428
- - [x] Block forging with KES/OpCert signing
429
- - [x] Slot battle detection
430
- - [x] Mempool
431
- - [x] Accept transactions from local clients
432
- - [x] Distribute transactions to other nodes
433
- - [x] Validation of transaction on add
434
- - [x] Consumer tracking
435
- - [x] Transaction purging on chain update
436
- - [x] Watermark-based eviction and rejection
437
- - [x] Database Recovery
438
- - [x] Chain rollback support (SQLite, PostgreSQL, and MySQL plugins)
439
- - [x] State restoration on rollback
440
- - [x] WAL mode for crash recovery
441
- - [x] Automatic rollback on transaction error
442
- - [x] Stake Snapshots
443
- - [x] Mark/Set/Go rotation at epoch boundaries
444
- - [x] Genesis snapshot capture
445
- - [x] API Servers
446
- - [x] UTxO RPC (gRPC)
447
- - [ ] WIP Blockfrost-compatible REST API
448
- - [x] Mesh (Coinbase Rosetta) API
449
- - [x] Mithril Bootstrap
450
- - [x] Built-in Mithril client
451
- - [x] Ledger state import (UTxOs, accounts, pools, DReps, epochs)
452
- - [x] Block loading from ImmutableDB
453
-
454
- Additional planned features can be found in our issue tracker and project boards.
455
-
456
- [Catalyst Fund 12 - Go Node (Dingo)](https://github.com/orgs/blinklabs-io/projects/16)<br/>
457
- [Catalyst Fund 13 - Archive Node](https://github.com/orgs/blinklabs-io/projects/17)
458
-
459
- Check the issue tracker for known issues. Due to rapid development, bugs happen
460
- especially as there is functionality which has not yet been developed.
461
-
462
- ## Development / Building
463
-
464
- This requires Go 1.25 or later. You also need `make`.
465
-
466
- ```bash
467
- # Format, test, and build (default target)
468
- make
469
-
470
- # Build only
11
+ > ⚠️ **WARNING: Dingo is under heavy active development and is not yet ready for mainnet block production use. It should only be used on testnets (preview, preprod, musashi) and devnets. Do not use Dingo on mainnet for block production with real funds.**
12
+
13
+ Dingo is Blink Labs' Cardano node implementation in Go. It implements the
14
+ Ouroboros networking and consensus protocols, validates ledger state, and
15
+ provides pluggable storage and client interfaces.
16
+
17
+ ## Documentation by audience
18
+
19
+ - **Node operators:** [Dingo guides](https://docs.blinklabs.io/guides/dingo/001-dingo/),
20
+ including the [quick start](https://docs.blinklabs.io/guides/dingo/002-quick-start-overview/),
21
+ [configuration and storage modes](https://docs.blinklabs.io/guides/dingo/005-node-configuration/),
22
+ [bootstrap and data maintenance](https://docs.blinklabs.io/guides/dingo/007-bootstrap-and-data-maintenance/),
23
+ and [stake pool operation](https://docs.blinklabs.io/guides/dingo/spo-guides/000-spo-guide/).
24
+ - **Application developers:** [APIs and archive services](https://docs.blinklabs.io/guides/dingo/006-apis-and-archive/)
25
+ and [using Dingo with Cardano CLI](https://docs.blinklabs.io/guides/dingo/004-using-dingo-with-cardano-cli/).
26
+ - The Kupo-compatible API is disabled by default. To enable it, configure
27
+ `DINGO_PLUGINS_API_KUPO_CONFIG_PORT` and use API storage mode.
28
+ - **Dingo contributors:** [development guide](docs/development.md),
29
+ [local DevNet](docs/devnet.md), [benchmarks and profiling](docs/benchmarks.md),
30
+ [architecture](ARCHITECTURE.md), [database design](DATABASE.md), and
31
+ [plugin development](database/plugin/PLUGIN_DEVELOPMENT.md).
32
+
33
+ ## Codebase
34
+
35
+ | Area | Location |
36
+ | --- | --- |
37
+ | Application composition and CLI | `node.go`, `internal/node/`, `cmd/dingo/` |
38
+ | Ledger validation and state | `ledger/`, `ledgerstate/` |
39
+ | Ouroboros protocols and peer management | `ouroboros/`, `connmanager/`, `peergov/`, `topology/` |
40
+ | Persistence and transaction pool | `database/`, `mempool/` |
41
+ | Client APIs and Dingo archive service | `api/`, `bark/` |
42
+
43
+ ## Build and test
44
+
45
+ The `@blinklabs/dingo` NPM package installs the matching release binary for
46
+ Linux, FreeBSD or macOS on amd64/arm64. It requires Node.js 22 or
47
+ later and `tar`. Run it with `npx @blinklabs/dingo --help`, or install it with
48
+ `npm install --global @blinklabs/dingo` and run `dingo --help`. Arguments, exit
49
+ codes and termination signals are passed to the release binary. Installation
50
+ fails if the platform has no released binary or the archive cannot be fetched
51
+ and extracted. If install scripts were disabled for a global installation,
52
+ `npm rebuild --global @blinklabs/dingo` runs the installer.
53
+
54
+ `npm test` checks the packed package and local, global and npx invocation using
55
+ an isolated release archive fixture.
56
+
57
+ Use Go 1.26 or later and `make`:
58
+
59
+ ```sh
471
60
  make build
472
-
473
- # Run
474
- ./dingo
475
-
476
- # Run without building a binary
477
- go run ./cmd/dingo/
61
+ ./dingo --help
478
62
  ```
479
63
 
480
- ### Testing
481
-
482
- ```bash
483
- make test # All tests with race detection
484
- go test -v -race -run TestName ./package/ # Single test
485
- make bench # Benchmarks
486
- ```
64
+ Run the test suite with race detection using `make test`. See the
65
+ [development guide](docs/development.md) for repository checks, integration
66
+ environments, and profiling. For basic node setup and usage, follow the
67
+ [operator quick start](https://docs.blinklabs.io/guides/dingo/002-quick-start-overview/).
487
68
 
488
- ### Profiling
489
-
490
- ```bash
491
- # Load testdata with CPU and memory profiling
492
- make test-load-profile
493
-
494
- # Analyze
495
- go tool pprof cpu.prof
496
- go tool pprof mem.prof
497
- ```
498
-
499
- ## DevNet
500
-
501
- 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.
502
-
503
- ### Architecture
504
-
505
- The DevNet uses Docker Compose to run three Cardano nodes plus a load generator on a bridge network:
506
-
507
- | Container | Role | Host Port |
508
- |-----------|------|-----------|
509
- | `dingo-producer` | Dingo block producer (pool 1) | 3010 |
510
- | `cardano-producer` | cardano-node block producer (pool 2) | 3011 |
511
- | `cardano-relay` | Relay node (no block production) | 3012 |
512
- | `txpump` | Submits payment transactions into Dingo's mempool | — |
513
-
514
- A `configurator` init container generates fresh pool keys and genesis files before nodes start. The `txpump` sidecar comes up after Dingo is healthy and continuously feeds the mempool so block bodies and tx-submission paths are exercised alongside consensus.
515
-
516
- ### Prerequisites
517
-
518
- - Docker with the Compose plugin (`docker compose`)
519
- - Go 1.25+
520
-
521
- ### Running the Automated Tests
522
-
523
- 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`:
524
-
525
- ```bash
526
- cd internal/test/devnet/
527
-
528
- # Run all devnet tests
529
- ./run-tests.sh
530
-
531
- # Run a specific test
532
- ./run-tests.sh -run TestBasicBlockForging
533
-
534
- # Keep containers running after tests pass (for inspection)
535
- ./run-tests.sh --keep-up
536
- ```
537
-
538
- Override host ports if needed:
539
-
540
- ```bash
541
- DEVNET_DINGO_PORT=4010 DEVNET_CARDANO_PORT=4011 DEVNET_RELAY_PORT=4012 ./run-tests.sh
542
- ```
543
-
544
- ### Running the DevNet Manually
545
-
546
- For longer-running manual tests (soak testing, observing behavior over multiple epochs, debugging):
547
-
548
- ```bash
549
- cd internal/test/devnet/
550
-
551
- # Start all containers
552
- ./start.sh
553
-
554
- # Watch logs
555
- docker compose -f docker-compose.yml logs -f
556
-
557
- # Watch a specific node
558
- docker compose -f docker-compose.yml logs -f dingo-producer
559
-
560
- # Stop and clean up
561
- ./stop.sh
562
- ```
563
-
564
- Containers remain running until you stop them. The DevNet parameters (in `testnet.yaml`) use 1-second slots and 500-slot epochs (~8 minutes per epoch) with `activeSlotsCoeff=0.4` and `securityParam (k)=40`, so you can observe epoch transitions, leader election, and stake snapshot rotation relatively quickly.
565
-
566
- See [`internal/test/devnet/README.md`](internal/test/devnet/README.md) for full details on the harness, configurator, available test scenarios, and port/address overrides.
567
-
568
- ### Local DevNet (Without Docker)
569
-
570
- 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:
571
-
572
- ```bash
573
- # Run in devnet mode
574
- ./devmode.sh
575
-
576
- # With debug logging
577
- DEBUG=true ./devmode.sh
578
- ```
69
+ ## Repository documentation
579
70
 
580
- 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.
71
+ - [Development](docs/development.md)
72
+ - [Architecture](ARCHITECTURE.md)
73
+ - [Database](DATABASE.md)
74
+ - [MCP integration](docs/mcp/README.md)
75
+ - [Local DevNet](docs/devnet.md)
76
+ - [Benchmarks and profiling](docs/benchmarks.md)
77
+ - [Monitoring dashboards](docs/dashboards/README.md)
78
+ - [Badger garbage collection](docs/badger-gc.md)
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ // Copyright 2026 Blink Labs Software
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ 'use strict';
15
+
16
+ const path = require('node:path');
17
+ const { spawn } = require('node:child_process');
18
+ const { binaryPath } = require('../install');
19
+
20
+ const child = spawn(binaryPath(path.join(__dirname, '..', '..')), process.argv.slice(2), {
21
+ stdio: 'inherit',
22
+ });
23
+ const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
24
+ const forwards = new Map(signals.map((signal) => [signal, () => child.kill(signal)]));
25
+ for (const [signal, forward] of forwards) process.on(signal, forward);
26
+
27
+ child.once('error', (error) => {
28
+ for (const [signal, forward] of forwards) process.removeListener(signal, forward);
29
+ console.error(`Cannot run Dingo: ${error.message}. ` +
30
+ 'Run npm rebuild @blinklabs/dingo to install its binary.');
31
+ process.exitCode = 1;
32
+ });
33
+ child.once('exit', (code, signal) => {
34
+ for (const [name, forward] of forwards) process.removeListener(name, forward);
35
+ if (signal) process.kill(process.pid, signal);
36
+ else process.exitCode = code;
37
+ });