@blinklabs/dingo 0.46.4 → 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 +63 -565
- package/npm/bin/dingo.js +37 -0
- package/npm/checksums.json +8 -0
- package/npm/install.js +211 -0
- package/npm/postinstall.js +21 -0
- package/package.json +23 -14
- package/.dockerignore +0 -9
- package/AGENTS.md +0 -52
- package/ARCHITECTURE.md +0 -1157
- package/CLAUDE.md +0 -38
- package/RELEASE_NOTES.md +0 -2076
- package/benchmark_results.md +0 -130
- package/benchmark_results_bp_pi.md +0 -50
- package/benchmark_results_targeted.md +0 -102
- package/devmode.sh +0 -37
- package/dingo.yaml.example +0 -376
- package/docker-compose.yml +0 -51
- package/docs/dashboards/README.md +0 -188
- package/docs/dashboards/alerts.yaml +0 -29
- package/docs/dashboards/prometheus.yaml +0 -16
- package/docs/dashboards/provisioning.yaml +0 -14
- package/generate_benchmarks.sh +0 -588
- package/generate_bp_pi_report.sh +0 -359
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
package/npm/bin/dingo.js
ADDED
|
@@ -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
|
+
});
|