@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 +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 -2029
- 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/generate_bp_pi_report.sh
DELETED
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
set -euo pipefail
|
|
4
|
-
|
|
5
|
-
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
OUTPUT_FILE="${1:-benchmark_results_bp_pi.md}"
|
|
7
|
-
CACHE_DIR="${CACHE_DIR:-/tmp/dingo-bp-pi-go-cache}"
|
|
8
|
-
GOMAXPROCS_VALUE="${GOMAXPROCS_VALUE:-4}"
|
|
9
|
-
BENCH_TIME="${BENCH_TIME:-5s}"
|
|
10
|
-
IMMUTABLE_PATH="${IMMUTABLE_PATH:-database/immutable/testdata}"
|
|
11
|
-
RSS_LIMIT_MB="${RSS_LIMIT_MB:-1024}"
|
|
12
|
-
GOMEMLIMIT_VALUE="${GOMEMLIMIT_VALUE:-}"
|
|
13
|
-
BLOCK_CACHE_SIZE_VALUE="${BLOCK_CACHE_SIZE_VALUE:-}"
|
|
14
|
-
INDEX_CACHE_SIZE_VALUE="${INDEX_CACHE_SIZE_VALUE:-}"
|
|
15
|
-
MEMTABLE_SIZE_VALUE="${MEMTABLE_SIZE_VALUE:-}"
|
|
16
|
-
DEFAULT_DB_DIR="${DEFAULT_DB_DIR:-}"
|
|
17
|
-
DEFAULT_LOG_FILE="${DEFAULT_LOG_FILE:-}"
|
|
18
|
-
DB_DIR_BASE="${DB_DIR_BASE:-/tmp}"
|
|
19
|
-
TMP_BENCH_FILE="$(mktemp)"
|
|
20
|
-
TIME_FORMAT_STYLE=""
|
|
21
|
-
TIME_CMD=()
|
|
22
|
-
AUTO_DEFAULT_DB_DIR=0
|
|
23
|
-
AUTO_DEFAULT_LOG_FILE=0
|
|
24
|
-
DINGO_CACHE_ARGS=()
|
|
25
|
-
|
|
26
|
-
cleanup() {
|
|
27
|
-
local exit_status=$?
|
|
28
|
-
|
|
29
|
-
rm -f "$TMP_BENCH_FILE"
|
|
30
|
-
if [[ "$exit_status" -ne 0 ]]; then
|
|
31
|
-
if [[ "$AUTO_DEFAULT_LOG_FILE" -eq 1 ]]; then
|
|
32
|
-
printf 'preserving profile log for debugging: %s\n' \
|
|
33
|
-
"$DEFAULT_LOG_FILE" >&2
|
|
34
|
-
fi
|
|
35
|
-
if [[ "$AUTO_DEFAULT_DB_DIR" -eq 1 ]]; then
|
|
36
|
-
printf 'preserving profile database for debugging: %s\n' \
|
|
37
|
-
"$DEFAULT_DB_DIR" >&2
|
|
38
|
-
fi
|
|
39
|
-
return "$exit_status"
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
if [[ "$AUTO_DEFAULT_LOG_FILE" -eq 1 ]]; then
|
|
43
|
-
rm -f "$DEFAULT_LOG_FILE"
|
|
44
|
-
fi
|
|
45
|
-
if [[ "$AUTO_DEFAULT_DB_DIR" -eq 1 ]]; then
|
|
46
|
-
rm -rf "$DEFAULT_DB_DIR"
|
|
47
|
-
fi
|
|
48
|
-
return "$exit_status"
|
|
49
|
-
}
|
|
50
|
-
trap cleanup EXIT
|
|
51
|
-
|
|
52
|
-
create_temp_dir() {
|
|
53
|
-
mktemp -d "${DB_DIR_BASE%/}/dingo-bp-pi-db-default.XXXXXX"
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
create_temp_file() {
|
|
57
|
-
mktemp "${DB_DIR_BASE%/}/dingo-bp-pi-default.XXXXXX.log"
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
resolve_path() {
|
|
61
|
-
local path="$1"
|
|
62
|
-
local current
|
|
63
|
-
local candidate
|
|
64
|
-
local part
|
|
65
|
-
local -a parts=()
|
|
66
|
-
|
|
67
|
-
if [[ -z "$path" ]]; then
|
|
68
|
-
return 1
|
|
69
|
-
fi
|
|
70
|
-
|
|
71
|
-
if [[ "$path" == /* ]]; then
|
|
72
|
-
current="/"
|
|
73
|
-
else
|
|
74
|
-
current="$(pwd -P)"
|
|
75
|
-
fi
|
|
76
|
-
|
|
77
|
-
local IFS='/'
|
|
78
|
-
read -r -a parts <<< "$path"
|
|
79
|
-
for part in "${parts[@]}"; do
|
|
80
|
-
case "$part" in
|
|
81
|
-
""|".")
|
|
82
|
-
continue
|
|
83
|
-
;;
|
|
84
|
-
"..")
|
|
85
|
-
if [[ "$current" != "/" ]]; then
|
|
86
|
-
current="${current%/*}"
|
|
87
|
-
if [[ -z "$current" ]]; then
|
|
88
|
-
current="/"
|
|
89
|
-
fi
|
|
90
|
-
fi
|
|
91
|
-
;;
|
|
92
|
-
*)
|
|
93
|
-
if [[ "$current" == "/" ]]; then
|
|
94
|
-
candidate="/$part"
|
|
95
|
-
else
|
|
96
|
-
candidate="$current/$part"
|
|
97
|
-
fi
|
|
98
|
-
if [[ -d "$candidate" ]]; then
|
|
99
|
-
current="$(cd "$candidate" && pwd -P)"
|
|
100
|
-
else
|
|
101
|
-
current="$candidate"
|
|
102
|
-
fi
|
|
103
|
-
;;
|
|
104
|
-
esac
|
|
105
|
-
done
|
|
106
|
-
|
|
107
|
-
printf '%s\n' "$current"
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
configure_time_cmd() {
|
|
111
|
-
if command -v gtime >/dev/null 2>&1 &&
|
|
112
|
-
gtime -f "elapsed=%e rss_kb=%M" true >/dev/null 2>&1; then
|
|
113
|
-
TIME_FORMAT_STYLE="gnu"
|
|
114
|
-
TIME_CMD=(gtime -f "elapsed=%e rss_kb=%M")
|
|
115
|
-
return 0
|
|
116
|
-
fi
|
|
117
|
-
|
|
118
|
-
if /usr/bin/time -f "elapsed=%e rss_kb=%M" true >/dev/null 2>&1; then
|
|
119
|
-
TIME_FORMAT_STYLE="gnu"
|
|
120
|
-
TIME_CMD=(/usr/bin/time -f "elapsed=%e rss_kb=%M")
|
|
121
|
-
return 0
|
|
122
|
-
fi
|
|
123
|
-
|
|
124
|
-
if /usr/bin/time -l true >/dev/null 2>&1; then
|
|
125
|
-
TIME_FORMAT_STYLE="bsd"
|
|
126
|
-
TIME_CMD=(/usr/bin/time -l)
|
|
127
|
-
return 0
|
|
128
|
-
fi
|
|
129
|
-
|
|
130
|
-
echo "error: failed to find a supported time command" >&2
|
|
131
|
-
return 1
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
validate_db_dir() {
|
|
135
|
-
local db_dir="$1"
|
|
136
|
-
local log_file="$2"
|
|
137
|
-
local resolved_db_dir
|
|
138
|
-
local resolved_base_dir
|
|
139
|
-
|
|
140
|
-
if [[ -z "$db_dir" || "$db_dir" == "/" || "$db_dir" == "." || "$db_dir" == "~" ]]; then
|
|
141
|
-
printf 'error: refusing to remove unsafe db_dir value %q\n' "$db_dir" >"$log_file"
|
|
142
|
-
return 1
|
|
143
|
-
fi
|
|
144
|
-
|
|
145
|
-
if ! resolved_db_dir="$(resolve_path "$db_dir")"; then
|
|
146
|
-
printf 'error: failed to resolve db_dir %q\n' "$db_dir" >"$log_file"
|
|
147
|
-
return 1
|
|
148
|
-
fi
|
|
149
|
-
if ! resolved_base_dir="$(resolve_path "$DB_DIR_BASE")"; then
|
|
150
|
-
printf 'error: failed to resolve DB_DIR_BASE %q\n' "$DB_DIR_BASE" >"$log_file"
|
|
151
|
-
return 1
|
|
152
|
-
fi
|
|
153
|
-
|
|
154
|
-
if [[ "$resolved_db_dir" == "$resolved_base_dir" ]]; then
|
|
155
|
-
printf 'error: refusing to remove db_dir %q because it resolves to the base directory %q\n' \
|
|
156
|
-
"$resolved_db_dir" "$resolved_base_dir" >"$log_file"
|
|
157
|
-
return 1
|
|
158
|
-
fi
|
|
159
|
-
|
|
160
|
-
case "$resolved_db_dir" in
|
|
161
|
-
"$resolved_base_dir"/*) ;;
|
|
162
|
-
*)
|
|
163
|
-
printf 'error: refusing to remove db_dir %q outside allowed base %q\n' \
|
|
164
|
-
"$resolved_db_dir" "$resolved_base_dir" >"$log_file"
|
|
165
|
-
return 1
|
|
166
|
-
;;
|
|
167
|
-
esac
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
extract_profile_line() {
|
|
171
|
-
local log_file="$1"
|
|
172
|
-
|
|
173
|
-
case "$TIME_FORMAT_STYLE" in
|
|
174
|
-
gnu)
|
|
175
|
-
awk '/elapsed=/{ line = $0 } END { print line }' "$log_file"
|
|
176
|
-
;;
|
|
177
|
-
bsd)
|
|
178
|
-
awk '
|
|
179
|
-
/^[[:space:]]*[0-9]+([.][0-9]+)?[[:space:]]+real([[:space:]]|$)/ {
|
|
180
|
-
elapsed = $1
|
|
181
|
-
}
|
|
182
|
-
/^[[:space:]]*[0-9]+[[:space:]]+maximum resident set size([[:space:]]|$)/ {
|
|
183
|
-
rss_kb = $1
|
|
184
|
-
}
|
|
185
|
-
END {
|
|
186
|
-
if (elapsed != "" || rss_kb != "") {
|
|
187
|
-
printf "elapsed=%s rss_kb=%s\n", elapsed, rss_kb
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
' "$log_file"
|
|
191
|
-
;;
|
|
192
|
-
*)
|
|
193
|
-
return 1
|
|
194
|
-
;;
|
|
195
|
-
esac
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
run_load_profile() {
|
|
199
|
-
local db_dir="$1"
|
|
200
|
-
local log_file="$2"
|
|
201
|
-
shift 2
|
|
202
|
-
|
|
203
|
-
validate_db_dir "$db_dir" "$log_file"
|
|
204
|
-
rm -rf "$db_dir"
|
|
205
|
-
: > "$log_file"
|
|
206
|
-
local -a env_args=(
|
|
207
|
-
PATH="$PATH"
|
|
208
|
-
HOME="${HOME:-/tmp}"
|
|
209
|
-
GOMAXPROCS="$GOMAXPROCS_VALUE"
|
|
210
|
-
DINGO_RUN_MODE=serve
|
|
211
|
-
DINGO_STORAGE_MODE=core
|
|
212
|
-
)
|
|
213
|
-
if [[ -n "$GOMEMLIMIT_VALUE" ]]; then
|
|
214
|
-
env_args+=(GOMEMLIMIT="$GOMEMLIMIT_VALUE")
|
|
215
|
-
fi
|
|
216
|
-
env -i \
|
|
217
|
-
"${env_args[@]}" \
|
|
218
|
-
"${TIME_CMD[@]}" \
|
|
219
|
-
./dingo \
|
|
220
|
-
--config /dev/null \
|
|
221
|
-
--blob badger \
|
|
222
|
-
--metadata sqlite \
|
|
223
|
-
--data-dir "$db_dir" \
|
|
224
|
-
"${DINGO_CACHE_ARGS[@]}" \
|
|
225
|
-
load "$IMMUTABLE_PATH" "$@" \
|
|
226
|
-
> "$log_file" 2>&1
|
|
227
|
-
|
|
228
|
-
extract_profile_line "$log_file"
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
parse_metric() {
|
|
232
|
-
local line="$1"
|
|
233
|
-
local key="$2"
|
|
234
|
-
echo "$line" | awk -v needle="$key" '{
|
|
235
|
-
for (i = 1; i <= NF; i++) {
|
|
236
|
-
split($i, kv, "=")
|
|
237
|
-
if (kv[1] == needle) {
|
|
238
|
-
print kv[2]
|
|
239
|
-
exit
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}'
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
configure_time_cmd
|
|
246
|
-
|
|
247
|
-
if [[ -n "$BLOCK_CACHE_SIZE_VALUE" ]]; then
|
|
248
|
-
DINGO_CACHE_ARGS+=(--block-cache-size "$BLOCK_CACHE_SIZE_VALUE")
|
|
249
|
-
fi
|
|
250
|
-
if [[ -n "$INDEX_CACHE_SIZE_VALUE" ]]; then
|
|
251
|
-
DINGO_CACHE_ARGS+=(--index-cache-size "$INDEX_CACHE_SIZE_VALUE")
|
|
252
|
-
fi
|
|
253
|
-
if [[ -n "$MEMTABLE_SIZE_VALUE" ]]; then
|
|
254
|
-
DINGO_CACHE_ARGS+=(--memtable-size "$MEMTABLE_SIZE_VALUE")
|
|
255
|
-
fi
|
|
256
|
-
|
|
257
|
-
DB_DIR_BASE="$(resolve_path "$DB_DIR_BASE")"
|
|
258
|
-
|
|
259
|
-
if [[ -z "$DEFAULT_DB_DIR" ]]; then
|
|
260
|
-
DEFAULT_DB_DIR="$(create_temp_dir)"
|
|
261
|
-
AUTO_DEFAULT_DB_DIR=1
|
|
262
|
-
fi
|
|
263
|
-
|
|
264
|
-
if [[ -z "$DEFAULT_LOG_FILE" ]]; then
|
|
265
|
-
DEFAULT_LOG_FILE="$(create_temp_file)"
|
|
266
|
-
AUTO_DEFAULT_LOG_FILE=1
|
|
267
|
-
fi
|
|
268
|
-
|
|
269
|
-
pushd "$ROOT_DIR" >/dev/null
|
|
270
|
-
|
|
271
|
-
env \
|
|
272
|
-
GOCACHE="$CACHE_DIR" \
|
|
273
|
-
GOMAXPROCS="$GOMAXPROCS_VALUE" \
|
|
274
|
-
./generate_benchmarks.sh \
|
|
275
|
-
"$TMP_BENCH_FILE" \
|
|
276
|
-
--write \
|
|
277
|
-
--packages ./ledger \
|
|
278
|
-
--bench 'Benchmark(BlockfetchNearTipThroughput|BlockfetchNearTipThroughputPredecoded|BlockfetchNearTipQueuedHeaderPredecoded|BlockfetchNearTipFlushOnlyPredecoded|VerifyBlockHeader)$' \
|
|
279
|
-
--benchtime "$BENCH_TIME" \
|
|
280
|
-
--title "Four-Thread Block Producer Sizing Benchmark Results (Non-Pi Host)" \
|
|
281
|
-
--scope "Four-thread block producer path (GOMAXPROCS=${GOMAXPROCS_VALUE}) in core mode on a non-Pi host" \
|
|
282
|
-
--data-source "database/immutable/testdata plus local immutable load runs"
|
|
283
|
-
|
|
284
|
-
env \
|
|
285
|
-
GOCACHE="$CACHE_DIR" \
|
|
286
|
-
GOFLAGS=-buildvcs=false \
|
|
287
|
-
CGO_ENABLED=0 \
|
|
288
|
-
go build -o ./dingo ./cmd/dingo
|
|
289
|
-
|
|
290
|
-
default_line="$(run_load_profile "$DEFAULT_DB_DIR" "$DEFAULT_LOG_FILE")"
|
|
291
|
-
|
|
292
|
-
default_elapsed="$(parse_metric "$default_line" "elapsed")"
|
|
293
|
-
default_rss_kb="$(parse_metric "$default_line" "rss_kb")"
|
|
294
|
-
|
|
295
|
-
if [[ ! "$default_elapsed" =~ ^[0-9]+([.][0-9]+)?$ ]]; then
|
|
296
|
-
echo "error: failed to parse numeric elapsed value from $DEFAULT_LOG_FILE: ${default_elapsed:-<empty>}" >&2
|
|
297
|
-
exit 1
|
|
298
|
-
fi
|
|
299
|
-
if [[ ! "$default_rss_kb" =~ ^[0-9]+$ ]]; then
|
|
300
|
-
echo "error: failed to parse numeric rss_kb value from $DEFAULT_LOG_FILE: ${default_rss_kb:-<empty>}" >&2
|
|
301
|
-
exit 1
|
|
302
|
-
fi
|
|
303
|
-
|
|
304
|
-
default_rss_mb="$(awk "BEGIN { printf \"%.1f\", ${default_rss_kb} / 1024 }")"
|
|
305
|
-
rss_limit_kb=$((RSS_LIMIT_MB * 1024))
|
|
306
|
-
|
|
307
|
-
if (( default_rss_kb > rss_limit_kb )); then
|
|
308
|
-
echo "error: peak RSS ${default_rss_mb} MB exceeds limit ${RSS_LIMIT_MB} MB" >&2
|
|
309
|
-
exit 1
|
|
310
|
-
fi
|
|
311
|
-
|
|
312
|
-
{
|
|
313
|
-
echo "# Four-Thread Block Producer Sizing Report (Non-Pi Host)"
|
|
314
|
-
echo
|
|
315
|
-
echo "Assumptions:"
|
|
316
|
-
printf -- "- \`storageMode=core\`\n"
|
|
317
|
-
printf -- "- \`runMode=serve\`, \`blob=badger\`, \`metadata=sqlite\`\n"
|
|
318
|
-
printf -- "- \`GOMAXPROCS=%s\`\n" "$GOMAXPROCS_VALUE"
|
|
319
|
-
printf -- "- target peak RSS: \`<= %s MB\`\n" "$RSS_LIMIT_MB"
|
|
320
|
-
printf -- "- immutable fixture: \`%s\`\n" "$IMMUTABLE_PATH"
|
|
321
|
-
if [[ -n "$GOMEMLIMIT_VALUE" ]]; then
|
|
322
|
-
printf -- "- test-only \`GOMEMLIMIT=%s\`\n" "$GOMEMLIMIT_VALUE"
|
|
323
|
-
fi
|
|
324
|
-
if [[ -n "$BLOCK_CACHE_SIZE_VALUE" || -n "$INDEX_CACHE_SIZE_VALUE" || -n "$MEMTABLE_SIZE_VALUE" ]]; then
|
|
325
|
-
echo "- explicit Badger test-only overrides:"
|
|
326
|
-
if [[ -n "$BLOCK_CACHE_SIZE_VALUE" ]]; then
|
|
327
|
-
printf -- " - \`--block-cache-size=%s\`\n" "$BLOCK_CACHE_SIZE_VALUE"
|
|
328
|
-
fi
|
|
329
|
-
if [[ -n "$INDEX_CACHE_SIZE_VALUE" ]]; then
|
|
330
|
-
printf -- " - \`--index-cache-size=%s\`\n" "$INDEX_CACHE_SIZE_VALUE"
|
|
331
|
-
fi
|
|
332
|
-
if [[ -n "$MEMTABLE_SIZE_VALUE" ]]; then
|
|
333
|
-
printf -- " - \`--memtable-size=%s\`\n" "$MEMTABLE_SIZE_VALUE"
|
|
334
|
-
fi
|
|
335
|
-
fi
|
|
336
|
-
echo "- measurements were collected on non-Pi hardware and are a sizing proxy, not Raspberry Pi device benchmarks"
|
|
337
|
-
echo "- block producer peer count remains small; this is not a relay profile"
|
|
338
|
-
echo
|
|
339
|
-
echo "## Load Footprint"
|
|
340
|
-
echo
|
|
341
|
-
echo "| Profile | Elapsed | Peak RSS | Notes |"
|
|
342
|
-
echo "| --- | --- | --- | --- |"
|
|
343
|
-
if [[ -n "$BLOCK_CACHE_SIZE_VALUE" || -n "$INDEX_CACHE_SIZE_VALUE" || -n "$MEMTABLE_SIZE_VALUE" || -n "$GOMEMLIMIT_VALUE" ]]; then
|
|
344
|
-
printf -- "| \`core-constrained\` | \`%ss\` | \`%s MB\` | Explicit test-only memory/cache overrides |\n" "$default_elapsed" "$default_rss_mb"
|
|
345
|
-
else
|
|
346
|
-
printf -- "| \`core-default\` | \`%ss\` | \`%s MB\` | Current default \`serve/core\` cache profile |\n" "$default_elapsed" "$default_rss_mb"
|
|
347
|
-
fi
|
|
348
|
-
echo
|
|
349
|
-
echo "## Recommendation"
|
|
350
|
-
echo
|
|
351
|
-
printf -- "For Raspberry Pi-class sizing in \`storageMode=core\`, keep production defaults aligned with normal Badger behavior and use explicit memory/cache constraints only in this harness when validating low-memory targets.\n"
|
|
352
|
-
printf -- "This run stayed under the configured \`%s MB\` RSS limit.\n" "$RSS_LIMIT_MB"
|
|
353
|
-
echo "Explicit Badger cache settings still override these defaults if an operator wants to tune further."
|
|
354
|
-
echo "Treat this as a sizing baseline rather than a direct Raspberry Pi hardware measurement."
|
|
355
|
-
echo
|
|
356
|
-
cat "$TMP_BENCH_FILE"
|
|
357
|
-
} > "$OUTPUT_FILE"
|
|
358
|
-
|
|
359
|
-
popd >/dev/null
|