From b91081d108bb35f6bc2f4ba3e5121fed9a196c66 Mon Sep 17 00:00:00 2001 From: stephenh-axiom-xyz Date: Sun, 15 Dec 2024 22:42:14 -0500 Subject: [PATCH] docs: SDK code runs (#1071) --- book/src/advanced-usage/sdk.md | 64 +++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/book/src/advanced-usage/sdk.md b/book/src/advanced-usage/sdk.md index 51a0145de3..e4f2fba1f5 100644 --- a/book/src/advanced-usage/sdk.md +++ b/book/src/advanced-usage/sdk.md @@ -9,12 +9,19 @@ For more information on the basic CLI flow, see [Overview of Basic Usage](./over If you have a guest program and would like to try running the **host program** specified below, you can do so by adding the following imports and setup at the top of the file. You may need to modify the imports and/or the `SomeStruct` struct to match your program. ```rust -use openvm::{platform::memory::MEM_SIZE, transpiler::elf::Elf}; -use openvm_circuit::arch::instructions::exe::OpenVmExe -use openvm_circuit::arch::VmExecutor; -use openvm_sdk::{config::SdkVmConfig, Sdk, StdIn}; - -let sdk = Sdk; +use std::{fs, sync::Arc}; +use eyre::Result; +use openvm::platform::memory::MEM_SIZE; +use openvm_build::{GuestOptions, TargetFilter}; +use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader; +use openvm_sdk::{ + config::{AggConfig, AppConfig, SdkVmConfig}, + prover::AppProver, + Sdk, StdIn, +}; +use openvm_stark_sdk::config::FriParameters; +use openvm_transpiler::elf::Elf; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] pub struct SomeStruct { @@ -29,6 +36,7 @@ The SDK provides lower-level control over the building and transpiling process. ```rust // 1. Build the VmConfig with the extensions needed. +let sdk = Sdk; let vm_config = SdkVmConfig::builder() .system(Default::default()) .rv32i(Default::default()) @@ -40,7 +48,8 @@ let guest_opts = GuestOptions::default().with_features(vec!["parallel"]); let target_filter = TargetFilter::default().with_kind("bin".to_string()); let elf = sdk.build(guest_opts, "your_path_project_root", &target_filter)?; // 2b. Load the ELF from a file -let elf = Elf::decode("your_path_to_elf", MEM_SIZE as u32)?; +let elf_bytes = fs::read("your_path_to_elf")?; +let elf = Elf::decode(&elf_bytes, MEM_SIZE as u32)?; // 3. Transpile the ELF into a VmExe let exe = sdk.transpile(elf, vm_config.transpiler())?; @@ -55,12 +64,13 @@ To run your program and see the public value output, you can do the following: ```rust // 4. Format your input into StdIn -let my_input = SomeStruct; // anything that can be serialized +let my_input = SomeStruct { a: 1, b: 2 }; // anything that can be serialized let mut stdin = StdIn::default(); stdin.write(&my_input); // 5. Run the program -let output = sdk.execute(exe, vm_config, input)?; +let output = sdk.execute(exe.clone(), vm_config.clone(), stdin.clone())?; +println!("public values output: {:?}", output); ``` ### Using `StdIn` @@ -84,15 +94,14 @@ let app_config = AppConfig::new(app_fri_params, vm_config); let app_committed_exe = sdk.commit_app_exe(app_fri_params, exe)?; // 8. Generate an AppProvingKey -let app_pk = sdk.app_keygen(app_config)?; +let app_pk = Arc::new(sdk.app_keygen(app_config)?); // 9a. Generate a proof -let proof = sdk.generate_app_proof(app_pk, app_committed_exe, stdin)?; +let proof = sdk.generate_app_proof(app_pk.clone(), app_committed_exe.clone(), stdin.clone())?; // 9b. Generate a proof with an AppProver with custom fields -let mut app_prover = - AppProver::new(app_pk.app_vm_pk.clone(), app_committed_exe) - .with_program_name(program_name); -let proof = app_prover.generate_app_proof(stdin); +let app_prover = AppProver::new(app_pk.app_vm_pk.clone(), app_committed_exe.clone()) + .with_program_name("test_program"); +let proof = app_prover.generate_app_proof(stdin.clone()); ``` ## Verifying Proofs @@ -111,20 +120,33 @@ Generating and verifying an EVM proof is an extension of the above process. ```rust // 11. Generate the aggregation proving key const DEFAULT_PARAMS_DIR: &str = concat!(env!("HOME"), "/.openvm/params/"); -let halo2_params_reader = Halo2ParamsReader::new(DEFAULT_PARAMS_DIR); +let halo2_params_reader = CacheHalo2ParamsReader::new(DEFAULT_PARAMS_DIR); let agg_config = AggConfig::default(); let agg_pk = sdk.agg_keygen(agg_config, &halo2_params_reader)?; -// 12. Generate an EVM proof -let proof = sdk.generate_evm_proof(&halo2_params_reader, app_pk, app_committed_exe, agg_pk, stdin)?; - -// 13. Generate the SNARK verifier contract +// 12. Generate the SNARK verifier contract let verifier = sdk.generate_snark_verifier_contract(&halo2_params_reader, &agg_pk)?; +// 13. Generate an EVM proof +let proof = sdk.generate_evm_proof( + &halo2_params_reader, + app_pk, + app_committed_exe, + agg_pk, + stdin, +)?; + // 14. Verify the EVM proof -sdk.verify_evm_proof(&verifier, &proof)?; +let success = sdk.verify_evm_proof(&verifier, &proof); +assert!(success); ``` +> ⚠️ **WARNING** +> Generating an EVM proof will require a substantial amount of computation and memory. If you have run `cargo openvm setup` and don't need a specialized aggregation configuration, consider deserializing the proving key from the file `~/.openvm/agg.pk` instead of generating it. + +> ⚠️ **WARNING** +> The aggregation proving key `agg_pk` above is large. Avoidå cloning it if possible. + Note that `DEFAULT_PARAMS_DIR` is the directory where Halo2 parameters are stored by the `cargo openvm setup` CLI command. For more information on the setup process, see the [onchain verify](../writing-apps/onchain-verify.md) doc. > ⚠️ **WARNING**