diff --git a/emmarin/apps/swapvm/stf/host/src/lib.rs b/emmarin/apps/swapvm/stf/host/src/lib.rs index 1ea39cf..4186721 100644 --- a/emmarin/apps/swapvm/stf/host/src/lib.rs +++ b/emmarin/apps/swapvm/stf/host/src/lib.rs @@ -3,11 +3,9 @@ use std::collections::BTreeMap; use app::{swap_goal_unit, SwapArgs, ZoneData}; use cl::crust::{BundleWitness, InputWitness, NoteCommitment, Nullifier, Tx, TxWitness, Unit}; use cl::ds::mmr::{MMRFolds, MMRProof, MMR}; -use cl::mantle::ledger::Ledger; -use cl::mantle::ledger::LedgerState; +use cl::mantle::ledger::{Ledger, LedgerState, LedgerWitness}; use cl::mantle::ZoneState; use ledger::stf::{risc0_stf, StfProof}; -use ledger_proof_statements::ledger::SyncLog; use methods::{STF_ELF, STF_ID}; use risc0_zkvm::{ExecutorEnv, Prover, Result}; @@ -92,10 +90,6 @@ impl ExecutorState { } } - for nf in &swapvm_update.inputs { - self.ledger.add_nullifiers(vec![*nf]); - } - if tx.balance.unit_balance(swap_goal_unit().unit()).is_neg() { // this is a SWAP let (swap_goal_cm, swap_args_bytes) = &swapvm_update.outputs[0]; @@ -133,16 +127,16 @@ impl ExecutorState { pub fn update_and_get_executor_tx(&mut self) -> (TxWitness, Vec) { let mut tx = TxWitness::default(); let mut new_fund_notes = Vec::new(); - let mut ledger = self.ledger.clone(); let expected_pool_balances = self.swapvm.expected_pool_balances(); let fund_notes = std::mem::take(&mut self.fund_notes); for note in &self.swapvm.swaps_output { tx = tx.add_output(note.clone(), ""); - ledger.add_commitment(¬e.note_commitment()); + self.ledger.add_commitment(¬e.note_commitment()); } + self.swapvm.nfs.clear(); for (unit, value) in expected_pool_balances { let note = if let Some(note) = fund_notes.get(&unit) { note.evolve(value) @@ -152,9 +146,10 @@ impl ExecutorState { new_fund_notes.push(note); let output = note.to_output(); tx = tx.add_output(output, ""); - let (mmr, path) = ledger.add_commitment(&output.note_commitment()); + let (mmr, path) = self.ledger.add_commitment(&output.note_commitment()); self.fund_notes .insert(note.unit_witness.unit(), FundNote { note, mmr, path }); + self.swapvm.nfs.insert(note.nullifier()); } for (_, FundNote { note, mmr, path }) in fund_notes.into_iter() { @@ -164,7 +159,6 @@ impl ExecutorState { for (goal_note, mmr, path) in std::mem::take(&mut self.goal_notes) { tx = tx.add_input(goal_note, (mmr, path)); } - (tx, new_fund_notes) } @@ -176,9 +170,8 @@ impl ExecutorState { pub struct StfPrivate { pub zone_data: ZoneData, - pub old_ledger: Ledger, + pub old_ledger: LedgerWitness, pub new_ledger: Ledger, - pub sync_logs: Vec, pub fund_notes: Vec, pub bundle: BundleWitness, } @@ -189,7 +182,7 @@ impl StfPrivate { .write(&self.zone_data)? .write(&self.old_ledger)? .write(&self.new_ledger)? - .write(&STF_ID)? + .write(&unsafe { std::intrinsics::transmute::<_, [u8; 32]>(STF_ID) })? .write(&self.bundle)? .write(&self.fund_notes)? .build()?; diff --git a/emmarin/apps/swapvm/stf/host/tests/swap.rs b/emmarin/apps/swapvm/stf/host/tests/swap.rs index c51c60c..0f65119 100644 --- a/emmarin/apps/swapvm/stf/host/tests/swap.rs +++ b/emmarin/apps/swapvm/stf/host/tests/swap.rs @@ -54,7 +54,7 @@ fn setup_executor(mut rng: impl RngCore, ledger: LedgerState) -> ExecutorState { #[test] fn simple_swap() { let mut rng = rand::thread_rng(); - let mut ledger = LedgerState::default(); + let ledger = LedgerState::default(); // ---- setup scenario ---- @@ -68,15 +68,16 @@ fn simple_swap() { zone_id: ZONE_ID, nf_sk: alice_sk, }; - let alice_in_proof = ledger.add_commitment(&alice_in.note_commitment()); - let mut exec_state = setup_executor(&mut rng, ledger.clone()); + let mut exec_state = setup_executor(&mut rng, ledger); + let (alice_in_proof, _) = exec_state.observe_cm(&alice_in.note_commitment()); // ----- end setup ---- // Alice now has a valid 10 NMO note, she wants to swap it for 90 MEM // ---- begin swap ---- let old_zone_state = exec_state.zone_state(); + let old_zone_data = exec_state.swapvm.clone(); let mut temp_ledger_state = exec_state.ledger.clone(); @@ -108,16 +109,24 @@ fn simple_swap() { txs: vec![swap_tx_proof.public(), proved_exec_tx.public()], }; - let _ = swap_bundle.clone().commit(); - let swap_bundle_proof = ProvedBundle::prove(vec![swap_tx_proof, proved_exec_tx]); - + exec_state.ledger.add_bundle(swap_bundle.root()); + exec_state.observe_nfs( + swap_bundle + .clone() + .commit() + .updates + .get(&exec_state.swapvm.zone_id) + .unwrap() + .into_iter() + .flat_map(|u| u.inputs.iter().copied()) + .collect::>(), + ); // prove stf let stf_proof = StfPrivate { - zone_data: exec_state.swapvm.clone(), - old_ledger: ledger.to_witness().commit(), + zone_data: old_zone_data, + old_ledger: temp_ledger_state.to_witness(), new_ledger: exec_state.ledger.clone().to_witness().commit(), - sync_logs: Vec::new(), fund_notes, bundle: swap_bundle, } diff --git a/emmarin/apps/swapvm/stf/methods/guest/src/main.rs b/emmarin/apps/swapvm/stf/methods/guest/src/main.rs index abdec07..c2c6791 100644 --- a/emmarin/apps/swapvm/stf/methods/guest/src/main.rs +++ b/emmarin/apps/swapvm/stf/methods/guest/src/main.rs @@ -25,11 +25,12 @@ fn main() { stf, }; + ledger_witness.add_bundle(bundle.root()); + // ensure that we've seen every bundle in this ledger update + assert_eq!(ledger_witness.bundles.commit(), new_ledger.bundles_root); + // The last bundle should be a single executor tx that updates the zone data let executor_tx = bundle.txs.pop().unwrap(); - - ledger_witness.add_bundle(bundle.root()); - for tx in bundle.txs { let Some(zone_update) = tx.updates.get(&zone_id) else { // this tx does not concern this zone, ignore it. @@ -70,9 +71,6 @@ fn main() { } } - // ensure that we've seen every bundle in this ledger update - assert_eq!(ledger_witness.bundles.commit(), new_ledger.bundles_root); - let public = StfPublic { old: old_state, new: ZoneState {