@blinklabs/dingo 0.20.0 → 0.21.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 +33 -5
- package/dingo.yaml.example +78 -5
- package/package.json +1 -1
- package/PLUGIN_DEVELOPMENT.md +0 -306
package/README.md
CHANGED
|
@@ -13,7 +13,15 @@
|
|
|
13
13
|
|
|
14
14
|
⚠️ This is a work in progress and is currently under heavy development
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
A high-performance Cardano blockchain node implementation in Go by Blink Labs. Dingo provides:
|
|
17
|
+
- Full chain synchronization and validation via Ouroboros consensus protocol
|
|
18
|
+
- UTxO tracking with 41 UTXO validation rules and Plutus smart contract execution
|
|
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
|
|
22
|
+
- Chain rollback support for handling forks with automatic state restoration
|
|
23
|
+
|
|
24
|
+
Note: On Windows systems, named pipes are used instead of Unix sockets for node-to-client communication.
|
|
17
25
|
|
|
18
26
|
<div align="center">
|
|
19
27
|
<img src="./.github/dingo-20241210.png" alt="dingo screenshot" width="640">
|
|
@@ -77,6 +85,7 @@ Dingo supports pluggable storage backends for both blob storage (blocks, transac
|
|
|
77
85
|
|
|
78
86
|
**Metadata Storage Plugins:**
|
|
79
87
|
- `sqlite` - SQLite relational database (default)
|
|
88
|
+
- `postgres` - PostgreSQL relational database
|
|
80
89
|
|
|
81
90
|
### Plugin Selection
|
|
82
91
|
|
|
@@ -123,6 +132,13 @@ Each plugin supports specific configuration options. See `dingo.yaml.example` fo
|
|
|
123
132
|
**SQLite Options:**
|
|
124
133
|
- `data-dir` - Path to SQLite database file
|
|
125
134
|
|
|
135
|
+
**PostgreSQL Options:**
|
|
136
|
+
- `host` - PostgreSQL server hostname
|
|
137
|
+
- `port` - PostgreSQL server port
|
|
138
|
+
- `username` - Database user
|
|
139
|
+
- `password` - Database password
|
|
140
|
+
- `database` - Database name
|
|
141
|
+
|
|
126
142
|
### Listing Available Plugins
|
|
127
143
|
|
|
128
144
|
You can see all available plugins and their descriptions:
|
|
@@ -164,10 +180,12 @@ testing, so success/failure reports are very welcome and encouraged!
|
|
|
164
180
|
- [x] LocalTxMonitor
|
|
165
181
|
- [x] LocalTxSubmission
|
|
166
182
|
- [x] LocalStateQuery
|
|
167
|
-
- [
|
|
183
|
+
- [x] Peer governor
|
|
168
184
|
- [x] Topology config
|
|
169
|
-
- [
|
|
170
|
-
- [
|
|
185
|
+
- [x] Peer churn (full PeerChurnEvent with gossip/public root churn, bootstrap events)
|
|
186
|
+
- [x] Ledger peers
|
|
187
|
+
- [x] Peer sharing
|
|
188
|
+
- [x] Denied peers tracking
|
|
171
189
|
- [x] Connection manager
|
|
172
190
|
- [x] Inbound connections
|
|
173
191
|
- [x] Node-to-client over TCP
|
|
@@ -178,12 +196,14 @@ testing, so success/failure reports are very welcome and encouraged!
|
|
|
178
196
|
- [ ] Ledger
|
|
179
197
|
- [x] Blocks
|
|
180
198
|
- [x] Block storage
|
|
181
|
-
- [
|
|
199
|
+
- [x] Chain selection (density comparison, VRF tie-breaker, ChainForkEvent)
|
|
182
200
|
- [x] UTxO tracking
|
|
183
201
|
- [x] Protocol parameters
|
|
202
|
+
- [x] Genesis validation
|
|
184
203
|
- [ ] Certificates
|
|
185
204
|
- [x] Pool registration
|
|
186
205
|
- [x] Stake registration/delegation
|
|
206
|
+
- [x] Account registration checks
|
|
187
207
|
- [ ] Governance
|
|
188
208
|
- [ ] Transaction validation
|
|
189
209
|
- [ ] Phase 1 validation
|
|
@@ -201,6 +221,14 @@ testing, so success/failure reports are very welcome and encouraged!
|
|
|
201
221
|
- [x] Validation of transaction on add
|
|
202
222
|
- [x] Consumer tracking
|
|
203
223
|
- [x] Transaction purging on chain update
|
|
224
|
+
- [x] Database Recovery
|
|
225
|
+
- [x] Chain rollback support (SQLite and PostgreSQL plugins)
|
|
226
|
+
- [x] State restoration on rollback
|
|
227
|
+
- [x] WAL mode for crash recovery
|
|
228
|
+
- [x] Automatic rollback on transaction error
|
|
229
|
+
- [x] Plutus Validation
|
|
230
|
+
- [x] Plutus V3 smart contract validation
|
|
231
|
+
- [ ] Plutus V1/V2 smart contract validation
|
|
204
232
|
|
|
205
233
|
Additional planned features can be found in our issue tracker and project boards.
|
|
206
234
|
|
package/dingo.yaml.example
CHANGED
|
@@ -46,12 +46,50 @@ database:
|
|
|
46
46
|
|
|
47
47
|
# Metadata storage plugin configuration
|
|
48
48
|
metadata:
|
|
49
|
-
# Plugin to use for metadata storage (sqlite)
|
|
49
|
+
# Plugin to use for metadata storage (sqlite, postgres, mysql)
|
|
50
50
|
plugin: "sqlite"
|
|
51
51
|
# Configuration options for each plugin
|
|
52
52
|
sqlite:
|
|
53
|
-
#
|
|
53
|
+
# Path to SQLite database file
|
|
54
54
|
data-dir: ".dingo/metadata.db"
|
|
55
|
+
postgres:
|
|
56
|
+
# NOTE: These are example values for local development only.
|
|
57
|
+
# Do not use these credentials in production environments.
|
|
58
|
+
# Postgres host
|
|
59
|
+
host: "localhost"
|
|
60
|
+
# Postgres port
|
|
61
|
+
port: 5432
|
|
62
|
+
# Postgres user
|
|
63
|
+
user: "postgres"
|
|
64
|
+
# Postgres password (required - no default)
|
|
65
|
+
password: ""
|
|
66
|
+
# Postgres database name
|
|
67
|
+
database: "postgres"
|
|
68
|
+
# Postgres sslmode
|
|
69
|
+
ssl-mode: "disable"
|
|
70
|
+
# Postgres TimeZone
|
|
71
|
+
timezone: "UTC"
|
|
72
|
+
# Full Postgres DSN (overrides other options when set)
|
|
73
|
+
dsn: ""
|
|
74
|
+
mysql:
|
|
75
|
+
# NOTE: These are example values for local development only.
|
|
76
|
+
# Do not use these credentials in production environments.
|
|
77
|
+
# MySQL host
|
|
78
|
+
host: "localhost"
|
|
79
|
+
# MySQL port
|
|
80
|
+
port: 3306
|
|
81
|
+
# MySQL user
|
|
82
|
+
user: "root"
|
|
83
|
+
# MySQL password (required - no default)
|
|
84
|
+
password: ""
|
|
85
|
+
# MySQL database name
|
|
86
|
+
database: "mysql"
|
|
87
|
+
# MySQL TLS mode (mapped to tls= in DSN)
|
|
88
|
+
ssl-mode: ""
|
|
89
|
+
# MySQL time zone location
|
|
90
|
+
timezone: "UTC"
|
|
91
|
+
# Full MySQL DSN (overrides other options when set)
|
|
92
|
+
dsn: ""
|
|
55
93
|
|
|
56
94
|
# Path to the UNIX domain socket file used by the server
|
|
57
95
|
socketPath: "dingo.socket"
|
|
@@ -98,9 +136,44 @@ intersectTip: false
|
|
|
98
136
|
# Default: 1048576 (1 MB)
|
|
99
137
|
mempoolCapacity: 1048576
|
|
100
138
|
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
|
|
139
|
+
# Operational mode: "serve" (default), "load", or "dev"
|
|
140
|
+
# - serve: Full node with network connectivity (default)
|
|
141
|
+
# - load: Batch import from ImmutableDB (requires immutableDbPath)
|
|
142
|
+
# - dev: Development mode (forge blocks, disable outbound, skip topology)
|
|
143
|
+
# Note: CLI commands (serve, load) take priority over this setting
|
|
144
|
+
#
|
|
145
|
+
# Can be overridden with the DINGO_RUN_MODE environment variable
|
|
146
|
+
runMode: "serve"
|
|
147
|
+
|
|
148
|
+
# Path to ImmutableDB for batch import (used when runMode is "load")
|
|
149
|
+
# Can also be provided as argument to 'dingo load' command
|
|
150
|
+
#
|
|
151
|
+
# Can be overridden with the DINGO_IMMUTABLE_DB_PATH environment variable
|
|
152
|
+
immutableDbPath: ""
|
|
104
153
|
|
|
105
154
|
# Validate historical blocks during ledger processing (default: false)
|
|
106
155
|
validateHistorical: false
|
|
156
|
+
|
|
157
|
+
# Peer targets - target number of peers in each state
|
|
158
|
+
# These are goals the system works toward, not hard limits.
|
|
159
|
+
# Use 0 for default values, -1 for unlimited
|
|
160
|
+
# Default: known=150, established=50, active=20
|
|
161
|
+
#
|
|
162
|
+
# Target number of known (cold) peers
|
|
163
|
+
targetNumberOfKnownPeers: 0
|
|
164
|
+
# Target number of established (warm) peers
|
|
165
|
+
targetNumberOfEstablishedPeers: 0
|
|
166
|
+
# Target number of active (hot) peers
|
|
167
|
+
targetNumberOfActivePeers: 0
|
|
168
|
+
|
|
169
|
+
# Per-source quotas for active peers
|
|
170
|
+
# These specify how active peer slots are distributed by source.
|
|
171
|
+
# Use 0 for default values.
|
|
172
|
+
# Default: topology=3, gossip=12, ledger=5
|
|
173
|
+
#
|
|
174
|
+
# Active peer slots for topology sources (local + public roots)
|
|
175
|
+
activePeersTopologyQuota: 0
|
|
176
|
+
# Active peer slots for gossip sources
|
|
177
|
+
activePeersGossipQuota: 0
|
|
178
|
+
# Active peer slots for ledger sources
|
|
179
|
+
activePeersLedgerQuota: 0
|
package/package.json
CHANGED
package/PLUGIN_DEVELOPMENT.md
DELETED
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
# Plugin Development Guide
|
|
2
|
-
|
|
3
|
-
This guide explains how to develop plugins for Dingo's storage system.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
Dingo supports pluggable storage backends through a registration-based plugin system. Plugins can extend the system with new blob storage (blocks, transactions) and metadata storage (indexes, state) implementations.
|
|
8
|
-
|
|
9
|
-
## Plugin Types
|
|
10
|
-
|
|
11
|
-
### Blob Storage Plugins
|
|
12
|
-
Store blockchain data (blocks, transactions, etc.). Examples:
|
|
13
|
-
- `badger` - Local BadgerDB key-value store
|
|
14
|
-
- `gcs` - Google Cloud Storage
|
|
15
|
-
- `s3` - AWS S3
|
|
16
|
-
|
|
17
|
-
#### Iterator lifetime note
|
|
18
|
-
Blob plugins expose iterators via `NewIterator(txn, opts)`. Items returned by the
|
|
19
|
-
iterator's `Item()` must only be accessed while the transaction used to create
|
|
20
|
-
the iterator is still active — implementations may validate transaction state at
|
|
21
|
-
access time and will return errors if the transaction has been committed or
|
|
22
|
-
rolled back. See `database/types/types.go` `BlobIterator` for details.
|
|
23
|
-
|
|
24
|
-
### Metadata Storage Plugins
|
|
25
|
-
Store metadata and indexes. Examples:
|
|
26
|
-
- `sqlite` - SQLite relational database
|
|
27
|
-
|
|
28
|
-
## Plugin Interface
|
|
29
|
-
|
|
30
|
-
All plugins must implement the `plugin.Plugin` interface:
|
|
31
|
-
|
|
32
|
-
```go
|
|
33
|
-
type Plugin interface {
|
|
34
|
-
Start() error
|
|
35
|
-
Stop() error
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Plugin Registration
|
|
40
|
-
|
|
41
|
-
Plugins register themselves during package initialization using the `plugin.Register()` function:
|
|
42
|
-
|
|
43
|
-
```go
|
|
44
|
-
func init() {
|
|
45
|
-
plugin.Register(plugin.PluginEntry{
|
|
46
|
-
Type: plugin.PluginTypeBlob, // or PluginTypeMetadata
|
|
47
|
-
Name: "myplugin",
|
|
48
|
-
Description: "My custom storage plugin",
|
|
49
|
-
NewFromOptionsFunc: NewFromCmdlineOptions,
|
|
50
|
-
Options: []plugin.PluginOption{
|
|
51
|
-
// Plugin-specific options
|
|
52
|
-
},
|
|
53
|
-
})
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Plugin Options
|
|
58
|
-
|
|
59
|
-
Plugins define configuration options using the `PluginOption` struct:
|
|
60
|
-
|
|
61
|
-
```go
|
|
62
|
-
plugin.PluginOption{
|
|
63
|
-
Name: "data-dir", // Option name
|
|
64
|
-
Type: plugin.PluginOptionTypeString, // Data type
|
|
65
|
-
Description: "Data directory path", // Help text
|
|
66
|
-
DefaultValue: "/tmp/data", // Default value
|
|
67
|
-
Dest: &cmdlineOptions.dataDir, // Destination variable
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Supported option types:
|
|
72
|
-
- `PluginOptionTypeString`
|
|
73
|
-
- `PluginOptionTypeBool`
|
|
74
|
-
- `PluginOptionTypeInt`
|
|
75
|
-
- `PluginOptionTypeUint`
|
|
76
|
-
|
|
77
|
-
## Environment Variables
|
|
78
|
-
|
|
79
|
-
Plugins automatically support environment variables with the pattern:
|
|
80
|
-
`DINGO_DATABASE_{TYPE}_{PLUGIN}_{OPTION}`
|
|
81
|
-
|
|
82
|
-
Examples:
|
|
83
|
-
- `DINGO_DATABASE_BLOB_BADGER_DATA_DIR=/data`
|
|
84
|
-
- `DINGO_DATABASE_METADATA_SQLITE_DATA_DIR=/metadata.db`
|
|
85
|
-
|
|
86
|
-
## YAML Configuration
|
|
87
|
-
|
|
88
|
-
Plugins can be configured in `dingo.yaml`:
|
|
89
|
-
|
|
90
|
-
```yaml
|
|
91
|
-
database:
|
|
92
|
-
blob:
|
|
93
|
-
plugin: "myplugin"
|
|
94
|
-
myplugin:
|
|
95
|
-
option1: "value1"
|
|
96
|
-
option2: 42
|
|
97
|
-
metadata:
|
|
98
|
-
plugin: "sqlite"
|
|
99
|
-
sqlite:
|
|
100
|
-
data-dir: "/data/metadata.db"
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Configuration Precedence
|
|
104
|
-
|
|
105
|
-
1. Command-line flags (highest priority)
|
|
106
|
-
2. Environment variables
|
|
107
|
-
3. YAML configuration
|
|
108
|
-
4. Default values (lowest priority)
|
|
109
|
-
|
|
110
|
-
## Command Line Options
|
|
111
|
-
|
|
112
|
-
Plugins support command-line flags with the pattern:
|
|
113
|
-
`--{type}-{plugin}-{option}`
|
|
114
|
-
|
|
115
|
-
Examples:
|
|
116
|
-
- `--blob-badger-data-dir /data`
|
|
117
|
-
- `--metadata-sqlite-data-dir /metadata.db`
|
|
118
|
-
|
|
119
|
-
## Plugin Development Steps
|
|
120
|
-
|
|
121
|
-
### 1. Create Plugin Structure
|
|
122
|
-
|
|
123
|
-
```text
|
|
124
|
-
database/plugin/{type}/{name}/
|
|
125
|
-
├── plugin.go # Registration and options
|
|
126
|
-
├── options.go # Option functions
|
|
127
|
-
├── database.go # Core implementation
|
|
128
|
-
└── options_test.go # Unit tests
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### 2. Implement Core Plugin
|
|
132
|
-
|
|
133
|
-
Create the main plugin struct that implements `plugin.Plugin`:
|
|
134
|
-
|
|
135
|
-
```go
|
|
136
|
-
type MyPlugin struct {
|
|
137
|
-
// Fields
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
func (p *MyPlugin) Start() error {
|
|
141
|
-
// Initialize resources
|
|
142
|
-
return nil
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
func (p *MyPlugin) Stop() error {
|
|
146
|
-
// Clean up resources
|
|
147
|
-
return nil
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### 3. Define Options
|
|
152
|
-
|
|
153
|
-
Create option functions following the pattern:
|
|
154
|
-
|
|
155
|
-
```go
|
|
156
|
-
func WithOptionName(value Type) OptionFunc {
|
|
157
|
-
return func(p *MyPlugin) {
|
|
158
|
-
p.field = value
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### 4. Implement Constructors
|
|
164
|
-
|
|
165
|
-
Provide both options-based and legacy constructors:
|
|
166
|
-
|
|
167
|
-
```go
|
|
168
|
-
func NewWithOptions(opts ...OptionFunc) (*MyPlugin, error) {
|
|
169
|
-
p := &MyPlugin{}
|
|
170
|
-
for _, opt := range opts {
|
|
171
|
-
opt(p)
|
|
172
|
-
}
|
|
173
|
-
return p, nil
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
func New(legacyParam1, legacyParam2) (*MyPlugin, error) {
|
|
177
|
-
// For backward compatibility
|
|
178
|
-
return NewWithOptions(
|
|
179
|
-
WithOption1(legacyParam1),
|
|
180
|
-
WithOption2(legacyParam2),
|
|
181
|
-
)
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### 5. Register Plugin
|
|
186
|
-
|
|
187
|
-
In `plugin.go`, register during initialization:
|
|
188
|
-
|
|
189
|
-
```go
|
|
190
|
-
var cmdlineOptions struct {
|
|
191
|
-
option1 string
|
|
192
|
-
option2 int
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
func init() {
|
|
196
|
-
plugin.Register(plugin.PluginEntry{
|
|
197
|
-
Type: plugin.PluginTypeBlob,
|
|
198
|
-
Name: "myplugin",
|
|
199
|
-
Description: "My custom plugin",
|
|
200
|
-
NewFromOptionsFunc: NewFromCmdlineOptions,
|
|
201
|
-
Options: []plugin.PluginOption{
|
|
202
|
-
{
|
|
203
|
-
Name: "option1",
|
|
204
|
-
Type: plugin.PluginOptionTypeString,
|
|
205
|
-
Description: "First option",
|
|
206
|
-
DefaultValue: "default",
|
|
207
|
-
Dest: &cmdlineOptions.option1,
|
|
208
|
-
},
|
|
209
|
-
// More options...
|
|
210
|
-
},
|
|
211
|
-
})
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
func NewFromCmdlineOptions() plugin.Plugin {
|
|
215
|
-
p, err := NewWithOptions(
|
|
216
|
-
WithOption1(cmdlineOptions.option1),
|
|
217
|
-
WithOption2(cmdlineOptions.option2),
|
|
218
|
-
)
|
|
219
|
-
if err != nil {
|
|
220
|
-
panic(err)
|
|
221
|
-
}
|
|
222
|
-
return p
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### 6. Add Tests
|
|
227
|
-
|
|
228
|
-
Create comprehensive tests:
|
|
229
|
-
|
|
230
|
-
```go
|
|
231
|
-
func TestOptions(t *testing.T) {
|
|
232
|
-
// Test option functions
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
func TestLifecycle(t *testing.T) {
|
|
236
|
-
p, err := NewWithOptions(WithOption1("test"))
|
|
237
|
-
// Test Start/Stop
|
|
238
|
-
}
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### 7. Update Imports
|
|
242
|
-
|
|
243
|
-
Add your plugin to the import list in the appropriate store file:
|
|
244
|
-
- `database/plugin/blob/blob.go` for blob plugins
|
|
245
|
-
- `database/plugin/metadata/metadata.go` for metadata plugins
|
|
246
|
-
|
|
247
|
-
## Example: Complete Plugin
|
|
248
|
-
|
|
249
|
-
See the existing plugins for complete examples:
|
|
250
|
-
- `database/plugin/blob/badger/` - BadgerDB implementation
|
|
251
|
-
- `database/plugin/metadata/sqlite/` - SQLite implementation
|
|
252
|
-
- `database/plugin/blob/gcs/` - Google Cloud Storage implementation
|
|
253
|
-
- `database/plugin/blob/aws/` - AWS S3 implementation
|
|
254
|
-
|
|
255
|
-
## Best Practices
|
|
256
|
-
|
|
257
|
-
1. **Error Handling**: Always return descriptive errors
|
|
258
|
-
2. **Resource Management**: Properly implement Start/Stop for resource lifecycle
|
|
259
|
-
3. **Thread Safety**: Ensure plugins are safe for concurrent use
|
|
260
|
-
4. **Configuration Validation**: Validate configuration during construction
|
|
261
|
-
5. **Backward Compatibility**: Maintain compatibility with existing deployments
|
|
262
|
-
6. **Documentation**: Document all options and their effects
|
|
263
|
-
7. **Testing**: Provide comprehensive unit and integration tests
|
|
264
|
-
|
|
265
|
-
## Testing Your Plugin
|
|
266
|
-
|
|
267
|
-
### Unit Tests
|
|
268
|
-
Test individual components and option functions.
|
|
269
|
-
|
|
270
|
-
### Integration Tests
|
|
271
|
-
Test the complete plugin lifecycle and interaction with the plugin system.
|
|
272
|
-
|
|
273
|
-
### CLI Testing
|
|
274
|
-
Use the CLI to test plugin listing and selection:
|
|
275
|
-
|
|
276
|
-
```bash
|
|
277
|
-
./dingo --blob list
|
|
278
|
-
./dingo --metadata list
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### Configuration Testing
|
|
282
|
-
Test environment variables and YAML configuration:
|
|
283
|
-
|
|
284
|
-
```bash
|
|
285
|
-
DINGO_DATABASE_BLOB_MYPLUGIN_OPTION1=value ./dingo --blob myplugin
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
## Programmatic Option Overrides (for tests)
|
|
289
|
-
|
|
290
|
-
When writing tests or programmatically constructing database instances you can override plugin options
|
|
291
|
-
without importing plugin implementation packages directly by using the plugin registry helper:
|
|
292
|
-
|
|
293
|
-
```go
|
|
294
|
-
// Set data-dir for the blob plugin to a per-test temp directory
|
|
295
|
-
plugin.SetPluginOption(plugin.PluginTypeBlob, "badger", "data-dir", t.TempDir())
|
|
296
|
-
|
|
297
|
-
// Set data-dir for the metadata plugin
|
|
298
|
-
plugin.SetPluginOption(plugin.PluginTypeMetadata, "sqlite", "data-dir", t.TempDir())
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
The helper sets the plugin option's destination variable in the registry before plugin instantiation.
|
|
302
|
-
If the requested option is not defined by the targeted plugin the call is non-fatal and returns nil,
|
|
303
|
-
allowing tests to run regardless of which plugin implementation is selected.
|
|
304
|
-
|
|
305
|
-
Using `t.TempDir()` guarantees each test uses its own on-disk path and prevents concurrent tests from
|
|
306
|
-
colliding on shared directories (for example the default `.dingo` Badger directory).
|