Skip to content

Commit a2c1a43

Browse files
tomusdrwclaude
andauthored
Add STATE_BACKEND support for A/B benchmarking (#118)
* Add STATE_BACKEND support for A/B benchmarking fjall vs lmdb Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Pass STATE_BACKEND directly to JAM_FUZZ_DB (support full fjall/lmdb) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Bump conformance timeout to 35min for full-fjall backend Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6682487 commit a2c1a43

10 files changed

Lines changed: 46 additions & 12 deletions

.github/workflows/docker-imports-full.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ on:
77
description: 'typeberry version: `next` (default), `<semver>-<sha>` (pre-release), or `<semver>` (release)'
88
required: false
99
default: 'next'
10+
backend:
11+
description: 'State backend: fjall, lmdb, fjall-hybrid, lmdb-hybrid (default: version default)'
12+
required: false
13+
default: ''
1014
schedule:
1115
# 3:30 AM Europe/Warsaw (1:30 UTC, using UTC+2 summer time)
1216
- cron: '30 1 * * *'
@@ -60,6 +64,8 @@ jobs:
6064
- name: Run full-chain import test
6165
run: |
6266
npm exec tsx --test tests/docker-imports-full.test.ts
67+
env:
68+
STATE_BACKEND: ${{ github.event.inputs.backend || '' }}
6369

6470
- name: Reap test containers and volumes
6571
if: always()

.github/workflows/docker-imports.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ on:
1111
description: 'typeberry version: `next` (default), `<semver>-<sha>` (pre-release), or `<semver>` (release)'
1212
required: false
1313
default: 'next'
14+
backend:
15+
description: 'State backend: fjall, lmdb, fjall-hybrid, lmdb-hybrid (default: version default)'
16+
required: false
17+
default: ''
1418
repository_dispatch:
1519
schedule:
1620
# 1x/day (reduced from 5x) — staggered overnight to relieve the single shared self-hosted runner.
@@ -66,6 +70,8 @@ jobs:
6670
- name: Run Docker Imports test
6771
run: |
6872
npm exec tsx --test tests/docker-imports.test.ts
73+
env:
74+
STATE_BACKEND: ${{ github.event.inputs.backend || '' }}
6975

7076
- name: Reap test containers and volumes
7177
if: always()

.github/workflows/minifuzz.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ on:
1111
description: 'typeberry version: `next` (default), `<semver>-<sha>` (pre-release), or `<semver>` (release)'
1212
required: false
1313
default: 'next'
14+
backend:
15+
description: 'State backend: fjall, lmdb, fjall-hybrid, lmdb-hybrid (default: version default)'
16+
required: false
17+
default: ''
1418
repository_dispatch:
1519
schedule:
1620
# 2x/day (reduced from 5x) — staggered overnight to relieve the single shared self-hosted runner.
@@ -57,6 +61,8 @@ jobs:
5761
- name: Run Minifuzz ${{ matrix.test }} test
5862
run: |
5963
npm exec tsx --test tests/minifuzz/${{ matrix.test }}.test.ts
64+
env:
65+
STATE_BACKEND: ${{ github.event.inputs.backend || '' }}
6066

6167
- name: Reap test containers and volumes
6268
if: always()

.github/workflows/npm-minifuzz.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ on:
1111
description: 'typeberry version: `next` (default), `<semver>-<sha>` (pre-release), or `<semver>` (release)'
1212
required: false
1313
default: 'next'
14+
backend:
15+
description: 'State backend: fjall, lmdb, fjall-hybrid, lmdb-hybrid (default: version default)'
16+
required: false
17+
default: ''
1418
repository_dispatch:
1519
schedule:
1620
# 2x/day (reduced from 5x) — staggered overnight to relieve the single shared self-hosted runner.
@@ -56,3 +60,5 @@ jobs:
5660
- name: Run Minifuzz ${{ matrix.test }} test (npm image)
5761
run: |
5862
npm exec tsx --test tests/minifuzz/${{ matrix.test }}.test.ts
63+
env:
64+
STATE_BACKEND: ${{ github.event.inputs.backend || '' }}

.github/workflows/picofuzz-full.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ on:
77
description: 'typeberry version: `next` (default), `<semver>-<sha>` (pre-release), or `<semver>` (release)'
88
required: false
99
default: 'next'
10+
backend:
11+
description: 'State backend: fjall, lmdb, fjall-hybrid, lmdb-hybrid (default: version default)'
12+
required: false
13+
default: ''
1014
schedule:
1115
# 4:30 AM Europe/Warsaw (2:30 UTC, using UTC+2 summer time)
1216
- cron: '30 2 * * *'
@@ -85,6 +89,8 @@ jobs:
8589
- name: Run picofuzz full chain
8690
run: |
8791
npm exec tsx --test tests/picofuzz/full_chain.test.ts
92+
env:
93+
STATE_BACKEND: ${{ github.event.inputs.backend || '' }}
8894

8995
- name: Upload CSV results
9096
uses: actions/upload-artifact@v7

.github/workflows/picofuzz.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ on:
1111
description: 'typeberry version: `next` (default), `<semver>-<sha>` (pre-release), or `<semver>` (release)'
1212
required: false
1313
default: 'next'
14+
backend:
15+
description: 'State backend: fjall, lmdb, fjall-hybrid, lmdb-hybrid (default: version default)'
16+
required: false
17+
default: ''
1418
repository_dispatch:
1519
schedule:
1620
# 2x/day (reduced from 5x) — staggered overnight to relieve the single shared self-hosted runner.
@@ -100,6 +104,8 @@ jobs:
100104
- name: Run picofuzz ${{ matrix.test }}
101105
run: |
102106
npm exec tsx --test tests/picofuzz/${{ matrix.test }}.test.ts
107+
env:
108+
STATE_BACKEND: ${{ github.event.inputs.backend || '' }}
103109

104110
- name: Upload CSV results
105111
uses: actions/upload-artifact@v7

tests/common.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ for (const sig of ["SIGINT", "SIGTERM", "SIGHUP"] as const) {
6060
*/
6161
export const TYPEBERRY_IMAGE = process.env.TYPEBERRY_IMAGE ?? "typeberry:test";
6262

63+
const STATE_BACKEND = process.env.STATE_BACKEND ?? "";
64+
6365
const DOCKER_OPTIONS = (mem = "512m") => [
6466
"--cpu-shares",
6567
"2048",
@@ -146,6 +148,9 @@ export async function typeberry({
146148
}) {
147149
const containerName = uniqueContainerName("typeberry");
148150
trackedContainers.add(containerName);
151+
if (STATE_BACKEND && !options.inMemory) {
152+
dockerArgs = [...dockerArgs, "-e", `JAM_FUZZ_DB=${STATE_BACKEND}`];
153+
}
149154
// Global config directives applied before the `fuzz-target` subcommand, in
150155
// order. `--config=default` is the implicit default; we list it explicitly so
151156
// jq-style overrides have a base config to layer onto.
@@ -157,13 +162,6 @@ export async function typeberry({
157162
configArgs.push('--config=.flavor="full"');
158163
}
159164
if (options.inMemory === true) {
160-
// Force a pure in-memory state db. The default config sets
161-
// `database_base_path: "./database"`, which the fuzz-target inherits and
162-
// turns into an on-disk LMDB/fjall store; clearing it makes the node's
163-
// resolveFuzzDbBase() return undefined → in-memory backend. Used by the
164-
// conformance suite, whose short per-vector genesis resets are slow on the
165-
// on-disk fuzz db and don't need its heap-bounding (state roots are
166-
// storage-agnostic, so correctness is unaffected).
167165
configArgs.push('--config=.database_base_path="undefined"');
168166
}
169167
const typeberry = ExternalProcess.spawn(

tests/docker-imports-full.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { ExternalProcess } from "./external-process.js";
88
// so this is sized well above that. Kept under the workflow's 390-min job cap so
99
// the test self-aborts and reaps its container before GitHub hard-kills the job.
1010
const TEST_TIMEOUT = 360 * 60 * 1_000;
11+
const STATE_BACKEND = process.env.STATE_BACKEND ?? "";
1112

1213
// The dump holds blocks for time slots 0..100051; typeberry logs the slot of
1314
// the best block, so reaching the last block prints `Best: #100051`
@@ -33,6 +34,7 @@ describe("Docker image can import the full-chainspec block dump", { timeout: TES
3334
"--config=default",
3435
'--config=.flavor="full"',
3536
"--config=.chain_spec=/block-dumps/full/chain-spec-full.json",
37+
...(STATE_BACKEND ? [`--config=.state_backend="${STATE_BACKEND}"`] : []),
3638
"import",
3739
"/block-dumps/full/chain-100k.bin",
3840
)

tests/docker-imports.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { TYPEBERRY_IMAGE } from "./common.js";
33
import { ExternalProcess } from "./external-process.js";
44

55
const TEST_TIMEOUT = 5 * 60 * 1_000;
6+
const STATE_BACKEND = process.env.STATE_BACKEND ?? "";
67

78
describe("Docker image can import block dumps", { timeout: TEST_TIMEOUT }, () => {
89
["fallback", "safrole", "storage", "storage_light"].forEach((dir) => {
@@ -17,6 +18,7 @@ describe("Docker image can import block dumps", { timeout: TEST_TIMEOUT }, () =>
1718
TYPEBERRY_IMAGE,
1819
"--config=default",
1920
"--config=.chain_spec=/block-dumps/chain-spec.json",
21+
...(STATE_BACKEND ? [`--config=.state_backend="${STATE_BACKEND}"`] : []),
2022
"import",
2123
`/block-dumps/${dir}.bin`,
2224
).terminateAfter(TEST_TIMEOUT);

tests/picofuzz/conformance.test.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ runPicofuzzTest("conformance", EXAMPLES_DIR, {
99
noLogs: true,
1010
ignore: [],
1111
highMemory: true,
12-
// Run with a pure in-memory state db. Conformance re-initializes genesis state
13-
// on every vector, which is pathologically slow on the on-disk fuzz db (the
14-
// genesis reset re-opens/wipes the keyspace each time) — the on-disk fjall
15-
// backend pushed this suite past its timeout. State roots don't depend on the
16-
// storage backend, so in-memory keeps conformance correct and fast.
1712
inMemory: true,
13+
timeoutMs: 45 * 60 * 1000,
1814
});

0 commit comments

Comments
 (0)