Skip to content

Commit ab3e21f

Browse files
committed
shadow-testing: fix prover stack overflow by adding RUST_MIN_STACK
- Add export RUST_MIN_STACK=16777216 to 04-prover-up.sh - Document the batch proof stack overflow issue in LESSONS_LEARNED.md - Chunk proofs work with default stack, but batch/bundle proofs need 16MB
1 parent 02e375b commit ab3e21f

2 files changed

Lines changed: 121 additions & 0 deletions

File tree

tests/shadow-testing/docs/LESSONS_LEARNED.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,123 @@ cast call 0xA0673eC0A48aa924f067F1274EcD281A10c5f19F \
596596
- [ ] Relayer started with `--config <path>` and `--min-codec-version 10`
597597
- [ ] Target bundles/batches reset to `rollup_status = 1`
598598
- [ ] Parent batch exists in shadow DB
599+
600+
---
601+
602+
## 2026-06-04: Shadow Testing with New zkvm-prover — Bundles 13450-13454
603+
604+
### What Happened
605+
Attempted to prove bundles 13450-13454 using the local shadow prover (current build with OpenVM 1.6.0 / zkvm-prover `ed3b964`). The bundles and their batches/chunks were imported from Sepolia production RDS.
606+
607+
### Lesson 1: Import Production Data, Then Clear Proofs and Reset Status
608+
609+
**Wrong approach** (what was done initially):
610+
- Imported bundles with production proofs from RDS
611+
- Kept the proofs in the DB
612+
- Tried to assign bundle tasks directly to the prover
613+
- Coordinator failed with `ProofEnum deserialization` error because the imported proofs were generated by a different zkvm-prover version
614+
615+
**Correct approach**:
616+
1. Import raw metadata (batch headers, chunk info, L2 blocks, state roots) from RDS
617+
2. **Clear all `proof` fields** after import:
618+
```sql
619+
UPDATE chunk SET proof = NULL, proving_status = 1, ... WHERE ...;
620+
UPDATE batch SET proof = NULL, proving_status = 1, chunk_proofs_status = 0, ... WHERE ...;
621+
UPDATE bundle SET proof = NULL, proving_status = 1, batch_proofs_status = 1, ... WHERE ...;
622+
```
623+
3. Let the local prover regenerate all proofs from scratch
624+
4. The coordinator verifies the newly-generated proofs
625+
626+
**Why**: Proofs are tied to the specific zkvm-prover / circuit version. The `StarkProof` struct uses `bincode_v1` serialization for `Proof<SC>`, and the binary format changes when the `openvm-stark-backend` or `openvm-sdk` versions change. Proofs generated by version `f18523c` cannot be deserialized by version `ed3b964`.
627+
628+
### Lesson 2: Prover Config Must Use Valid Proof Types
629+
630+
**Wrong config**:
631+
```json
632+
"supported_proof_types": [0, 1, 2, 3]
633+
```
634+
Type `0` = `ProofTypeUndefined`, which the coordinator rejects with `illegal proof type: 0`.
635+
636+
**Correct config**:
637+
```json
638+
"supported_proof_types": [1, 2, 3]
639+
```
640+
- `1` = Chunk
641+
- `2` = Batch
642+
- `3` = Bundle
643+
644+
### Lesson 3: Prover Binary Takes Only `--config` Flag
645+
646+
**Wrong invocation**:
647+
```bash
648+
prover --config prover.json --http.addr 0.0.0.0 --http.port 10080
649+
```
650+
The prover binary does NOT accept `--http.addr` or `--http.port`. It only takes `--config <path>`.
651+
652+
**Correct invocation**:
653+
```bash
654+
prover --config prover.json
655+
```
656+
The listener address goes in the config file:
657+
```json
658+
"health_listener_addr": "127.0.0.1:10080"
659+
```
660+
661+
### Lesson 4: GPU OOM When Running Multiple Provers Concurrently
662+
663+
**Symptom**: Running 4 provers (one per GPU) caused repeated CUDA OOM errors:
664+
```
665+
GPU allocation failed: OutOfMemory { requested: 4294967296, available: 2965372928 }
666+
thread 'tokio-rt-worker' panicked at ... cudaErrorMemoryAllocation: out of memory
667+
```
668+
669+
**Root Cause**: Each prover allocates a large GPU memory pool for circuit proving. Running multiple provers on the same physical GPU (or even different GPUs if the system is under memory pressure) exceeds available VRAM.
670+
671+
**Mitigation**:
672+
- Use the script's default of 2 GPUs (`GPUS="0,1"`) instead of 4
673+
- Or run provers sequentially on a single GPU
674+
- Monitor GPU memory with `nvidia-smi` during proving
675+
676+
**Note**: With 1-2 provers on RTX 3090s, chunk proof generation takes ~700-800s. Batch and bundle proofs take longer.
677+
678+
### Lesson 5: GORM `[]byte` Mapping for PostgreSQL `bytea` Works Correctly
679+
680+
**Initial suspicion**: The `json.Unmarshal(batch.Proof, &message.OpenVMBatchProof)` failure was thought to be caused by GORM corrupting the `bytea` field.
681+
682+
**Verification**: A standalone Go test using the exact same GORM model and PostgreSQL `bytea` type successfully read and unmarshaled all batch proofs (1,089,806 bytes each).
683+
684+
**Conclusion**: GORM correctly handles PostgreSQL `bytea` fields. The actual deserialization failure happens in the Rust `libzkp` layer (`gen_universal_task`), not in Go.
685+
686+
### Pre-Proving Checklist for New Guest Version Tests
687+
688+
- [ ] Import raw data from RDS (exclude `proof` columns, or clear them after import)
689+
- [ ] Reset `proving_status` to 1 for all chunks, batches, bundles
690+
- [ ] Reset `chunk_proofs_status` to 0 for batches
691+
- [ ] Reset `batch_proofs_status` to 1 for bundles
692+
- [ ] Prover config has `"supported_proof_types": [1, 2, 3]` (NOT `[0, 1, 2, 3]`)
693+
- [ ] Prover launched with `--config <path>` only (no `--http.addr`/`--http.port`)
694+
- [ ] Coordinator asset hashes match prover circuit hashes
695+
- [ ] GPU count is appropriate for available VRAM (2 GPUs recommended for RTX 3090)
696+
- [ ] Shadow bypass is configured if testing finalize without real on-chain verification
697+
698+
### 6. Prover Batch Proof Stack Overflow — Set `RUST_MIN_STACK`
699+
700+
**Date**: 2026-06-04
701+
702+
**Symptom**: After chunk proofs succeed, prover crashes during batch proof generation with:
703+
```
704+
thread 'tokio-rt-worker' has overflowed its stack
705+
fatal runtime error: stack overflow, aborting
706+
```
707+
Crash occurs in `gen_proof_universal` during aggregation keygen, right after `coset_lde_batch`.
708+
709+
**Root Cause**: The default Rust thread stack size (2 MB) is insufficient for OpenVM 1.6.0 batch/bundle proof generation. Chunk proofs work fine, but batch proofs require deeper recursion in the STARK prover.
710+
711+
**Fix**: Set `RUST_MIN_STACK=16777216` (16 MB) before starting the prover. The `zkvm-prover/Makefile` already sets this, but custom startup scripts must also export it:
712+
713+
```bash
714+
export RUST_MIN_STACK=16777216
715+
CUDA_VISIBLE_DEVICES="$gpu_id" nohup "$PROVER_BIN" --config "$config_file" > "$log_file" 2>&1 &
716+
```
717+
718+
**Lesson**: Always ensure `RUST_MIN_STACK` is exported in prover startup scripts, not just in the build Makefile.

tests/shadow-testing/scripts/04-prover-up.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ EOF
9090

9191
log_info "Starting prover on GPU $gpu_id..."
9292

93+
export RUST_MIN_STACK=16777216
9394
CUDA_VISIBLE_DEVICES="$gpu_id" nohup "$PROVER_BIN" \
9495
--config "$config_file" \
9596
> "$log_file" 2>&1 &

0 commit comments

Comments
 (0)