Try   HackMD

Snarkifying process_block_header() (Risc0)

TLDR

  • I'm now able to pass a BeaconState and a BeaconBlock into risc0 zkVM to perform BeaconState::process_block_header() within the guest VM.
  • The program was able to prove this specific operation in 15 minutes. 15 minutes per a subset transition function is far from ideal
  • Out of the 3 operations: 1) reading the state, 2) reading the block, 3) processing the block header, reading the state took over 92.5% of the cycle count. Loading the state into the guest VM seems to be the biggest bottleneck.
  • Still not able to output the result into the receipt journal.
  • See the work at https://github.com/ReamLabs/consenzero/pull/1/

Details

  • Thanks to @junsong's headwork on process_* skeleton and Varun's process_block_header() implementation, I'm now able to drop this into risc0 zkVM with only slight hacking, i.e. removing ssz_types::serde_utils::quoted_u64_var_list::deserialize() from the BeaconState
  • I benchmarked 3 points in the guest program. This is the result which is consistent across multiple runs.
    ​​​​read_pre_state: 47791528
    ​​​​read_block: 49553
    ​​​​process_block_header: 3809599
    
    Clearly loading the state took most (92.5%) of the cycle count.
  • I also confirmed by benchmarking from the host
    • Removing all guest VM code -> The proving time was instant
    • Removing all but passing in just the block -> The proving time was also instant
    • Removing all but passing in just the state -> The proving time went up to ~10 minutes
  • From my limited understanding, right now I guess these are the 3 possible directions?
    1. Trim down the beam chain state
    2. Split the prove into multiple subjects so they can be parallelized, then recursively proved
    3. Optimize the zkVM

Next

  • Make the program output the post-state into the receipt journal
  • Explore optimizations