@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.
@@ -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