diff --git a/artifacts/program_methods/amm.bin b/artifacts/program_methods/amm.bin index 72bab162..e9e758c2 100644 Binary files a/artifacts/program_methods/amm.bin and b/artifacts/program_methods/amm.bin differ diff --git a/artifacts/program_methods/authenticated_transfer.bin b/artifacts/program_methods/authenticated_transfer.bin index 5fd291d7..dd111e37 100644 Binary files a/artifacts/program_methods/authenticated_transfer.bin and b/artifacts/program_methods/authenticated_transfer.bin differ diff --git a/artifacts/program_methods/pinata.bin b/artifacts/program_methods/pinata.bin index 7d98f6bb..c7aeee91 100644 Binary files a/artifacts/program_methods/pinata.bin and b/artifacts/program_methods/pinata.bin differ diff --git a/artifacts/program_methods/pinata_token.bin b/artifacts/program_methods/pinata_token.bin index 51692ae1..7f0e95b8 100644 Binary files a/artifacts/program_methods/pinata_token.bin and b/artifacts/program_methods/pinata_token.bin differ diff --git a/artifacts/program_methods/privacy_preserving_circuit.bin b/artifacts/program_methods/privacy_preserving_circuit.bin index 28bbaba4..05311bb8 100644 Binary files a/artifacts/program_methods/privacy_preserving_circuit.bin and b/artifacts/program_methods/privacy_preserving_circuit.bin differ diff --git a/artifacts/program_methods/token.bin b/artifacts/program_methods/token.bin index b26e52cd..caf216f8 100644 Binary files a/artifacts/program_methods/token.bin and b/artifacts/program_methods/token.bin differ diff --git a/artifacts/test_program_methods/burner.bin b/artifacts/test_program_methods/burner.bin index e2c3bdf1..1e375475 100644 Binary files a/artifacts/test_program_methods/burner.bin and b/artifacts/test_program_methods/burner.bin differ diff --git a/artifacts/test_program_methods/chain_caller.bin b/artifacts/test_program_methods/chain_caller.bin index f02b0621..3b7c0b39 100644 Binary files a/artifacts/test_program_methods/chain_caller.bin and b/artifacts/test_program_methods/chain_caller.bin differ diff --git a/artifacts/test_program_methods/changer_claimer.bin b/artifacts/test_program_methods/changer_claimer.bin index 6c929b34..1a5d6684 100644 Binary files a/artifacts/test_program_methods/changer_claimer.bin and b/artifacts/test_program_methods/changer_claimer.bin differ diff --git a/artifacts/test_program_methods/claimer.bin b/artifacts/test_program_methods/claimer.bin index c7885bba..b4860f56 100644 Binary files a/artifacts/test_program_methods/claimer.bin and b/artifacts/test_program_methods/claimer.bin differ diff --git a/artifacts/test_program_methods/data_changer.bin b/artifacts/test_program_methods/data_changer.bin index a45a027f..ac40692f 100644 Binary files a/artifacts/test_program_methods/data_changer.bin and b/artifacts/test_program_methods/data_changer.bin differ diff --git a/artifacts/test_program_methods/extra_output.bin b/artifacts/test_program_methods/extra_output.bin index c149d572..a9464cda 100644 Binary files a/artifacts/test_program_methods/extra_output.bin and b/artifacts/test_program_methods/extra_output.bin differ diff --git a/artifacts/test_program_methods/malicious_authorization_changer.bin b/artifacts/test_program_methods/malicious_authorization_changer.bin index 2aa1b518..cb1f1023 100644 Binary files a/artifacts/test_program_methods/malicious_authorization_changer.bin and b/artifacts/test_program_methods/malicious_authorization_changer.bin differ diff --git a/artifacts/test_program_methods/minter.bin b/artifacts/test_program_methods/minter.bin index 9b454fc2..cbc9f392 100644 Binary files a/artifacts/test_program_methods/minter.bin and b/artifacts/test_program_methods/minter.bin differ diff --git a/artifacts/test_program_methods/missing_output.bin b/artifacts/test_program_methods/missing_output.bin index eb41b0af..b1cf1d2b 100644 Binary files a/artifacts/test_program_methods/missing_output.bin and b/artifacts/test_program_methods/missing_output.bin differ diff --git a/artifacts/test_program_methods/modified_transfer.bin b/artifacts/test_program_methods/modified_transfer.bin index c424767b..b4a5d79d 100644 Binary files a/artifacts/test_program_methods/modified_transfer.bin and b/artifacts/test_program_methods/modified_transfer.bin differ diff --git a/artifacts/test_program_methods/nonce_changer.bin b/artifacts/test_program_methods/nonce_changer.bin index e1f1284e..e2244310 100644 Binary files a/artifacts/test_program_methods/nonce_changer.bin and b/artifacts/test_program_methods/nonce_changer.bin differ diff --git a/artifacts/test_program_methods/noop.bin b/artifacts/test_program_methods/noop.bin index 60ab5423..3d8a2b7d 100644 Binary files a/artifacts/test_program_methods/noop.bin and b/artifacts/test_program_methods/noop.bin differ diff --git a/artifacts/test_program_methods/program_owner_changer.bin b/artifacts/test_program_methods/program_owner_changer.bin index 06e83e8a..80b98160 100644 Binary files a/artifacts/test_program_methods/program_owner_changer.bin and b/artifacts/test_program_methods/program_owner_changer.bin differ diff --git a/artifacts/test_program_methods/simple_balance_transfer.bin b/artifacts/test_program_methods/simple_balance_transfer.bin index 8c6dbde7..071e0bd3 100644 Binary files a/artifacts/test_program_methods/simple_balance_transfer.bin and b/artifacts/test_program_methods/simple_balance_transfer.bin differ diff --git a/common/src/test_utils.rs b/common/src/test_utils.rs index 09651c18..432bdc40 100644 --- a/common/src/test_utils.rs +++ b/common/src/test_utils.rs @@ -1,4 +1,5 @@ use nssa::AccountId; +use nssa_core::account::Nonce; use crate::{ HashType, @@ -64,7 +65,7 @@ pub fn create_transaction_native_token_transfer( signing_key: nssa::PrivateKey, ) -> NSSATransaction { let account_ids = vec![from, to]; - let nonces = vec![nonce]; + let nonces = vec![Nonce(nonce)]; let program_id = nssa::program::Program::authenticated_transfer_program().id(); let message = nssa::public_transaction::Message::try_new( program_id, diff --git a/examples/program_deployment/src/bin/run_hello_world_with_authorization.rs b/examples/program_deployment/src/bin/run_hello_world_with_authorization.rs index 5e7df2d2..f38443ac 100644 --- a/examples/program_deployment/src/bin/run_hello_world_with_authorization.rs +++ b/examples/program_deployment/src/bin/run_hello_world_with_authorization.rs @@ -3,6 +3,7 @@ use nssa::{ program::Program, public_transaction::{Message, WitnessSet}, }; +use nssa_core::account::Nonce; use wallet::WalletCore; // Before running this example, compile the `hello_world_with_authorization.rs` guest program with: @@ -62,7 +63,13 @@ async fn main() { .await .expect("Node should be reachable to query account data"); let signing_keys = [signing_key]; - let message = Message::try_new(program.id(), vec![account_id], nonces, greeting).unwrap(); + let message = Message::try_new( + program.id(), + vec![account_id], + nonces.iter().map(|x| Nonce(*x)).collect(), + greeting, + ) + .unwrap(); // Pass the signing key to sign the message. This will be used by the node // to flag the pre_state as `is_authorized` when executing the program let witness_set = WitnessSet::for_message(&message, &signing_keys); diff --git a/explorer_service/src/components/account_preview.rs b/explorer_service/src/components/account_preview.rs index bbe59c0f..c40391a8 100644 --- a/explorer_service/src/components/account_preview.rs +++ b/explorer_service/src/components/account_preview.rs @@ -31,7 +31,7 @@ pub fn AccountPreview(account_id: AccountId, account: Account) -> impl IntoView
"Nonce: " - {nonce.to_string()} + {nonce.0.to_string()}
"Data: " diff --git a/explorer_service/src/pages/account_page.rs b/explorer_service/src/pages/account_page.rs index 4c0af1ac..69afd006 100644 --- a/explorer_service/src/pages/account_page.rs +++ b/explorer_service/src/pages/account_page.rs @@ -94,7 +94,7 @@ pub fn AccountPage() -> impl IntoView { let account_id_str = acc_id.to_string(); let program_id = program_owner.to_string(); let balance_str = balance.to_string(); - let nonce_str = nonce.to_string(); + let nonce_str = nonce.0.to_string(); let data_len = data.0.len(); view! {
diff --git a/explorer_service/src/pages/transaction_page.rs b/explorer_service/src/pages/transaction_page.rs index d0f1b4da..ad9bb45d 100644 --- a/explorer_service/src/pages/transaction_page.rs +++ b/explorer_service/src/pages/transaction_page.rs @@ -124,7 +124,7 @@ pub fn TransactionPage() -> impl IntoView { {account_id_str} - " (nonce: " {nonce.to_string()} ")" + " (nonce: " {nonce.0.to_string()} ")"
} @@ -198,7 +198,7 @@ pub fn TransactionPage() -> impl IntoView { {account_id_str} - " (nonce: " {nonce.to_string()} ")" + " (nonce: " {nonce.0.to_string()} ")"
} diff --git a/indexer/service/protocol/src/convert.rs b/indexer/service/protocol/src/convert.rs index 1de28aa3..130468ff 100644 --- a/indexer/service/protocol/src/convert.rs +++ b/indexer/service/protocol/src/convert.rs @@ -46,7 +46,7 @@ impl From for Account { program_owner: program_owner.into(), balance, data: data.into(), - nonce, + nonce: Nonce(nonce.0), } } } @@ -66,7 +66,7 @@ impl TryFrom for nssa_core::account::Account { program_owner: program_owner.into(), balance, data: data.try_into()?, - nonce, + nonce: nssa_core::account::Nonce(nonce.0), }) } } @@ -244,7 +244,7 @@ impl From for PublicMessage { Self { program_id: program_id.into(), account_ids: account_ids.into_iter().map(Into::into).collect(), - nonces, + nonces: nonces.iter().map(|x| Nonce(x.0)).collect(), instruction_data, } } @@ -261,7 +261,10 @@ impl From for nssa::public_transaction::Message { Self::new_preserialized( program_id.into(), account_ids.into_iter().map(Into::into).collect(), - nonces, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(x.0)) + .collect(), instruction_data, ) } @@ -279,7 +282,7 @@ impl From for PrivacyPre } = value; Self { public_account_ids: public_account_ids.into_iter().map(Into::into).collect(), - nonces, + nonces: nonces.iter().map(|x| Nonce(x.0)).collect(), public_post_states: public_post_states.into_iter().map(Into::into).collect(), encrypted_private_post_states: encrypted_private_post_states .into_iter() @@ -308,7 +311,10 @@ impl TryFrom for nssa::privacy_preserving_transaction: } = value; Ok(Self { public_account_ids: public_account_ids.into_iter().map(Into::into).collect(), - nonces, + nonces: nonces + .iter() + .map(|x| nssa_core::account::Nonce(x.0)) + .collect(), public_post_states: public_post_states .into_iter() .map(TryInto::try_into) diff --git a/indexer/service/protocol/src/lib.rs b/indexer/service/protocol/src/lib.rs index 8fdd3289..47acabc1 100644 --- a/indexer/service/protocol/src/lib.rs +++ b/indexer/service/protocol/src/lib.rs @@ -14,7 +14,8 @@ use serde_with::{DeserializeFromStr, SerializeDisplay}; #[cfg(feature = "convert")] mod convert; -pub type Nonce = u128; +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)] +pub struct Nonce(pub u128); #[derive( Debug, Copy, Clone, PartialEq, Eq, Hash, SerializeDisplay, DeserializeFromStr, JsonSchema, diff --git a/integration_tests/src/config.rs b/integration_tests/src/config.rs index 9d69fe22..f23c9825 100644 --- a/integration_tests/src/config.rs +++ b/integration_tests/src/config.rs @@ -4,7 +4,10 @@ use anyhow::{Context, Result}; use indexer_service::{BackoffConfig, BedrockClientConfig, ChannelId, IndexerConfig}; use key_protocol::key_management::KeyChain; use nssa::{Account, AccountId, PrivateKey, PublicKey}; -use nssa_core::{account::Data, program::DEFAULT_PROGRAM_ID}; +use nssa_core::{ + account::{Data, Nonce}, + program::DEFAULT_PROGRAM_ID, +}; use sequencer_core::config::{ AccountInitialData, BedrockConfig, CommitmentsInitialData, SequencerConfig, }; @@ -156,7 +159,7 @@ impl InitialData { balance: 10_000, data: Data::default(), program_owner: DEFAULT_PROGRAM_ID, - nonce: 0, + nonce: Nonce(0), }, ), ( @@ -165,7 +168,7 @@ impl InitialData { balance: 20_000, data: Data::default(), program_owner: DEFAULT_PROGRAM_ID, - nonce: 0, + nonce: Nonce(0), }, ), ], diff --git a/integration_tests/tests/account.rs b/integration_tests/tests/account.rs index ec53da78..f0a2f9a8 100644 --- a/integration_tests/tests/account.rs +++ b/integration_tests/tests/account.rs @@ -20,7 +20,7 @@ async fn get_existing_account() -> Result<()> { ); assert_eq!(account.balance, 10000); assert!(account.data.is_empty()); - assert_eq!(account.nonce, 0); + assert_eq!(account.nonce.0, 0); info!("Successfully retrieved account with correct details"); diff --git a/integration_tests/tests/auth_transfer/public.rs b/integration_tests/tests/auth_transfer/public.rs index da30fe5a..354f4723 100644 --- a/integration_tests/tests/auth_transfer/public.rs +++ b/integration_tests/tests/auth_transfer/public.rs @@ -235,7 +235,7 @@ async fn initialize_public_account() -> Result<()> { Program::authenticated_transfer_program().id() ); assert_eq!(account.balance, 0); - assert_eq!(account.nonce, 1); + assert_eq!(account.nonce.0, 1); assert!(account.data.is_empty()); info!("Successfully initialized public account"); diff --git a/integration_tests/tests/program_deployment.rs b/integration_tests/tests/program_deployment.rs index 098083d2..6a40e56c 100644 --- a/integration_tests/tests/program_deployment.rs +++ b/integration_tests/tests/program_deployment.rs @@ -58,7 +58,7 @@ async fn deploy_and_execute_program() -> Result<()> { assert_eq!(post_state_account.program_owner, data_changer.id()); assert_eq!(post_state_account.balance, 0); assert_eq!(post_state_account.data.as_ref(), &[0]); - assert_eq!(post_state_account.nonce, 0); + assert_eq!(post_state_account.nonce.0, 0); info!("Successfully deployed and executed program"); diff --git a/integration_tests/tests/tps.rs b/integration_tests/tests/tps.rs index 2c58721e..1c85dc2d 100644 --- a/integration_tests/tests/tps.rs +++ b/integration_tests/tests/tps.rs @@ -15,7 +15,7 @@ use nssa::{ }; use nssa_core::{ MembershipProof, NullifierPublicKey, - account::{AccountWithMetadata, data::Data}, + account::{AccountWithMetadata, Nonce, data::Data}, encryption::ViewingPublicKey, }; use tokio::test; @@ -135,7 +135,7 @@ impl TpsTestManager { let message = putx::Message::try_new( program.id(), [pair[0].1, pair[1].1].to_vec(), - [0u128].to_vec(), + [Nonce(0u128)].to_vec(), amount, ) .unwrap(); @@ -164,7 +164,7 @@ impl TpsTestManager { let key_chain = KeyChain::new_os_random(); let account = Account { balance: 100, - nonce: 0xdeadbeef, + nonce: Nonce(0xdeadbeef), program_owner: Program::authenticated_transfer_program().id(), data: Data::default(), }; @@ -198,7 +198,7 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction { let sender_pre = AccountWithMetadata::new( Account { balance: 100, - nonce: 0xdeadbeef, + nonce: Nonce(0xdeadbeef), program_owner: program.id(), data: Data::default(), }, @@ -232,7 +232,6 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction { vec![sender_pre, recipient_pre], Program::serialize_instruction(balance_to_move).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], vec![ (sender_npk.clone(), sender_ss), (recipient_npk.clone(), recipient_ss), diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index e57e6b13..fbf12a87 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -10,7 +10,7 @@ use anyhow::Result; use integration_tests::{BlockingTestContext, TIME_TO_WAIT_FOR_BLOCK_SECONDS}; use log::info; use nssa::{Account, AccountId, PrivateKey, PublicKey, program::Program}; -use nssa_core::program::DEFAULT_PROGRAM_ID; +use nssa_core::{account::Nonce, program::DEFAULT_PROGRAM_ID}; use tempfile::tempdir; use wallet::WalletCore; use wallet_ffi::{ @@ -487,7 +487,7 @@ fn test_wallet_ffi_get_account_public() -> Result<()> { ); assert_eq!(account.balance, 10000); assert!(account.data.is_empty()); - assert_eq!(account.nonce, 0); + assert_eq!(account.nonce.0, 0); unsafe { wallet_ffi_free_account_data((&mut out_account) as *mut FfiAccount); @@ -523,7 +523,7 @@ fn test_wallet_ffi_get_account_private() -> Result<()> { ); assert_eq!(account.balance, 10000); assert!(account.data.is_empty()); - assert_eq!(account.nonce, 0); + assert_eq!(account.nonce, Nonce(0)); unsafe { wallet_ffi_free_account_data((&mut out_account) as *mut FfiAccount); diff --git a/nssa/core/src/account.rs b/nssa/core/src/account.rs index 9bcdcd4b..e50de749 100644 --- a/nssa/core/src/account.rs +++ b/nssa/core/src/account.rs @@ -3,14 +3,52 @@ use std::{fmt::Display, str::FromStr}; use base58::{FromBase58, ToBase58}; use borsh::{BorshDeserialize, BorshSerialize}; pub use data::Data; +use risc0_zkvm::sha::{Impl, Sha256}; use serde::{Deserialize, Serialize}; use serde_with::{DeserializeFromStr, SerializeDisplay}; -use crate::program::ProgramId; +use crate::{NullifierPublicKey, NullifierSecretKey, program::ProgramId}; pub mod data; -pub type Nonce = u128; +#[derive( + Copy, + Debug, + Default, + Clone, + Eq, + PartialEq, + Serialize, + Deserialize, + BorshDeserialize, + BorshSerialize, +)] +pub struct Nonce(pub u128); + +impl Nonce { + pub fn public_account_nonce_increment(mut self) { + self.0 += 1; + } + + pub fn private_account_nonce_init(self, npk: &NullifierPublicKey) -> Nonce { + let mut bytes: [u8; 64] = [0u8; 64]; + bytes[..32].copy_from_slice(&npk.0); + let result: [u8; 32] = Impl::hash_bytes(&bytes).as_bytes().try_into().unwrap(); + let result = result.first_chunk::<16>().unwrap(); + + Nonce(u128::from_le_bytes(*result)) + } + + pub fn private_account_nonce_increment(self, nsk: &NullifierSecretKey) -> Nonce { + let mut bytes: [u8; 64] = [0u8; 64]; + bytes[..32].copy_from_slice(nsk); + bytes[32..48].copy_from_slice(&self.0.to_le_bytes()); + let result: [u8; 32] = Impl::hash_bytes(&bytes).as_bytes().try_into().unwrap(); + let result = result.first_chunk::<16>().unwrap(); + + Nonce(u128::from_le_bytes(*result)) + } +} /// Account to be used both in public and private contexts #[derive( @@ -123,7 +161,7 @@ mod tests { fn test_zero_nonce_account_data_creation() { let new_acc = Account::default(); - assert_eq!(new_acc.nonce, 0); + assert_eq!(new_acc.nonce.0, 0); } #[test] @@ -150,7 +188,7 @@ mod tests { .to_vec() .try_into() .unwrap(), - nonce: 0xdeadbeef, + nonce: Nonce(0xdeadbeef), }; let fingerprint = AccountId::new([8; 32]); let new_acc_with_metadata = AccountWithMetadata::new(account.clone(), true, fingerprint); @@ -197,4 +235,21 @@ mod tests { let expected_account_id = AccountId::new([0; 32]); assert!(default_account_id == expected_account_id); } + + #[test] + fn initialize_private_nonce() { + let npk = NullifierPublicKey([42; 32]); + let nonce = Nonce::default().private_account_nonce_init(&npk); + let expected_nonce = Nonce(37937661125547691021612781941709513486); + assert_eq!(nonce, expected_nonce); + } + + #[test] + fn increment_private_nonce() { + let nsk: NullifierSecretKey = [42u8; 32]; + let nonce = + Nonce(37937661125547691021612781941709513486).private_account_nonce_increment(&nsk); + let expected_nonce = Nonce(327300903218789900388409116014290259894); + assert_eq!(nonce, expected_nonce); + } } diff --git a/nssa/core/src/circuit_io.rs b/nssa/core/src/circuit_io.rs index dedcf780..8893cd2d 100644 --- a/nssa/core/src/circuit_io.rs +++ b/nssa/core/src/circuit_io.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::{ Commitment, CommitmentSetDigest, MembershipProof, Nullifier, NullifierPublicKey, NullifierSecretKey, SharedSecretKey, - account::{Account, AccountWithMetadata, Nonce}, + account::{Account, AccountWithMetadata}, encryption::Ciphertext, program::{ProgramId, ProgramOutput}, }; @@ -18,8 +18,6 @@ pub struct PrivacyPreservingCircuitInput { /// - `1` - private account with authentication /// - `2` - private account without authentication pub visibility_mask: Vec, - /// Nonces of private accounts. - pub private_account_nonces: Vec, /// Public keys of private accounts. pub private_account_keys: Vec<(NullifierPublicKey, SharedSecretKey)>, /// Nullifier secret keys for authorized private accounts. @@ -55,7 +53,7 @@ mod tests { use super::*; use crate::{ Commitment, Nullifier, NullifierPublicKey, - account::{Account, AccountId, AccountWithMetadata}, + account::{Account, AccountId, AccountWithMetadata, Nonce}, }; #[test] @@ -67,7 +65,7 @@ mod tests { program_owner: [1, 2, 3, 4, 5, 6, 7, 8], balance: 12345678901234567890, data: b"test data".to_vec().try_into().unwrap(), - nonce: 18446744073709551614, + nonce: Nonce(18446744073709551614), }, true, AccountId::new([0; 32]), @@ -77,7 +75,7 @@ mod tests { program_owner: [9, 9, 9, 8, 8, 8, 7, 7], balance: 123123123456456567112, data: b"test data".to_vec().try_into().unwrap(), - nonce: 9999999999999999999999, + nonce: Nonce(9999999999999999999999), }, false, AccountId::new([1; 32]), @@ -87,7 +85,7 @@ mod tests { program_owner: [1, 2, 3, 4, 5, 6, 7, 8], balance: 100, data: b"post state data".to_vec().try_into().unwrap(), - nonce: 18446744073709551615, + nonce: Nonce(18446744073709551615), }], ciphertexts: vec![Ciphertext(vec![255, 255, 1, 1, 2, 2])], new_commitments: vec![Commitment::new( diff --git a/nssa/core/src/commitment.rs b/nssa/core/src/commitment.rs index b08e3005..9a5bce2d 100644 --- a/nssa/core/src/commitment.rs +++ b/nssa/core/src/commitment.rs @@ -47,7 +47,7 @@ impl Commitment { this.extend_from_slice(&word.to_le_bytes()); } this.extend_from_slice(&account.balance.to_le_bytes()); - this.extend_from_slice(&account.nonce.to_le_bytes()); + this.extend_from_slice(&account.nonce.0.to_le_bytes()); let hashed_data: [u8; 32] = Impl::hash_bytes(&account.data) .as_bytes() .try_into() diff --git a/nssa/core/src/encoding.rs b/nssa/core/src/encoding.rs index 34be3782..cb80a9a9 100644 --- a/nssa/core/src/encoding.rs +++ b/nssa/core/src/encoding.rs @@ -23,7 +23,7 @@ impl Account { bytes.extend_from_slice(&word.to_le_bytes()); } bytes.extend_from_slice(&self.balance.to_le_bytes()); - bytes.extend_from_slice(&self.nonce.to_le_bytes()); + bytes.extend_from_slice(&self.nonce.0.to_le_bytes()); let data_length: u32 = self.data.len() as u32; bytes.extend_from_slice(&data_length.to_le_bytes()); bytes.extend_from_slice(self.data.as_ref()); @@ -32,7 +32,7 @@ impl Account { #[cfg(feature = "host")] pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result { - use crate::account::data::Data; + use crate::account::{Nonce, data::Data}; let mut u32_bytes = [0u8; 4]; let mut u128_bytes = [0u8; 16]; @@ -50,7 +50,7 @@ impl Account { // nonce cursor.read_exact(&mut u128_bytes)?; - let nonce = u128::from_le_bytes(u128_bytes); + let nonce = Nonce(u128::from_le_bytes(u128_bytes)); // data let data = Data::from_cursor(cursor)?; @@ -161,13 +161,14 @@ impl AccountId { #[cfg(test)] mod tests { use super::*; + use crate::account::Nonce; #[test] fn test_enconding() { let account = Account { program_owner: [1, 2, 3, 4, 5, 6, 7, 8], balance: 123456789012345678901234567890123456, - nonce: 42, + nonce: Nonce(42), data: b"hola mundo".to_vec().try_into().unwrap(), }; @@ -225,10 +226,12 @@ mod tests { #[cfg(feature = "host")] #[test] fn test_account_to_bytes_roundtrip() { + use crate::account::Nonce; + let account = Account { program_owner: [1, 2, 3, 4, 5, 6, 7, 8], balance: 123456789012345678901234567890123456, - nonce: 42, + nonce: Nonce(42), data: b"hola mundo".to_vec().try_into().unwrap(), }; let bytes = account.to_bytes(); diff --git a/nssa/core/src/program.rs b/nssa/core/src/program.rs index a6a04425..5b907d6e 100644 --- a/nssa/core/src/program.rs +++ b/nssa/core/src/program.rs @@ -328,6 +328,7 @@ impl WrappedBalanceSum { #[cfg(test)] mod tests { use super::*; + use crate::account::Nonce; #[test] fn test_post_state_new_with_claim_constructor() { @@ -335,7 +336,7 @@ mod tests { program_owner: [1, 2, 3, 4, 5, 6, 7, 8], balance: 1337, data: vec![0xde, 0xad, 0xbe, 0xef].try_into().unwrap(), - nonce: 10, + nonce: Nonce(10), }; let account_post_state = AccountPostState::new_claimed(account.clone()); @@ -350,7 +351,7 @@ mod tests { program_owner: [1, 2, 3, 4, 5, 6, 7, 8], balance: 1337, data: vec![0xde, 0xad, 0xbe, 0xef].try_into().unwrap(), - nonce: 10, + nonce: Nonce(10), }; let account_post_state = AccountPostState::new(account.clone()); @@ -365,7 +366,7 @@ mod tests { program_owner: [1, 2, 3, 4, 5, 6, 7, 8], balance: 1337, data: vec![0xde, 0xad, 0xbe, 0xef].try_into().unwrap(), - nonce: 10, + nonce: Nonce(10), }; let mut account_post_state = AccountPostState::new(account.clone()); diff --git a/nssa/src/privacy_preserving_transaction/circuit.rs b/nssa/src/privacy_preserving_transaction/circuit.rs index 9a28badd..5cd9c1bf 100644 --- a/nssa/src/privacy_preserving_transaction/circuit.rs +++ b/nssa/src/privacy_preserving_transaction/circuit.rs @@ -59,7 +59,6 @@ pub fn execute_and_prove( pre_states: Vec, instruction_data: InstructionData, visibility_mask: Vec, - private_account_nonces: Vec, private_account_keys: Vec<(NullifierPublicKey, SharedSecretKey)>, private_account_nsks: Vec, private_account_membership_proofs: Vec>, @@ -116,7 +115,6 @@ pub fn execute_and_prove( let circuit_input = PrivacyPreservingCircuitInput { program_outputs, visibility_mask, - private_account_nonces, private_account_keys, private_account_nsks, private_account_membership_proofs, @@ -171,7 +169,7 @@ impl Proof { mod tests { use nssa_core::{ Commitment, DUMMY_COMMITMENT_HASH, EncryptionScheme, Nullifier, - account::{Account, AccountId, AccountWithMetadata, data::Data}, + account::{Account, AccountId, AccountWithMetadata, Nonce, data::Data}, }; use super::*; @@ -209,14 +207,14 @@ mod tests { let expected_sender_post = Account { program_owner: program.id(), balance: 100 - balance_to_move, - nonce: 0, + nonce: Nonce(0), data: Data::default(), }; let expected_recipient_post = Account { program_owner: program.id(), balance: balance_to_move, - nonce: 0xdeadbeef, + nonce: Nonce(0xdeadbeef), data: Data::default(), }; @@ -229,7 +227,6 @@ mod tests { vec![sender, recipient], Program::serialize_instruction(balance_to_move).unwrap(), vec![0, 2], - vec![0xdeadbeef], vec![(recipient_keys.npk(), shared_secret)], vec![], vec![None], @@ -263,10 +260,11 @@ mod tests { let sender_keys = test_private_account_keys_1(); let recipient_keys = test_private_account_keys_2(); + let sender_nonce = Nonce(0xdeadbeef); let sender_pre = AccountWithMetadata::new( Account { balance: 100, - nonce: 0xdeadbeef, + nonce: sender_nonce, program_owner: program.id(), data: Data::default(), }, @@ -301,13 +299,13 @@ mod tests { let expected_private_account_1 = Account { program_owner: program.id(), balance: 100 - balance_to_move, - nonce: 0xdeadbeef1, + nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk), ..Default::default() }; let expected_private_account_2 = Account { program_owner: program.id(), balance: balance_to_move, - nonce: 0xdeadbeef2, + nonce: Nonce::default().private_account_nonce_init(&recipient_keys.npk()), ..Default::default() }; let expected_new_commitments = vec![ @@ -325,7 +323,6 @@ mod tests { vec![sender_pre.clone(), recipient], Program::serialize_instruction(balance_to_move).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], vec![ (sender_keys.npk(), shared_secret_1), (recipient_keys.npk(), shared_secret_2), diff --git a/nssa/src/privacy_preserving_transaction/message.rs b/nssa/src/privacy_preserving_transaction/message.rs index 47b0aa42..b323f452 100644 --- a/nssa/src/privacy_preserving_transaction/message.rs +++ b/nssa/src/privacy_preserving_transaction/message.rs @@ -89,7 +89,7 @@ impl Message { pub mod tests { use nssa_core::{ Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, SharedSecretKey, - account::Account, + account::{Account, Nonce}, encryption::{EphemeralPublicKey, ViewingPublicKey}, }; use sha2::{Digest, Sha256}; @@ -111,7 +111,7 @@ pub mod tests { let public_account_ids = vec![AccountId::new([1; 32])]; - let nonces = vec![1, 2, 3]; + let nonces = vec![Nonce(1), Nonce(2), Nonce(3)]; let public_post_states = vec![Account::default()]; diff --git a/nssa/src/public_transaction/transaction.rs b/nssa/src/public_transaction/transaction.rs index 7c8f7f74..cc934ea9 100644 --- a/nssa/src/public_transaction/transaction.rs +++ b/nssa/src/public_transaction/transaction.rs @@ -222,6 +222,7 @@ impl PublicTransaction { #[cfg(test)] pub mod tests { + use nssa_core::account::Nonce; use sha2::{Digest, digest::FixedOutput}; use crate::{ @@ -247,7 +248,7 @@ pub mod tests { fn transaction_for_tests() -> PublicTransaction { let (key1, key2, addr1, addr2) = keys_for_tests(); - let nonces = vec![0, 0]; + let nonces = vec![Nonce(0), Nonce(0)]; let instruction = 1337; let message = Message::try_new( Program::authenticated_transfer_program().id(), @@ -325,7 +326,7 @@ pub mod tests { fn test_account_id_list_cant_have_duplicates() { let (key1, _, addr1, _) = keys_for_tests(); let state = state_for_tests(); - let nonces = vec![0, 0]; + let nonces = vec![Nonce(0), Nonce(0)]; let instruction = 1337; let message = Message::try_new( Program::authenticated_transfer_program().id(), @@ -345,7 +346,7 @@ pub mod tests { fn test_number_of_nonces_must_match_number_of_signatures() { let (key1, key2, addr1, addr2) = keys_for_tests(); let state = state_for_tests(); - let nonces = vec![0]; + let nonces = vec![Nonce(0)]; let instruction = 1337; let message = Message::try_new( Program::authenticated_transfer_program().id(), @@ -365,7 +366,7 @@ pub mod tests { fn test_all_signatures_must_be_valid() { let (key1, key2, addr1, addr2) = keys_for_tests(); let state = state_for_tests(); - let nonces = vec![0, 0]; + let nonces = vec![Nonce(0), Nonce(0)]; let instruction = 1337; let message = Message::try_new( Program::authenticated_transfer_program().id(), @@ -386,7 +387,7 @@ pub mod tests { fn test_nonces_must_match_the_state_current_nonces() { let (key1, key2, addr1, addr2) = keys_for_tests(); let state = state_for_tests(); - let nonces = vec![0, 1]; + let nonces = vec![Nonce(0), Nonce(1)]; let instruction = 1337; let message = Message::try_new( Program::authenticated_transfer_program().id(), @@ -406,7 +407,7 @@ pub mod tests { fn test_program_id_must_belong_to_bulitin_program_ids() { let (key1, key2, addr1, addr2) = keys_for_tests(); let state = state_for_tests(); - let nonces = vec![0, 0]; + let nonces = vec![Nonce(0), Nonce(0)]; let instruction = 1337; let unknown_program_id = [0xdeadbeef; 8]; let message = diff --git a/nssa/src/public_transaction/witness_set.rs b/nssa/src/public_transaction/witness_set.rs index 9b9cd290..9d72dca8 100644 --- a/nssa/src/public_transaction/witness_set.rs +++ b/nssa/src/public_transaction/witness_set.rs @@ -51,6 +51,8 @@ impl WitnessSet { #[cfg(test)] mod tests { + use nssa_core::account::Nonce; + use super::*; use crate::AccountId; @@ -62,7 +64,7 @@ mod tests { let pubkey2 = PublicKey::new_from_private_key(&key2); let addr1 = AccountId::from(&pubkey1); let addr2 = AccountId::from(&pubkey2); - let nonces = vec![1, 2]; + let nonces = vec![Nonce(1), Nonce(2)]; let instruction = vec![1, 2, 3, 4]; let message = Message::try_new([0; 8], vec![addr1, addr2], nonces, instruction).unwrap(); diff --git a/nssa/src/state.rs b/nssa/src/state.rs index f5ec2b46..30c5a441 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -3,7 +3,7 @@ use std::collections::{BTreeSet, HashMap, HashSet}; use borsh::{BorshDeserialize, BorshSerialize}; use nssa_core::{ Commitment, CommitmentSetDigest, DUMMY_COMMITMENT, MembershipProof, Nullifier, - account::{Account, AccountId}, + account::{Account, AccountId, Nonce}, program::ProgramId, }; @@ -166,7 +166,7 @@ impl V02State { for account_id in tx.signer_account_ids() { let current_account = self.get_account_by_id_mut(account_id); - current_account.nonce += 1; + current_account.nonce.0 += 1; } Ok(()) @@ -202,7 +202,7 @@ impl V02State { // 5. Increment nonces for public signers for account_id in tx.signer_account_ids() { let current_account = self.get_account_by_id_mut(account_id); - current_account.nonce += 1; + current_account.nonce.0 += 1; } Ok(()) @@ -286,7 +286,7 @@ impl V02State { balance: 1500, // Difficulty: 3 data: vec![3; 33].try_into().expect("should fit"), - nonce: 0, + nonce: Nonce(0), }, ); } @@ -344,7 +344,7 @@ pub mod tests { balance: u128, ) -> PublicTransaction { let account_ids = vec![from, to]; - let nonces = vec![nonce]; + let nonces = vec![Nonce(nonce)]; let program_id = Program::authenticated_transfer_program().id(); let message = public_transaction::Message::try_new(program_id, account_ids, nonces, balance).unwrap(); @@ -458,8 +458,8 @@ pub mod tests { assert_eq!(state.get_account_by_id(from).balance, 95); assert_eq!(state.get_account_by_id(to).balance, 5); - assert_eq!(state.get_account_by_id(from).nonce, 1); - assert_eq!(state.get_account_by_id(to).nonce, 0); + assert_eq!(state.get_account_by_id(from).nonce.0, 1); + assert_eq!(state.get_account_by_id(to).nonce.0, 0); } #[test] @@ -480,8 +480,8 @@ pub mod tests { assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_)))); assert_eq!(state.get_account_by_id(from).balance, 100); assert_eq!(state.get_account_by_id(to).balance, 0); - assert_eq!(state.get_account_by_id(from).nonce, 0); - assert_eq!(state.get_account_by_id(to).nonce, 0); + assert_eq!(state.get_account_by_id(from).nonce.0, 0); + assert_eq!(state.get_account_by_id(to).nonce.0, 0); } #[test] @@ -503,8 +503,8 @@ pub mod tests { assert_eq!(state.get_account_by_id(from).balance, 192); assert_eq!(state.get_account_by_id(to).balance, 108); - assert_eq!(state.get_account_by_id(from).nonce, 1); - assert_eq!(state.get_account_by_id(to).nonce, 0); + assert_eq!(state.get_account_by_id(from).nonce.0, 1); + assert_eq!(state.get_account_by_id(to).nonce.0, 0); } #[test] @@ -527,9 +527,9 @@ pub mod tests { assert_eq!(state.get_account_by_id(account_id1).balance, 95); assert_eq!(state.get_account_by_id(account_id2).balance, 2); assert_eq!(state.get_account_by_id(account_id3).balance, 3); - assert_eq!(state.get_account_by_id(account_id1).nonce, 1); - assert_eq!(state.get_account_by_id(account_id2).nonce, 1); - assert_eq!(state.get_account_by_id(account_id3).nonce, 0); + assert_eq!(state.get_account_by_id(account_id1).nonce.0, 1); + assert_eq!(state.get_account_by_id(account_id2).nonce.0, 1); + assert_eq!(state.get_account_by_id(account_id3).nonce.0, 0); } impl V02State { @@ -560,7 +560,7 @@ pub mod tests { ..Account::default() }; let account_with_default_values_except_nonce = Account { - nonce: 37, + nonce: Nonce(37), ..Account::default() }; let account_with_default_values_except_data = Account { @@ -915,7 +915,6 @@ pub mod tests { vec![sender, recipient], Program::serialize_instruction(balance_to_move).unwrap(), vec![0, 2], - vec![0xdeadbeef], vec![(recipient_keys.npk(), shared_secret)], vec![], vec![None], @@ -940,7 +939,6 @@ pub mod tests { sender_private_account: &Account, recipient_keys: &TestPrivateKeys, balance_to_move: u128, - new_nonces: [Nonce; 2], state: &V02State, ) -> PrivacyPreservingTransaction { let program = Program::authenticated_transfer_program(); @@ -962,7 +960,6 @@ pub mod tests { vec![sender_pre, recipient_pre], Program::serialize_instruction(balance_to_move).unwrap(), vec![1, 2], - new_nonces.to_vec(), vec![ (sender_keys.npk(), shared_secret_1), (recipient_keys.npk(), shared_secret_2), @@ -994,7 +991,6 @@ pub mod tests { sender_private_account: &Account, recipient_account_id: &AccountId, balance_to_move: u128, - new_nonce: Nonce, state: &V02State, ) -> PrivacyPreservingTransaction { let program = Program::authenticated_transfer_program(); @@ -1015,7 +1011,6 @@ pub mod tests { vec![sender_pre, recipient_pre], Program::serialize_instruction(balance_to_move).unwrap(), vec![1, 0], - vec![new_nonce], vec![(sender_keys.npk(), shared_secret)], vec![sender_keys.nsk], vec![state.get_proof_for_commitment(&sender_commitment)], @@ -1056,7 +1051,7 @@ pub mod tests { let expected_sender_post = { let mut this = state.get_account_by_id(sender_keys.account_id()); this.balance -= balance_to_move; - this.nonce += 1; + this.nonce.0 += 1; this }; @@ -1080,10 +1075,11 @@ pub mod tests { #[test] fn test_transition_from_privacy_preserving_transaction_private() { let sender_keys = test_private_account_keys_1(); + let sender_nonce = Nonce(0xdeadbeef); let sender_private_account = Account { program_owner: Program::authenticated_transfer_program().id(), balance: 100, - nonce: 0xdeadbeef, + nonce: sender_nonce, data: Data::default(), }; let recipient_keys = test_private_account_keys_2(); @@ -1098,7 +1094,6 @@ pub mod tests { &sender_private_account, &recipient_keys, balance_to_move, - [0xcafecafe, 0xfecafeca], &state, ); @@ -1106,7 +1101,7 @@ pub mod tests { &sender_keys.npk(), &Account { program_owner: Program::authenticated_transfer_program().id(), - nonce: 0xcafecafe, + nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk), balance: sender_private_account.balance - balance_to_move, data: Data::default(), }, @@ -1120,7 +1115,7 @@ pub mod tests { &recipient_keys.npk(), &Account { program_owner: Program::authenticated_transfer_program().id(), - nonce: 0xfecafeca, + nonce: Nonce::default().private_account_nonce_init(&recipient_keys.npk()), balance: balance_to_move, ..Account::default() }, @@ -1146,10 +1141,11 @@ pub mod tests { #[test] fn test_transition_from_privacy_preserving_transaction_deshielded() { let sender_keys = test_private_account_keys_1(); + let sender_nonce = Nonce(0xdeadbeef); let sender_private_account = Account { program_owner: Program::authenticated_transfer_program().id(), balance: 100, - nonce: 0xdeadbeef, + nonce: Nonce(0xdeadbeef), data: Data::default(), }; let recipient_keys = test_public_account_keys_1(); @@ -1173,7 +1169,6 @@ pub mod tests { &sender_private_account, &recipient_keys.account_id(), balance_to_move, - 0xcafecafe, &state, ); @@ -1181,7 +1176,7 @@ pub mod tests { &sender_keys.npk(), &Account { program_owner: Program::authenticated_transfer_program().id(), - nonce: 0xcafecafe, + nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk), balance: sender_private_account.balance - balance_to_move, data: Data::default(), }, @@ -1230,7 +1225,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -1257,7 +1251,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -1284,7 +1277,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -1311,7 +1303,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -1340,7 +1331,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.to_owned().into(), ); @@ -1367,7 +1357,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -1403,7 +1392,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -1430,7 +1418,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -1466,7 +1453,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -1504,7 +1490,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -1529,12 +1514,10 @@ pub mod tests { AccountWithMetadata::new(Account::default(), false, &recipient_keys.npk()); // Setting only one nonce for an execution with two private accounts. - let private_account_nonces = [0xdeadbeef1]; let result = execute_and_prove( vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - private_account_nonces.to_vec(), vec![ ( sender_keys.npk(), @@ -1578,7 +1561,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], private_account_keys.to_vec(), vec![sender_keys.nsk], vec![Some((0, vec![]))], @@ -1611,7 +1593,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], vec![ ( sender_keys.npk(), @@ -1653,7 +1634,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], vec![ ( sender_keys.npk(), @@ -1711,7 +1691,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], private_account_keys.to_vec(), private_account_nsks.to_vec(), private_account_membership_proofs.to_vec(), @@ -1749,7 +1728,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], vec![ ( sender_keys.npk(), @@ -1797,7 +1775,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], vec![ ( sender_keys.npk(), @@ -1844,7 +1821,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], vec![ ( sender_keys.npk(), @@ -1880,7 +1856,7 @@ pub mod tests { let private_account_2 = AccountWithMetadata::new( Account { // Non default nonce - nonce: 0xdeadbeef, + nonce: Nonce(0xdeadbeef), ..Account::default() }, false, @@ -1891,7 +1867,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], vec![ ( sender_keys.npk(), @@ -1936,7 +1911,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], vec![ ( sender_keys.npk(), @@ -1978,7 +1952,6 @@ pub mod tests { vec![], vec![], vec![], - vec![], &program.into(), ); @@ -2004,12 +1977,10 @@ pub mod tests { // Setting three new private account nonces for a circuit execution with only two private // accounts. - let private_account_nonces = [0xdeadbeef1, 0xdeadbeef2, 0xdeadbeef3]; let result = execute_and_prove( vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - private_account_nonces.to_vec(), vec![ ( sender_keys.npk(), @@ -2065,7 +2036,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), vec![1, 2], - vec![0xdeadbeef1, 0xdeadbeef2], private_account_keys.to_vec(), vec![sender_keys.nsk], vec![Some((0, vec![]))], @@ -2101,7 +2071,6 @@ pub mod tests { vec![private_account_1, private_account_2], Program::serialize_instruction(10u128).unwrap(), visibility_mask.to_vec(), - vec![0xdeadbeef1, 0xdeadbeef2], vec![ ( sender_keys.npk(), @@ -2123,10 +2092,11 @@ pub mod tests { #[test] fn test_private_accounts_can_only_be_initialized_once() { let sender_keys = test_private_account_keys_1(); + let sender_nonce = Nonce(0xdeadbeef); let sender_private_account = Account { program_owner: Program::authenticated_transfer_program().id(), balance: 100, - nonce: 0xdeadbeef, + nonce: sender_nonce, data: Data::default(), }; let recipient_keys = test_private_account_keys_2(); @@ -2141,7 +2111,6 @@ pub mod tests { &sender_private_account, &recipient_keys, balance_to_move, - [0xcafecafe, 0xfecafeca], &state, ); @@ -2152,7 +2121,7 @@ pub mod tests { let sender_private_account = Account { program_owner: Program::authenticated_transfer_program().id(), balance: 100 - balance_to_move, - nonce: 0xcafecafe, + nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk), data: Data::default(), }; @@ -2161,7 +2130,6 @@ pub mod tests { &sender_private_account, &recipient_keys, balance_to_move, - [0x1234, 0x5678], &state, ); @@ -2197,7 +2165,6 @@ pub mod tests { vec![private_account_1.clone(), private_account_1], Program::serialize_instruction(100u128).unwrap(), visibility_mask.to_vec(), - vec![0xdeadbeef1, 0xdeadbeef2], vec![ (sender_keys.npk(), shared_secret), (sender_keys.npk(), shared_secret), @@ -2233,9 +2200,13 @@ pub mod tests { ..Account::default() }; - let message = - public_transaction::Message::try_new(program.id(), vec![from, to], vec![0], amount) - .unwrap(); + let message = public_transaction::Message::try_new( + program.id(), + vec![from, to], + vec![Nonce(0)], + amount, + ) + .unwrap(); let witness_set = public_transaction::WitnessSet::for_message(&message, &[&from_key]); let tx = PublicTransaction::new(message, witness_set); @@ -2275,7 +2246,7 @@ pub mod tests { program.id(), vec![to, from], // The chain_caller program permutes the account order in the chain // call - vec![0], + vec![Nonce(0)], instruction, ) .unwrap(); @@ -2314,7 +2285,7 @@ pub mod tests { program.id(), vec![to, from], // The chain_caller program permutes the account order in the chain // call - vec![0], + vec![Nonce(0)], instruction, ) .unwrap(); @@ -2576,7 +2547,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::user_token_a_holding_init(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2588,7 +2559,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::user_token_b_holding_init(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2608,7 +2579,7 @@ pub mod tests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), } } @@ -2621,7 +2592,7 @@ pub mod tests { total_supply: BalanceForTests::token_a_supply(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), } } @@ -2634,7 +2605,7 @@ pub mod tests { total_supply: BalanceForTests::token_b_supply(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), } } @@ -2647,7 +2618,7 @@ pub mod tests { total_supply: BalanceForTests::token_lp_supply(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), } } @@ -2659,7 +2630,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::vault_a_balance_init(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2671,7 +2642,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::vault_b_balance_init(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2683,7 +2654,7 @@ pub mod tests { definition_id: IdForTests::token_lp_definition_id(), balance: BalanceForTests::user_token_lp_holding_init(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2695,7 +2666,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::vault_a_balance_swap_1(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2707,7 +2678,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::vault_b_balance_swap_1(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2727,7 +2698,7 @@ pub mod tests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), } } @@ -2739,7 +2710,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::user_token_a_holding_swap_1(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2751,7 +2722,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::user_token_b_holding_swap_1(), }), - nonce: 1, + nonce: Nonce(1), } } @@ -2763,7 +2734,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::vault_a_balance_swap_2(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2775,7 +2746,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::vault_b_balance_swap_2(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2795,7 +2766,7 @@ pub mod tests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), } } @@ -2807,7 +2778,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::user_token_a_holding_swap_2(), }), - nonce: 1, + nonce: Nonce(1), } } @@ -2819,7 +2790,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::user_token_b_holding_swap_2(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2831,7 +2802,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::vault_a_balance_add(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2843,7 +2814,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::vault_b_balance_add(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2863,7 +2834,7 @@ pub mod tests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), } } @@ -2875,7 +2846,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::user_token_a_holding_add(), }), - nonce: 1, + nonce: Nonce(1), } } @@ -2887,7 +2858,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::user_token_b_holding_add(), }), - nonce: 1, + nonce: Nonce(1), } } @@ -2899,7 +2870,7 @@ pub mod tests { definition_id: IdForTests::token_lp_definition_id(), balance: BalanceForTests::user_token_lp_holding_add(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2912,7 +2883,7 @@ pub mod tests { total_supply: BalanceForTests::token_lp_supply_add(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), } } @@ -2924,7 +2895,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::vault_a_balance_remove(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2936,7 +2907,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::vault_b_balance_remove(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2956,7 +2927,7 @@ pub mod tests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), } } @@ -2968,7 +2939,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::user_token_a_holding_remove(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2980,7 +2951,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::user_token_b_holding_remove(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -2992,7 +2963,7 @@ pub mod tests { definition_id: IdForTests::token_lp_definition_id(), balance: BalanceForTests::user_token_lp_holding_remove(), }), - nonce: 1, + nonce: Nonce(1), } } @@ -3005,7 +2976,7 @@ pub mod tests { total_supply: BalanceForTests::token_lp_supply_remove(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), } } @@ -3018,7 +2989,7 @@ pub mod tests { total_supply: 0, metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), } } @@ -3030,7 +3001,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: 0, }), - nonce: 0, + nonce: Nonce(0), } } @@ -3042,7 +3013,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: 0, }), - nonce: 0, + nonce: Nonce(0), } } @@ -3062,7 +3033,7 @@ pub mod tests { fees: 0u128, active: false, }), - nonce: 0, + nonce: Nonce(0), } } @@ -3074,7 +3045,7 @@ pub mod tests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::user_token_a_holding_new_definition(), }), - nonce: 1, + nonce: Nonce(1), } } @@ -3086,7 +3057,7 @@ pub mod tests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::user_token_b_holding_new_definition(), }), - nonce: 1, + nonce: Nonce(1), } } @@ -3098,7 +3069,7 @@ pub mod tests { definition_id: IdForTests::token_lp_definition_id(), balance: BalanceForTests::user_token_a_holding_new_definition(), }), - nonce: 0, + nonce: Nonce(0), } } @@ -3111,7 +3082,7 @@ pub mod tests { total_supply: BalanceForTests::vault_a_balance_init(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), } } @@ -3131,7 +3102,7 @@ pub mod tests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), } } @@ -3143,7 +3114,7 @@ pub mod tests { definition_id: IdForTests::token_lp_definition_id(), balance: 0, }), - nonce: 0, + nonce: Nonce(0), } } } @@ -3230,7 +3201,7 @@ pub mod tests { IdForTests::user_token_b_id(), IdForTests::user_token_lp_id(), ], - vec![0], + vec![Nonce(0)], instruction, ) .unwrap(); @@ -3307,7 +3278,7 @@ pub mod tests { IdForTests::user_token_b_id(), IdForTests::user_token_lp_id(), ], - vec![0, 0], + vec![Nonce(0), Nonce(0)], instruction, ) .unwrap(); @@ -3391,7 +3362,7 @@ pub mod tests { IdForTests::user_token_b_id(), IdForTests::user_token_lp_id(), ], - vec![0, 0], + vec![Nonce(0), Nonce(0)], instruction, ) .unwrap(); @@ -3463,7 +3434,7 @@ pub mod tests { IdForTests::user_token_b_id(), IdForTests::user_token_lp_id(), ], - vec![0, 0], + vec![Nonce(0), Nonce(0)], instruction, ) .unwrap(); @@ -3526,7 +3497,7 @@ pub mod tests { IdForTests::user_token_b_id(), IdForTests::user_token_lp_id(), ], - vec![0, 0], + vec![Nonce(0), Nonce(0)], instruction, ) .unwrap(); @@ -3586,7 +3557,7 @@ pub mod tests { IdForTests::user_token_a_id(), IdForTests::user_token_b_id(), ], - vec![0], + vec![Nonce(0)], instruction, ) .unwrap(); @@ -3636,7 +3607,7 @@ pub mod tests { IdForTests::user_token_a_id(), IdForTests::user_token_b_id(), ], - vec![0], + vec![Nonce(0)], instruction, ) .unwrap(); @@ -3751,7 +3722,7 @@ pub mod tests { chain_caller.id(), vec![to, from], // The chain_caller program permutes the account order in the chain // call - vec![0], + vec![Nonce(0)], instruction, ) .unwrap(); @@ -3821,8 +3792,8 @@ pub mod tests { dependencies.insert(auth_transfers.id(), auth_transfers); let program_with_deps = ProgramWithDependencies::new(chain_caller, dependencies); - let from_new_nonce = 0xdeadbeef1; - let to_new_nonce = 0xdeadbeef2; + let from_new_nonce = Nonce::default().private_account_nonce_increment(&from_keys.nsk); + let to_new_nonce = Nonce::default().private_account_nonce_increment(&to_keys.nsk); let from_expected_post = Account { balance: initial_balance - number_of_calls as u128 * amount, @@ -3843,7 +3814,6 @@ pub mod tests { vec![to_account, from_account], Program::serialize_instruction(instruction).unwrap(), vec![1, 1], - vec![from_new_nonce, to_new_nonce], vec![(from_keys.npk(), to_ss), (to_keys.npk(), from_ss)], vec![from_keys.nsk, to_keys.nsk], vec![ @@ -4039,14 +4009,14 @@ pub mod tests { let expected_sender_post = { let mut this = state.get_account_by_id(sender_id); this.balance = sender_init_balance; - this.nonce = 0; + this.nonce = Nonce(0); this }; let expected_recipient_post = { let mut this = state.get_account_by_id(sender_id); this.balance = recipient_init_balance; - this.nonce = 0; + this.nonce = Nonce(0); this }; @@ -4075,14 +4045,11 @@ pub mod tests { // Balance to initialize the account with (0 for a new account) let balance: u128 = 0; - let nonce = 0xdeadbeef1; - // Execute and prove the circuit with the authorized account but no commitment proof let (output, proof) = execute_and_prove( vec![authorized_account], Program::serialize_instruction(balance).unwrap(), vec![1], - vec![nonce], vec![(private_keys.npk(), shared_secret)], vec![private_keys.nsk], vec![None], @@ -4128,14 +4095,12 @@ pub mod tests { let epk = EphemeralPublicKey::from_scalar(esk); let balance: u128 = 0; - let nonce = 0xdeadbeef1; // Step 2: Execute claimer program to claim the account with authentication let (output, proof) = execute_and_prove( vec![authorized_account.clone()], Program::serialize_instruction(balance).unwrap(), vec![1], - vec![nonce], vec![(private_keys.npk(), shared_secret)], vec![private_keys.nsk], vec![None], @@ -4176,14 +4141,11 @@ pub mod tests { let esk2 = [4; 32]; let shared_secret2 = SharedSecretKey::new(&esk2, &private_keys.vpk()); - let nonce2 = 0xdeadbeef2; - // Step 3: Try to execute noop program with authentication but without initialization let res = execute_and_prove( vec![account_metadata], Program::serialize_instruction(()).unwrap(), vec![1], - vec![nonce2], vec![(private_keys.npk(), shared_secret2)], vec![private_keys.nsk], vec![None], @@ -4253,7 +4215,6 @@ pub mod tests { vec![private_account], Program::serialize_instruction(instruction).unwrap(), vec![1], - vec![2], vec![( sender_keys.npk(), SharedSecretKey::new(&[3; 32], &sender_keys.vpk()), @@ -4281,7 +4242,6 @@ pub mod tests { vec![private_account], Program::serialize_instruction(instruction).unwrap(), vec![1], - vec![2], vec![( sender_keys.npk(), SharedSecretKey::new(&[3; 32], &sender_keys.vpk()), @@ -4333,14 +4293,11 @@ pub mod tests { dependencies.insert(auth_transfers.id(), auth_transfers); let program_with_deps = ProgramWithDependencies::new(malicious_program, dependencies); - let recipient_new_nonce = 0xdeadbeef1; - // Act - execute the malicious program - this should fail during proving let result = execute_and_prove( vec![sender_account, recipient_account], Program::serialize_instruction(instruction).unwrap(), vec![0, 1], - vec![recipient_new_nonce], vec![(recipient_keys.npk(), recipient)], vec![recipient_keys.nsk], vec![state.get_proof_for_commitment(&recipient_commitment)], diff --git a/program_methods/guest/src/bin/privacy_preserving_circuit.rs b/program_methods/guest/src/bin/privacy_preserving_circuit.rs index 4bbd895f..7735b57d 100644 --- a/program_methods/guest/src/bin/privacy_preserving_circuit.rs +++ b/program_methods/guest/src/bin/privacy_preserving_circuit.rs @@ -20,7 +20,6 @@ fn main() { let PrivacyPreservingCircuitInput { program_outputs, visibility_mask, - private_account_nonces, private_account_keys, private_account_nsks, private_account_membership_proofs, @@ -32,7 +31,6 @@ fn main() { let output = compute_circuit_output( execution_state, &visibility_mask, - &private_account_nonces, &private_account_keys, &private_account_nsks, &private_account_membership_proofs, @@ -223,7 +221,6 @@ impl ExecutionState { fn compute_circuit_output( execution_state: ExecutionState, visibility_mask: &[u8], - private_account_nonces: &[Nonce], private_account_keys: &[(NullifierPublicKey, SharedSecretKey)], private_account_nsks: &[NullifierSecretKey], private_account_membership_proofs: &[Option], @@ -243,7 +240,6 @@ fn compute_circuit_output( "Invalid visibility mask length" ); - let mut private_nonces_iter = private_account_nonces.iter(); let mut private_keys_iter = private_account_keys.iter(); let mut private_nsks_iter = private_account_nsks.iter(); let mut private_membership_proofs_iter = private_account_membership_proofs.iter(); @@ -269,7 +265,7 @@ fn compute_circuit_output( "AccountId mismatch" ); - let new_nullifier = if visibility_mask == 1 { + let (new_nullifier, new_nonce) = if visibility_mask == 1 { // Private account with authentication let Some(nsk) = private_nsks_iter.next() else { @@ -293,12 +289,19 @@ fn compute_circuit_output( panic!("Missing membership proof"); }; - compute_nullifier_and_set_digest( + let new_nullifier = compute_nullifier_and_set_digest( membership_proof_opt.as_ref(), &pre_state.account, npk, nsk, - ) + ); + + let new_nonce = pre_state + .account + .nonce + .private_account_nonce_increment(&nsk); + + (new_nullifier, new_nonce) } else { // Private account without authentication @@ -323,16 +326,17 @@ fn compute_circuit_output( ); let nullifier = Nullifier::for_account_initialization(npk); - (nullifier, DUMMY_COMMITMENT_HASH) + + let new_nonce = Nonce::default().private_account_nonce_init(npk); + + ((nullifier, DUMMY_COMMITMENT_HASH), new_nonce) }; output.new_nullifiers.push(new_nullifier); // Update post-state with new nonce let mut post_with_updated_nonce = post_state; - let Some(new_nonce) = private_nonces_iter.next() else { - panic!("Missing private account nonce"); - }; - post_with_updated_nonce.nonce = *new_nonce; + + post_with_updated_nonce.nonce = new_nonce; //*new_nonce; // Compute commitment let commitment_post = Commitment::new(npk, &post_with_updated_nonce); @@ -353,8 +357,6 @@ fn compute_circuit_output( } } - assert!(private_nonces_iter.next().is_none(), "Too many nonces"); - assert!( private_keys_iter.next().is_none(), "Too many private account keys" diff --git a/programs/amm/src/tests.rs b/programs/amm/src/tests.rs index 021e32b2..3740582e 100644 --- a/programs/amm/src/tests.rs +++ b/programs/amm/src/tests.rs @@ -7,7 +7,7 @@ use amm_core::{ compute_pool_pda, compute_vault_pda, compute_vault_pda_seed, }; use nssa_core::{ - account::{Account, AccountId, AccountWithMetadata, Data}, + account::{Account, AccountId, AccountWithMetadata, Data, Nonce}, program::{ChainedCall, ProgramId}, }; use token_core::{TokenDefinition, TokenHolding}; @@ -410,7 +410,7 @@ impl AccountForTests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::user_token_a_balance(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::user_token_a_id(), @@ -426,7 +426,7 @@ impl AccountForTests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::user_token_b_balance(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::user_token_b_id(), @@ -442,7 +442,7 @@ impl AccountForTests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::vault_a_reserve_init(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::vault_a_id(), @@ -458,7 +458,7 @@ impl AccountForTests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::vault_b_reserve_init(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::vault_b_id(), @@ -474,7 +474,7 @@ impl AccountForTests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::vault_a_reserve_high(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::vault_a_id(), @@ -490,7 +490,7 @@ impl AccountForTests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::vault_b_reserve_high(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::vault_b_id(), @@ -506,7 +506,7 @@ impl AccountForTests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::vault_a_reserve_low(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::vault_a_id(), @@ -522,7 +522,7 @@ impl AccountForTests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::vault_b_reserve_low(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::vault_b_id(), @@ -538,7 +538,7 @@ impl AccountForTests { definition_id: IdForTests::token_a_definition_id(), balance: 0, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::vault_a_id(), @@ -554,7 +554,7 @@ impl AccountForTests { definition_id: IdForTests::token_b_definition_id(), balance: 0, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::vault_b_id(), @@ -571,7 +571,7 @@ impl AccountForTests { total_supply: BalanceForTests::vault_a_reserve_init(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::token_lp_definition_id(), @@ -588,7 +588,7 @@ impl AccountForTests { total_supply: BalanceForTests::vault_a_reserve_init(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::vault_a_id(), @@ -604,7 +604,7 @@ impl AccountForTests { definition_id: IdForTests::token_lp_definition_id(), balance: 0, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::user_token_lp_id(), @@ -620,7 +620,7 @@ impl AccountForTests { definition_id: IdForTests::token_lp_definition_id(), balance: BalanceForTests::user_token_lp_balance(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::user_token_lp_id(), @@ -644,7 +644,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -668,7 +668,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -692,7 +692,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -716,7 +716,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -740,7 +740,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -764,7 +764,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -788,7 +788,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -812,7 +812,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -836,7 +836,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -860,7 +860,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -884,7 +884,7 @@ impl AccountForTests { fees: 0u128, active: false, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -908,7 +908,7 @@ impl AccountForTests { fees: 0u128, active: false, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: AccountId::new([4; 32]), @@ -924,7 +924,7 @@ impl AccountForTests { definition_id: IdForTests::token_a_definition_id(), balance: BalanceForTests::vault_a_reserve_init(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: AccountId::new([4; 32]), @@ -940,7 +940,7 @@ impl AccountForTests { definition_id: IdForTests::token_b_definition_id(), balance: BalanceForTests::vault_b_reserve_init(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: AccountId::new([4; 32]), @@ -964,7 +964,7 @@ impl AccountForTests { fees: 0u128, active: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), diff --git a/programs/token/src/tests.rs b/programs/token/src/tests.rs index cf95c4d4..00380cbb 100644 --- a/programs/token/src/tests.rs +++ b/programs/token/src/tests.rs @@ -1,6 +1,6 @@ #![cfg(test)] -use nssa_core::account::{Account, AccountId, AccountWithMetadata, Data}; +use nssa_core::account::{Account, AccountId, AccountWithMetadata, Data, Nonce}; use token_core::{ MetadataStandard, NewTokenDefinition, NewTokenMetadata, TokenDefinition, TokenHolding, }; @@ -32,7 +32,7 @@ impl AccountForTests { total_supply: BalanceForTests::init_supply(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -49,7 +49,7 @@ impl AccountForTests { total_supply: BalanceForTests::init_supply(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: false, account_id: IdForTests::pool_definition_id(), @@ -65,7 +65,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id_diff(), balance: BalanceForTests::holding_balance(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id(), @@ -81,7 +81,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::holding_balance(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id(), @@ -97,7 +97,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::holding_balance(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: false, account_id: IdForTests::holding_id(), @@ -113,7 +113,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::init_supply(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: false, account_id: IdForTests::holding_id(), @@ -130,7 +130,7 @@ impl AccountForTests { total_supply: BalanceForTests::init_supply_burned(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -146,7 +146,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::holding_balance_burned(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: false, account_id: IdForTests::holding_id(), @@ -170,7 +170,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::mint_success(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: false, account_id: IdForTests::holding_id(), @@ -186,7 +186,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::holding_balance_mint(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -203,7 +203,7 @@ impl AccountForTests { total_supply: BalanceForTests::init_supply_mint(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -219,7 +219,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::mint_overflow(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -236,7 +236,7 @@ impl AccountForTests { printable_supply: BalanceForTests::printable_copies(), metadata_id: AccountId::new([0; 32]), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -260,7 +260,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::init_supply(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id(), @@ -277,7 +277,7 @@ impl AccountForTests { total_supply: BalanceForTests::init_supply(), metadata_id: None, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::pool_definition_id(), @@ -293,7 +293,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::init_supply(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id(), @@ -309,7 +309,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::init_supply(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id_2(), @@ -325,7 +325,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::recipient_post_transfer(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id_2(), @@ -341,7 +341,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), balance: BalanceForTests::sender_post_transfer(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id(), @@ -357,7 +357,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), print_balance: BalanceForTests::printable_copies(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id(), @@ -373,7 +373,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), print_balance: 1, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id(), @@ -389,7 +389,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), print_balance: BalanceForTests::printable_copies() - 1, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id(), @@ -405,7 +405,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), owned: true, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: false, account_id: IdForTests::holding_id(), @@ -421,7 +421,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), print_balance: BalanceForTests::printable_copies(), }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id_2(), @@ -437,7 +437,7 @@ impl AccountForTests { definition_id: IdForTests::pool_definition_id(), print_balance: 0, }), - nonce: 0, + nonce: Nonce(0), }, is_authorized: true, account_id: IdForTests::holding_id(), diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index 7185ed9c..ad2121e7 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -221,7 +221,7 @@ impl JsonHandler account_ids .into_iter() - .map(|account_id| state.state().get_account_by_id(account_id).nonce) + .map(|account_id| state.state().get_account_by_id(account_id).nonce.0) .collect() }; diff --git a/test_program_methods/guest/src/bin/nonce_changer.rs b/test_program_methods/guest/src/bin/nonce_changer.rs index 17aa966a..06c6fb6b 100644 --- a/test_program_methods/guest/src/bin/nonce_changer.rs +++ b/test_program_methods/guest/src/bin/nonce_changer.rs @@ -12,7 +12,7 @@ fn main() { let account_pre = &pre.account; let mut account_post = account_pre.clone(); - account_post.nonce += 1; + account_post.nonce.0 += 1; write_nssa_outputs( instruction_words, diff --git a/wallet-ffi/src/types.rs b/wallet-ffi/src/types.rs index e99286c7..cc8ad08a 100644 --- a/wallet-ffi/src/types.rs +++ b/wallet-ffi/src/types.rs @@ -215,7 +215,7 @@ impl From for FfiAccount { balance: value.balance.into(), data, data_len, - nonce: value.nonce.into(), + nonce: value.nonce.0.into(), } } } @@ -236,7 +236,7 @@ impl TryFrom<&FfiAccount> for nssa::Account { program_owner: value.program_owner.data, balance: value.balance.into(), data, - nonce: value.nonce.into(), + nonce: nssa_core::account::Nonce(value.nonce.into()), }) } } diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index 15a1046d..990ea100 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -23,7 +23,6 @@ base64.workspace = true bytemuck.workspace = true borsh.workspace = true hex.workspace = true -rand.workspace = true itertools.workspace = true sha2.workspace = true futures.workspace = true diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index 20c04968..eda0bb2f 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -4,8 +4,6 @@ use anyhow::Result; use base64::{Engine, engine::general_purpose::STANDARD as BASE64}; use key_protocol::key_protocol_core::NSSAUserData; use nssa::Account; -use nssa_core::account::Nonce; -use rand::{RngCore, rngs::OsRng}; use serde::Serialize; use crate::{ @@ -115,12 +113,6 @@ pub fn produce_data_for_storage( } } -pub(crate) fn produce_random_nonces(size: usize) -> Vec { - let mut result = vec![[0; 16]; size]; - result.iter_mut().for_each(|bytes| OsRng.fill_bytes(bytes)); - result.into_iter().map(Nonce::from_le_bytes).collect() -} - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum AccountPrivacyKind { Public, @@ -162,7 +154,7 @@ impl From for HumanReadableAccount { balance: account.balance, program_owner_b64, data_b64, - nonce: account.nonce, + nonce: account.nonce.0, } } } diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index cb364fd3..37eca95c 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -22,7 +22,7 @@ use tokio::io::AsyncWriteExt; use crate::{ config::{PersistentStorage, WalletConfigOverrides}, - helperfunctions::{produce_data_for_storage, produce_random_nonces}, + helperfunctions::produce_data_for_storage, poller::TxPoller, }; @@ -328,7 +328,6 @@ impl WalletCore { pre_states, instruction_data, acc_manager.visibility_mask().to_vec(), - produce_random_nonces(private_account_keys.len()), private_account_keys .iter() .map(|keys| (keys.npk.clone(), keys.ssk)) diff --git a/wallet/src/program_facades/amm.rs b/wallet/src/program_facades/amm.rs index 0722a769..5b459c0f 100644 --- a/wallet/src/program_facades/amm.rs +++ b/wallet/src/program_facades/amm.rs @@ -80,7 +80,10 @@ impl Amm<'_> { let message = nssa::public_transaction::Message::try_new( program.id(), account_ids, - nonces, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(*x)) + .collect(), instruction, ) .unwrap(); @@ -187,7 +190,10 @@ impl Amm<'_> { let message = nssa::public_transaction::Message::try_new( program.id(), account_ids, - nonces, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(*x)) + .collect(), instruction, ) .unwrap(); @@ -274,7 +280,10 @@ impl Amm<'_> { let message = nssa::public_transaction::Message::try_new( program.id(), account_ids, - nonces, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(*x)) + .collect(), instruction, ) .unwrap(); @@ -356,7 +365,10 @@ impl Amm<'_> { let message = nssa::public_transaction::Message::try_new( program.id(), account_ids, - nonces, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(*x)) + .collect(), instruction, ) .unwrap(); diff --git a/wallet/src/program_facades/native_token_transfer/public.rs b/wallet/src/program_facades/native_token_transfer/public.rs index 3e4815a1..34572fe0 100644 --- a/wallet/src/program_facades/native_token_transfer/public.rs +++ b/wallet/src/program_facades/native_token_transfer/public.rs @@ -25,8 +25,16 @@ impl NativeTokenTransfer<'_> { let account_ids = vec![from, to]; let program_id = Program::authenticated_transfer_program().id(); - let message = - Message::try_new(program_id, account_ids, nonces, balance_to_move).unwrap(); + let message = Message::try_new( + program_id, + account_ids, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(*x)) + .collect(), + balance_to_move, + ) + .unwrap(); let signing_key = self.0.storage.user_data.get_pub_account_signing_key(from); @@ -55,7 +63,16 @@ impl NativeTokenTransfer<'_> { let instruction: u128 = 0; let account_ids = vec![from]; let program_id = Program::authenticated_transfer_program().id(); - let message = Message::try_new(program_id, account_ids, nonces, instruction).unwrap(); + let message = Message::try_new( + program_id, + account_ids, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(*x)) + .collect(), + instruction, + ) + .unwrap(); let signing_key = self.0.storage.user_data.get_pub_account_signing_key(from); diff --git a/wallet/src/program_facades/token.rs b/wallet/src/program_facades/token.rs index 9543f593..ecf15d56 100644 --- a/wallet/src/program_facades/token.rs +++ b/wallet/src/program_facades/token.rs @@ -139,7 +139,10 @@ impl Token<'_> { let message = nssa::public_transaction::Message::try_new( program_id, account_ids, - nonces, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(*x)) + .collect(), instruction, ) .unwrap(); @@ -338,7 +341,10 @@ impl Token<'_> { let message = nssa::public_transaction::Message::try_new( Program::token().id(), account_ids, - nonces, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(*x)) + .collect(), instruction, ) .expect("Instruction should serialize"); @@ -470,7 +476,10 @@ impl Token<'_> { let message = nssa::public_transaction::Message::try_new( Program::token().id(), account_ids, - nonces, + nonces + .iter() + .map(|x| nssa_core::account::Nonce(*x)) + .collect(), instruction, ) .unwrap();