From aa4e03b567519ddcb254c6256739715251aa4cda Mon Sep 17 00:00:00 2001 From: David Rusu Date: Fri, 9 Aug 2024 15:34:27 +0400 Subject: [PATCH 1/4] aat: deposit ptx test --- .../executor/tests/deposit_ptx.rs | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs diff --git a/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs b/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs new file mode 100644 index 0000000..18013b0 --- /dev/null +++ b/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs @@ -0,0 +1,147 @@ +use std::collections::{BTreeMap, VecDeque}; + +use cl::{NoteWitness, NullifierNonce, NullifierSecret}; +use common::{StateWitness, Tx, ZoneMetadata, ZONE_CL_FUNDS_UNIT}; +use ledger::death_constraint::DeathProof; +use rand_core::CryptoRngCore; + +fn zone_state_death_constraint() -> [u8; 32] { + ledger::death_constraint::risc0_id_to_cl_death_constraint(goas_risc0_proofs::ZONE_STATE_ID) +} + +fn zone_fund_death_constraint() -> [u8; 32] { + ledger::death_constraint::risc0_id_to_cl_death_constraint( + goas_risc0_proofs::SPEND_ZONE_FUNDS_ID, + ) +} + +fn zone_fund_note(value: u64, zone_meta: ZoneMetadata) -> cl::NoteWitness { + cl::NoteWitness { + value, + unit: *common::ZONE_CL_FUNDS_UNIT, + death_constraint: zone_meta.funds_vk, + state: zone_meta.id(), + } +} + +fn zone_state_utxo(zone: &StateWitness, mut rng: impl CryptoRngCore) -> cl::OutputWitness { + cl::OutputWitness::public( + cl::NoteWitness { + value: 1, + unit: zone.zone_metadata.unit, + death_constraint: zone.zone_metadata.zone_vk, + state: zone.commit().0, + }, + NullifierNonce::random(&mut rng), + ) +} + +#[test] +fn test_deposit() { + let mut rng = rand::thread_rng(); + + let alice = 42; + let alice_sk = NullifierSecret::random(&mut rng); + + let init_state = StateWitness { + balances: BTreeMap::new(), + included_txs: vec![], + zone_metadata: ZoneMetadata { + zone_vk: zone_state_death_constraint(), + funds_vk: zone_fund_death_constraint(), + unit: cl::note::unit_point("ZONE_STATE"), + }, + nonce: [0; 32], + }; + + let zone_state_in = cl::InputWitness::public(zone_state_utxo(&init_state, &mut rng)); + + let deposit = common::Deposit { + to: alice, + amount: 78, + }; + + let end_state = init_state.clone().deposit(deposit).evolve_nonce(); + + let zone_state_out = cl::OutputWitness::public( + cl::NoteWitness { + state: end_state.commit().0, + ..zone_state_in.note + }, + zone_state_in.evolved_nonce(), + ); + let zone_fund_out = cl::OutputWitness::public( + zone_fund_note(78, init_state.zone_metadata), + NullifierNonce::from_bytes(end_state.nonce), + ); + + let mut alice_state = [0u8; 32]; + alice_state[..4].copy_from_slice(&alice.to_le_bytes()); + + let alice_deposit = cl::InputWitness::random( + cl::OutputWitness::random( + NoteWitness::new( + 78, + *ZONE_CL_FUNDS_UNIT, + DeathProof::nop_constraint(), + alice_state, + ), + alice_sk.commit(), + &mut rng, + ), + alice_sk, + &mut rng, + ); + + let deposit_ptx = cl::PartialTxWitness { + inputs: vec![zone_state_in, alice_deposit], + outputs: vec![zone_state_out, zone_fund_out], + }; + + let death_proofs = BTreeMap::from_iter([ + ( + zone_state_in.nullifier(), + executor::prove_zone_stf( + init_state.clone(), + vec![Tx::Deposit(deposit)], + deposit_ptx.input_witness(0), // input state note (input #0) + deposit_ptx.output_witness(0), // output state note (output #0) + deposit_ptx.output_witness(1), // output funds note (output #1) + VecDeque::from_iter([]), // no withdrawals + VecDeque::from_iter([deposit_ptx.input_witness(1)]), // alices deposit (input #1) + ), + ), + ( + alice_deposit.nullifier(), + ledger::DeathProof::prove_nop(alice_deposit.nullifier(), deposit_ptx.commit().root()), + ), + ]); + + let note_commitments = vec![ + zone_state_in.note_commitment(), + alice_deposit.note_commitment(), + ]; + + let deposit_proof = + ledger::partial_tx::ProvedPartialTx::prove(&deposit_ptx, death_proofs, ¬e_commitments) + .expect("deposit proof failed"); + + assert!(deposit_proof.verify()); + + assert_eq!(deposit_proof.outputs[0].output, zone_state_out.commit()); + assert_eq!( + zone_state_out.note.state, + StateWitness { + balances: BTreeMap::from_iter([(alice, 78)]), + included_txs: vec![Tx::Deposit(deposit)], + zone_metadata: init_state.zone_metadata, + nonce: init_state.evolve_nonce().nonce, + } + .commit() + .0 + ); + assert_eq!( + deposit_ptx.commit().balance(), + cl::Balance::zero(deposit_ptx.balance_blinding()) + ); +} From 72e198eeb5abc8c9f7c4bd83169c2b46f058c06b Mon Sep 17 00:00:00 2001 From: David Rusu Date: Fri, 9 Aug 2024 19:46:36 +0400 Subject: [PATCH 2/4] goas: bind the deposit tx to the deposit note --- .../executor/tests/deposit_ptx.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs b/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs index 18013b0..526c8fe 100644 --- a/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs +++ b/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs @@ -1,7 +1,7 @@ -use std::collections::{BTreeMap, VecDeque}; +use std::collections::BTreeMap; use cl::{NoteWitness, NullifierNonce, NullifierSecret}; -use common::{StateWitness, Tx, ZoneMetadata, ZONE_CL_FUNDS_UNIT}; +use common::{BoundTx, StateWitness, Tx, ZoneMetadata, ZONE_CL_FUNDS_UNIT}; use ledger::death_constraint::DeathProof; use rand_core::CryptoRngCore; @@ -83,7 +83,7 @@ fn test_deposit() { NoteWitness::new( 78, *ZONE_CL_FUNDS_UNIT, - DeathProof::nop_constraint(), + DeathProof::nop_constraint(), // alice should demand a tx inclusion proof for the deposit alice_state, ), alice_sk.commit(), @@ -103,12 +103,13 @@ fn test_deposit() { zone_state_in.nullifier(), executor::prove_zone_stf( init_state.clone(), - vec![Tx::Deposit(deposit)], + vec![BoundTx { + tx: Tx::Deposit(deposit), + bind: deposit_ptx.input_witness(1), // bind it to the deposit note + }], deposit_ptx.input_witness(0), // input state note (input #0) deposit_ptx.output_witness(0), // output state note (output #0) deposit_ptx.output_witness(1), // output funds note (output #1) - VecDeque::from_iter([]), // no withdrawals - VecDeque::from_iter([deposit_ptx.input_witness(1)]), // alices deposit (input #1) ), ), ( From 7a7bea39318a512257945e108208003a5e3f6cdc Mon Sep 17 00:00:00 2001 From: David Rusu Date: Fri, 9 Aug 2024 20:00:31 +0400 Subject: [PATCH 3/4] goas: factor out common zone config to executor lib --- .../atomic_asset_transfer/executor/src/lib.rs | 20 ++++++++++++++++++- .../executor/tests/deposit_ptx.rs | 16 +-------------- .../executor/tests/withdraw_ptx.rs | 16 +-------------- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/goas/atomic_asset_transfer/executor/src/lib.rs b/goas/atomic_asset_transfer/executor/src/lib.rs index c224e4c..7565f79 100644 --- a/goas/atomic_asset_transfer/executor/src/lib.rs +++ b/goas/atomic_asset_transfer/executor/src/lib.rs @@ -1,6 +1,24 @@ -use common::{BoundTx, StateWitness}; +use common::{BoundTx, StateWitness, ZoneMetadata}; use goas_proof_statements::{zone_funds::SpendFundsPrivate, zone_state::ZoneStatePrivate}; +pub fn zone_state_death_constraint() -> [u8; 32] { + ledger::death_constraint::risc0_id_to_cl_death_constraint(goas_risc0_proofs::ZONE_STATE_ID) +} + +pub fn zone_fund_death_constraint() -> [u8; 32] { + ledger::death_constraint::risc0_id_to_cl_death_constraint( + goas_risc0_proofs::SPEND_ZONE_FUNDS_ID, + ) +} + +pub fn zone_metadata(zone_mnemonic: &str) -> ZoneMetadata { + ZoneMetadata { + zone_vk: zone_state_death_constraint(), + funds_vk: zone_fund_death_constraint(), + unit: cl::note::unit_point(zone_mnemonic), + } +} + pub fn prove_zone_stf( state: StateWitness, inputs: Vec, diff --git a/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs b/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs index 526c8fe..b43b349 100644 --- a/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs +++ b/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs @@ -5,16 +5,6 @@ use common::{BoundTx, StateWitness, Tx, ZoneMetadata, ZONE_CL_FUNDS_UNIT}; use ledger::death_constraint::DeathProof; use rand_core::CryptoRngCore; -fn zone_state_death_constraint() -> [u8; 32] { - ledger::death_constraint::risc0_id_to_cl_death_constraint(goas_risc0_proofs::ZONE_STATE_ID) -} - -fn zone_fund_death_constraint() -> [u8; 32] { - ledger::death_constraint::risc0_id_to_cl_death_constraint( - goas_risc0_proofs::SPEND_ZONE_FUNDS_ID, - ) -} - fn zone_fund_note(value: u64, zone_meta: ZoneMetadata) -> cl::NoteWitness { cl::NoteWitness { value, @@ -46,11 +36,7 @@ fn test_deposit() { let init_state = StateWitness { balances: BTreeMap::new(), included_txs: vec![], - zone_metadata: ZoneMetadata { - zone_vk: zone_state_death_constraint(), - funds_vk: zone_fund_death_constraint(), - unit: cl::note::unit_point("ZONE_STATE"), - }, + zone_metadata: executor::zone_metadata("ZONE"), nonce: [0; 32], }; diff --git a/goas/atomic_asset_transfer/executor/tests/withdraw_ptx.rs b/goas/atomic_asset_transfer/executor/tests/withdraw_ptx.rs index ca137b7..75fc45c 100644 --- a/goas/atomic_asset_transfer/executor/tests/withdraw_ptx.rs +++ b/goas/atomic_asset_transfer/executor/tests/withdraw_ptx.rs @@ -5,16 +5,6 @@ use common::{BoundTx, StateWitness, Tx, ZoneMetadata, ZONE_CL_FUNDS_UNIT}; use ledger::death_constraint::DeathProof; use rand_core::CryptoRngCore; -fn zone_state_death_constraint() -> [u8; 32] { - ledger::death_constraint::risc0_id_to_cl_death_constraint(goas_risc0_proofs::ZONE_STATE_ID) -} - -fn zone_fund_death_constraint() -> [u8; 32] { - ledger::death_constraint::risc0_id_to_cl_death_constraint( - goas_risc0_proofs::SPEND_ZONE_FUNDS_ID, - ) -} - fn zone_fund_utxo( value: u64, zone_meta: ZoneMetadata, @@ -53,11 +43,7 @@ fn test_withdrawal() { let init_state = StateWitness { balances: BTreeMap::from_iter([(alice, 100)]), included_txs: vec![], - zone_metadata: ZoneMetadata { - zone_vk: zone_state_death_constraint(), - funds_vk: zone_fund_death_constraint(), - unit: cl::note::unit_point("ZONE_STATE"), - }, + zone_metadata: executor::zone_metadata("ZONE"), nonce: [0; 32], }; From 0e278d92841fa74124dfe1553938d03d07d7eff5 Mon Sep 17 00:00:00 2001 From: David Rusu Date: Fri, 9 Aug 2024 20:14:34 +0400 Subject: [PATCH 4/4] goas: remove state from alice's deposit note --- goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs b/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs index b43b349..45afa0d 100644 --- a/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs +++ b/goas/atomic_asset_transfer/executor/tests/deposit_ptx.rs @@ -60,17 +60,12 @@ fn test_deposit() { zone_fund_note(78, init_state.zone_metadata), NullifierNonce::from_bytes(end_state.nonce), ); - - let mut alice_state = [0u8; 32]; - alice_state[..4].copy_from_slice(&alice.to_le_bytes()); - let alice_deposit = cl::InputWitness::random( cl::OutputWitness::random( - NoteWitness::new( + NoteWitness::stateless( 78, *ZONE_CL_FUNDS_UNIT, DeathProof::nop_constraint(), // alice should demand a tx inclusion proof for the deposit - alice_state, ), alice_sk.commit(), &mut rng,