Skip to content

Commit 22685bd

Browse files
barnabasbusachetanybclaude
authored
fix(zkboost): fill mock_proving_time defaults from slot duration (#1401)
## Summary - A partial override like `mock_proving_time: { kind: constant }` silently became 0ms because dict.get on the missing `ms` key returned 0, while omitting `mock_proving_time` entirely fell back to the launcher's hardcoded 6000ms — surprising and inconsistent. - Fill in kind-appropriate defaults during input validation so partial overrides behave like the no-override case. Defaults now scale with `slot_duration_ms` (2/3 of slot): `constant.ms`, `random.min_ms`/`max_ms` (default_ms/2 .. default_ms*2), and `linear.ms_per_mgas`. - Updated the launcher's defensive fallback and the auto-injected default zkvm to use the same 2/3-of-slot scaling. ## Test plan - [ ] `kurtosis lint --format .` passes - [ ] `zkvms: [{ kind: mock, proof_type: reth-zisk }]` → mock proving time defaults to 4000ms on 6s slots (2/3 of 6000) - [ ] `zkvms: [{ kind: mock, proof_type: reth-zisk, mock_proving_time: { kind: constant } }]` → resolves to 4000ms (no longer 0ms) - [ ] `zkvms: [{ kind: mock, proof_type: reth-zisk, mock_proving_time: { kind: random } }]` → resolves to 2000–8000ms on 6s slots - [ ] On a 12s slot, defaults scale to 8000ms / 4000–16000ms --------- Co-authored-by: Chetany Bhardwaj <chetanyiot@gmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b6bb63b commit 22685bd

3 files changed

Lines changed: 73 additions & 46 deletions

File tree

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,8 +1226,8 @@ zkboost_params:
12261226
- name: zkboost
12271227
el_participant_index: 0
12281228
# List of zkVM backend configurations.
1229-
# If empty or not set, the default shown below (a mock reth-zisk zkvm) is
1230-
# auto-configured. Each entry must have a unique proof_type.
1229+
# If empty or not set, a mock reth-zisk zkvm is auto-configured with
1230+
# random timing scaled to slot duration. Each entry must have a unique proof_type.
12311231
#
12321232
# Common fields for all entries:
12331233
# kind (required): the zkVM backend type
@@ -1236,13 +1236,13 @@ zkboost_params:
12361236
# "external" - connects to an already-deployed prover via HTTP
12371237
# proof_type (required): identifies the EL client + zkVM combination
12381238
# "ethrex-risc0", "ethrex-sp1", "ethrex-zisk", "reth-openvm", "reth-risc0", "reth-sp1", "reth-zisk"
1239-
# proof_timeout_secs: timeout for proof generation in seconds (default: 12, must be > 0)
1239+
# proof_timeout_secs: timeout for proof generation in seconds (default: 3/4 of slot duration, must be > 0)
12401240
#
12411241
# Mock-specific fields (only for kind: mock):
1242-
# mock_proving_time: controls simulated proving duration (default: { kind: constant, ms: 6000 })
1243-
# { kind: constant, ms: <ms> } - fixed duration
1244-
# { kind: random, min_ms: <min>, max_ms: <max> } - uniformly random, min_ms must be <= max_ms
1245-
# { kind: linear, ms_per_mgas: <ms> } - proportional to block per million gas usage
1242+
# mock_proving_time: controls simulated proving duration
1243+
# { kind: constant, ms: <ms> } - fixed duration (default: 2/3 of slot_duration_ms)
1244+
# { kind: random, min_ms: <min>, max_ms: <max> } - uniformly random (defaults: min=1/3, max=4/3 of slot)
1245+
# { kind: linear, ms_per_mgas: <ms> } - proportional to block gas (default: 150 ms/Mgas)
12461246
# mock_proof_size: simulated proof size in bytes, must be >= 32 (default: 131072 / 128 KiB)
12471247
# mock_failure: whether to simulate proving failures (default: false)
12481248
#

src/package_io/input_parser.star

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -500,14 +500,15 @@ def input_parser(plan, input_args):
500500

501501
# Inject default mock zkvm if none configured globally or per instance.
502502
if len(result["zkboost_params"]["zkvms"]) == 0 and not has_instance_zkvms:
503+
default_ms = result["network_params"]["slot_duration_ms"] * 2 // 3
503504
result["zkboost_params"]["zkvms"] = [
504505
{
505506
"kind": "mock",
506507
"proof_type": "reth-zisk",
507508
"mock_proving_time": {
508509
"kind": "random",
509-
"min_ms": 2000,
510-
"max_ms": 8000,
510+
"min_ms": default_ms // 2,
511+
"max_ms": default_ms * 2,
511512
},
512513
"mock_proof_size": 128 << 10,
513514
},
@@ -592,11 +593,17 @@ def input_parser(plan, input_args):
592593
if proof_type not in configured_proof_types:
593594
configured_proof_types.append(proof_type)
594595

595-
proof_timeout = zkvm.get("proof_timeout_secs", 12)
596-
if proof_timeout <= 0:
596+
# Default proof_timeout_secs to 3/4 of slot duration (minimum 1 second)
597+
default_proof_timeout = max(
598+
1, result["network_params"]["slot_duration_ms"] * 3 // 4000
599+
)
600+
zkvm["proof_timeout_secs"] = zkvm.get(
601+
"proof_timeout_secs", default_proof_timeout
602+
)
603+
if zkvm["proof_timeout_secs"] <= 0:
597604
fail(
598605
"{0}: proof_timeout_secs must be > 0, got {1}".format(
599-
zkvm_path, proof_timeout
606+
zkvm_path, zkvm["proof_timeout_secs"]
600607
)
601608
)
602609

@@ -605,32 +612,55 @@ def input_parser(plan, input_args):
605612
fail("{0}: external zkvm requires 'endpoint'".format(zkvm_path))
606613

607614
if kind == "mock":
615+
# Normalize mock_proving_time - handle omitted, null, and partial cases
608616
mock_proving_time = zkvm.get("mock_proving_time")
609-
if mock_proving_time != None:
610-
pt_kind = mock_proving_time.get("kind", "constant")
611-
if pt_kind not in ["constant", "random", "linear"]:
617+
if mock_proving_time == None:
618+
mock_proving_time = {}
619+
pt_kind = mock_proving_time.get("kind", "constant")
620+
if pt_kind not in ["constant", "random", "linear"]:
621+
fail(
622+
"{0}: unsupported mock_proving_time kind '{1}', please use 'constant', 'random' or 'linear'".format(
623+
zkvm_path, pt_kind
624+
)
625+
)
626+
# Fill in kind-appropriate defaults so partial or omitted
627+
# mock_proving_time doesn't silently become 0ms.
628+
# Duration defaults scale with slot duration (2/3 of slot).
629+
default_ms = result["network_params"]["slot_duration_ms"] * 2 // 3
630+
mock_proving_time["kind"] = pt_kind
631+
if pt_kind == "constant":
632+
mock_proving_time["ms"] = mock_proving_time.get("ms", default_ms)
633+
elif pt_kind == "random":
634+
mock_proving_time["min_ms"] = mock_proving_time.get(
635+
"min_ms", default_ms // 2
636+
)
637+
mock_proving_time["max_ms"] = mock_proving_time.get(
638+
"max_ms", default_ms * 2
639+
)
640+
if mock_proving_time["min_ms"] > mock_proving_time["max_ms"]:
612641
fail(
613-
"{0}: unsupported mock_proving_time kind '{1}', please use 'constant', 'random' or 'linear'".format(
614-
zkvm_path, pt_kind
642+
"{0}: mock_proving_time random min_ms ({1}) must be <= max_ms ({2})".format(
643+
zkvm_path,
644+
mock_proving_time["min_ms"],
645+
mock_proving_time["max_ms"],
615646
)
616647
)
617-
if pt_kind == "random":
618-
min_ms = mock_proving_time.get("min_ms", 0)
619-
max_ms = mock_proving_time.get("max_ms", 0)
620-
if min_ms > max_ms:
621-
fail(
622-
"{0}: mock_proving_time random min_ms ({1}) must be <= max_ms ({2})".format(
623-
zkvm_path, min_ms, max_ms
624-
)
625-
)
648+
elif pt_kind == "linear":
649+
# ms_per_mgas is a rate (ms per mega-gas), not a duration
650+
mock_proving_time["ms_per_mgas"] = mock_proving_time.get(
651+
"ms_per_mgas", 150
652+
)
653+
zkvm["mock_proving_time"] = mock_proving_time
626654

627-
mock_proof_size = zkvm.get("mock_proof_size", 128 << 10)
628-
if mock_proof_size < 32:
655+
# Set mock_proof_size and mock_failure defaults
656+
zkvm["mock_proof_size"] = zkvm.get("mock_proof_size", 128 << 10)
657+
if zkvm["mock_proof_size"] < 32:
629658
fail(
630659
"{0}: mock_proof_size must be >= 32, got {1}".format(
631-
zkvm_path, mock_proof_size
660+
zkvm_path, zkvm["mock_proof_size"]
632661
)
633662
)
663+
zkvm["mock_failure"] = zkvm.get("mock_failure", False)
634664

635665
_validate_ere_gpu_config(effective_ere_zkvms_by_proof_type.values())
636666
_validate_requested_proof_types(result["participants"], configured_proof_types)

src/zkboost/zkboost_launcher.star

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ def launch_zkboost(
6565
):
6666
tolerations = shared_utils.get_tolerations(global_tolerations=global_tolerations)
6767

68-
default_proof_timeout_secs = network_params.seconds_per_slot * 3 // 4
69-
7068
# Per-instance zkvms: each instance falls back to the global
7169
# `zkboost_params.zkvms` if no per-instance list is set. Resolve artifacts
7270
# (ere image/elf_url, verifier program_vk_url) for each, then collect every
@@ -122,9 +120,7 @@ def launch_zkboost(
122120
entry = {
123121
"Kind": zkvm["kind"],
124122
"ProofType": zkvm["proof_type"],
125-
"ProofTimeoutSecs": zkvm.get(
126-
"proof_timeout_secs", default_proof_timeout_secs
127-
),
123+
"ProofTimeoutSecs": zkvm["proof_timeout_secs"],
128124
}
129125
if zkvm["kind"] == "ere":
130126
entry["Endpoint"] = ere_server_endpoints[zkvm["proof_type"]]
@@ -137,18 +133,19 @@ def launch_zkboost(
137133
# zkboost loads ere-verifier-* in-process; only the .vk URL is needed.
138134
entry["ProgramVkUrl"] = zkvm["program_vk_url"]
139135
elif zkvm["kind"] == "mock":
140-
mock_proving_time = zkvm.get(
141-
"mock_proving_time", {"kind": "constant", "ms": 6000}
142-
)
143-
entry["MockProvingTimeKind"] = mock_proving_time.get("kind", "constant")
144-
entry["MockProvingTimeConstantMs"] = mock_proving_time.get("ms", 6000)
145-
entry["MockProvingTimeRandomMinMs"] = mock_proving_time.get("min_ms", 0)
146-
entry["MockProvingTimeRandomMaxMs"] = mock_proving_time.get("max_ms", 0)
147-
entry["MockProvingTimeLinearMsPerMgas"] = mock_proving_time.get(
148-
"ms_per_mgas", 0
149-
)
150-
entry["MockProofSize"] = zkvm.get("mock_proof_size", 128 << 10)
151-
entry["MockFailure"] = zkvm.get("mock_failure", False)
136+
mock_proving_time = zkvm["mock_proving_time"]
137+
entry["MockProvingTimeKind"] = mock_proving_time["kind"]
138+
if mock_proving_time["kind"] == "constant":
139+
entry["MockProvingTimeConstantMs"] = mock_proving_time["ms"]
140+
elif mock_proving_time["kind"] == "random":
141+
entry["MockProvingTimeRandomMinMs"] = mock_proving_time["min_ms"]
142+
entry["MockProvingTimeRandomMaxMs"] = mock_proving_time["max_ms"]
143+
elif mock_proving_time["kind"] == "linear":
144+
entry["MockProvingTimeLinearMsPerMgas"] = mock_proving_time[
145+
"ms_per_mgas"
146+
]
147+
entry["MockProofSize"] = zkvm["mock_proof_size"]
148+
entry["MockFailure"] = zkvm["mock_failure"]
152149
zkvms.append(entry)
153150

154151
template_data = {

0 commit comments

Comments
 (0)