Skip to content

Redeem miner rewards#498

Draft
n13 wants to merge 11 commits into
mainfrom
redeem-miner-rewards
Draft

Redeem miner rewards#498
n13 wants to merge 11 commits into
mainfrom
redeem-miner-rewards

Conversation

@n13
Copy link
Copy Markdown
Collaborator

@n13 n13 commented May 23, 2026

Redeem miner rewards

Mobile-app flow for redeeming wormhole rewards (claims aggregated leaf proofs and submits an unsigned verify_aggregated_proof extrinsic to the chain).

Memory optimization

The original implementation peaked at 4.4 GB resident on iOS, which OOM-killed the app on devices without the com.apple.developer.kernel.increased-memory-limit entitlement (≈1.4 GB jetsam ceiling). After matching the wormhole-memprof configuration exactly, peak is now 2.3 GB resident (~50% reduction) and phys_footprint stays under 300 MB throughout the run.

Root causes fixed

  1. Wrong task_vm_info struct layout. Earlier instrumentation read min_address as phys_footprint on ARM64 iOS, reporting a phantom constant ~4 GB and sending us chasing the wrong things. Fixed by matching Apple's kernel layout (integer_t = i32 for region_count / page_size) with a compile-time size_of assert at 152 bytes.
  2. Mobile aggregator was loading aggregated_prover.bin (972 MB) from disk and then rebuilding the aggregation circuit anyway just to extract targets. Switched to the same fresh-build constructor wormhole-memprof uses (Layer0AggregationProver::new) via aggregate_proofs_fresh. This skips both the disk-load peak and the redundant target-rebuild.
  3. Leaf circuit was bigger than the aggregator. wormhole_leaf_circuit_config() was returning standard_recursion_config() (143 wires / 80 routed), so the aggregator had to recursively verify a larger leaf than needed. Aligned the leaf with the aggregator's wire counts (135 / 60) — the same shape wormhole-memprof's leaf_config_matching uses to hit its 2.5 GB benchmark.
  4. Rayon pool size. Single-threaded plonky2 (provingThreads: 1) allocated bigger contiguous FFT buffers than the chunked parallel path. Set to 8, matching the wormhole-memprof sweep's measured sweet spot.
  5. Stale circuit binaries. Bumped the on-device cache directory circuitscircuits_v3 so the new 135/60 leaf bins regenerate on first run instead of failing common-data checks against old 143/80 bins.

Diagnostic infrastructure added

  • Accurate per-phase memory checkpoints in wormhole.rs ([mem] <tag> phys=… resident=… compressed=… internal=… external=… virt=…) with a detailed dump variant.
  • Phase markers inside the locally-patched Layer0Aggregator::aggregate() (build_prover / commit / prove) and Layer0AggregationProver::new_from_bytes so each substep is timed individually.
  • Memory checkpoints around every claim-service and UTXO-service phase ([ClaimMem], [UtxoMem]).

ZK parameters (matches wormhole-memprof exactly)

Aggregator circuit (wormhole_aggregator_circuit_config())

Parameter Value
zk_config RowBlinding (leaf_hiding: true)
num_wires 135
num_routed_wires 60
num_constants 2
use_base_arithmetic_gate true
security_bits 100
num_challenges 2
max_quotient_degree_factor 8
fri_config.rate_bits 3
fri_config.cap_height 4
fri_config.proof_of_work_bits 16
fri_config.num_query_rounds 28
fri_config.reduction_strategy ConstantArityBits(4, 5)

Leaf circuit (wormhole_leaf_circuit_config(), updated this PR)

Parameter Value
zk_config Disabled (leaf_hiding: false)
num_wires 135 (was 143)
num_routed_wires 60 (was 80)
num_constants 2
use_base_arithmetic_gate true
security_bits 100
num_challenges 2
max_quotient_degree_factor 8
fri_config.rate_bits 3
fri_config.cap_height 4
fri_config.proof_of_work_bits 16
fri_config.num_query_rounds 28
fri_config.reduction_strategy ConstantArityBits(4, 5)

Runtime knobs

Knob Value
maxProofsPerBatch 16
proofConcurrency 1
provingThreads (rayon global pool) 8
freshBuild true (use aggregate_proofs_fresh)
Plonky2 hash Poseidon (Goldilocks, D=2)
Plonky2 config type PoseidonGoldilocksConfig
Plonky2 field GoldilocksField

Memory before / after

Phase Before (resident) After (resident)
baseline / idle ~20 MB ~20 MB
16 leaf proofs ~1.7 GB ~700 MB
aggregation prove peak 4.4 GB (OOM on device w/o entitlement) 2.3 GB
post-claim ~3.9 GB (uncollected) ~400 MB

phys_footprint (the metric iOS Jetsam evaluates) stays under 300 MB throughout — the resident_size peak above includes allocator-reusable pages that don't count against Jetsam.

Files changed

  • quantus_sdk/rust/src/api/wormhole.rs — fresh-build aggregator path, accurate task_vm_info reading, per-phase log_mem checkpoints.
  • quantus_sdk/lib/src/services/wormhole_claim_service.dart — claim orchestration with memory checkpoints between every phase.
  • quantus_sdk/lib/src/services/wormhole_utxo_service.dart — unspent-transfer discovery with memory checkpoints.
  • quantus_sdk/lib/src/services/circuit_manager.dart — cache dir bumped to circuits_v3.
  • mobile-app/lib/v2/screens/settings/redeem_progress_screen.dartmaxProofsPerBatch: 16, provingThreads: 8, freshBuild: true.
  • mobile-app/ios/Runner/Runner.entitlements — extended-virtual-addressing kept; increased-memory-limit removed (no longer required at the current peak; can be re-added if a device still hits jetsam).

@n13 n13 closed this May 23, 2026
@n13 n13 reopened this May 23, 2026
@n13 n13 marked this pull request as draft May 25, 2026 05:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant