From d70e990715ecb0d2f4e5140af25bb150642c4e67 Mon Sep 17 00:00:00 2001 From: Domi1999 Date: Thu, 4 Jan 2024 10:55:00 +0100 Subject: [PATCH] refactor: bumping up to Miden v0.7 to clean up a bit --- benchmarking-cli/Cargo.toml | 5 +- benchmarking-cli/src/main.rs | 19 +- benchmarking-cli/src/utils_input.rs | 4 +- playground/miden-wasm/Cargo.toml | 10 +- playground/miden-wasm/src/lib.rs | 18 +- playground/miden-wasm/src/transaction.rs | 285 --------------------- playground/miden-wasm/src/utils_debug.rs | 6 +- playground/miden-wasm/src/utils_input.rs | 4 +- playground/src/components/DropDown.tsx | 4 +- playground/src/pages/CodingEnvironment.tsx | 12 +- 10 files changed, 46 insertions(+), 321 deletions(-) delete mode 100644 playground/miden-wasm/src/transaction.rs diff --git a/benchmarking-cli/Cargo.toml b/benchmarking-cli/Cargo.toml index 67baeed..0ad01cb 100644 --- a/benchmarking-cli/Cargo.toml +++ b/benchmarking-cli/Cargo.toml @@ -6,7 +6,8 @@ edition = "2021" [dependencies] clap = { version = "4.0.0", features = ["derive"] } hex = { version = "0.4.0", default-features = false } -miden-stdlib = { version = "0.5.0", package = "miden-stdlib", default-features = false } -miden_vm = { version = "0.6.0", package = "miden-vm", features = ["concurrent"]} +miden-air = { version = "0.7.0", package = "miden-air", default-features = false } +miden-stdlib = { version = "0.6.0", package = "miden-stdlib", default-features = false } +miden_vm = { version = "0.7.0", package = "miden-vm", features = ["concurrent"]} serde = { version = "1", features = ["derive"] } # You only need this if you want app persistence serde_json = "1.0.48" diff --git a/benchmarking-cli/src/main.rs b/benchmarking-cli/src/main.rs index 8eb80a2..8a29a86 100644 --- a/benchmarking-cli/src/main.rs +++ b/benchmarking-cli/src/main.rs @@ -1,7 +1,8 @@ mod utils_input; mod utils_program; use clap::Parser; -use miden_vm::ProofOptions; +use miden_vm::{ProvingOptions, DefaultHost, MemAdviceProvider}; +use miden_air::ExecutionOptions; use std::fs; use std::time::Instant; @@ -73,12 +74,18 @@ fn main() -> Result<(), Box> { let program_to_run = program.program.clone().unwrap(); + let host = DefaultHost::new(MemAdviceProvider::from(inputs.advice_provider.clone())); + + let execution_options = ExecutionOptions::new(None, 64) + .map_err(|err| format!("{err}"))?; + // Execution time let now = Instant::now(); let trace = miden_vm::execute( &program_to_run, inputs.stack_inputs.clone(), - inputs.advice_provider.clone(), + host, + execution_options, ) .map_err(|err| format!("Failed to generate exection trace = {:?}", err)) .unwrap(); @@ -87,16 +94,18 @@ fn main() -> Result<(), Box> { // Proving time let proof_options = if args.security == "high" { - ProofOptions::with_128_bit_security(false) + ProvingOptions::with_128_bit_security(false) } else { - ProofOptions::with_96_bit_security(false) + ProvingOptions::with_96_bit_security(false) }; + let host = DefaultHost::new(MemAdviceProvider::from(inputs.advice_provider)); + let now = Instant::now(); let (output, proof) = miden_vm::prove( &program.program.unwrap(), inputs.stack_inputs.clone(), - inputs.advice_provider, + host, proof_options, ) .expect("Proving failed"); diff --git a/benchmarking-cli/src/utils_input.rs b/benchmarking-cli/src/utils_input.rs index 4a5eb5b..a2f5cb6 100644 --- a/benchmarking-cli/src/utils_input.rs +++ b/benchmarking-cli/src/utils_input.rs @@ -193,7 +193,7 @@ impl Inputs { Self { stack_inputs: StackInputs::new(vec![]), advice_provider: MemAdviceProvider::default(), - stack_outputs: StackOutputs::new(vec![], vec![]), + stack_outputs: StackOutputs::new(vec![], vec![]).unwrap(), } } @@ -252,7 +252,7 @@ fn test_parse_output() { }"#; let mut inputs: Inputs = Inputs::new(); - inputs.deserialize_outputs(output_str).unwrap(); + inputs.deserialize_inputs(output_str).unwrap(); let output: StackOutputs = inputs.stack_outputs; diff --git a/playground/miden-wasm/Cargo.toml b/playground/miden-wasm/Cargo.toml index 3a02ed5..be38305 100644 --- a/playground/miden-wasm/Cargo.toml +++ b/playground/miden-wasm/Cargo.toml @@ -7,13 +7,11 @@ edition = "2021" crate-type = ["cdylib", "rlib"] [dependencies] -assembly = { package = "miden-assembly", git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "frisitano-tx-result", default-features = false } +assembly = { package = "miden-assembly", version = "0.7.0", default-features = false } hex = { version = "0.4", default-features = false } -miden-vm = { package = "miden-vm", git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "frisitano-tx-result", default-features = false } -miden-tx = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "frisitano-prover-tx", features = ["testing"], default-features = false } -miden-stdlib = { package = "miden-stdlib", git = "https://github.com/0xPolygonMiden/miden-vm.git", branch = "frisitano-tx-result", default-features = false } -miden-objects = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "frisitano-prover-tx", features = ["testing"], default-features = false } -miden-lib = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "frisitano-prover-tx", default-features = false } +miden-air = { package = "miden-air", version = "0.7.0", default-features = false } +miden-vm = { package = "miden-vm", version = "0.7.0", default-features = false } +miden-stdlib = { package = "miden-stdlib", version = "0.6.0", default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde-wasm-bindgen = "0.4" diff --git a/playground/miden-wasm/src/lib.rs b/playground/miden-wasm/src/lib.rs index 61dbc97..9299cd0 100644 --- a/playground/miden-wasm/src/lib.rs +++ b/playground/miden-wasm/src/lib.rs @@ -1,8 +1,8 @@ -mod transaction; mod utils_debug; mod utils_input; mod utils_program; -use miden_vm::{ExecutionProof, ProofOptions}; +use miden_vm::{ExecutionProof, ProvingOptions, DefaultHost, MemAdviceProvider}; +use miden_air::ExecutionOptions; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; @@ -28,10 +28,16 @@ pub fn run_program(code_frontend: &str, inputs_frontend: &str) -> Result Result); - -impl From for Digest { - fn from(digest: RpoDigest) -> Self { - Digest(digest.into_iter().map(|n| n.as_int()).collect::>()) - } -} - -impl From for Vec { - fn from(digest: Digest) -> Self { - digest.0 - } -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WasmPreparedTransaction { - pub account_id: u64, - pub block_hash: Vec, - pub block_number: u32, - pub consumed_notes: Vec, - pub tx_script_root: Option>, - pub tx_program_root: Vec, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WasmNote { - pub script_root: Vec, - pub inputs_hash: Vec, - pub vault_hash: Vec, - pub assets: Vec>, - pub serial_num: Vec, - pub metadata: Vec, -} - -impl From<&Note> for WasmNote { - fn from(note: &Note) -> Self { - let assets = note - .vault() - .iter() - .map(|x| { - Word::from(*x) - .iter() - .map(|x| x.as_int()) - .collect::>() - }) - .collect(); - Self { - script_root: Into::::into(note.script().hash()).into(), - inputs_hash: Into::::into(note.inputs().hash()).into(), - vault_hash: Into::::into(note.vault().hash()).into(), - assets, - serial_num: note.serial_num().into_iter().map(|x| x.as_int()).collect(), - metadata: Into::::into(note.metadata()) - .into_iter() - .map(|x| x.as_int()) - .collect(), - } - } -} - -impl From for WasmPreparedTransaction { - fn from(tx: PreparedTransaction) -> Self { - Self { - account_id: tx.account().id().into(), - block_hash: Into::::into(tx.block_header().hash()).into(), - block_number: tx.block_header().block_num().as_int() as u32, - consumed_notes: tx.consumed_notes().notes().iter().map(Into::into).collect(), - tx_script_root: tx - .tx_script_root() - .and_then(|x| Some(Into::::into(x).into())), - tx_program_root: Into::::into(tx.tx_program().root().hash()).into(), - } - } -} - -// PREPARE TRANSACTION -// ================================================================================================ - -#[wasm_bindgen] -pub fn prepare_transaction() -> Result { - let data_store = MockDataStore::new(); - let mut executor = TransactionExecutor::new(data_store.clone()); - - let account_id = data_store.account.id(); - executor - .load_account(account_id) - .map_err(|err| format!("Failed to load account - {:?}", err))?; - - let block_ref = data_store.block_header.block_num().as_int() as u32; - let note_origins = data_store - .notes - .iter() - .take(1) - .map(|note| note.proof().as_ref().unwrap().origin().clone()) - .collect::>(); - - let result: WasmPreparedTransaction = executor - .prepare_transaction(data_store.account.id(), block_ref, ¬e_origins, None) - .map_err(|err| format!("Failed to prepare transaction - {:?}", err))? - .into(); - - let serializer = Serializer::new().serialize_large_number_types_as_bigints(true); - Ok(result.serialize(&serializer)?) -} - -// PROVE TRANSACTION TYPES -// ================================================================================================ - -#[derive(Serialize, Deserialize, Debug)] -pub struct WasmProvenTransaction { - pub account_id: u64, - pub initial_account_hash: Vec, - pub final_account_hash: Vec, - pub consumed_notes: Vec>, - pub created_notes: Vec>, - pub tx_script_root: Option>, - pub stack_inputs: Vec, - pub stack_outputs: Vec, - pub program_hash: Vec, - pub proof: Vec, -} - -impl From for WasmProvenTransaction { - fn from(proven_transaction: ProvenTransaction) -> WasmProvenTransaction { - let consumed_notes = proven_transaction - .consumed_notes() - .iter() - .map(|x| { - Into::<[Felt; 8]>::into(*x) - .iter() - .map(|x| x.as_int()) - .collect::>() - }) - .collect::>(); - let created_notes = proven_transaction - .created_notes() - .iter() - .map(|x| { - Into::<[Felt; 8]>::into(*x) - .iter() - .map(|x| x.as_int()) - .collect::>() - }) - .collect::>(); - - WasmProvenTransaction { - account_id: proven_transaction.account_id().into(), - initial_account_hash: Into::::into(proven_transaction.initial_account_hash()) - .into(), - final_account_hash: Into::::into(proven_transaction.final_account_hash()) - .into(), - consumed_notes, - created_notes, - tx_script_root: proven_transaction - .tx_script_root() - .and_then(|x| Some(Into::::into(x).into())), - stack_inputs: proven_transaction - .stack_inputs() - .values() - .iter() - .rev() - .map(|x| x.as_int()) - .collect::>(), - stack_outputs: proven_transaction - .stack_outputs() - .stack() - .iter() - .cloned() - .collect(), - program_hash: Into::::into(proven_transaction.program_hash()).into(), - proof: proven_transaction.proof().to_bytes(), - } - } -} - -// PROVE TRANSACTION -// ================================================================================================ - -pub fn do_prove_transaction() -> Result { - let data_store = MockDataStore::new(); - let mut executor = TransactionExecutor::new(data_store.clone()); - - let account_id = data_store.account.id(); - executor - .load_account(account_id) - .map_err(|err| format!("Failed to load account - {:?}", err))?; - - let block_ref = data_store.block_header.block_num().as_int() as u32; - let note_origins = data_store - .notes - .iter() - .take(1) - .map(|note| note.proof().as_ref().unwrap().origin().clone()) - .collect::>(); - - let prepared_transaction = executor - .prepare_transaction(data_store.account.id(), block_ref, ¬e_origins, None) - .map_err(|err| format!("Failed to prepare transaction - {:?}", err))?; - - let prover = TransactionProver::new(ProofOptions::default()); - Ok(prover - .prove_prepared_transaction(prepared_transaction) - .map_err(|e| format!("Failed to prove prepared transaction - {:?}", e))? - .into()) -} - -#[wasm_bindgen] -pub fn prove_transaction() -> Result { - let proven_transaction: WasmProvenTransaction = do_prove_transaction()?; - - let serializer = Serializer::new().serialize_large_number_types_as_bigints(true); - Ok(proven_transaction.serialize(&serializer)?) -} - -// VERIFY TRANSACTION -// ================================================================================================ - -#[wasm_bindgen] -pub fn verify_transaction( - stack_inputs: Vec, - stack_outputs: Vec, - program_hash: Vec, - proof: Vec, -) -> Result { - let stack_inputs = StackInputs::try_from_values(stack_inputs) - .map_err(|e| format!("Invalid stack inputs: {}", e))?; - let stack_outputs = StackOutputs::new(stack_outputs, Default::default()); - let program_hash: [Felt; 4] = program_hash - .into_iter() - .map(|x| Felt::try_from(x.to_le_bytes()).map_err(|x| format!("{x}"))) - .collect::, String>>()? - .try_into() - .map_err(|x| format!("Invalid program hash: {:?}", x))?; - let program_hash = RpoDigest::new(program_hash); - let proof = ExecutionProof::from_bytes(&proof) - .map_err(|err| format!("Failed to deserialize proof - {}", err))?; - let assembler = Assembler::default() - .with_library(&MidenLib::default()) - .expect("library is well formed") - .with_library(&StdLibrary::default()) - .expect("library is well formed") - .with_kernel(SatKernel::kernel()) - .expect("kernel is well formed"); - let program_info = ProgramInfo::new(program_hash, assembler.kernel().clone()); - let _result: u32 = miden_vm::verify(program_info, stack_inputs, stack_outputs, proof) - .map_err(|err| format!("Program failed verification! - {}", err))?; - - Ok(true) -} - -// TESTS -// ================================================================================================ - -#[test] -fn test_verify_transaction() { - let proven_transaction = do_prove_transaction().unwrap(); - assert!(verify_transaction( - proven_transaction.stack_inputs, - proven_transaction.stack_outputs, - proven_transaction.program_hash, - proven_transaction.proof - ) - .is_ok()); -} diff --git a/playground/miden-wasm/src/utils_debug.rs b/playground/miden-wasm/src/utils_debug.rs index f182893..effc788 100644 --- a/playground/miden-wasm/src/utils_debug.rs +++ b/playground/miden-wasm/src/utils_debug.rs @@ -1,6 +1,6 @@ use crate::utils_input::Inputs; use crate::utils_program::{MidenProgram, DEBUG_ON}; -use miden_vm::{math::StarkField, VmState, VmStateIterator, Word}; +use miden_vm::{math::StarkField, VmState, VmStateIterator, Word, DefaultHost, MemAdviceProvider}; use wasm_bindgen::prelude::*; // This is the main struct that will be exported to JS @@ -49,10 +49,12 @@ impl DebugExecutor { let mut inputs = Inputs::new(); inputs.deserialize_inputs(inputs_frontend).unwrap(); + let host = DefaultHost::new(MemAdviceProvider::from(inputs.advice_provider)); + let mut vm_state_iter = miden_vm::execute_iter( &program.program.unwrap(), inputs.stack_inputs, - inputs.advice_provider, + host, ); let vm_state = vm_state_iter diff --git a/playground/miden-wasm/src/utils_input.rs b/playground/miden-wasm/src/utils_input.rs index 84d0987..399dec1 100644 --- a/playground/miden-wasm/src/utils_input.rs +++ b/playground/miden-wasm/src/utils_input.rs @@ -227,7 +227,7 @@ impl Inputs { Self { stack_inputs: StackInputs::new(vec![Felt::ZERO]), advice_provider: MemAdviceProvider::default(), - stack_outputs: StackOutputs::new(vec![], vec![]), + stack_outputs: StackOutputs::new(vec![], vec![]).unwrap(), } } @@ -249,7 +249,7 @@ impl Inputs { let outputs = StackOutputs::new( outputs_as_json.stack_output, outputs_as_json.overflow_addrs.unwrap_or(vec![]), - ); + ).unwrap(); self.stack_outputs = outputs; diff --git a/playground/src/components/DropDown.tsx b/playground/src/components/DropDown.tsx index 97a585b..548d86b 100644 --- a/playground/src/components/DropDown.tsx +++ b/playground/src/components/DropDown.tsx @@ -42,7 +42,7 @@ export default function DropDown({
- {selected.replace(/_/g, ' ')} + {selected} - {example.replace(/_/g, ' ')} + {example} {selected ? ( diff --git a/playground/src/pages/CodingEnvironment.tsx b/playground/src/pages/CodingEnvironment.tsx index ad9fe7d..1de4102 100644 --- a/playground/src/pages/CodingEnvironment.tsx +++ b/playground/src/pages/CodingEnvironment.tsx @@ -146,20 +146,12 @@ export default function CodingEnvironment(): JSX.Element { const start = Date.now(); const { stack_output, trace_len, overflow_addrs, proof }: Outputs = prove_program(code, inputs); - const overflow = overflow_addrs ? overflow_addrs.toString() : null; - if (overflow) { - setOutput(`{ + const overflow = overflow_addrs ? overflow_addrs.toString() : "[]"; + setOutput(`{ "stack_output" : [${stack_output.toString()}], "overflow_addrs" : [${overflow}], "trace_len" : ${trace_len} }`); - } else { - setOutput(`{ -"stack_output" : [${stack_output.toString()}], -"trace_len" : ${trace_len} -}`); - } - toast.success(`Proving successful in ${Date.now() - start} ms`, { id: 'provingToast' });