diff --git a/goas/atomic_asset_transfer/common/src/lib.rs b/goas/atomic_asset_transfer/common/src/lib.rs index e351dcd..126128e 100644 --- a/goas/atomic_asset_transfer/common/src/lib.rs +++ b/goas/atomic_asset_transfer/common/src/lib.rs @@ -14,8 +14,6 @@ use std::collections::BTreeMap; // TODO: sparse merkle tree pub const MAX_BALANCES: usize = 1 << 8; -pub const MAX_TXS: usize = 1 << 8; -pub const MAX_EVENTS: usize = 1 << 8; // state of the zone #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] @@ -105,14 +103,19 @@ impl StateWitness { } pub fn balances_root(&self) -> [u8; 32] { - let balance_bytes = Vec::from_iter(self.balances.iter().map(|(owner, balance)| { - let mut bytes: Vec = vec![]; - bytes.extend(owner); - bytes.extend(balance.to_le_bytes()); - bytes - })); - let balance_merkle_leaves = cl::merkle::padded_leaves(&balance_bytes); - merkle::root::(balance_merkle_leaves) + let mut hasher = Sha256::new(); + + for (owner, balance) in self.balances.iter() { + hasher.update(owner); + hasher.update(balance.to_le_bytes()); + } + + for _ in self.balances.len()..MAX_BALANCES { + hasher.update([0u8; PUBLIC_KEY_LENGTH]); + hasher.update(0u64.to_le_bytes()); + } + + hasher.finalize().into() } pub fn total_balance(&self) -> u64 { diff --git a/goas/atomic_asset_transfer/executor/Cargo.toml b/goas/atomic_asset_transfer/executor/Cargo.toml index ce38b7a..cfffe48 100644 --- a/goas/atomic_asset_transfer/executor/Cargo.toml +++ b/goas/atomic_asset_transfer/executor/Cargo.toml @@ -20,4 +20,5 @@ rand_core = "0.6.0" cl = { path = "../../cl/cl" } ledger = { path = "../../cl/ledger" } ledger_proof_statements = { path = "../../cl/ledger_proof_statements" } -goas_proof_statements = { path = "../proof_statements" } \ No newline at end of file +goas_proof_statements = { path = "../proof_statements" } +rayon = "1.10.0" diff --git a/goas/atomic_asset_transfer/executor/tests/atomic_transfer.rs b/goas/atomic_asset_transfer/executor/tests/atomic_transfer.rs index 29e0fa8..3e04106 100644 --- a/goas/atomic_asset_transfer/executor/tests/atomic_transfer.rs +++ b/goas/atomic_asset_transfer/executor/tests/atomic_transfer.rs @@ -1,10 +1,13 @@ use std::collections::BTreeMap; -use cl::{BalanceWitness, BundleWitness, NoteWitness, NullifierNonce}; +use cl::{BalanceWitness, BundleWitness, NoteWitness, Nullifier, NullifierNonce}; use common::{new_account, BoundTx, Deposit, SignedBoundTx, Tx, Withdraw}; use executor::ZoneNotes; use goas_proof_statements::user_note::{UserAtomicTransfer, UserIntent}; +use ledger::DeathProof; +use rayon::prelude::*; + #[test] fn test_atomic_transfer() { let mut rng = rand::thread_rng(); @@ -86,57 +89,70 @@ fn test_atomic_transfer() { &mut alice, ); - let death_proofs = BTreeMap::from_iter([ - ( - alice_intent_in.nullifier(), - executor::prove_user_atomic_transfer(UserAtomicTransfer { - user_note: atomic_transfer_ptx.input_witness(0), - user_intent: alice_intent, - zone_a: atomic_transfer_ptx.output_witness(0), - zone_b: atomic_transfer_ptx.output_witness(2), - zone_a_roots: zone_a_end.state.state_roots(), - zone_b_roots: zone_b_end.state.state_roots(), - withdraw_tx: withdraw_inclusion, - deposit_tx: deposit_inclusion, - }), - ), - ( - zone_a_start.state_input_witness().nullifier(), - executor::prove_zone_stf( - zone_a_start.state.clone(), - vec![(signed_withdraw, atomic_transfer_ptx.input_witness(0))], // withdraw bound to input intent note - atomic_transfer_ptx.input_witness(1), // input state note - atomic_transfer_ptx.output_witness(0), // output state note - atomic_transfer_ptx.output_witness(1), // output funds note + let death_proof = |idx: usize| -> (Nullifier, DeathProof) { + match idx { + 0 => ( + alice_intent_in.nullifier(), + executor::prove_user_atomic_transfer(UserAtomicTransfer { + user_note: atomic_transfer_ptx.input_witness(0), + user_intent: alice_intent, + zone_a: atomic_transfer_ptx.output_witness(0), + zone_b: atomic_transfer_ptx.output_witness(2), + zone_a_roots: zone_a_end.state.state_roots(), + zone_b_roots: zone_b_end.state.state_roots(), + withdraw_tx: withdraw_inclusion.clone(), + deposit_tx: deposit_inclusion.clone(), + }), ), - ), - ( - zone_a_start.fund_input_witness().nullifier(), - executor::prove_zone_fund_constraint( - atomic_transfer_ptx.input_witness(2), // input fund note - atomic_transfer_ptx.output_witness(0), // output state note - &zone_a_end.state, - ), - ), - ( - zone_b_start.state_input_witness().nullifier(), - executor::prove_zone_stf( - zone_b_start.state.clone(), - vec![(signed_deposit, atomic_transfer_ptx.input_witness(0))], // deposit bound to input intent note - atomic_transfer_ptx.input_witness(3), // input state note - atomic_transfer_ptx.output_witness(2), // output state note - atomic_transfer_ptx.output_witness(3), // output funds note - ), - ), - ( - zone_b_start.fund_input_witness().nullifier(), - executor::prove_zone_fund_constraint( - atomic_transfer_ptx.input_witness(4), // input fund note (input #1) - atomic_transfer_ptx.output_witness(2), // output state note (output #0) - &zone_b_end.state, - ), - ), - ]); + 1 => { + ( + zone_a_start.state_input_witness().nullifier(), + executor::prove_zone_stf( + zone_a_start.state.clone(), + vec![(signed_withdraw, atomic_transfer_ptx.input_witness(0))], // withdraw bound to input intent note + atomic_transfer_ptx.input_witness(1), // input state note + atomic_transfer_ptx.output_witness(0), // output state note + atomic_transfer_ptx.output_witness(1), // output funds note + ), + ) + } + 2 => { + ( + zone_a_start.fund_input_witness().nullifier(), + executor::prove_zone_fund_constraint( + atomic_transfer_ptx.input_witness(2), // input fund note + atomic_transfer_ptx.output_witness(0), // output state note + &zone_a_end.state, + ), + ) + } + 3 => { + ( + zone_b_start.state_input_witness().nullifier(), + executor::prove_zone_stf( + zone_b_start.state.clone(), + vec![(signed_deposit, atomic_transfer_ptx.input_witness(0))], // deposit bound to input intent note + atomic_transfer_ptx.input_witness(3), // input state note + atomic_transfer_ptx.output_witness(2), // output state note + atomic_transfer_ptx.output_witness(3), // output funds note + ), + ) + } + 4 => { + ( + zone_b_start.fund_input_witness().nullifier(), + executor::prove_zone_fund_constraint( + atomic_transfer_ptx.input_witness(4), // input fund note (input #1) + atomic_transfer_ptx.output_witness(2), // output state note (output #0) + &zone_b_end.state, + ), + ) + } + _ => panic!("Invalid idx"), + } + }; + + let death_proofs = (0..5).into_par_iter().map(death_proof).collect(); let user_ptx_proof = ledger::partial_tx::ProvedPartialTx::prove(&user_ptx, BTreeMap::new(), &[])