@blinklabs/dingo 0.20.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/AGENTS.md +115 -0
- package/ARCHITECTURE.md +839 -0
- package/README.md +457 -42
- package/RELEASE_NOTES.md +91 -0
- package/{devnet.sh → devmode.sh} +5 -5
- package/dingo.yaml.example +185 -7
- package/docker-compose.yml +51 -0
- package/package.json +1 -1
- package/PLUGIN_DEVELOPMENT.md +0 -306
package/README.md
CHANGED
|
@@ -9,11 +9,22 @@
|
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 API servers: UTxO RPC, Blockfrost-compatible REST, Mesh (Coinbase Rosetta)
|
|
26
|
+
|
|
27
|
+
Note: On Windows systems, named pipes are used instead of Unix sockets for node-to-client communication.
|
|
17
28
|
|
|
18
29
|
<div align="center">
|
|
19
30
|
<img src="./.github/dingo-20241210.png" alt="dingo screenshot" width="640">
|
|
@@ -21,11 +32,13 @@
|
|
|
21
32
|
|
|
22
33
|
## Running
|
|
23
34
|
|
|
24
|
-
Dingo supports configuration via
|
|
25
|
-
|
|
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
|
|
26
40
|
|
|
27
|
-
|
|
28
|
-
This behavior can be changed via the following environment variables:
|
|
41
|
+
The following environment variables modify Dingo's behavior:
|
|
29
42
|
|
|
30
43
|
- `CARDANO_BIND_ADDR`
|
|
31
44
|
- IP address to bind for listening (default: `0.0.0.0`)
|
|
@@ -58,25 +71,292 @@ This behavior can be changed via the following environment variables:
|
|
|
58
71
|
- This socket speaks Ouroboros NtC and is used by client software
|
|
59
72
|
- `CARDANO_TOPOLOGY`
|
|
60
73
|
- Full path to the Cardano node topology (default: "")
|
|
61
|
-
- `
|
|
62
|
-
- TCP port to bind for listening for UTxO RPC (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)
|
|
63
89
|
- `TLS_CERT_FILE_PATH` - SSL certificate to use, requires `TLS_KEY_FILE_PATH`
|
|
64
90
|
(default: empty)
|
|
65
91
|
- `TLS_KEY_FILE_PATH` - SSL certificate key to use (default: empty)
|
|
66
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
|
+
|
|
67
345
|
## Database Plugins
|
|
68
346
|
|
|
69
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.
|
|
70
348
|
|
|
71
349
|
### Available Plugins
|
|
72
350
|
|
|
73
|
-
|
|
351
|
+
Blob Storage Plugins:
|
|
74
352
|
- `badger` - BadgerDB local key-value store (default)
|
|
75
353
|
- `gcs` - Google Cloud Storage blob store
|
|
76
354
|
- `s3` - AWS S3 blob store
|
|
77
355
|
|
|
78
|
-
|
|
356
|
+
Metadata Storage Plugins:
|
|
79
357
|
- `sqlite` - SQLite relational database (default)
|
|
358
|
+
- `postgres` - PostgreSQL relational database
|
|
359
|
+
- `mysql` - MySQL relational database
|
|
80
360
|
|
|
81
361
|
### Plugin Selection
|
|
82
362
|
|
|
@@ -102,27 +382,45 @@ database:
|
|
|
102
382
|
|
|
103
383
|
Each plugin supports specific configuration options. See `dingo.yaml.example` for detailed configuration examples.
|
|
104
384
|
|
|
105
|
-
|
|
385
|
+
BadgerDB Options:
|
|
106
386
|
- `data-dir` - Directory for database files
|
|
107
387
|
- `block-cache-size` - Block cache size in bytes
|
|
108
388
|
- `index-cache-size` - Index cache size in bytes
|
|
109
389
|
- `gc` - Enable garbage collection
|
|
110
390
|
|
|
111
|
-
|
|
391
|
+
Google Cloud Storage Options:
|
|
112
392
|
- `bucket` - GCS bucket name
|
|
113
393
|
- `project-id` - Google Cloud project ID
|
|
114
394
|
- `prefix` - Path prefix within bucket
|
|
115
395
|
|
|
116
|
-
|
|
396
|
+
AWS S3 Options:
|
|
117
397
|
- `bucket` - S3 bucket name
|
|
118
398
|
- `region` - AWS region
|
|
119
399
|
- `prefix` - Path prefix within bucket
|
|
120
400
|
- `access-key-id` - AWS access key ID (optional - uses default credential chain if not provided)
|
|
121
401
|
- `secret-access-key` - AWS secret access key (optional - uses default credential chain if not provided)
|
|
122
402
|
|
|
123
|
-
|
|
403
|
+
SQLite Options:
|
|
124
404
|
- `data-dir` - Path to SQLite database file
|
|
125
405
|
|
|
406
|
+
PostgreSQL Options:
|
|
407
|
+
- `host` - PostgreSQL server hostname
|
|
408
|
+
- `port` - PostgreSQL server port
|
|
409
|
+
- `username` - Database user
|
|
410
|
+
- `password` - Database password
|
|
411
|
+
- `database` - Database name
|
|
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
|
+
|
|
126
424
|
### Listing Available Plugins
|
|
127
425
|
|
|
128
426
|
You can see all available plugins and their descriptions:
|
|
@@ -135,21 +433,6 @@ You can see all available plugins and their descriptions:
|
|
|
135
433
|
|
|
136
434
|
For information on developing custom storage plugins, see [PLUGIN_DEVELOPMENT.md](PLUGIN_DEVELOPMENT.md).
|
|
137
435
|
|
|
138
|
-
### Example
|
|
139
|
-
|
|
140
|
-
Running on mainnet (:sweat_smile:):
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
CARDANO_NETWORK=mainnet CARDANO_CONFIG=path/to/cardano/configs/mainnet/config.json ./dingo
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Note: you can find cardano configuration files at
|
|
147
|
-
<https://github.com/blinklabs-io/docker-cardano-configs/tree/main/config>
|
|
148
|
-
|
|
149
|
-
Dingo will drop a `dingo.socket` file which can be used by other clients, such
|
|
150
|
-
as `cardano-cli` or software like `adder` or `kupo`. This has only had limited
|
|
151
|
-
testing, so success/failure reports are very welcome and encouraged!
|
|
152
|
-
|
|
153
436
|
## Features
|
|
154
437
|
|
|
155
438
|
- [x] Network
|
|
@@ -164,10 +447,12 @@ testing, so success/failure reports are very welcome and encouraged!
|
|
|
164
447
|
- [x] LocalTxMonitor
|
|
165
448
|
- [x] LocalTxSubmission
|
|
166
449
|
- [x] LocalStateQuery
|
|
167
|
-
- [
|
|
450
|
+
- [x] Peer governor
|
|
168
451
|
- [x] Topology config
|
|
169
|
-
- [
|
|
170
|
-
- [
|
|
452
|
+
- [x] Peer churn (full PeerChurnEvent with gossip/public root churn, bootstrap events)
|
|
453
|
+
- [x] Ledger peers
|
|
454
|
+
- [x] Peer sharing
|
|
455
|
+
- [x] Denied peers tracking
|
|
171
456
|
- [x] Connection manager
|
|
172
457
|
- [x] Inbound connections
|
|
173
458
|
- [x] Node-to-client over TCP
|
|
@@ -178,29 +463,59 @@ testing, so success/failure reports are very welcome and encouraged!
|
|
|
178
463
|
- [ ] Ledger
|
|
179
464
|
- [x] Blocks
|
|
180
465
|
- [x] Block storage
|
|
181
|
-
- [
|
|
466
|
+
- [x] Chain selection (density comparison, VRF tie-breaker, ChainForkEvent)
|
|
182
467
|
- [x] UTxO tracking
|
|
183
468
|
- [x] Protocol parameters
|
|
469
|
+
- [x] Genesis validation
|
|
470
|
+
- [x] Block header validation (VRF/KES/OpCert cryptographic verification)
|
|
184
471
|
- [ ] Certificates
|
|
185
472
|
- [x] Pool registration
|
|
186
473
|
- [x] Stake registration/delegation
|
|
474
|
+
- [x] Account registration checks
|
|
475
|
+
- [x] DRep registration
|
|
187
476
|
- [ ] Governance
|
|
188
477
|
- [ ] Transaction validation
|
|
189
478
|
- [ ] Phase 1 validation
|
|
190
479
|
- [x] UTxO rules
|
|
480
|
+
- [x] Fee validation (full fee calculation with script costs)
|
|
481
|
+
- [x] Transaction size and ExUnit budget validation
|
|
191
482
|
- [ ] Witnesses
|
|
192
483
|
- [ ] Block body
|
|
193
484
|
- [ ] Certificates
|
|
194
485
|
- [ ] Delegation/pools
|
|
195
486
|
- [ ] Governance
|
|
196
|
-
- [
|
|
197
|
-
- [
|
|
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
|
|
198
495
|
- [x] Mempool
|
|
199
496
|
- [x] Accept transactions from local clients
|
|
200
497
|
- [x] Distribute transactions to other nodes
|
|
201
498
|
- [x] Validation of transaction on add
|
|
202
499
|
- [x] Consumer tracking
|
|
203
500
|
- [x] Transaction purging on chain update
|
|
501
|
+
- [x] Watermark-based eviction and rejection
|
|
502
|
+
- [x] Database Recovery
|
|
503
|
+
- [x] Chain rollback support (SQLite, PostgreSQL, and MySQL plugins)
|
|
504
|
+
- [x] State restoration on rollback
|
|
505
|
+
- [x] WAL mode for crash recovery
|
|
506
|
+
- [x] Automatic rollback on transaction error
|
|
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
|
|
204
519
|
|
|
205
520
|
Additional planned features can be found in our issue tracker and project boards.
|
|
206
521
|
|
|
@@ -212,17 +527,117 @@ especially as there is functionality which has not yet been developed.
|
|
|
212
527
|
|
|
213
528
|
## Development / Building
|
|
214
529
|
|
|
215
|
-
This requires Go 1.
|
|
530
|
+
This requires Go 1.24 or later. You also need `make`.
|
|
216
531
|
|
|
217
532
|
```bash
|
|
218
|
-
#
|
|
533
|
+
# Format, test, and build (default target)
|
|
219
534
|
make
|
|
535
|
+
|
|
536
|
+
# Build only
|
|
537
|
+
make build
|
|
538
|
+
|
|
220
539
|
# Run
|
|
221
540
|
./dingo
|
|
541
|
+
|
|
542
|
+
# Run without building a binary
|
|
543
|
+
go run ./cmd/dingo/
|
|
222
544
|
```
|
|
223
545
|
|
|
224
|
-
|
|
546
|
+
### Testing
|
|
225
547
|
|
|
226
548
|
```bash
|
|
227
|
-
|
|
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
|
|
228
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
|
|
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.
|