From 643dbb8e554c51df70029ad5415fbba5c9b027f6 Mon Sep 17 00:00:00 2001 From: David Rusu Date: Mon, 24 Feb 2025 18:50:03 +0400 Subject: [PATCH] zone witness in cross zone transfer scenario --- emmarin/cl/cl/src/crust/iow.rs | 2 +- emmarin/cl/ledger/src/ledger.rs | 2 +- emmarin/cl/ledger/tests/simple_transfer.rs | 111 ++++++++++----------- 3 files changed, 54 insertions(+), 61 deletions(-) diff --git a/emmarin/cl/cl/src/crust/iow.rs b/emmarin/cl/cl/src/crust/iow.rs index 71f1e12..88bcba9 100644 --- a/emmarin/cl/cl/src/crust/iow.rs +++ b/emmarin/cl/cl/src/crust/iow.rs @@ -113,7 +113,7 @@ impl OutputWitness { ) } - pub fn split_input( + pub fn spend_with_change( input: InputWitness, amount: u64, to_pk: NullifierCommitment, diff --git a/emmarin/cl/ledger/src/ledger.rs b/emmarin/cl/ledger/src/ledger.rs index a2e1722..9705503 100644 --- a/emmarin/cl/ledger/src/ledger.rs +++ b/emmarin/cl/ledger/src/ledger.rs @@ -11,7 +11,7 @@ pub struct ProvedLedgerTransition { } impl ProvedLedgerTransition { - pub fn prove(mut ledger: LedgerState, zone_id: ZoneId, bundles: Vec) -> Self { + pub fn prove(ledger: &mut LedgerState, zone_id: ZoneId, bundles: Vec) -> Self { let mut env = risc0_zkvm::ExecutorEnv::builder(); let mut w_bundles = Vec::new(); let mut nullifiers = Vec::new(); diff --git a/emmarin/cl/ledger/tests/simple_transfer.rs b/emmarin/cl/ledger/tests/simple_transfer.rs index 7fb64d5..0a2ddc4 100644 --- a/emmarin/cl/ledger/tests/simple_transfer.rs +++ b/emmarin/cl/ledger/tests/simple_transfer.rs @@ -1,8 +1,8 @@ use cl::{ crust::{ balance::{UnitWitness, NOP_COVENANT}, - BundleWitness, InputWitness, Nullifier, NullifierCommitment, NullifierSecret, - OutputWitness, TxWitness, + BundleWitness, InputWitness, NoteCommitment, Nullifier, NullifierCommitment, + NullifierSecret, OutputWitness, TxWitness, }, ds::mmr::{MMRProof, MMR}, mantle::{ @@ -16,7 +16,7 @@ use ledger::{ update::ProvedBatchUpdate, }; use ledger_proof_statements::stf::StfPublic; -use rand::Rng; +use rand::{Rng, RngCore}; use rand_core::CryptoRngCore; const ZONE_A: ZoneId = [0u8; 32]; @@ -52,13 +52,14 @@ fn cross_transfer_transition( to: User, amount: u64, to_zone: ZoneId, - mut ledger_in: LedgerState, - mut ledger_out: LedgerState, + ledger_in: &mut LedgerState, + ledger_out: &mut LedgerState, ) -> (ProvedLedgerTransition, ProvedLedgerTransition) { assert!(amount <= input.value); let mut rng = rand::thread_rng(); - let (transfer, change) = OutputWitness::split_input(input, amount, to.pk(), to_zone, &mut rng); + let (transfer, change) = + OutputWitness::spend_with_change(input, amount, to.pk(), to_zone, &mut rng); let tx_witness = TxWitness::default() .add_input(input, input_proof) @@ -81,35 +82,51 @@ fn cross_transfer_transition( println!("proving ledger A transition"); let ledger_in_transition = - ProvedLedgerTransition::prove(ledger_in.clone(), input.zone_id, vec![bundle.clone()]); + ProvedLedgerTransition::prove(ledger_in, input.zone_id, vec![bundle.clone()]); println!("proving ledger B transition"); - let ledger_out_transition = - ProvedLedgerTransition::prove(ledger_out.clone(), to_zone, vec![bundle]); - - ledger_in.add_commitment(&change.note_commitment()); - ledger_in.add_nullifiers(vec![input.nullifier()]); - - ledger_out.add_commitment(&transfer.note_commitment()); - - assert_eq!( - ledger_in_transition.public().ledger, - ledger_in.to_witness().commit() - ); - assert_eq!( - ledger_out_transition.public().ledger, - ledger_out.to_witness().commit() - ); + let ledger_out_transition = ProvedLedgerTransition::prove(ledger_out, to_zone, vec![bundle]); (ledger_in_transition, ledger_out_transition) } +struct ZoneWitness { + ledger: LedgerState, +} + +impl ZoneWitness { + fn new() -> Self { + let ledger = LedgerState::default(); + + Self { ledger } + } + + fn state(&self) -> ZoneState { + ZoneState { + stf: StfProof::nop_stf(), + zone_data: [0; 32], + ledger: self.ledger.to_witness().commit(), + } + } + + fn fill_nfs(&mut self, amount: usize, mut rng: impl RngCore) { + self.ledger.add_nullifiers( + std::iter::repeat_with(|| Nullifier(rng.gen())) + .take(amount) + .collect(), + ); + } + + fn add_commitment(&mut self, cm: &NoteCommitment) -> (MMR, MMRProof) { + self.ledger.add_commitment(cm) + } +} + #[test] fn zone_update_cross() { let mut rng = rand::thread_rng(); - // alice is sending 8 NMO to bob. - + // Alice is sending 8 NMO to bob. let alice = User::random(&mut rng); let bob = User::random(&mut rng); @@ -118,49 +135,25 @@ fn zone_update_cross() { let alice_input = InputWitness::from_output(utxo, alice.sk(), nmo()); - let mut ledger_a = LedgerState::default(); + let mut zone_a = ZoneWitness::new(); + zone_a.fill_nfs(2_usize.pow(10), &mut rng); + let alice_cm_proof = zone_a.add_commitment(&utxo.note_commitment()); - // To make the scenario a bit more realistic, we fill the nullifier set with a bunch of nullififiers - ledger_a.add_nullifiers( - std::iter::repeat_with(|| Nullifier(rng.gen())) - .take(2_usize.pow(10)) - .collect(), - ); - let alice_cm_proof = ledger_a.add_commitment(&utxo.note_commitment()); + let mut zone_b = ZoneWitness::new(); - let ledger_b = LedgerState::default(); + let (zone_a_old, zone_b_old) = (zone_a.state(), zone_b.state()); - let zone_a_old = ZoneState { - stf: StfProof::nop_stf(), - zone_data: [0; 32], - ledger: ledger_a.to_witness().commit(), - }; - - let zone_b_old = ZoneState { - stf: StfProof::nop_stf(), - zone_data: [0; 32], - ledger: ledger_b.to_witness().commit(), - }; - - let (ledger_a_transition, ledger_b_transition) = cross_transfer_transition( + let (ledger_proof_a, ledger_proof_b) = cross_transfer_transition( alice_input, alice_cm_proof, bob, 8, ZONE_B, - ledger_a, - ledger_b, + &mut zone_a.ledger, + &mut zone_b.ledger, ); - let zone_a_new = ZoneState { - ledger: ledger_a_transition.public().ledger, - ..zone_a_old - }; - - let zone_b_new = ZoneState { - ledger: ledger_b_transition.public().ledger, - ..zone_b_old - }; + let (zone_a_new, zone_b_new) = (zone_a.state(), zone_b.state()); let stf_proof_a = StfProof::prove_nop(StfPublic { old: zone_a_old, @@ -187,7 +180,7 @@ fn zone_update_cross() { let proved_batch = ProvedBatchUpdate { batch, - ledger_proofs: vec![ledger_a_transition, ledger_b_transition], + ledger_proofs: vec![ledger_proof_a, ledger_proof_b], stf_proofs: vec![stf_proof_a, stf_proof_b], };