From 99640bd70c1834ff6a0b2ff47486bf901d219414 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Fri, 8 Aug 2025 10:07:10 +0300 Subject: [PATCH 01/13] feat: dump command --- wallet/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 81cf14e..da58aee 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -149,6 +149,7 @@ pub enum Command { #[arg(long)] amount: u64, }, + DumpAccountsOnDisc, } ///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config @@ -177,6 +178,9 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { info!("Results of tx send is {res:#?}"); } + Command::DumpAccountsOnDisc => { + info!("Accounts stored at path"); + } } Ok(()) From c0318de646905a7fcff99e6b5c4eed8176ed2fa7 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Fri, 8 Aug 2025 15:22:04 +0300 Subject: [PATCH 02/13] fix: restore and dump methods --- wallet/src/helperfunctions.rs | 22 +++++++ wallet/src/lib.rs | 111 +++++++++++++++++++++++----------- 2 files changed, 97 insertions(+), 36 deletions(-) diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index 8f6af22..9a65f39 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -1,5 +1,6 @@ use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr}; +use accounts::account_core::Account; use anyhow::{anyhow, Result}; use crate::{config::NodeConfig, HOME_DIR_ENV_VAR}; @@ -41,3 +42,24 @@ pub fn produce_account_addr_from_hex(hex_str: String) -> Result<[u8; 32]> { .try_into() .map_err(|_| anyhow!("Failed conversion to 32 bytes")) } + +///Fetch list of accounts stored at `NSSA_WALLET_HOME_DIR/curr_accounts.json` +/// +/// If file not present, it is considered as empty list of persistent accounts +pub fn fetch_persistent_accounts() -> Result> { + let home = get_home()?; + let accs_path = home.join("curr_accounts.json"); + + match File::open(accs_path) { + Ok(file) => { + let reader = BufReader::new(file); + Ok(serde_json::from_reader(reader)?) + } + Err(err) => match err.kind() { + std::io::ErrorKind::NotFound => Ok(vec![]), + _ => { + anyhow::bail!("IO error {err:#?}"); + } + }, + } +} diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index da58aee..f058820 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{fs::File, io::Write, path::PathBuf, sync::Arc}; use common::{ execution_input::PublicNativeTokenSend, @@ -14,11 +14,12 @@ use common::transaction::TransactionBody; use config::NodeConfig; use log::info; use sc_core::proofs_circuits::pedersen_commitment_vec; -use tokio::sync::RwLock; use clap::{Parser, Subcommand}; -use crate::helperfunctions::{fetch_config, produce_account_addr_from_hex}; +use crate::helperfunctions::{ + fetch_config, fetch_persistent_accounts, get_home, produce_account_addr_from_hex, +}; pub const HOME_DIR_ENV_VAR: &str = "NSSA_WALLET_HOME_DIR"; pub const BLOCK_GEN_DELAY_SECS: u64 = 20; @@ -29,7 +30,7 @@ pub mod helperfunctions; pub mod requests_structs; pub struct NodeCore { - pub storage: Arc>, + pub storage: NodeChainStore, pub node_config: NodeConfig, pub sequencer_client: Arc, } @@ -43,20 +44,26 @@ impl NodeCore { storage.acc_map.insert(acc.address, acc); } - let wrapped_storage = Arc::new(RwLock::new(storage)); + //Persistent accounts take precedence for initial accounts + let persistent_accounts = fetch_persistent_accounts()?; + for acc in persistent_accounts { + storage.acc_map.insert(acc.address, acc); + } Ok(Self { - storage: wrapped_storage, + storage, node_config: config.clone(), sequencer_client: client.clone(), }) } pub async fn get_roots(&self) -> [[u8; 32]; 2] { - let storage = self.storage.read().await; [ - storage.utxo_commitments_store.get_root().unwrap_or([0; 32]), - storage.pub_tx_store.get_root().unwrap_or([0; 32]), + self.storage + .utxo_commitments_store + .get_root() + .unwrap_or([0; 32]), + self.storage.pub_tx_store.get_root().unwrap_or([0; 32]), ] } @@ -66,11 +73,7 @@ impl NodeCore { let addr = account.address; - { - let mut write_guard = self.storage.write().await; - - write_guard.acc_map.insert(account.address, account); - } + self.storage.acc_map.insert(account.address, account); addr } @@ -84,11 +87,7 @@ impl NodeCore { ) -> Result { let tx_roots = self.get_roots().await; - let public_context = { - let read_guard = self.storage.read().await; - - read_guard.produce_context(from) - }; + let public_context = self.storage.produce_context(from); let (tweak, secret_r, commitment) = pedersen_commitment_vec( //Will not panic, as public context is serializable @@ -113,31 +112,60 @@ impl NodeCore { ); tx.log(); - { - let read_guard = self.storage.read().await; + let account = self.storage.acc_map.get(&from); - let account = read_guard.acc_map.get(&from); + if let Some(account) = account { + let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); - if let Some(account) = account { - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); + let signed_transaction = Transaction::new(tx, key_to_sign_transaction); - let signed_transaction = Transaction::new(tx, key_to_sign_transaction); - - Ok(self - .sequencer_client - .send_tx(signed_transaction, tx_roots) - .await?) - } else { - Err(ExecutionFailureKind::AmountMismatchError) - } + Ok(self + .sequencer_client + .send_tx(signed_transaction, tx_roots) + .await?) + } else { + Err(ExecutionFailureKind::AmountMismatchError) } } + + ///Dumps all accounts from acc_map at `path` + /// + ///Currently storing everything in one file + /// + ///ToDo: extend storage + pub fn store_present_accounts_at_path(&self, path: PathBuf) -> Result { + let dump_path = path.join("curr_accounts.json"); + + let curr_accs: Vec = self + .storage + .acc_map + .values() + .cloned() + .collect(); + let accs_serialized = serde_json::to_vec_pretty(&curr_accs)?; + + let mut acc_file = File::create(&dump_path).unwrap(); + acc_file.write_all(&accs_serialized).unwrap(); + + Ok(dump_path) + } + + ///Dumps all accounts from acc_map at `NSSA_WALLET_HOME_DIR` + /// + ///Currently storing everything in one file + /// + ///ToDo: extend storage + pub fn store_present_accounts_at_home(&self) -> Result { + let home = get_home()?; + self.store_present_accounts_at_path(home) + } } ///Represents CLI command for a wallet #[derive(Subcommand, Debug, Clone)] #[clap(about)] pub enum Command { + ///Send native token transfer from `from` to `to` for `amount` SendNativeTokenTransfer { ///from - valid 32 byte hex string #[arg(long)] @@ -149,7 +177,12 @@ pub enum Command { #[arg(long)] amount: u64, }, - DumpAccountsOnDisc, + ///Dump accounts at destination + DumpAccountsOnDisc { + ///Dump path for accounts + #[arg(short, long)] + dump_path: PathBuf, + }, } ///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config @@ -178,8 +211,14 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { info!("Results of tx send is {res:#?}"); } - Command::DumpAccountsOnDisc => { - info!("Accounts stored at path"); + Command::DumpAccountsOnDisc { dump_path } => { + let node_config = fetch_config()?; + + let wallet_core = NodeCore::start_from_config_update_chain(node_config).await?; + + wallet_core.store_present_accounts_at_path(dump_path.clone())?; + + info!("Accounts stored at path {dump_path:#?}"); } } From dbb276e470f58f5d1df82ef85db0fba540ba623f Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Fri, 8 Aug 2025 17:01:21 +0300 Subject: [PATCH 03/13] fix: fmt --- wallet/src/lib.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index f058820..a02611c 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -136,12 +136,7 @@ impl NodeCore { pub fn store_present_accounts_at_path(&self, path: PathBuf) -> Result { let dump_path = path.join("curr_accounts.json"); - let curr_accs: Vec = self - .storage - .acc_map - .values() - .cloned() - .collect(); + let curr_accs: Vec = self.storage.acc_map.values().cloned().collect(); let accs_serialized = serde_json::to_vec_pretty(&curr_accs)?; let mut acc_file = File::create(&dump_path).unwrap(); From 8727dabe273572fa441c9c5915034ed0cf5c0600 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Mon, 11 Aug 2025 09:05:18 +0300 Subject: [PATCH 04/13] fix: merge fixes --- wallet/src/lib.rs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index b169fa4..df78de7 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -29,7 +29,7 @@ pub mod config; pub mod helperfunctions; pub struct WalletCore { - pub storage: Arc>, + pub storage: WalletChainStore, pub wallet_config: WalletConfig, pub sequencer_client: Arc, } @@ -50,7 +50,7 @@ impl WalletCore { } Ok(Self { - storage: wrapped_storage, + storage, wallet_config: config.clone(), sequencer_client: client.clone(), }) @@ -74,11 +74,7 @@ impl WalletCore { to: AccountAddress, balance_to_move: u64, ) -> Result { - let public_context = { - let read_guard = self.storage.read().await; - - read_guard.produce_context(from) - }; + let public_context = self.storage.produce_context(from); let (tweak, secret_r, commitment) = pedersen_commitment_vec( //Will not panic, as public context is serializable @@ -110,12 +106,9 @@ impl WalletCore { let signed_transaction = Transaction::new(tx, key_to_sign_transaction); - let signed_transaction = Transaction::new(tx, key_to_sign_transaction); - - Ok(self.sequencer_client.send_tx(signed_transaction).await?) - } else { - Err(ExecutionFailureKind::AmountMismatchError) - } + Ok(self.sequencer_client.send_tx(signed_transaction).await?) + } else { + Err(ExecutionFailureKind::AmountMismatchError) } } @@ -207,7 +200,7 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { Command::DumpAccountsOnDisc { dump_path } => { let node_config = fetch_config()?; - let wallet_core = NodeCore::start_from_config_update_chain(node_config).await?; + let wallet_core = WalletCore::start_from_config_update_chain(node_config).await?; wallet_core.store_present_accounts_at_path(dump_path.clone())?; From a3444f0c5c09f6c1c6280a454843ef5d1124449c Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Mon, 11 Aug 2025 14:01:13 +0300 Subject: [PATCH 05/13] fix: tests updates --- accounts/src/account_core/mod.rs | 8 +++ ci_scripts/test-ubuntu.sh | 2 +- .../configs/debug/wallet/wallet_config.json | 2 + integration_tests/src/lib.rs | 70 +++++++++++++++++++ wallet/src/chain_storage/mod.rs | 2 + wallet/src/lib.rs | 18 ++++- 6 files changed, 100 insertions(+), 2 deletions(-) diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index 1926649..f586019 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -25,6 +25,7 @@ pub struct Account { pub key_holder: AddressKeyHolder, pub address: AccountAddress, pub balance: u64, + pub nonce: u64, pub utxos: HashMap, } @@ -33,6 +34,7 @@ pub struct AccountForSerialization { pub key_holder: AddressKeyHolder, pub address: AccountAddress, pub balance: u64, + pub nonce: u64, pub utxos: HashMap, } @@ -42,6 +44,7 @@ impl From for AccountForSerialization { key_holder: value.key_holder, address: value.address, balance: value.balance, + nonce: value.nonce, utxos: value .utxos .into_iter() @@ -57,6 +60,7 @@ impl From for Account { key_holder: value.key_holder, address: value.address, balance: value.balance, + nonce: value.nonce, utxos: value .utxos .into_iter() @@ -120,12 +124,14 @@ impl Account { let public_key = *key_holder.get_pub_account_signing_key().verifying_key(); let address = address::from_public_key(&public_key); let balance = 0; + let nonce = 0; let utxos = HashMap::new(); Self { key_holder, address, balance, + nonce, utxos, } } @@ -134,12 +140,14 @@ impl Account { let key_holder = AddressKeyHolder::new_os_random(); let public_key = *key_holder.get_pub_account_signing_key().verifying_key(); let address = address::from_public_key(&public_key); + let nonce = 0; let utxos = HashMap::new(); Self { key_holder, address, balance, + nonce, utxos, } } diff --git a/ci_scripts/test-ubuntu.sh b/ci_scripts/test-ubuntu.sh index 90aa19e..db14402 100644 --- a/ci_scripts/test-ubuntu.sh +++ b/ci_scripts/test-ubuntu.sh @@ -6,5 +6,5 @@ source env.sh cargo test --release cd integration_tests -export NSSA_WALLET_HOME_DIR=$(pwd)/configs/debug/node/ +export NSSA_WALLET_HOME_DIR=$(pwd)/configs/debug/wallet/ cargo run $(pwd)/configs/debug all \ No newline at end of file diff --git a/integration_tests/configs/debug/wallet/wallet_config.json b/integration_tests/configs/debug/wallet/wallet_config.json index a1edc2f..e4dc7e9 100644 --- a/integration_tests/configs/debug/wallet/wallet_config.json +++ b/integration_tests/configs/debug/wallet/wallet_config.json @@ -40,6 +40,7 @@ 215 ], "balance": 10000, + "nonce": 0, "key_holder": { "address": [ 13, @@ -157,6 +158,7 @@ 100 ], "balance": 20000, + "nonce": 0, "key_holder": { "address": [ 151, diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index c323c3b..1f9684d 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -180,6 +180,72 @@ pub async fn test_failure() { info!("Success!"); } +pub async fn test_success_two_transactions() { + let command = Command::SendNativeTokenTransfer { + from: ACC_SENDER.to_string(), + nonce: 0, + to: ACC_RECEIVER.to_string(), + amount: 100, + }; + + let wallet_config = fetch_config().unwrap(); + + let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap(); + + wallet::execute_subcommand(command).await.unwrap(); + + info!("Waiting for next block creation"); + tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; + + info!("Checking correct balance move"); + let acc_1_balance = seq_client + .get_account_balance(ACC_SENDER.to_string()) + .await + .unwrap(); + let acc_2_balance = seq_client + .get_account_balance(ACC_RECEIVER.to_string()) + .await + .unwrap(); + + info!("Balance of sender : {acc_1_balance:#?}"); + info!("Balance of receiver : {acc_2_balance:#?}"); + + assert_eq!(acc_1_balance.balance, 9900); + assert_eq!(acc_2_balance.balance, 20100); + + info!("First TX Success!"); + + let command = Command::SendNativeTokenTransfer { + from: ACC_SENDER.to_string(), + nonce: 1, + to: ACC_RECEIVER.to_string(), + amount: 100, + }; + + wallet::execute_subcommand(command).await.unwrap(); + + info!("Waiting for next block creation"); + tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; + + info!("Checking correct balance move"); + let acc_1_balance = seq_client + .get_account_balance(ACC_SENDER.to_string()) + .await + .unwrap(); + let acc_2_balance = seq_client + .get_account_balance(ACC_RECEIVER.to_string()) + .await + .unwrap(); + + info!("Balance of sender : {acc_1_balance:#?}"); + info!("Balance of receiver : {acc_2_balance:#?}"); + + assert_eq!(acc_1_balance.balance, 9800); + assert_eq!(acc_2_balance.balance, 20200); + + info!("Second TX Success!"); +} + macro_rules! test_cleanup_wrap { ($home_dir:ident, $test_func:ident) => {{ let res = pre_test($home_dir.clone()).await.unwrap(); @@ -212,10 +278,14 @@ pub async fn main_tests_runner() -> Result<()> { "test_failure" => { test_cleanup_wrap!(home_dir, test_failure); } + "test_success_two_transactions" => { + test_cleanup_wrap!(home_dir, test_success_two_transactions); + } "all" => { test_cleanup_wrap!(home_dir, test_success_move_to_another_account); test_cleanup_wrap!(home_dir, test_success); test_cleanup_wrap!(home_dir, test_failure); + test_cleanup_wrap!(home_dir, test_success_two_transactions); } _ => { anyhow::bail!("Unknown test name"); diff --git a/wallet/src/chain_storage/mod.rs b/wallet/src/chain_storage/mod.rs index 4d5e7ab..f0fa6b1 100644 --- a/wallet/src/chain_storage/mod.rs +++ b/wallet/src/chain_storage/mod.rs @@ -115,6 +115,7 @@ mod tests { 249 ], "balance": 100, + "nonce": 0, "key_holder": { "nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718", "pub_account_signing_key": [ @@ -199,6 +200,7 @@ mod tests { 85 ], "balance": 200, + "nonce": 0, "key_holder": { "nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271", "pub_account_signing_key": [ diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index df78de7..9c17751 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -112,6 +112,15 @@ impl WalletCore { } } + ///Helperfunction to increment nonces for all given accounts + fn increment_nonces(&mut self, accounts_to_increment_nonces: &[AccountAddress]) { + for acc_addr in accounts_to_increment_nonces { + if let Some(acc) = self.storage.acc_map.get_mut(acc_addr) { + acc.nonce += 1; + } + } + } + ///Dumps all accounts from acc_map at `path` /// ///Currently storing everything in one file @@ -189,13 +198,20 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { let from = produce_account_addr_from_hex(from)?; let to = produce_account_addr_from_hex(to)?; - let wallet_core = WalletCore::start_from_config_update_chain(wallet_config).await?; + let mut wallet_core = WalletCore::start_from_config_update_chain(wallet_config).await?; let res = wallet_core .send_public_native_token_transfer(from, nonce, to, amount) .await?; info!("Results of tx send is {res:#?}"); + + //ToDo: Insert transaction polling logic here + wallet_core.increment_nonces(&[from, to]); + + let acc_storage_path = wallet_core.store_present_accounts_at_home()?; + + info!("Accounts stored at {acc_storage_path:#?}"); } Command::DumpAccountsOnDisc { dump_path } => { let node_config = fetch_config()?; From 6bced517644b1ab3879aa35d5c4695edb5f3bcb2 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Tue, 12 Aug 2025 14:35:10 +0300 Subject: [PATCH 06/13] fix: AccountAddress wrapped into struct --- accounts/src/account_core/address.rs | 53 +++++++-- accounts/src/account_core/mod.rs | 20 ++-- accounts/src/key_management/mod.rs | 10 +- sc_core/src/proofs_circuits.rs | 5 +- sc_core/src/public_context.rs | 9 +- sequencer_core/src/lib.rs | 41 ++++--- .../src/sequencer_store/accounts_store.rs | 105 ++++++++++++------ sequencer_rpc/src/process.rs | 3 +- wallet/src/chain_storage/accounts_store.rs | 2 +- wallet/src/helperfunctions.rs | 4 +- wallet/src/lib.rs | 4 +- zkvm/src/lib.rs | 6 +- 12 files changed, 172 insertions(+), 90 deletions(-) diff --git a/accounts/src/account_core/address.rs b/accounts/src/account_core/address.rs index 2fadacd..a25ba0d 100644 --- a/accounts/src/account_core/address.rs +++ b/accounts/src/account_core/address.rs @@ -1,17 +1,44 @@ -use common::transaction::SignaturePublicKey; +use common::transaction::{SignaturePublicKey, Tag}; +use serde::{Deserialize, Serialize}; use tiny_keccak::{Hasher, Keccak}; -// TODO: Consider wrapping `AccountAddress` in a struct. +#[derive( + Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, Default, +)] +pub struct AccountAddress(pub(crate) [u8; 32]); -pub type AccountAddress = [u8; 32]; +impl AccountAddress { + pub fn new(value: [u8; 32]) -> Self { + Self(value) + } -/// Returns the address associated with a public key -pub fn from_public_key(public_key: &SignaturePublicKey) -> AccountAddress { - let mut address = [0; 32]; - let mut keccak_hasher = Keccak::v256(); - keccak_hasher.update(&public_key.to_sec1_bytes()); - keccak_hasher.finalize(&mut address); - address + pub fn tag(&self) -> Tag { + self.0[0] + } + + pub fn raw_addr(&self) -> [u8; 32] { + self.0 + } +} + +impl TryFrom> for AccountAddress { + type Error = Vec; + + fn try_from(value: Vec) -> Result { + let addr_val: [u8; 32] = value.try_into()?; + + Ok(AccountAddress::new(addr_val)) + } +} + +impl From<&SignaturePublicKey> for AccountAddress { + fn from(value: &SignaturePublicKey) -> Self { + let mut address = [0; 32]; + let mut keccak_hasher = Keccak::v256(); + keccak_hasher.update(&value.to_sec1_bytes()); + keccak_hasher.finalize(&mut address); + AccountAddress::new(address) + } } #[cfg(test)] @@ -19,7 +46,6 @@ mod tests { use common::transaction::SignaturePrivateKey; use super::*; - use crate::account_core::address; #[test] fn test_address_key_equal_keccak_pub_sign_key() { @@ -31,6 +57,9 @@ mod tests { keccak_hasher.update(&public_key.to_sec1_bytes()); keccak_hasher.finalize(&mut expected_address); - assert_eq!(expected_address, address::from_public_key(public_key)); + assert_eq!( + AccountAddress::new(expected_address), + AccountAddress::from(public_key) + ); } } diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index f586019..de3f5aa 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -114,7 +114,7 @@ impl AccountPublicMask { } pub fn make_tag(&self) -> Tag { - self.address[0] + self.address.tag() } } @@ -122,7 +122,7 @@ impl Account { pub fn new() -> Self { let key_holder = AddressKeyHolder::new_os_random(); let public_key = *key_holder.get_pub_account_signing_key().verifying_key(); - let address = address::from_public_key(&public_key); + let address = AccountAddress::from(&public_key); let balance = 0; let nonce = 0; let utxos = HashMap::new(); @@ -139,7 +139,7 @@ impl Account { pub fn new_with_balance(balance: u64) -> Self { let key_holder = AddressKeyHolder::new_os_random(); let public_key = *key_holder.get_pub_account_signing_key().verifying_key(); - let address = address::from_public_key(&public_key); + let address = AccountAddress::from(&public_key); let nonce = 0; let utxos = HashMap::new(); @@ -191,7 +191,7 @@ impl Account { privacy_flag: bool, ) -> Result<()> { let asset_utxo = UTXO::new( - self.address, + self.address.raw_addr(), serde_json::to_vec(&asset)?, amount, privacy_flag, @@ -204,12 +204,16 @@ impl Account { pub fn log(&self) { info!("Keys generated"); - info!("Account address is {:?}", hex::encode(self.address)); + //use HexString + info!( + "Account address is {:?}", + hex::encode(self.address.raw_addr()) + ); info!("Account balance is {:?}", self.balance); } pub fn make_tag(&self) -> Tag { - self.address[0] + self.address.tag() } ///Produce account public mask @@ -247,8 +251,8 @@ mod tests { #[test] fn test_add_new_utxo_outputs() { let mut account = Account::new(); - let utxo1 = generate_dummy_utxo(account.address, 100); - let utxo2 = generate_dummy_utxo(account.address, 200); + let utxo1 = generate_dummy_utxo(account.address.raw_addr(), 100); + let utxo2 = generate_dummy_utxo(account.address.raw_addr(), 200); let result = account.add_new_utxo_outputs(vec![utxo1.clone(), utxo2.clone()]); diff --git a/accounts/src/key_management/mod.rs b/accounts/src/key_management/mod.rs index c1a78fb..8558c50 100644 --- a/accounts/src/key_management/mod.rs +++ b/accounts/src/key_management/mod.rs @@ -120,7 +120,10 @@ mod tests { use elliptic_curve::point::AffineCoordinates; use k256::{AffinePoint, ProjectivePoint, Scalar}; - use crate::{account_core::address, key_management::ephemeral_key_holder::EphemeralKeyHolder}; + use crate::{ + account_core::address::AccountAddress, + key_management::ephemeral_key_holder::EphemeralKeyHolder, + }; use super::*; @@ -347,7 +350,7 @@ mod tests { let verifying_key = signing_key.verifying_key(); - let address = address::from_public_key(verifying_key); + let address = AccountAddress::from(verifying_key); println!("======Prerequisites======"); println!(); @@ -373,7 +376,8 @@ mod tests { println!("======Public data======"); println!(); - println!("Address{:?}", hex::encode(address)); + //Use HexString + println!("Address{:?}", hex::encode(address.raw_addr())); println!( "Nulifier public key {:?}", hex::encode(serde_json::to_vec(&nullifer_public_key).unwrap()) diff --git a/sc_core/src/proofs_circuits.rs b/sc_core/src/proofs_circuits.rs index 08ce431..9e2f580 100644 --- a/sc_core/src/proofs_circuits.rs +++ b/sc_core/src/proofs_circuits.rs @@ -1,3 +1,4 @@ +use accounts::account_core::address::AccountAddress; use bincode; use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; use rand::{thread_rng, RngCore}; @@ -82,7 +83,7 @@ pub fn private_circuit( for in_utxo in input_utxos { let nullifier_public_key = public_context .account_masks - .get(&in_utxo.owner) + .get(&AccountAddress::new(in_utxo.owner)) .unwrap() .nullifier_public_key; @@ -125,7 +126,7 @@ pub fn deshielded_circuit( for in_utxo in input_utxos { let nullifier_public_key = public_context .account_masks - .get(&in_utxo.owner) + .get(&AccountAddress::new(in_utxo.owner)) .unwrap() .nullifier_public_key; diff --git a/sc_core/src/public_context.rs b/sc_core/src/public_context.rs index e225513..aab9ede 100644 --- a/sc_core/src/public_context.rs +++ b/sc_core/src/public_context.rs @@ -28,7 +28,12 @@ impl Serialize for PublicSCContext { where S: serde::Serializer, { - let mut account_masks_keys: Vec<[u8; 32]> = self.account_masks.keys().cloned().collect(); + let mut account_masks_keys: Vec<[u8; 32]> = self + .account_masks + .keys() + .cloned() + .map(|addr| addr.raw_addr()) + .collect(); account_masks_keys.sort(); let mut account_mask_values: Vec = @@ -111,7 +116,7 @@ mod tests { account_masks.insert(acc_3.address, acc_3.make_account_public_mask()); PublicSCContext { - caller_address, + caller_address: AccountAddress::new(caller_address), caller_balance: 100, account_masks, comitment_store_root, diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 810166d..fd15b0e 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -1,6 +1,6 @@ use std::fmt::Display; -use accounts::account_core::address::{self, AccountAddress}; +use accounts::account_core::address::AccountAddress; use anyhow::Result; use common::{ block::HashableBlockData, @@ -135,10 +135,10 @@ impl SequencerCore { if let Ok(native_transfer_action) = serde_json::from_slice::(execution_input) { - let signer_address = address::from_public_key(&tx.transaction().public_key); + let signer_address = AccountAddress::from(&tx.transaction().public_key); //Correct sender check - if native_transfer_action.from != signer_address { + if AccountAddress::new(native_transfer_action.from) != signer_address { return Err(TransactionMalformationErrorKind::IncorrectSender); } } @@ -219,8 +219,7 @@ impl SequencerCore { serde_json::from_slice::(execution_input) { // Nonce check - let signer_addres = - address::from_public_key(&mempool_tx.auth_tx.transaction().public_key); + let signer_addres = AccountAddress::from(&mempool_tx.auth_tx.transaction().public_key); if self.store.acc_store.get_account_nonce(&signer_addres) != native_transfer_action.nonce { @@ -230,11 +229,11 @@ impl SequencerCore { let from_balance = self .store .acc_store - .get_account_balance(&native_transfer_action.from); + .get_account_balance(&AccountAddress::new(native_transfer_action.from)); let to_balance = self .store .acc_store - .get_account_balance(&native_transfer_action.to); + .get_account_balance(&AccountAddress::new(native_transfer_action.to)); //Balance check if from_balance < native_transfer_action.balance_to_move { @@ -242,11 +241,11 @@ impl SequencerCore { } self.store.acc_store.set_account_balance( - &native_transfer_action.from, + &AccountAddress::new(native_transfer_action.from), from_balance - native_transfer_action.balance_to_move, ); self.store.acc_store.set_account_balance( - &native_transfer_action.to, + &AccountAddress::new(native_transfer_action.to), to_balance + native_transfer_action.balance_to_move, ); @@ -620,19 +619,25 @@ mod tests { common_setup(&mut sequencer); - let acc1 = hex::decode(sequencer.sequencer_config.initial_accounts[0].addr.clone()) - .unwrap() - .try_into() - .unwrap(); - let acc2 = hex::decode(sequencer.sequencer_config.initial_accounts[1].addr.clone()) - .unwrap() - .try_into() - .unwrap(); + let acc1: AccountAddress = + hex::decode(sequencer.sequencer_config.initial_accounts[0].addr.clone()) + .unwrap() + .try_into() + .unwrap(); + let acc2: AccountAddress = + hex::decode(sequencer.sequencer_config.initial_accounts[1].addr.clone()) + .unwrap() + .try_into() + .unwrap(); let sign_key1 = create_signing_key_for_account1(); let tx = common::test_utils::create_dummy_transaction_native_token_transfer( - acc1, 0, acc2, 100, sign_key1, + acc1.raw_addr(), + 0, + acc2.raw_addr(), + 100, + sign_key1, ); sequencer diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index 4f02220..b7012cf 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -155,30 +155,38 @@ mod tests { #[test] fn test_zero_balance_account_data_creation() { - let new_acc = AccountPublicData::new([1; 32]); + let address = AccountAddress::new([1; 32]); + + let new_acc = AccountPublicData::new(address); assert_eq!(new_acc.balance, 0); - assert_eq!(new_acc.address, [1; 32]); + assert_eq!(new_acc.address, address); } #[test] fn test_zero_nonce_account_data_creation() { - let new_acc = AccountPublicData::new([1; 32]); + let address = AccountAddress::new([1; 32]); + + let new_acc = AccountPublicData::new(address); assert_eq!(new_acc.nonce, 0); } #[test] fn test_non_zero_balance_account_data_creation() { - let new_acc = AccountPublicData::new_with_balance([1; 32], 10); + let address = AccountAddress::new([1; 32]); + + let new_acc = AccountPublicData::new_with_balance(address, 10); assert_eq!(new_acc.balance, 10); - assert_eq!(new_acc.address, [1; 32]); + assert_eq!(new_acc.address, address); } #[test] fn test_zero_nonce_account_data_creation_with_balance() { - let new_acc = AccountPublicData::new_with_balance([1; 32], 10); + let address = AccountAddress::new([1; 32]); + + let new_acc = AccountPublicData::new_with_balance(address, 10); assert_eq!(new_acc.nonce, 0); } @@ -192,94 +200,117 @@ mod tests { #[test] fn account_sequencer_store_register_acc() { + let address = AccountAddress::new([1; 32]); + let mut seq_acc_store = SequencerAccountsStore::default(); - seq_acc_store.register_account([1; 32]); + seq_acc_store.register_account(address); - assert!(seq_acc_store.contains_account(&[1; 32])); + assert!(seq_acc_store.contains_account(&address)); - let acc_balance = seq_acc_store.get_account_balance(&[1; 32]); + let acc_balance = seq_acc_store.get_account_balance(&address); assert_eq!(acc_balance, 0); } #[test] fn account_sequencer_store_unregister_acc_not_present() { + let address1 = AccountAddress::new([1; 32]); + let address2 = AccountAddress::new([2; 32]); + let mut seq_acc_store = SequencerAccountsStore::default(); - seq_acc_store.register_account([1; 32]); + seq_acc_store.register_account(address1); - let rem_res = seq_acc_store.unregister_account([2; 32]).unwrap(); + let rem_res = seq_acc_store.unregister_account(address2).unwrap(); assert!(rem_res.is_none()); } #[test] fn account_sequencer_store_unregister_acc_not_zero_balance() { - let mut seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); + let address1 = AccountAddress::new([1; 32]); + let address2 = AccountAddress::new([2; 32]); - let rem_res = seq_acc_store.unregister_account([1; 32]); + let mut seq_acc_store = SequencerAccountsStore::new(&[(address1, 12), (address2, 100)]); + + let rem_res = seq_acc_store.unregister_account(address1); assert!(rem_res.is_err()); } #[test] fn account_sequencer_store_unregister_acc() { + let address = AccountAddress::new([1; 32]); + let mut seq_acc_store = SequencerAccountsStore::default(); - seq_acc_store.register_account([1; 32]); + seq_acc_store.register_account(address); - assert!(seq_acc_store.contains_account(&[1; 32])); + assert!(seq_acc_store.contains_account(&address)); - seq_acc_store.unregister_account([1; 32]).unwrap().unwrap(); + seq_acc_store.unregister_account(address).unwrap().unwrap(); - assert!(!seq_acc_store.contains_account(&[1; 32])); + assert!(!seq_acc_store.contains_account(&address)); } #[test] fn account_sequencer_store_with_preset_accounts_1() { - let seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); + let address1 = AccountAddress::new([1; 32]); + let address2 = AccountAddress::new([2; 32]); - assert!(seq_acc_store.contains_account(&[1; 32])); - assert!(seq_acc_store.contains_account(&[2; 32])); + let seq_acc_store = SequencerAccountsStore::new(&[(address1, 12), (address2, 100)]); - let acc_balance = seq_acc_store.get_account_balance(&[1; 32]); + assert!(seq_acc_store.contains_account(&address1)); + assert!(seq_acc_store.contains_account(&address2)); + + let acc_balance = seq_acc_store.get_account_balance(&address1); assert_eq!(acc_balance, 12); - let acc_balance = seq_acc_store.get_account_balance(&[2; 32]); + let acc_balance = seq_acc_store.get_account_balance(&address2); assert_eq!(acc_balance, 100); } #[test] fn account_sequencer_store_with_preset_accounts_2() { + let address1 = AccountAddress::new([6; 32]); + let address2 = AccountAddress::new([7; 32]); + let address3 = AccountAddress::new([8; 32]); + let seq_acc_store = - SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); + SequencerAccountsStore::new(&[(address1, 120), (address2, 15), (address3, 10)]); - assert!(seq_acc_store.contains_account(&[6; 32])); - assert!(seq_acc_store.contains_account(&[7; 32])); - assert!(seq_acc_store.contains_account(&[8; 32])); + assert!(seq_acc_store.contains_account(&address1)); + assert!(seq_acc_store.contains_account(&address2)); + assert!(seq_acc_store.contains_account(&address3)); - let acc_balance = seq_acc_store.get_account_balance(&[6; 32]); + let acc_balance = seq_acc_store.get_account_balance(&address1); assert_eq!(acc_balance, 120); - let acc_balance = seq_acc_store.get_account_balance(&[7; 32]); + let acc_balance = seq_acc_store.get_account_balance(&address2); assert_eq!(acc_balance, 15); - let acc_balance = seq_acc_store.get_account_balance(&[8; 32]); + let acc_balance = seq_acc_store.get_account_balance(&address3); assert_eq!(acc_balance, 10); } #[test] fn account_sequencer_store_fetch_unknown_account() { - let seq_acc_store = - SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); + let address1 = AccountAddress::new([6; 32]); + let address2 = AccountAddress::new([7; 32]); + let address3 = AccountAddress::new([8; 32]); - let acc_balance = seq_acc_store.get_account_balance(&[9; 32]); + let address4 = AccountAddress::new([9; 32]); + + let seq_acc_store = + SequencerAccountsStore::new(&[(address1, 120), (address2, 15), (address3, 10)]); + + let acc_balance = seq_acc_store.get_account_balance(&address4); assert_eq!(acc_balance, 0); } @@ -293,19 +324,21 @@ mod tests { #[test] fn account_sequencer_store_set_balance_to_unknown_account() { + let address = AccountAddress::new([1; 32]); + let mut seq_acc_store = SequencerAccountsStore::default(); - let ret = seq_acc_store.set_account_balance(&[1; 32], 100); + let ret = seq_acc_store.set_account_balance(&address, 100); assert_eq!(ret, 0); - assert!(seq_acc_store.contains_account(&[1; 32])); - assert_eq!(seq_acc_store.get_account_balance(&[1; 32]), 100); + assert!(seq_acc_store.contains_account(&address)); + assert_eq!(seq_acc_store.get_account_balance(&address), 100); } #[test] fn test_increase_nonce() { let mut account_store = SequencerAccountsStore::default(); - let address = [1; 32]; + let address = AccountAddress::new([1; 32]); let first_nonce = account_store.increase_nonce(&address); assert_eq!(first_nonce, 0); let second_nonce = account_store.increase_nonce(&address); diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index eadfe55..c2b59bf 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -1,3 +1,4 @@ +use accounts::account_core::address::AccountAddress; use actix_web::Error as HttpError; use sequencer_core::config::AccountInitialData; use serde_json::Value; @@ -72,7 +73,7 @@ impl JsonHandler { { let mut acc_store = self.sequencer_state.lock().await; - acc_store.register_account(acc_req.address); + acc_store.register_account(AccountAddress::new(acc_req.address)); } let helperstruct = RegisterAccountResponse { diff --git a/wallet/src/chain_storage/accounts_store.rs b/wallet/src/chain_storage/accounts_store.rs index cd46a6f..36d657a 100644 --- a/wallet/src/chain_storage/accounts_store.rs +++ b/wallet/src/chain_storage/accounts_store.rs @@ -82,7 +82,7 @@ mod tests { let mut store = WalletAccountsStore::new(); let account_addr: [u8; 32] = pad_to_32("nonexistent".to_string().as_bytes()); - store.unregister_account(account_addr); + store.unregister_account(AccountAddress::new(account_addr)); assert!(store.accounts.is_empty()); } diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index a66b1e0..e36215d 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -1,6 +1,6 @@ use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr}; -use accounts::account_core::Account; +use accounts::account_core::{address::AccountAddress, Account}; use anyhow::{anyhow, Result}; use crate::{config::WalletConfig, HOME_DIR_ENV_VAR}; @@ -20,7 +20,7 @@ pub fn fetch_config() -> Result { } //ToDo: Replace with structures conversion in future -pub fn produce_account_addr_from_hex(hex_str: String) -> Result<[u8; 32]> { +pub fn produce_account_addr_from_hex(hex_str: String) -> Result { hex::decode(hex_str)? .try_into() .map_err(|_| anyhow!("Failed conversion to 32 bytes")) diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 9c17751..b8d23d4 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -86,9 +86,9 @@ impl WalletCore { let tx: TransactionBody = sc_core::transaction_payloads_tools::create_public_transaction_payload( serde_json::to_vec(&PublicNativeTokenSend { - from, + from: from.raw_addr(), nonce, - to, + to: to.raw_addr(), balance_to_move, }) .unwrap(), diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 0fbae70..3048370 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -187,7 +187,7 @@ pub fn prove_send_utxo_shielded( return Err(ExecutionFailureKind::AmountMismatchError); } - let temp_utxo_to_spend = UTXO::new(owner, vec![], amount, true); + let temp_utxo_to_spend = UTXO::new(owner.raw_addr(), vec![], amount, true); let utxo_payload = temp_utxo_to_spend.into_payload(); let mut builder = ExecutorEnv::builder(); @@ -561,7 +561,7 @@ mod tests { let utxo_exec = execute_mint_utxo(amount, owner, randomness).expect("execution failed"); assert_eq!(utxo_exec.amount, amount); - assert_eq!(utxo_exec.owner, owner); + assert_eq!(utxo_exec.owner, owner.raw_addr()); } #[test] @@ -571,7 +571,7 @@ mod tests { let (utxo, _) = prove_mint_utxo(amount, owner).expect("proof failed"); assert_eq!(utxo.amount, amount); - assert_eq!(utxo.owner, owner); + assert_eq!(utxo.owner, owner.raw_addr()); } #[test] From 939553cc8514cfcd59e4ecd9ef0cbb14140be7a7 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 13 Aug 2025 13:42:00 +0300 Subject: [PATCH 07/13] fix: structural upgrades finalized --- accounts/src/account_core/mod.rs | 38 ++- accounts/src/key_management/mod.rs | 2 +- .../configs/debug/wallet/wallet_config.json | 8 +- nssa/Cargo.toml | 5 +- nssa/program_methods/Cargo.toml | 1 - nssa/program_methods/guest/Cargo.toml | 3 +- nssa/rust-toolchain.toml | 1 - nssa/src/address.rs | 222 +++++++++++++++++- nssa/src/lib.rs | 2 +- nssa/src/public_transaction/transaction.rs | 8 +- nssa/src/public_transaction/witness_set.rs | 4 +- nssa/src/state.rs | 45 ++-- nssa/test_program_methods/Cargo.toml | 1 - nssa/test_program_methods/guest/Cargo.toml | 3 +- sc_core/Cargo.toml | 3 + sc_core/src/proofs_circuits.rs | 5 +- sc_core/src/public_context.rs | 16 +- sequencer_core/src/sequencer_store/mod.rs | 5 +- wallet/src/chain_storage/accounts_store.rs | 9 +- wallet/src/chain_storage/mod.rs | 11 +- wallet/src/helperfunctions.rs | 9 +- wallet/src/lib.rs | 11 +- zkvm/Cargo.toml | 3 + zkvm/src/lib.rs | 56 ++--- 24 files changed, 345 insertions(+), 126 deletions(-) diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index 2447868..da6aa27 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -4,18 +4,14 @@ use anyhow::Result; use common::{merkle_tree_public::TreeHashType, transaction::Tag}; use k256::AffinePoint; use log::info; +use nssa::Address; use serde::{Deserialize, Serialize}; use utxo::utxo_core::UTXO; -pub mod address; - -use crate::{ - account_core::address::AccountAddress, - key_management::{ - constants_types::{CipherText, Nonce}, - ephemeral_key_holder::EphemeralKeyHolder, - AddressKeyHolder, - }, +use crate::key_management::{ + constants_types::{CipherText, Nonce}, + ephemeral_key_holder::EphemeralKeyHolder, + AddressKeyHolder, }; pub type PublicKey = AffinePoint; @@ -23,7 +19,7 @@ pub type PublicKey = AffinePoint; #[derive(Clone, Debug)] pub struct Account { pub key_holder: AddressKeyHolder, - pub address: AccountAddress, + pub address: Address, pub balance: u64, pub utxos: HashMap, } @@ -31,7 +27,7 @@ pub struct Account { #[derive(Serialize, Deserialize, Clone, Debug)] pub struct AccountForSerialization { pub key_holder: AddressKeyHolder, - pub address: AccountAddress, + pub address: Address, pub balance: u64, pub utxos: HashMap, } @@ -95,7 +91,7 @@ impl<'de> Deserialize<'de> for Account { pub struct AccountPublicMask { pub nullifier_public_key: AffinePoint, pub viewing_public_key: AffinePoint, - pub address: AccountAddress, + pub address: Address, pub balance: u64, } @@ -110,7 +106,7 @@ impl AccountPublicMask { } pub fn make_tag(&self) -> Tag { - self.address[0] + self.address.tag() } } @@ -119,13 +115,13 @@ impl Account { let key_holder = AddressKeyHolder::new_os_random(); let public_key = nssa::PublicKey::new_from_private_key(key_holder.get_pub_account_signing_key()); - let address = nssa::Address::from_public_key(&public_key); + let address = nssa::Address::from(&public_key); let balance = 0; let utxos = HashMap::new(); Self { key_holder, - address: *address.value(), + address, balance, utxos, } @@ -135,12 +131,12 @@ impl Account { let key_holder = AddressKeyHolder::new_os_random(); let public_key = nssa::PublicKey::new_from_private_key(key_holder.get_pub_account_signing_key()); - let address = nssa::Address::from_public_key(&public_key); + let address = nssa::Address::from(&public_key); let utxos = HashMap::new(); Self { key_holder, - address: *address.value(), + address, balance, utxos, } @@ -185,7 +181,7 @@ impl Account { privacy_flag: bool, ) -> Result<()> { let asset_utxo = UTXO::new( - self.address, + *self.address.value(), serde_json::to_vec(&asset)?, amount, privacy_flag, @@ -203,7 +199,7 @@ impl Account { } pub fn make_tag(&self) -> Tag { - self.address[0] + self.address.tag() } ///Produce account public mask @@ -241,8 +237,8 @@ mod tests { #[test] fn test_add_new_utxo_outputs() { let mut account = Account::new(); - let utxo1 = generate_dummy_utxo(account.address, 100); - let utxo2 = generate_dummy_utxo(account.address, 200); + let utxo1 = generate_dummy_utxo(*account.address.value(), 100); + let utxo2 = generate_dummy_utxo(*account.address.value(), 200); let result = account.add_new_utxo_outputs(vec![utxo1.clone(), utxo2.clone()]); diff --git a/accounts/src/key_management/mod.rs b/accounts/src/key_management/mod.rs index a9cb196..9e48cbd 100644 --- a/accounts/src/key_management/mod.rs +++ b/accounts/src/key_management/mod.rs @@ -343,7 +343,7 @@ mod tests { let public_key = nssa::PublicKey::new_from_private_key(&pub_account_signing_key); - let address = nssa::Address::from_public_key(&public_key); + let address = nssa::Address::from(&public_key); println!("======Prerequisites======"); println!(); diff --git a/integration_tests/configs/debug/wallet/wallet_config.json b/integration_tests/configs/debug/wallet/wallet_config.json index ab6191d..6085a36 100644 --- a/integration_tests/configs/debug/wallet/wallet_config.json +++ b/integration_tests/configs/debug/wallet/wallet_config.json @@ -5,10 +5,10 @@ "seq_poll_timeout_secs": 10, "initial_accounts": [ { - "address": [27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143], + "address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", "balance": 10000, "key_holder": { - "address": [27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143], + "address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", "nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718", "pub_account_signing_key": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "top_secret_key_holder": { @@ -23,10 +23,10 @@ "utxos": {} }, { - "address": [77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217, 234, 216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102], + "address": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766", "balance": 20000, "key_holder": { - "address": [77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217, 234, 216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102], + "address": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766", "nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271", "pub_account_signing_key": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], "top_secret_key_holder": { diff --git a/nssa/Cargo.toml b/nssa/Cargo.toml index fef52ef..540dd62 100644 --- a/nssa/Cargo.toml +++ b/nssa/Cargo.toml @@ -12,7 +12,10 @@ serde = "1.0.219" sha2 = "0.10.9" secp256k1 = "0.31.1" rand = "0.8" +hex = "0.4.3" +anyhow.workspace = true +serde_json.workspace = true [dev-dependencies] test-program-methods = { path = "test_program_methods" } -hex = "0.4.3" + diff --git a/nssa/program_methods/Cargo.toml b/nssa/program_methods/Cargo.toml index 0f31c9b..ea7e36b 100644 --- a/nssa/program_methods/Cargo.toml +++ b/nssa/program_methods/Cargo.toml @@ -8,4 +8,3 @@ risc0-build = { version = "2.3.1" } [package.metadata.risc0] methods = ["guest"] - diff --git a/nssa/program_methods/guest/Cargo.toml b/nssa/program_methods/guest/Cargo.toml index 12bddbf..4b377c8 100644 --- a/nssa/program_methods/guest/Cargo.toml +++ b/nssa/program_methods/guest/Cargo.toml @@ -7,5 +7,4 @@ edition = "2021" [dependencies] risc0-zkvm = { version = "2.3.1", default-features = false, features = ['std'] } -nssa-core = {path = "../../core"} - +nssa-core = { path = "../../core" } diff --git a/nssa/rust-toolchain.toml b/nssa/rust-toolchain.toml index 8663d46..36614c3 100644 --- a/nssa/rust-toolchain.toml +++ b/nssa/rust-toolchain.toml @@ -2,4 +2,3 @@ channel = "stable" components = ["rustfmt", "rust-src"] profile = "minimal" - diff --git a/nssa/src/address.rs b/nssa/src/address.rs index 4aa4c45..6604fdd 100644 --- a/nssa/src/address.rs +++ b/nssa/src/address.rs @@ -1,8 +1,11 @@ -use serde::{Deserialize, Serialize}; +use anyhow::anyhow; +use serde::{Deserialize, Serialize, de::Visitor}; use crate::signature::PublicKey; -#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)] +pub const LENGTH_MISMATCH_ERROR_MESSAGE: &str = "Slice length != 32 "; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct Address { value: [u8; 32], } @@ -12,12 +15,221 @@ impl Address { Self { value } } - pub fn from_public_key(public_key: &PublicKey) -> Self { - // TODO: Check specs - Address::new(*public_key.value()) + pub fn tag(&self) -> u8 { + self.value[0] } pub fn value(&self) -> &[u8; 32] { &self.value } } + +impl AsRef<[u8]> for Address { + fn as_ref(&self) -> &[u8] { + &self.value + } +} + +impl TryFrom> for Address { + type Error = anyhow::Error; + + fn try_from(value: Vec) -> Result { + let addr_val: [u8; 32] = value + .try_into() + .map_err(|_| anyhow!(LENGTH_MISMATCH_ERROR_MESSAGE))?; + + Ok(Address::new(addr_val)) + } +} + +impl From<&PublicKey> for Address { + fn from(value: &PublicKey) -> Self { + // TODO: Check specs + Self::new(*value.value()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HexString(String); + +impl HexString { + pub fn inner(&self) -> &str { + &self.0 + } +} + +#[derive(Debug, thiserror::Error)] +pub enum HexStringConsistencyError { + #[error("Hex decode error")] + HexError(#[from] hex::FromHexError), + #[error("Decode slice does not fit 32 bytes")] + SizeError(#[from] anyhow::Error), +} + +impl TryFrom<&str> for HexString { + type Error = HexStringConsistencyError; + + fn try_from(value: &str) -> Result { + let decoded_str = hex::decode(value)?; + let _: Address = decoded_str.try_into()?; + + Ok(Self(value.to_string())) + } +} + +impl Serialize for HexString { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.0) + } +} + +struct HexStringVisitor; + +impl<'de> Visitor<'de> for HexStringVisitor { + type Value = String; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("expected a valid string") + } + + fn visit_string(self, v: String) -> Result + where + E: serde::de::Error, + { + Ok(v) + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + Ok(v.to_string()) + } +} + +impl<'de> Deserialize<'de> for HexString { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let str_cand = deserializer.deserialize_string(HexStringVisitor)?; + + let hex_string = + HexString::try_from(str_cand.as_str()).map_err(|err| serde::de::Error::custom(err))?; + + Ok(hex_string) + } +} + +impl From for Address { + fn from(value: HexString) -> Self { + Address::try_from(hex::decode(value.inner()).unwrap()).unwrap() + } +} + +impl From
for HexString { + fn from(value: Address) -> Self { + HexString::try_from(hex::encode(value).as_str()).unwrap() + } +} + +impl Serialize for Address { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let hex_string: HexString = (*self).into(); + + hex_string.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for Address { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let hex_sring = HexString::deserialize(deserializer)?; + + Ok(hex_sring.into()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[derive(Debug, Serialize, Deserialize)] + struct Ser1 { + f1: String, + } + + #[derive(Debug, Serialize, Deserialize, PartialEq)] + struct Ser2 { + f1: HexString, + } + + #[derive(Debug, Serialize, Deserialize, PartialEq)] + struct Ser3 { + f1: Address, + } + + #[test] + fn test_hex_ser() { + let str_for_tests = hex::encode([42; 32]); + + let hex_str_for_tests = HexString::try_from(str_for_tests.as_str()).unwrap(); + + let ser1_str = Ser1 { f1: str_for_tests }; + + let ser2_str = Ser2 { + f1: hex_str_for_tests, + }; + + let ser1_str_ser = serde_json::to_string(&ser1_str).unwrap(); + let ser2_str_ser = serde_json::to_string(&ser2_str).unwrap(); + + println!("{ser2_str_ser:#?}"); + + assert_eq!(ser1_str_ser, ser2_str_ser); + } + + #[test] + fn test_hex_deser() { + let raw_json = r#"{ + "f1": "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" + }"#; + + let str_for_tests = hex::encode([42; 32]); + + let hex_str_for_tests = HexString::try_from(str_for_tests.as_str()).unwrap(); + + let ser2_str = Ser2 { + f1: hex_str_for_tests, + }; + + let ser1_str: Ser2 = serde_json::from_str(raw_json).unwrap(); + + assert_eq!(ser1_str, ser2_str); + } + + #[test] + fn test_addr_deser() { + let raw_json = r#"{ + "f1": "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" + }"#; + + let addr_for_tests = Address::new([42; 32]); + + let ser2_str = Ser3 { + f1: addr_for_tests, + }; + + let ser1_str: Ser3 = serde_json::from_str(raw_json).unwrap(); + + assert_eq!(ser1_str, ser2_str); + } +} diff --git a/nssa/src/lib.rs b/nssa/src/lib.rs index ab4fe02..9555b14 100644 --- a/nssa/src/lib.rs +++ b/nssa/src/lib.rs @@ -1,4 +1,4 @@ -mod address; +pub mod address; pub mod error; pub mod program; pub mod public_transaction; diff --git a/nssa/src/public_transaction/transaction.rs b/nssa/src/public_transaction/transaction.rs index bd16644..9b56575 100644 --- a/nssa/src/public_transaction/transaction.rs +++ b/nssa/src/public_transaction/transaction.rs @@ -39,7 +39,7 @@ impl PublicTransaction { self.witness_set .signatures_and_public_keys() .iter() - .map(|(_, public_key)| Address::from_public_key(public_key)) + .map(|(_, public_key)| Address::from(public_key)) .collect() } @@ -129,14 +129,14 @@ pub mod tests { fn keys_for_tests() -> (PrivateKey, PrivateKey, Address, Address) { let key1 = PrivateKey::try_new([1; 32]).unwrap(); let key2 = PrivateKey::try_new([2; 32]).unwrap(); - let addr1 = Address::from_public_key(&PublicKey::new_from_private_key(&key1)); - let addr2 = Address::from_public_key(&PublicKey::new_from_private_key(&key2)); + let addr1 = Address::from(&PublicKey::new_from_private_key(&key1)); + let addr2 = Address::from(&PublicKey::new_from_private_key(&key2)); (key1, key2, addr1, addr2) } fn state_for_tests() -> V01State { let (_, _, addr1, addr2) = keys_for_tests(); - let initial_data = [(*addr1.value(), 10000), (*addr2.value(), 20000)]; + let initial_data = [(addr1, 10000), (addr2, 20000)]; V01State::new_with_genesis_accounts(&initial_data) } diff --git a/nssa/src/public_transaction/witness_set.rs b/nssa/src/public_transaction/witness_set.rs index ae87080..f0e5c6b 100644 --- a/nssa/src/public_transaction/witness_set.rs +++ b/nssa/src/public_transaction/witness_set.rs @@ -49,8 +49,8 @@ mod tests { let key2 = PrivateKey::try_new([2; 32]).unwrap(); let pubkey1 = PublicKey::new_from_private_key(&key1); let pubkey2 = PublicKey::new_from_private_key(&key2); - let addr1 = Address::from_public_key(&pubkey1); - let addr2 = Address::from_public_key(&pubkey2); + let addr1 = Address::from(&pubkey1); + let addr2 = Address::from(&pubkey2); let nonces = vec![1, 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 f6d932e..ab5d7a1 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -10,18 +10,17 @@ pub struct V01State { } impl V01State { - pub fn new_with_genesis_accounts(initial_data: &[([u8; 32], u128)]) -> Self { + pub fn new_with_genesis_accounts(initial_data: &[(Address, u128)]) -> Self { let authenticated_transfer_program = Program::authenticated_transfer_program(); let public_state = initial_data .iter() .copied() - .map(|(address_value, balance)| { + .map(|(address, balance)| { let account = Account { balance, program_owner: authenticated_transfer_program.id(), ..Account::default() }; - let address = Address::new(address_value); (address, account) }) .collect(); @@ -106,9 +105,9 @@ mod tests { fn test_new_with_genesis() { let key1 = PrivateKey::try_new([1; 32]).unwrap(); let key2 = PrivateKey::try_new([2; 32]).unwrap(); - let addr1 = Address::from_public_key(&PublicKey::new_from_private_key(&key1)); - let addr2 = Address::from_public_key(&PublicKey::new_from_private_key(&key2)); - let initial_data = [(*addr1.value(), 100u128), (*addr2.value(), 151u128)]; + let addr1 = Address::from(&PublicKey::new_from_private_key(&key1)); + let addr2 = Address::from(&PublicKey::new_from_private_key(&key2)); + let initial_data = [(addr1, 100u128), (addr2, 151u128)]; let program = Program::authenticated_transfer_program(); let expected_public_state = { let mut this = HashMap::new(); @@ -157,8 +156,8 @@ mod tests { #[test] fn test_get_account_by_address_non_default_account() { let key = PrivateKey::try_new([1; 32]).unwrap(); - let addr = Address::from_public_key(&PublicKey::new_from_private_key(&key)); - let initial_data = [(*addr.value(), 100u128)]; + let addr = Address::from(&PublicKey::new_from_private_key(&key)); + let initial_data = [(addr, 100u128)]; let state = V01State::new_with_genesis_accounts(&initial_data); let expected_account = state.public_state.get(&addr).unwrap(); @@ -190,8 +189,8 @@ mod tests { #[test] fn transition_from_authenticated_transfer_program_invocation_default_account_destination() { let key = PrivateKey::try_new([1; 32]).unwrap(); - let address = Address::from_public_key(&PublicKey::new_from_private_key(&key)); - let initial_data = [(*address.value(), 100)]; + let address = Address::from(&PublicKey::new_from_private_key(&key)); + let initial_data = [(address, 100)]; let mut state = V01State::new_with_genesis_accounts(&initial_data); let from = address; let to = Address::new([2; 32]); @@ -210,8 +209,8 @@ mod tests { #[test] fn transition_from_authenticated_transfer_program_invocation_insuficient_balance() { let key = PrivateKey::try_new([1; 32]).unwrap(); - let address = Address::from_public_key(&PublicKey::new_from_private_key(&key)); - let initial_data = [(*address.value(), 100)]; + let address = Address::from(&PublicKey::new_from_private_key(&key)); + let initial_data = [(address, 100)]; let mut state = V01State::new_with_genesis_accounts(&initial_data); let from = address; let from_key = key; @@ -233,9 +232,9 @@ mod tests { fn transition_from_authenticated_transfer_program_invocation_non_default_account_destination() { let key1 = PrivateKey::try_new([1; 32]).unwrap(); let key2 = PrivateKey::try_new([2; 32]).unwrap(); - let address1 = Address::from_public_key(&PublicKey::new_from_private_key(&key1)); - let address2 = Address::from_public_key(&PublicKey::new_from_private_key(&key2)); - let initial_data = [(*address1.value(), 100), (*address2.value(), 200)]; + let address1 = Address::from(&PublicKey::new_from_private_key(&key1)); + let address2 = Address::from(&PublicKey::new_from_private_key(&key2)); + let initial_data = [(address1, 100), (address2, 200)]; let mut state = V01State::new_with_genesis_accounts(&initial_data); let from = address2; let from_key = key2; @@ -255,10 +254,10 @@ mod tests { #[test] fn transition_from_chained_authenticated_transfer_program_invocations() { let key1 = PrivateKey::try_new([8; 32]).unwrap(); - let address1 = Address::from_public_key(&PublicKey::new_from_private_key(&key1)); + let address1 = Address::from(&PublicKey::new_from_private_key(&key1)); let key2 = PrivateKey::try_new([2; 32]).unwrap(); - let address2 = Address::from_public_key(&PublicKey::new_from_private_key(&key2)); - let initial_data = [(*address1.value(), 100)]; + let address2 = Address::from(&PublicKey::new_from_private_key(&key2)); + let initial_data = [(address1, 100)]; let mut state = V01State::new_with_genesis_accounts(&initial_data); let address3 = Address::new([3; 32]); let balance_to_move = 5; @@ -336,7 +335,7 @@ mod tests { #[test] fn test_program_should_fail_if_modifies_nonces() { - let initial_data = [([1; 32], 100)]; + let initial_data = [(Address::new([1; 32]), 100)]; let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); let addresses = vec![Address::new([1; 32])]; let program_id = Program::nonce_changer_program().id(); @@ -352,7 +351,7 @@ mod tests { #[test] fn test_program_should_fail_if_output_accounts_exceed_inputs() { - let initial_data = [([1; 32], 100)]; + let initial_data = [(Address::new([1; 32]), 100)]; let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); let addresses = vec![Address::new([1; 32])]; let program_id = Program::extra_output_program().id(); @@ -368,7 +367,7 @@ mod tests { #[test] fn test_program_should_fail_with_missing_output_accounts() { - let initial_data = [([1; 32], 100)]; + let initial_data = [(Address::new([1; 32]), 100)]; let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); let addresses = vec![Address::new([1; 32]), Address::new([2; 32])]; let program_id = Program::missing_output_program().id(); @@ -384,7 +383,7 @@ mod tests { #[test] fn test_program_should_fail_if_modifies_program_owner_with_only_non_default_program_owner() { - let initial_data = [([1; 32], 0)]; + let initial_data = [(Address::new([1; 32]), 0)]; let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); let address = Address::new([1; 32]); let account = state.get_account_by_address(&address); @@ -478,7 +477,7 @@ mod tests { #[test] fn test_program_should_fail_if_transfers_balance_from_non_owned_account() { - let initial_data = [([1; 32], 100)]; + let initial_data = [(Address::new([1; 32]), 100)]; let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); let sender_address = Address::new([1; 32]); let receiver_address = Address::new([2; 32]); diff --git a/nssa/test_program_methods/Cargo.toml b/nssa/test_program_methods/Cargo.toml index 7da210b..dded508 100644 --- a/nssa/test_program_methods/Cargo.toml +++ b/nssa/test_program_methods/Cargo.toml @@ -8,4 +8,3 @@ risc0-build = { version = "2.3.1" } [package.metadata.risc0] methods = ["guest"] - diff --git a/nssa/test_program_methods/guest/Cargo.toml b/nssa/test_program_methods/guest/Cargo.toml index 12bddbf..4b377c8 100644 --- a/nssa/test_program_methods/guest/Cargo.toml +++ b/nssa/test_program_methods/guest/Cargo.toml @@ -7,5 +7,4 @@ edition = "2021" [dependencies] risc0-zkvm = { version = "2.3.1", default-features = false, features = ['std'] } -nssa-core = {path = "../../core"} - +nssa-core = { path = "../../core" } diff --git a/sc_core/Cargo.toml b/sc_core/Cargo.toml index d83264b..8a615a0 100644 --- a/sc_core/Cargo.toml +++ b/sc_core/Cargo.toml @@ -33,6 +33,9 @@ path = "../utxo" [dependencies.common] path = "../common" +[dependencies.nssa] +path = "../nssa" + [dependencies.secp256k1-zkp] workspace = true features = ["std", "rand-std", "rand", "serde", "global-context"] diff --git a/sc_core/src/proofs_circuits.rs b/sc_core/src/proofs_circuits.rs index 08ce431..d6fbbc2 100644 --- a/sc_core/src/proofs_circuits.rs +++ b/sc_core/src/proofs_circuits.rs @@ -1,5 +1,6 @@ use bincode; use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; +use nssa::Address; use rand::{thread_rng, RngCore}; use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tag, Tweak, SECP256K1}; use sha2::{Digest, Sha256}; @@ -82,7 +83,7 @@ pub fn private_circuit( for in_utxo in input_utxos { let nullifier_public_key = public_context .account_masks - .get(&in_utxo.owner) + .get(&Address::new(in_utxo.owner)) .unwrap() .nullifier_public_key; @@ -125,7 +126,7 @@ pub fn deshielded_circuit( for in_utxo in input_utxos { let nullifier_public_key = public_context .account_masks - .get(&in_utxo.owner) + .get(&Address::new(in_utxo.owner)) .unwrap() .nullifier_public_key; diff --git a/sc_core/src/public_context.rs b/sc_core/src/public_context.rs index e225513..cb14bbc 100644 --- a/sc_core/src/public_context.rs +++ b/sc_core/src/public_context.rs @@ -1,7 +1,8 @@ use std::collections::BTreeMap; -use accounts::account_core::{address::AccountAddress, AccountPublicMask}; +use accounts::account_core::AccountPublicMask; use common::merkle_tree_public::{merkle_tree::UTXOCommitmentsMerkleTree, TreeHashType}; +use nssa::Address; use serde::{ser::SerializeStruct, Serialize}; pub const PUBLIC_SC_CONTEXT: &str = "PublicSCContext"; @@ -16,9 +17,9 @@ pub const NULLIFIERS_SET: &str = "nullifiers_set"; ///Strucutre, representing context, given to a smart contract on a call pub struct PublicSCContext { - pub caller_address: AccountAddress, + pub caller_address: Address, pub caller_balance: u64, - pub account_masks: BTreeMap, + pub account_masks: BTreeMap, pub comitment_store_root: TreeHashType, pub commitments_tree: UTXOCommitmentsMerkleTree, } @@ -28,7 +29,12 @@ impl Serialize for PublicSCContext { where S: serde::Serializer, { - let mut account_masks_keys: Vec<[u8; 32]> = self.account_masks.keys().cloned().collect(); + let mut account_masks_keys: Vec<[u8; 32]> = self + .account_masks + .keys() + .cloned() + .map(|addr| *addr.value()) + .collect(); account_masks_keys.sort(); let mut account_mask_values: Vec = @@ -94,7 +100,7 @@ mod tests { use super::*; fn create_test_context() -> PublicSCContext { - let caller_address = [1; 32]; + let caller_address = Address::new([1; 32]); let comitment_store_root = [3; 32]; let commitments_tree = diff --git a/sequencer_core/src/sequencer_store/mod.rs b/sequencer_core/src/sequencer_store/mod.rs index fd39473..3d9708d 100644 --- a/sequencer_core/src/sequencer_store/mod.rs +++ b/sequencer_core/src/sequencer_store/mod.rs @@ -1,9 +1,8 @@ use std::path::Path; -use accounts::account_core::address::AccountAddress; use block_store::SequecerBlockStore; use common::block::HashableBlockData; -use nssa; +use nssa::{self, Address}; use rand::{rngs::OsRng, RngCore}; use crate::config::AccountInitialData; @@ -22,7 +21,7 @@ impl SequecerChainStore { is_genesis_random: bool, initial_accounts: &[AccountInitialData], ) -> Self { - let init_accs: Vec<(AccountAddress, u128)> = initial_accounts + let init_accs: Vec<(Address, u128)> = initial_accounts .iter() .map(|acc_data| { ( diff --git a/wallet/src/chain_storage/accounts_store.rs b/wallet/src/chain_storage/accounts_store.rs index cd46a6f..4dad474 100644 --- a/wallet/src/chain_storage/accounts_store.rs +++ b/wallet/src/chain_storage/accounts_store.rs @@ -1,8 +1,9 @@ -use accounts::account_core::{address::AccountAddress, Account}; +use accounts::account_core::Account; +use nssa::Address; use std::collections::HashMap; pub struct WalletAccountsStore { - pub accounts: HashMap, + pub accounts: HashMap, } impl WalletAccountsStore { @@ -16,7 +17,7 @@ impl WalletAccountsStore { self.accounts.insert(account.address, account); } - pub fn unregister_account(&mut self, account_addr: AccountAddress) { + pub fn unregister_account(&mut self, account_addr: Address) { self.accounts.remove(&account_addr); } } @@ -82,7 +83,7 @@ mod tests { let mut store = WalletAccountsStore::new(); let account_addr: [u8; 32] = pad_to_32("nonexistent".to_string().as_bytes()); - store.unregister_account(account_addr); + store.unregister_account(Address::new(account_addr)); assert!(store.accounts.is_empty()); } diff --git a/wallet/src/chain_storage/mod.rs b/wallet/src/chain_storage/mod.rs index 4467162..c04483b 100644 --- a/wallet/src/chain_storage/mod.rs +++ b/wallet/src/chain_storage/mod.rs @@ -1,8 +1,9 @@ use std::collections::{BTreeMap, HashMap}; -use accounts::account_core::{address::AccountAddress, Account}; +use accounts::account_core::Account; use anyhow::Result; use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; +use nssa::Address; use sc_core::public_context::PublicSCContext; use serde::{Deserialize, Serialize}; @@ -37,7 +38,7 @@ impl From for HashMap<[u8; 32], Account> { } pub struct WalletChainStore { - pub acc_map: HashMap, + pub acc_map: HashMap, pub utxo_commitments_store: UTXOCommitmentsMerkleTree, pub wallet_config: WalletConfig, } @@ -54,7 +55,7 @@ impl WalletChainStore { }) } - pub fn produce_context(&self, caller: AccountAddress) -> PublicSCContext { + pub fn produce_context(&self, caller: Address) -> PublicSCContext { let mut account_masks = BTreeMap::new(); for (acc_addr, acc) in &self.acc_map { @@ -80,7 +81,7 @@ mod tests { fn create_initial_accounts() -> Vec { let initial_acc1 = serde_json::from_str(r#"{ - "address": [27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143], + "address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", "balance": 100, "key_holder": { "nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718", @@ -98,7 +99,7 @@ mod tests { }"#).unwrap(); let initial_acc2 = serde_json::from_str(r#"{ - "address": [77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217, 234, 216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102], + "address": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766", "balance": 200, "key_holder": { "nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271", diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index aefb331..e5a328b 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -1,6 +1,7 @@ use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr}; -use anyhow::{anyhow, Result}; +use anyhow::Result; +use nssa::{address::HexString, Address}; use crate::{config::WalletConfig, HOME_DIR_ENV_VAR}; @@ -19,8 +20,6 @@ pub fn fetch_config() -> Result { } //ToDo: Replace with structures conversion in future -pub fn produce_account_addr_from_hex(hex_str: String) -> Result<[u8; 32]> { - hex::decode(hex_str)? - .try_into() - .map_err(|_| anyhow!("Failed conversion to 32 bytes")) +pub fn produce_account_addr_from_hex(hex_str: String) -> Result
{ + Ok(HexString::try_from(hex_str.as_str())?.into()) } diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index f4add81..b2fb090 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -5,11 +5,12 @@ use common::{ ExecutionFailureKind, }; -use accounts::account_core::{address::AccountAddress, Account}; +use accounts::account_core::Account; use anyhow::Result; use chain_storage::WalletChainStore; use config::WalletConfig; use log::info; +use nssa::Address; use tokio::sync::RwLock; use clap::{Parser, Subcommand}; @@ -47,7 +48,7 @@ impl WalletCore { }) } - pub async fn create_new_account(&mut self) -> AccountAddress { + pub async fn create_new_account(&mut self) -> Address { let account = Account::new(); account.log(); @@ -64,9 +65,9 @@ impl WalletCore { pub async fn send_public_native_token_transfer( &self, - from: AccountAddress, + from: Address, nonce: u128, - to: AccountAddress, + to: Address, balance_to_move: u128, ) -> Result { { @@ -75,7 +76,7 @@ impl WalletCore { let account = read_guard.acc_map.get(&from); if let Some(account) = account { - let addresses = vec![nssa::Address::new(from), nssa::Address::new(to)]; + let addresses = vec![from, to]; let nonces = vec![nonce]; let program_id = nssa::program::Program::authenticated_transfer_program().id(); let message = nssa::public_transaction::Message::try_new( diff --git a/zkvm/Cargo.toml b/zkvm/Cargo.toml index b518109..dc3cdae 100644 --- a/zkvm/Cargo.toml +++ b/zkvm/Cargo.toml @@ -24,6 +24,9 @@ path = "../utxo" [dependencies.common] path = "../common" +[dependencies.nssa] +path = "../nssa" + [features] cuda = ["risc0-zkvm/cuda"] default = [] diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 191456f..5bab1a3 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -1,5 +1,5 @@ -use accounts::account_core::address::AccountAddress; use common::ExecutionFailureKind; +use nssa::Address; use rand::{rngs::OsRng, RngCore}; use risc0_zkvm::{default_executor, default_prover, sha::Digest, ExecutorEnv, Receipt}; use serde::Serialize; @@ -35,7 +35,7 @@ pub fn gas_limits_check( #[allow(clippy::result_large_err)] pub fn prove_mint_utxo( amount_to_mint: u128, - owner: AccountAddress, + owner: Address, ) -> Result<(UTXO, Receipt), ExecutionFailureKind> { let mut builder = ExecutorEnv::builder(); @@ -74,8 +74,8 @@ pub fn prove_mint_utxo( #[allow(clippy::result_large_err)] pub fn prove_send_utxo( spent_utxo: UTXO, - owners_parts: Vec<(u128, AccountAddress)>, -) -> Result<(Vec<(UTXO, AccountAddress)>, Receipt), ExecutionFailureKind> { + owners_parts: Vec<(u128, Address)>, +) -> Result<(Vec<(UTXO, Address)>, Receipt), ExecutionFailureKind> { let cumulative_spent = owners_parts.iter().fold(0, |acc, item| acc + item.0); if cumulative_spent != spent_utxo.amount { @@ -113,7 +113,7 @@ pub fn prove_send_utxo( .map_err(ExecutionFailureKind::prove_error)? .receipt; - let digest: Vec<(UTXOPayload, AccountAddress)> = receipt + let digest: Vec<(UTXOPayload, Address)> = receipt .journal .decode() .map_err(|e| ExecutionFailureKind::DecodeError(e.to_string()))?; @@ -131,7 +131,7 @@ pub fn prove_send_utxo( pub fn prove_send_utxo_multiple_assets_one_receiver( spent_utxos: Vec, number_to_send: usize, - receiver: AccountAddress, + receiver: Address, ) -> Result<(Vec, Vec, Receipt), ExecutionFailureKind> { if number_to_send > spent_utxos.len() { return Err(ExecutionFailureKind::AmountMismatchError); @@ -186,17 +186,17 @@ pub fn prove_send_utxo_multiple_assets_one_receiver( #[allow(clippy::result_large_err)] pub fn prove_send_utxo_shielded( - owner: AccountAddress, + owner: Address, amount: u128, - owners_parts: Vec<(u128, AccountAddress)>, -) -> Result<(Vec<(UTXO, AccountAddress)>, Receipt), ExecutionFailureKind> { + owners_parts: Vec<(u128, Address)>, +) -> Result<(Vec<(UTXO, Address)>, Receipt), ExecutionFailureKind> { let cumulative_spent = owners_parts.iter().fold(0, |acc, item| acc + item.0); if cumulative_spent != amount { return Err(ExecutionFailureKind::AmountMismatchError); } - let temp_utxo_to_spend = UTXO::new(owner, vec![], amount, true); + let temp_utxo_to_spend = UTXO::new(*owner.value(), vec![], amount, true); let utxo_payload = temp_utxo_to_spend.into_payload(); let mut builder = ExecutorEnv::builder(); @@ -229,7 +229,7 @@ pub fn prove_send_utxo_shielded( .map_err(ExecutionFailureKind::prove_error)? .receipt; - let digest: Vec<(UTXOPayload, AccountAddress)> = receipt + let digest: Vec<(UTXOPayload, Address)> = receipt .journal .decode() .map_err(|e| ExecutionFailureKind::DecodeError(e.to_string()))?; @@ -246,8 +246,8 @@ pub fn prove_send_utxo_shielded( #[allow(clippy::result_large_err)] pub fn prove_send_utxo_deshielded( spent_utxo: UTXO, - owners_parts: Vec<(u128, AccountAddress)>, -) -> Result<(Vec<(u128, AccountAddress)>, Receipt), ExecutionFailureKind> { + owners_parts: Vec<(u128, Address)>, +) -> Result<(Vec<(u128, Address)>, Receipt), ExecutionFailureKind> { let cumulative_spent = owners_parts.iter().fold(0, |acc, item| acc + item.0); if cumulative_spent != spent_utxo.amount { @@ -285,7 +285,7 @@ pub fn prove_send_utxo_deshielded( .map_err(ExecutionFailureKind::prove_error)? .receipt; - let digest: Vec<(UTXOPayload, AccountAddress)> = receipt + let digest: Vec<(UTXOPayload, Address)> = receipt .journal .decode() .map_err(|e| ExecutionFailureKind::DecodeError(e.to_string()))?; @@ -303,7 +303,7 @@ pub fn prove_send_utxo_deshielded( pub fn prove_mint_utxo_multiple_assets( amount_to_mint: u128, number_of_assets: usize, - owner: AccountAddress, + owner: Address, ) -> Result<(Vec, Receipt), ExecutionFailureKind> { let mut builder = ExecutorEnv::builder(); @@ -344,7 +344,7 @@ pub fn prove_mint_utxo_multiple_assets( pub fn execute_mint_utxo( amount_to_mint: u128, - owner: AccountAddress, + owner: Address, randomness: [u8; 32], ) -> anyhow::Result { let mut builder = ExecutorEnv::builder(); @@ -366,8 +366,8 @@ pub fn execute_mint_utxo( pub fn execute_send_utxo( spent_utxo: UTXO, - owners_parts: Vec<(u128, AccountAddress)>, -) -> anyhow::Result<(UTXO, Vec<(UTXO, AccountAddress)>)> { + owners_parts: Vec<(u128, Address)>, +) -> anyhow::Result<(UTXO, Vec<(UTXO, Address)>)> { let mut builder = ExecutorEnv::builder(); let utxo_payload = spent_utxo.into_payload(); @@ -390,7 +390,7 @@ pub fn execute_send_utxo( let receipt = executor.execute(env, test_methods::SEND_UTXO_ELF)?; - let digest: (UTXOPayload, Vec<(UTXOPayload, AccountAddress)>) = receipt.journal.decode()?; + let digest: (UTXOPayload, Vec<(UTXOPayload, Address)>) = receipt.journal.decode()?; Ok(( UTXO::create_utxo_from_payload(digest.0), @@ -572,29 +572,29 @@ mod tests { #[test] fn test_execute_mint_utxo() { - let owner = AccountAddress::default(); + let owner = Address::default(); let amount = 123456789; let mut randomness = [0u8; 32]; OsRng.fill_bytes(&mut randomness); let utxo_exec = execute_mint_utxo(amount, owner, randomness).expect("execution failed"); assert_eq!(utxo_exec.amount, amount); - assert_eq!(utxo_exec.owner, owner); + assert_eq!(utxo_exec.owner, *owner.value()); } #[test] fn test_prove_mint_utxo() { - let owner = AccountAddress::default(); + let owner = Address::default(); let amount = 123456789; let (utxo, _) = prove_mint_utxo(amount, owner).expect("proof failed"); assert_eq!(utxo.amount, amount); - assert_eq!(utxo.owner, owner); + assert_eq!(utxo.owner, *owner.value()); } #[test] fn test_prove_send_utxo() { - let owner = AccountAddress::default(); + let owner = Address::default(); let amount = 100; let (input_utxo, _) = prove_mint_utxo(amount, owner).expect("mint failed"); @@ -608,7 +608,7 @@ mod tests { #[test] fn test_prove_send_utxo_deshielded() { - let owner = AccountAddress::default(); + let owner = Address::default(); let amount = 100; let (utxo, _) = prove_mint_utxo(amount, owner).unwrap(); let parts = vec![(60, owner), (40, owner)]; @@ -622,7 +622,7 @@ mod tests { #[test] fn test_prove_send_utxo_shielded() { - let owner = AccountAddress::default(); + let owner = Address::default(); let amount = 100; let parts = vec![(60, owner), (40, owner)]; @@ -635,8 +635,8 @@ mod tests { #[test] fn test_prove_send_utxo_multiple_assets_one_receiver() { - let owner = AccountAddress::default(); - let receiver = AccountAddress::default(); + let owner = Address::default(); + let receiver = Address::default(); let utxos = vec![ prove_mint_utxo(100, owner).unwrap().0, From fed2d50a9ab6e43ab5cb089c0b06806e0dc5582f Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 13 Aug 2025 13:44:41 +0300 Subject: [PATCH 08/13] Revert "fix: AccountAddress wrapped into struct" This reverts commit 6bced517644b1ab3879aa35d5c4695edb5f3bcb2. --- accounts/src/account_core/address.rs | 53 ++------- accounts/src/account_core/mod.rs | 20 ++-- accounts/src/key_management/mod.rs | 10 +- sc_core/src/proofs_circuits.rs | 5 +- sc_core/src/public_context.rs | 9 +- sequencer_core/src/lib.rs | 41 +++---- .../src/sequencer_store/accounts_store.rs | 103 ++++++------------ sequencer_rpc/src/process.rs | 3 +- wallet/src/chain_storage/accounts_store.rs | 2 +- wallet/src/helperfunctions.rs | 4 +- wallet/src/lib.rs | 4 +- zkvm/src/lib.rs | 6 +- 12 files changed, 89 insertions(+), 171 deletions(-) diff --git a/accounts/src/account_core/address.rs b/accounts/src/account_core/address.rs index a25ba0d..2fadacd 100644 --- a/accounts/src/account_core/address.rs +++ b/accounts/src/account_core/address.rs @@ -1,44 +1,17 @@ -use common::transaction::{SignaturePublicKey, Tag}; -use serde::{Deserialize, Serialize}; +use common::transaction::SignaturePublicKey; use tiny_keccak::{Hasher, Keccak}; -#[derive( - Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, Default, -)] -pub struct AccountAddress(pub(crate) [u8; 32]); +// TODO: Consider wrapping `AccountAddress` in a struct. -impl AccountAddress { - pub fn new(value: [u8; 32]) -> Self { - Self(value) - } +pub type AccountAddress = [u8; 32]; - pub fn tag(&self) -> Tag { - self.0[0] - } - - pub fn raw_addr(&self) -> [u8; 32] { - self.0 - } -} - -impl TryFrom> for AccountAddress { - type Error = Vec; - - fn try_from(value: Vec) -> Result { - let addr_val: [u8; 32] = value.try_into()?; - - Ok(AccountAddress::new(addr_val)) - } -} - -impl From<&SignaturePublicKey> for AccountAddress { - fn from(value: &SignaturePublicKey) -> Self { - let mut address = [0; 32]; - let mut keccak_hasher = Keccak::v256(); - keccak_hasher.update(&value.to_sec1_bytes()); - keccak_hasher.finalize(&mut address); - AccountAddress::new(address) - } +/// Returns the address associated with a public key +pub fn from_public_key(public_key: &SignaturePublicKey) -> AccountAddress { + let mut address = [0; 32]; + let mut keccak_hasher = Keccak::v256(); + keccak_hasher.update(&public_key.to_sec1_bytes()); + keccak_hasher.finalize(&mut address); + address } #[cfg(test)] @@ -46,6 +19,7 @@ mod tests { use common::transaction::SignaturePrivateKey; use super::*; + use crate::account_core::address; #[test] fn test_address_key_equal_keccak_pub_sign_key() { @@ -57,9 +31,6 @@ mod tests { keccak_hasher.update(&public_key.to_sec1_bytes()); keccak_hasher.finalize(&mut expected_address); - assert_eq!( - AccountAddress::new(expected_address), - AccountAddress::from(public_key) - ); + assert_eq!(expected_address, address::from_public_key(public_key)); } } diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index de3f5aa..f586019 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -114,7 +114,7 @@ impl AccountPublicMask { } pub fn make_tag(&self) -> Tag { - self.address.tag() + self.address[0] } } @@ -122,7 +122,7 @@ impl Account { pub fn new() -> Self { let key_holder = AddressKeyHolder::new_os_random(); let public_key = *key_holder.get_pub_account_signing_key().verifying_key(); - let address = AccountAddress::from(&public_key); + let address = address::from_public_key(&public_key); let balance = 0; let nonce = 0; let utxos = HashMap::new(); @@ -139,7 +139,7 @@ impl Account { pub fn new_with_balance(balance: u64) -> Self { let key_holder = AddressKeyHolder::new_os_random(); let public_key = *key_holder.get_pub_account_signing_key().verifying_key(); - let address = AccountAddress::from(&public_key); + let address = address::from_public_key(&public_key); let nonce = 0; let utxos = HashMap::new(); @@ -191,7 +191,7 @@ impl Account { privacy_flag: bool, ) -> Result<()> { let asset_utxo = UTXO::new( - self.address.raw_addr(), + self.address, serde_json::to_vec(&asset)?, amount, privacy_flag, @@ -204,16 +204,12 @@ impl Account { pub fn log(&self) { info!("Keys generated"); - //use HexString - info!( - "Account address is {:?}", - hex::encode(self.address.raw_addr()) - ); + info!("Account address is {:?}", hex::encode(self.address)); info!("Account balance is {:?}", self.balance); } pub fn make_tag(&self) -> Tag { - self.address.tag() + self.address[0] } ///Produce account public mask @@ -251,8 +247,8 @@ mod tests { #[test] fn test_add_new_utxo_outputs() { let mut account = Account::new(); - let utxo1 = generate_dummy_utxo(account.address.raw_addr(), 100); - let utxo2 = generate_dummy_utxo(account.address.raw_addr(), 200); + let utxo1 = generate_dummy_utxo(account.address, 100); + let utxo2 = generate_dummy_utxo(account.address, 200); let result = account.add_new_utxo_outputs(vec![utxo1.clone(), utxo2.clone()]); diff --git a/accounts/src/key_management/mod.rs b/accounts/src/key_management/mod.rs index 8558c50..c1a78fb 100644 --- a/accounts/src/key_management/mod.rs +++ b/accounts/src/key_management/mod.rs @@ -120,10 +120,7 @@ mod tests { use elliptic_curve::point::AffineCoordinates; use k256::{AffinePoint, ProjectivePoint, Scalar}; - use crate::{ - account_core::address::AccountAddress, - key_management::ephemeral_key_holder::EphemeralKeyHolder, - }; + use crate::{account_core::address, key_management::ephemeral_key_holder::EphemeralKeyHolder}; use super::*; @@ -350,7 +347,7 @@ mod tests { let verifying_key = signing_key.verifying_key(); - let address = AccountAddress::from(verifying_key); + let address = address::from_public_key(verifying_key); println!("======Prerequisites======"); println!(); @@ -376,8 +373,7 @@ mod tests { println!("======Public data======"); println!(); - //Use HexString - println!("Address{:?}", hex::encode(address.raw_addr())); + println!("Address{:?}", hex::encode(address)); println!( "Nulifier public key {:?}", hex::encode(serde_json::to_vec(&nullifer_public_key).unwrap()) diff --git a/sc_core/src/proofs_circuits.rs b/sc_core/src/proofs_circuits.rs index 9e2f580..08ce431 100644 --- a/sc_core/src/proofs_circuits.rs +++ b/sc_core/src/proofs_circuits.rs @@ -1,4 +1,3 @@ -use accounts::account_core::address::AccountAddress; use bincode; use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; use rand::{thread_rng, RngCore}; @@ -83,7 +82,7 @@ pub fn private_circuit( for in_utxo in input_utxos { let nullifier_public_key = public_context .account_masks - .get(&AccountAddress::new(in_utxo.owner)) + .get(&in_utxo.owner) .unwrap() .nullifier_public_key; @@ -126,7 +125,7 @@ pub fn deshielded_circuit( for in_utxo in input_utxos { let nullifier_public_key = public_context .account_masks - .get(&AccountAddress::new(in_utxo.owner)) + .get(&in_utxo.owner) .unwrap() .nullifier_public_key; diff --git a/sc_core/src/public_context.rs b/sc_core/src/public_context.rs index aab9ede..e225513 100644 --- a/sc_core/src/public_context.rs +++ b/sc_core/src/public_context.rs @@ -28,12 +28,7 @@ impl Serialize for PublicSCContext { where S: serde::Serializer, { - let mut account_masks_keys: Vec<[u8; 32]> = self - .account_masks - .keys() - .cloned() - .map(|addr| addr.raw_addr()) - .collect(); + let mut account_masks_keys: Vec<[u8; 32]> = self.account_masks.keys().cloned().collect(); account_masks_keys.sort(); let mut account_mask_values: Vec = @@ -116,7 +111,7 @@ mod tests { account_masks.insert(acc_3.address, acc_3.make_account_public_mask()); PublicSCContext { - caller_address: AccountAddress::new(caller_address), + caller_address, caller_balance: 100, account_masks, comitment_store_root, diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index fd15b0e..810166d 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -1,6 +1,6 @@ use std::fmt::Display; -use accounts::account_core::address::AccountAddress; +use accounts::account_core::address::{self, AccountAddress}; use anyhow::Result; use common::{ block::HashableBlockData, @@ -135,10 +135,10 @@ impl SequencerCore { if let Ok(native_transfer_action) = serde_json::from_slice::(execution_input) { - let signer_address = AccountAddress::from(&tx.transaction().public_key); + let signer_address = address::from_public_key(&tx.transaction().public_key); //Correct sender check - if AccountAddress::new(native_transfer_action.from) != signer_address { + if native_transfer_action.from != signer_address { return Err(TransactionMalformationErrorKind::IncorrectSender); } } @@ -219,7 +219,8 @@ impl SequencerCore { serde_json::from_slice::(execution_input) { // Nonce check - let signer_addres = AccountAddress::from(&mempool_tx.auth_tx.transaction().public_key); + let signer_addres = + address::from_public_key(&mempool_tx.auth_tx.transaction().public_key); if self.store.acc_store.get_account_nonce(&signer_addres) != native_transfer_action.nonce { @@ -229,11 +230,11 @@ impl SequencerCore { let from_balance = self .store .acc_store - .get_account_balance(&AccountAddress::new(native_transfer_action.from)); + .get_account_balance(&native_transfer_action.from); let to_balance = self .store .acc_store - .get_account_balance(&AccountAddress::new(native_transfer_action.to)); + .get_account_balance(&native_transfer_action.to); //Balance check if from_balance < native_transfer_action.balance_to_move { @@ -241,11 +242,11 @@ impl SequencerCore { } self.store.acc_store.set_account_balance( - &AccountAddress::new(native_transfer_action.from), + &native_transfer_action.from, from_balance - native_transfer_action.balance_to_move, ); self.store.acc_store.set_account_balance( - &AccountAddress::new(native_transfer_action.to), + &native_transfer_action.to, to_balance + native_transfer_action.balance_to_move, ); @@ -619,25 +620,19 @@ mod tests { common_setup(&mut sequencer); - let acc1: AccountAddress = - hex::decode(sequencer.sequencer_config.initial_accounts[0].addr.clone()) - .unwrap() - .try_into() - .unwrap(); - let acc2: AccountAddress = - hex::decode(sequencer.sequencer_config.initial_accounts[1].addr.clone()) - .unwrap() - .try_into() - .unwrap(); + let acc1 = hex::decode(sequencer.sequencer_config.initial_accounts[0].addr.clone()) + .unwrap() + .try_into() + .unwrap(); + let acc2 = hex::decode(sequencer.sequencer_config.initial_accounts[1].addr.clone()) + .unwrap() + .try_into() + .unwrap(); let sign_key1 = create_signing_key_for_account1(); let tx = common::test_utils::create_dummy_transaction_native_token_transfer( - acc1.raw_addr(), - 0, - acc2.raw_addr(), - 100, - sign_key1, + acc1, 0, acc2, 100, sign_key1, ); sequencer diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index b7012cf..4f02220 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -155,38 +155,30 @@ mod tests { #[test] fn test_zero_balance_account_data_creation() { - let address = AccountAddress::new([1; 32]); - - let new_acc = AccountPublicData::new(address); + let new_acc = AccountPublicData::new([1; 32]); assert_eq!(new_acc.balance, 0); - assert_eq!(new_acc.address, address); + assert_eq!(new_acc.address, [1; 32]); } #[test] fn test_zero_nonce_account_data_creation() { - let address = AccountAddress::new([1; 32]); - - let new_acc = AccountPublicData::new(address); + let new_acc = AccountPublicData::new([1; 32]); assert_eq!(new_acc.nonce, 0); } #[test] fn test_non_zero_balance_account_data_creation() { - let address = AccountAddress::new([1; 32]); - - let new_acc = AccountPublicData::new_with_balance(address, 10); + let new_acc = AccountPublicData::new_with_balance([1; 32], 10); assert_eq!(new_acc.balance, 10); - assert_eq!(new_acc.address, address); + assert_eq!(new_acc.address, [1; 32]); } #[test] fn test_zero_nonce_account_data_creation_with_balance() { - let address = AccountAddress::new([1; 32]); - - let new_acc = AccountPublicData::new_with_balance(address, 10); + let new_acc = AccountPublicData::new_with_balance([1; 32], 10); assert_eq!(new_acc.nonce, 0); } @@ -200,117 +192,94 @@ mod tests { #[test] fn account_sequencer_store_register_acc() { - let address = AccountAddress::new([1; 32]); - let mut seq_acc_store = SequencerAccountsStore::default(); - seq_acc_store.register_account(address); + seq_acc_store.register_account([1; 32]); - assert!(seq_acc_store.contains_account(&address)); + assert!(seq_acc_store.contains_account(&[1; 32])); - let acc_balance = seq_acc_store.get_account_balance(&address); + let acc_balance = seq_acc_store.get_account_balance(&[1; 32]); assert_eq!(acc_balance, 0); } #[test] fn account_sequencer_store_unregister_acc_not_present() { - let address1 = AccountAddress::new([1; 32]); - let address2 = AccountAddress::new([2; 32]); - let mut seq_acc_store = SequencerAccountsStore::default(); - seq_acc_store.register_account(address1); + seq_acc_store.register_account([1; 32]); - let rem_res = seq_acc_store.unregister_account(address2).unwrap(); + let rem_res = seq_acc_store.unregister_account([2; 32]).unwrap(); assert!(rem_res.is_none()); } #[test] fn account_sequencer_store_unregister_acc_not_zero_balance() { - let address1 = AccountAddress::new([1; 32]); - let address2 = AccountAddress::new([2; 32]); + let mut seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); - let mut seq_acc_store = SequencerAccountsStore::new(&[(address1, 12), (address2, 100)]); - - let rem_res = seq_acc_store.unregister_account(address1); + let rem_res = seq_acc_store.unregister_account([1; 32]); assert!(rem_res.is_err()); } #[test] fn account_sequencer_store_unregister_acc() { - let address = AccountAddress::new([1; 32]); - let mut seq_acc_store = SequencerAccountsStore::default(); - seq_acc_store.register_account(address); + seq_acc_store.register_account([1; 32]); - assert!(seq_acc_store.contains_account(&address)); + assert!(seq_acc_store.contains_account(&[1; 32])); - seq_acc_store.unregister_account(address).unwrap().unwrap(); + seq_acc_store.unregister_account([1; 32]).unwrap().unwrap(); - assert!(!seq_acc_store.contains_account(&address)); + assert!(!seq_acc_store.contains_account(&[1; 32])); } #[test] fn account_sequencer_store_with_preset_accounts_1() { - let address1 = AccountAddress::new([1; 32]); - let address2 = AccountAddress::new([2; 32]); + let seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); - let seq_acc_store = SequencerAccountsStore::new(&[(address1, 12), (address2, 100)]); + assert!(seq_acc_store.contains_account(&[1; 32])); + assert!(seq_acc_store.contains_account(&[2; 32])); - assert!(seq_acc_store.contains_account(&address1)); - assert!(seq_acc_store.contains_account(&address2)); - - let acc_balance = seq_acc_store.get_account_balance(&address1); + let acc_balance = seq_acc_store.get_account_balance(&[1; 32]); assert_eq!(acc_balance, 12); - let acc_balance = seq_acc_store.get_account_balance(&address2); + let acc_balance = seq_acc_store.get_account_balance(&[2; 32]); assert_eq!(acc_balance, 100); } #[test] fn account_sequencer_store_with_preset_accounts_2() { - let address1 = AccountAddress::new([6; 32]); - let address2 = AccountAddress::new([7; 32]); - let address3 = AccountAddress::new([8; 32]); - let seq_acc_store = - SequencerAccountsStore::new(&[(address1, 120), (address2, 15), (address3, 10)]); + SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); - assert!(seq_acc_store.contains_account(&address1)); - assert!(seq_acc_store.contains_account(&address2)); - assert!(seq_acc_store.contains_account(&address3)); + assert!(seq_acc_store.contains_account(&[6; 32])); + assert!(seq_acc_store.contains_account(&[7; 32])); + assert!(seq_acc_store.contains_account(&[8; 32])); - let acc_balance = seq_acc_store.get_account_balance(&address1); + let acc_balance = seq_acc_store.get_account_balance(&[6; 32]); assert_eq!(acc_balance, 120); - let acc_balance = seq_acc_store.get_account_balance(&address2); + let acc_balance = seq_acc_store.get_account_balance(&[7; 32]); assert_eq!(acc_balance, 15); - let acc_balance = seq_acc_store.get_account_balance(&address3); + let acc_balance = seq_acc_store.get_account_balance(&[8; 32]); assert_eq!(acc_balance, 10); } #[test] fn account_sequencer_store_fetch_unknown_account() { - let address1 = AccountAddress::new([6; 32]); - let address2 = AccountAddress::new([7; 32]); - let address3 = AccountAddress::new([8; 32]); - - let address4 = AccountAddress::new([9; 32]); - let seq_acc_store = - SequencerAccountsStore::new(&[(address1, 120), (address2, 15), (address3, 10)]); + SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); - let acc_balance = seq_acc_store.get_account_balance(&address4); + let acc_balance = seq_acc_store.get_account_balance(&[9; 32]); assert_eq!(acc_balance, 0); } @@ -324,21 +293,19 @@ mod tests { #[test] fn account_sequencer_store_set_balance_to_unknown_account() { - let address = AccountAddress::new([1; 32]); - let mut seq_acc_store = SequencerAccountsStore::default(); - let ret = seq_acc_store.set_account_balance(&address, 100); + let ret = seq_acc_store.set_account_balance(&[1; 32], 100); assert_eq!(ret, 0); - assert!(seq_acc_store.contains_account(&address)); - assert_eq!(seq_acc_store.get_account_balance(&address), 100); + assert!(seq_acc_store.contains_account(&[1; 32])); + assert_eq!(seq_acc_store.get_account_balance(&[1; 32]), 100); } #[test] fn test_increase_nonce() { let mut account_store = SequencerAccountsStore::default(); - let address = AccountAddress::new([1; 32]); + let address = [1; 32]; let first_nonce = account_store.increase_nonce(&address); assert_eq!(first_nonce, 0); let second_nonce = account_store.increase_nonce(&address); diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index c2b59bf..eadfe55 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -1,4 +1,3 @@ -use accounts::account_core::address::AccountAddress; use actix_web::Error as HttpError; use sequencer_core::config::AccountInitialData; use serde_json::Value; @@ -73,7 +72,7 @@ impl JsonHandler { { let mut acc_store = self.sequencer_state.lock().await; - acc_store.register_account(AccountAddress::new(acc_req.address)); + acc_store.register_account(acc_req.address); } let helperstruct = RegisterAccountResponse { diff --git a/wallet/src/chain_storage/accounts_store.rs b/wallet/src/chain_storage/accounts_store.rs index 36d657a..cd46a6f 100644 --- a/wallet/src/chain_storage/accounts_store.rs +++ b/wallet/src/chain_storage/accounts_store.rs @@ -82,7 +82,7 @@ mod tests { let mut store = WalletAccountsStore::new(); let account_addr: [u8; 32] = pad_to_32("nonexistent".to_string().as_bytes()); - store.unregister_account(AccountAddress::new(account_addr)); + store.unregister_account(account_addr); assert!(store.accounts.is_empty()); } diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index e36215d..a66b1e0 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -1,6 +1,6 @@ use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr}; -use accounts::account_core::{address::AccountAddress, Account}; +use accounts::account_core::Account; use anyhow::{anyhow, Result}; use crate::{config::WalletConfig, HOME_DIR_ENV_VAR}; @@ -20,7 +20,7 @@ pub fn fetch_config() -> Result { } //ToDo: Replace with structures conversion in future -pub fn produce_account_addr_from_hex(hex_str: String) -> Result { +pub fn produce_account_addr_from_hex(hex_str: String) -> Result<[u8; 32]> { hex::decode(hex_str)? .try_into() .map_err(|_| anyhow!("Failed conversion to 32 bytes")) diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index b8d23d4..9c17751 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -86,9 +86,9 @@ impl WalletCore { let tx: TransactionBody = sc_core::transaction_payloads_tools::create_public_transaction_payload( serde_json::to_vec(&PublicNativeTokenSend { - from: from.raw_addr(), + from, nonce, - to: to.raw_addr(), + to, balance_to_move, }) .unwrap(), diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 3048370..0fbae70 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -187,7 +187,7 @@ pub fn prove_send_utxo_shielded( return Err(ExecutionFailureKind::AmountMismatchError); } - let temp_utxo_to_spend = UTXO::new(owner.raw_addr(), vec![], amount, true); + let temp_utxo_to_spend = UTXO::new(owner, vec![], amount, true); let utxo_payload = temp_utxo_to_spend.into_payload(); let mut builder = ExecutorEnv::builder(); @@ -561,7 +561,7 @@ mod tests { let utxo_exec = execute_mint_utxo(amount, owner, randomness).expect("execution failed"); assert_eq!(utxo_exec.amount, amount); - assert_eq!(utxo_exec.owner, owner.raw_addr()); + assert_eq!(utxo_exec.owner, owner); } #[test] @@ -571,7 +571,7 @@ mod tests { let (utxo, _) = prove_mint_utxo(amount, owner).expect("proof failed"); assert_eq!(utxo.amount, amount); - assert_eq!(utxo.owner, owner.raw_addr()); + assert_eq!(utxo.owner, owner); } #[test] From a9d81b19ed7021ad0477966254b6020a94b04a20 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 13 Aug 2025 14:15:05 +0300 Subject: [PATCH 09/13] fix: lints and merge fixes --- accounts/src/account_core/mod.rs | 7 ---- nssa/Cargo.toml | 1 - nssa/src/address.rs | 6 +-- nssa/src/public_transaction/transaction.rs | 2 +- nssa/src/state.rs | 10 ++--- wallet/src/helperfunctions.rs | 1 + wallet/src/lib.rs | 48 ++++++++++------------ 7 files changed, 31 insertions(+), 44 deletions(-) diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index 9013582..da6aa27 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -21,7 +21,6 @@ pub struct Account { pub key_holder: AddressKeyHolder, pub address: Address, pub balance: u64, - pub nonce: u64, pub utxos: HashMap, } @@ -30,7 +29,6 @@ pub struct AccountForSerialization { pub key_holder: AddressKeyHolder, pub address: Address, pub balance: u64, - pub nonce: u64, pub utxos: HashMap, } @@ -40,7 +38,6 @@ impl From for AccountForSerialization { key_holder: value.key_holder, address: value.address, balance: value.balance, - nonce: value.nonce, utxos: value .utxos .into_iter() @@ -56,7 +53,6 @@ impl From for Account { key_holder: value.key_holder, address: value.address, balance: value.balance, - nonce: value.nonce, utxos: value .utxos .into_iter() @@ -121,14 +117,12 @@ impl Account { nssa::PublicKey::new_from_private_key(key_holder.get_pub_account_signing_key()); let address = nssa::Address::from(&public_key); let balance = 0; - let nonce = 0; let utxos = HashMap::new(); Self { key_holder, address, balance, - nonce, utxos, } } @@ -144,7 +138,6 @@ impl Account { key_holder, address, balance, - nonce, utxos, } } diff --git a/nssa/Cargo.toml b/nssa/Cargo.toml index 540dd62..7653fd7 100644 --- a/nssa/Cargo.toml +++ b/nssa/Cargo.toml @@ -18,4 +18,3 @@ serde_json.workspace = true [dev-dependencies] test-program-methods = { path = "test_program_methods" } - diff --git a/nssa/src/address.rs b/nssa/src/address.rs index 6604fdd..8f6d7ec 100644 --- a/nssa/src/address.rs +++ b/nssa/src/address.rs @@ -118,7 +118,7 @@ impl<'de> Deserialize<'de> for HexString { let str_cand = deserializer.deserialize_string(HexStringVisitor)?; let hex_string = - HexString::try_from(str_cand.as_str()).map_err(|err| serde::de::Error::custom(err))?; + HexString::try_from(str_cand.as_str()).map_err(serde::de::Error::custom)?; Ok(hex_string) } @@ -224,9 +224,7 @@ mod tests { let addr_for_tests = Address::new([42; 32]); - let ser2_str = Ser3 { - f1: addr_for_tests, - }; + let ser2_str = Ser3 { f1: addr_for_tests }; let ser1_str: Ser3 = serde_json::from_str(raw_json).unwrap(); diff --git a/nssa/src/public_transaction/transaction.rs b/nssa/src/public_transaction/transaction.rs index 9b56575..d160004 100644 --- a/nssa/src/public_transaction/transaction.rs +++ b/nssa/src/public_transaction/transaction.rs @@ -224,7 +224,7 @@ pub mod tests { let instruction = 1337; let message = Message::try_new( Program::authenticated_transfer_program().id(), - vec![addr1.clone(), addr1], + vec![addr1, addr1], nonces, instruction, ) diff --git a/nssa/src/state.rs b/nssa/src/state.rs index ab5d7a1..fc24355 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -197,7 +197,7 @@ mod tests { assert_eq!(state.get_account_by_address(&to), Account::default()); let balance_to_move = 5; - let tx = transfer_transaction(from.clone(), key, 0, to.clone(), balance_to_move); + let tx = transfer_transaction(from, key, 0, to, balance_to_move); state.transition_from_public_transaction(&tx).unwrap(); assert_eq!(state.get_account_by_address(&from).balance, 95); @@ -218,7 +218,7 @@ mod tests { let balance_to_move = 101; assert!(state.get_account_by_address(&from).balance < balance_to_move); - let tx = transfer_transaction(from.clone(), from_key, 0, to.clone(), balance_to_move); + let tx = transfer_transaction(from, from_key, 0, to, balance_to_move); let result = state.transition_from_public_transaction(&tx); assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_)))); @@ -242,7 +242,7 @@ mod tests { assert_ne!(state.get_account_by_address(&to), Account::default()); let balance_to_move = 8; - let tx = transfer_transaction(from.clone(), from_key, 0, to.clone(), balance_to_move); + let tx = transfer_transaction(from, from_key, 0, to, balance_to_move); state.transition_from_public_transaction(&tx).unwrap(); assert_eq!(state.get_account_by_address(&from).balance, 192); @@ -262,10 +262,10 @@ mod tests { let address3 = Address::new([3; 32]); let balance_to_move = 5; - let tx = transfer_transaction(address1.clone(), key1, 0, address2.clone(), balance_to_move); + let tx = transfer_transaction(address1, key1, 0, address2, balance_to_move); state.transition_from_public_transaction(&tx).unwrap(); let balance_to_move = 3; - let tx = transfer_transaction(address2.clone(), key2, 0, address3.clone(), balance_to_move); + let tx = transfer_transaction(address2, key2, 0, address3, balance_to_move); state.transition_from_public_transaction(&tx).unwrap(); assert_eq!(state.get_account_by_address(&address1).balance, 95); diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index da885aa..bfe9a95 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -1,5 +1,6 @@ use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr}; +use accounts::account_core::Account; use anyhow::Result; use nssa::{address::HexString, Address}; diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index f9b8c86..f697d5d 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -11,7 +11,6 @@ use chain_storage::WalletChainStore; use config::WalletConfig; use log::info; use nssa::Address; -use tokio::sync::RwLock; use clap::{Parser, Subcommand}; @@ -43,6 +42,9 @@ impl WalletCore { //Persistent accounts take precedence for initial accounts let persistent_accounts = fetch_persistent_accounts()?; + + info!("Fetched persistent accoounts {persistent_accounts:#?}"); + for acc in persistent_accounts { storage.acc_map.insert(acc.address, acc); } @@ -72,34 +74,29 @@ impl WalletCore { to: Address, balance_to_move: u128, ) -> Result { - { - let read_guard = self.storage.read().await; + let account = self.storage.acc_map.get(&from); if let Some(account) = account { - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); + let addresses = vec![from, to]; + let nonces = vec![nonce]; + let program_id = nssa::program::Program::authenticated_transfer_program().id(); + let message = nssa::public_transaction::Message::try_new( + program_id, + addresses, + nonces, + balance_to_move, + ) + .unwrap(); - if let Some(account) = account { - let addresses = vec![from, to]; - let nonces = vec![nonce]; - let program_id = nssa::program::Program::authenticated_transfer_program().id(); - let message = nssa::public_transaction::Message::try_new( - program_id, - addresses, - nonces, - balance_to_move, - ) - .unwrap(); + let signing_key = account.key_holder.get_pub_account_signing_key(); + let witness_set = + nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); - let signing_key = account.key_holder.get_pub_account_signing_key(); - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); + let tx = nssa::PublicTransaction::new(message, witness_set); - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self.sequencer_client.send_tx(tx).await?) - } else { - Err(ExecutionFailureKind::AmountMismatchError) - } + Ok(self.sequencer_client.send_tx(tx).await?) + } else { + Err(ExecutionFailureKind::AmountMismatchError) } } @@ -180,7 +177,7 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { let from = produce_account_addr_from_hex(from)?; let to = produce_account_addr_from_hex(to)?; - let mut wallet_core = WalletCore::start_from_config_update_chain(wallet_config).await?; + let wallet_core = WalletCore::start_from_config_update_chain(wallet_config).await?; let res = wallet_core .send_public_native_token_transfer(from, nonce, to, amount) @@ -189,7 +186,6 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { info!("Results of tx send is {res:#?}"); //ToDo: Insert transaction polling logic here - wallet_core.increment_nonces(&[from, to]); let acc_storage_path = wallet_core.store_present_accounts_at_home()?; From d7acffd8da62f61ea0d3fe1d5b250d93db7ea08f Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 13 Aug 2025 15:11:24 +0300 Subject: [PATCH 10/13] fix: test fix 1 --- zkvm/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 5bab1a3..4e8c150 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -350,7 +350,7 @@ pub fn execute_mint_utxo( let mut builder = ExecutorEnv::builder(); builder.write(&amount_to_mint)?; - builder.write(&owner)?; + builder.write(owner.value())?; builder.write(&randomness)?; let env = builder.build()?; @@ -378,7 +378,7 @@ pub fn execute_send_utxo( .map(|(amount, addr)| { let mut randomness = Randomness::default(); OsRng.fill_bytes(&mut randomness); - (amount, addr, randomness) + (amount, *addr.value(), randomness) }) .collect::>(); From e589ddae5a27ba812bf57cd37bc4f052a9513a72 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 13 Aug 2025 16:17:52 +0300 Subject: [PATCH 11/13] fix: test fix 2 --- Cargo.toml | 1 - {zkvm => nssa}/src/gas_calculator.rs | 0 nssa/src/lib.rs | 1 + wallet/Cargo.toml | 3 - wallet/src/config.rs | 4 +- wallet/src/lib.rs | 3 - zkvm/Cargo.toml | 33 - zkvm/src/lib.rs | 653 -------- zkvm/test_methods/Cargo.toml | 10 - zkvm/test_methods/build.rs | 3 - zkvm/test_methods/guest/Cargo.lock | 1348 ----------------- zkvm/test_methods/guest/Cargo.toml | 14 - .../guest/src/bin/big_calculation.rs | 14 - zkvm/test_methods/guest/src/bin/mint_utxo.rs | 32 - .../src/bin/mint_utxo_multiple_assets.rs | 39 - .../guest/src/bin/multiplication.rs | 9 - zkvm/test_methods/guest/src/bin/send_utxo.rs | 34 - .../src/bin/send_utxo_multiple_assets.rs | 41 - zkvm/test_methods/guest/src/bin/summation.rs | 9 - zkvm/test_methods/src/lib.rs | 1 - 20 files changed, 3 insertions(+), 2249 deletions(-) rename {zkvm => nssa}/src/gas_calculator.rs (100%) delete mode 100644 zkvm/Cargo.toml delete mode 100644 zkvm/src/lib.rs delete mode 100644 zkvm/test_methods/Cargo.toml delete mode 100644 zkvm/test_methods/build.rs delete mode 100644 zkvm/test_methods/guest/Cargo.lock delete mode 100644 zkvm/test_methods/guest/Cargo.toml delete mode 100644 zkvm/test_methods/guest/src/bin/big_calculation.rs delete mode 100644 zkvm/test_methods/guest/src/bin/mint_utxo.rs delete mode 100644 zkvm/test_methods/guest/src/bin/mint_utxo_multiple_assets.rs delete mode 100644 zkvm/test_methods/guest/src/bin/multiplication.rs delete mode 100644 zkvm/test_methods/guest/src/bin/send_utxo.rs delete mode 100644 zkvm/test_methods/guest/src/bin/send_utxo_multiple_assets.rs delete mode 100644 zkvm/test_methods/guest/src/bin/summation.rs delete mode 100644 zkvm/test_methods/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 4764b7c..147f98e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ members = [ "utxo", "sequencer_rpc", "mempool", - "zkvm", "wallet", "sequencer_core", "common", diff --git a/zkvm/src/gas_calculator.rs b/nssa/src/gas_calculator.rs similarity index 100% rename from zkvm/src/gas_calculator.rs rename to nssa/src/gas_calculator.rs diff --git a/nssa/src/lib.rs b/nssa/src/lib.rs index 9555b14..e24ea89 100644 --- a/nssa/src/lib.rs +++ b/nssa/src/lib.rs @@ -1,5 +1,6 @@ pub mod address; pub mod error; +pub mod gas_calculator; pub mod program; pub mod public_transaction; mod signature; diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index 2d7b770..a84229a 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -32,9 +32,6 @@ path = "../accounts" [dependencies.utxo] path = "../utxo" -[dependencies.zkvm] -path = "../zkvm" - [dependencies.nssa] path = "../nssa" diff --git a/wallet/src/config.rs b/wallet/src/config.rs index d2c3a78..127bbf6 100644 --- a/wallet/src/config.rs +++ b/wallet/src/config.rs @@ -1,8 +1,8 @@ use std::path::PathBuf; use accounts::account_core::Account; +use nssa::gas_calculator::GasCalculator; use serde::{Deserialize, Serialize}; -use zkvm::gas_calculator::GasCalculator; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GasConfig { @@ -22,7 +22,7 @@ pub struct GasConfig { pub gas_limit_runtime: u64, } -impl From for zkvm::gas_calculator::GasCalculator { +impl From for GasCalculator { fn from(value: GasConfig) -> Self { GasCalculator::new( value.gas_fee_per_byte_deploy, diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index f697d5d..dc9c31e 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -42,9 +42,6 @@ impl WalletCore { //Persistent accounts take precedence for initial accounts let persistent_accounts = fetch_persistent_accounts()?; - - info!("Fetched persistent accoounts {persistent_accounts:#?}"); - for acc in persistent_accounts { storage.acc_map.insert(acc.address, acc); } diff --git a/zkvm/Cargo.toml b/zkvm/Cargo.toml deleted file mode 100644 index dc3cdae..0000000 --- a/zkvm/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "zkvm" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true -thiserror.workspace = true -rand.workspace = true - -risc0-zkvm = "2.3.1" -test-methods = { path = "test_methods" } - -[dependencies.accounts] -path = "../accounts" - -[dependencies.utxo] -path = "../utxo" - -[dependencies.common] -path = "../common" - -[dependencies.nssa] -path = "../nssa" - -[features] -cuda = ["risc0-zkvm/cuda"] -default = [] -prove = ["risc0-zkvm/prove"] diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs deleted file mode 100644 index 4e8c150..0000000 --- a/zkvm/src/lib.rs +++ /dev/null @@ -1,653 +0,0 @@ -use common::ExecutionFailureKind; -use nssa::Address; -use rand::{rngs::OsRng, RngCore}; -use risc0_zkvm::{default_executor, default_prover, sha::Digest, ExecutorEnv, Receipt}; -use serde::Serialize; -use utxo::utxo_core::{Randomness, UTXOPayload, UTXO}; - -pub mod gas_calculator; - -pub use test_methods; - -#[allow(clippy::result_large_err)] -pub fn gas_limits_check( - input_buffer: INP, - elf: &[u8], - gas_calculator: &gas_calculator::GasCalculator, - attached_funds: u64, -) -> Result<(), ExecutionFailureKind> { - let mut input_buffer_len: usize = 0; - input_buffer_len += serde_json::to_vec(&input_buffer).unwrap().len(); - - let gas_limit = gas_calculator - .gas_runtime_full(elf, input_buffer_len) - .ok_or(ExecutionFailureKind::InsufficientGasError)?; - - let cost = gas_calculator.runtime_cost(gas_limit); - - if cost > attached_funds { - return Err(ExecutionFailureKind::InsufficientFundsError); - } - - Ok(()) -} - -#[allow(clippy::result_large_err)] -pub fn prove_mint_utxo( - amount_to_mint: u128, - owner: Address, -) -> Result<(UTXO, Receipt), ExecutionFailureKind> { - let mut builder = ExecutorEnv::builder(); - - builder - .write(&amount_to_mint) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&owner) - .map_err(ExecutionFailureKind::write_error)?; - - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - builder - .write(&randomness) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::MINT_UTXO_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: UTXOPayload = receipt - .journal - .decode() - .map_err(|e| ExecutionFailureKind::DecodeError(e.to_string()))?; - - Ok((UTXO::create_utxo_from_payload(digest), receipt)) -} - -#[allow(clippy::result_large_err)] -pub fn prove_send_utxo( - spent_utxo: UTXO, - owners_parts: Vec<(u128, Address)>, -) -> Result<(Vec<(UTXO, Address)>, Receipt), ExecutionFailureKind> { - let cumulative_spent = owners_parts.iter().fold(0, |acc, item| acc + item.0); - - if cumulative_spent != spent_utxo.amount { - return Err(ExecutionFailureKind::AmountMismatchError); - } - - let mut builder = ExecutorEnv::builder(); - let utxo_payload = spent_utxo.into_payload(); - - builder - .write(&utxo_payload) - .map_err(ExecutionFailureKind::write_error)?; - - let owners_parts_with_randomness = owners_parts - .into_iter() - .map(|(amount, addr)| { - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - (amount, addr, randomness) - }) - .collect::>(); - - builder - .write(&owners_parts_with_randomness) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::SEND_UTXO_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: Vec<(UTXOPayload, Address)> = receipt - .journal - .decode() - .map_err(|e| ExecutionFailureKind::DecodeError(e.to_string()))?; - - Ok(( - digest - .into_iter() - .map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr)) - .collect(), - receipt, - )) -} - -#[allow(clippy::result_large_err)] -pub fn prove_send_utxo_multiple_assets_one_receiver( - spent_utxos: Vec, - number_to_send: usize, - receiver: Address, -) -> Result<(Vec, Vec, Receipt), ExecutionFailureKind> { - if number_to_send > spent_utxos.len() { - return Err(ExecutionFailureKind::AmountMismatchError); - } - - let mut builder = ExecutorEnv::builder(); - let utxo_payload: Vec = spent_utxos - .into_iter() - .map(|spent_utxo| spent_utxo.into_payload()) - .collect(); - - builder - .write(&utxo_payload) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&number_to_send) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&receiver) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::SEND_UTXO_MULTIPLE_ASSETS_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: (Vec, Vec) = receipt - .journal - .decode() - .map_err(|e| ExecutionFailureKind::DecodeError(e.to_string()))?; - - Ok(( - digest - .0 - .into_iter() - .map(UTXO::create_utxo_from_payload) - .collect(), - digest - .1 - .into_iter() - .map(UTXO::create_utxo_from_payload) - .collect(), - receipt, - )) -} - -#[allow(clippy::result_large_err)] -pub fn prove_send_utxo_shielded( - owner: Address, - amount: u128, - owners_parts: Vec<(u128, Address)>, -) -> Result<(Vec<(UTXO, Address)>, Receipt), ExecutionFailureKind> { - let cumulative_spent = owners_parts.iter().fold(0, |acc, item| acc + item.0); - - if cumulative_spent != amount { - return Err(ExecutionFailureKind::AmountMismatchError); - } - - let temp_utxo_to_spend = UTXO::new(*owner.value(), vec![], amount, true); - let utxo_payload = temp_utxo_to_spend.into_payload(); - - let mut builder = ExecutorEnv::builder(); - - builder - .write(&utxo_payload) - .map_err(ExecutionFailureKind::write_error)?; - - let owners_parts_with_randomness = owners_parts - .into_iter() - .map(|(amount, addr)| { - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - (amount, addr, randomness) - }) - .collect::>(); - - builder - .write(&owners_parts_with_randomness) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::SEND_UTXO_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: Vec<(UTXOPayload, Address)> = receipt - .journal - .decode() - .map_err(|e| ExecutionFailureKind::DecodeError(e.to_string()))?; - - Ok(( - digest - .into_iter() - .map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr)) - .collect(), - receipt, - )) -} - -#[allow(clippy::result_large_err)] -pub fn prove_send_utxo_deshielded( - spent_utxo: UTXO, - owners_parts: Vec<(u128, Address)>, -) -> Result<(Vec<(u128, Address)>, Receipt), ExecutionFailureKind> { - let cumulative_spent = owners_parts.iter().fold(0, |acc, item| acc + item.0); - - if cumulative_spent != spent_utxo.amount { - return Err(ExecutionFailureKind::AmountMismatchError); - } - - let mut builder = ExecutorEnv::builder(); - let utxo_payload = spent_utxo.into_payload(); - - builder - .write(&utxo_payload) - .map_err(ExecutionFailureKind::write_error)?; - - let owners_parts_with_randomness = owners_parts - .into_iter() - .map(|(amount, addr)| { - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - (amount, addr, randomness) - }) - .collect::>(); - - builder - .write(&owners_parts_with_randomness) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::SEND_UTXO_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: Vec<(UTXOPayload, Address)> = receipt - .journal - .decode() - .map_err(|e| ExecutionFailureKind::DecodeError(e.to_string()))?; - - Ok(( - digest - .into_iter() - .map(|(payload, addr)| (payload.amount, addr)) - .collect(), - receipt, - )) -} - -#[allow(clippy::result_large_err)] -pub fn prove_mint_utxo_multiple_assets( - amount_to_mint: u128, - number_of_assets: usize, - owner: Address, -) -> Result<(Vec, Receipt), ExecutionFailureKind> { - let mut builder = ExecutorEnv::builder(); - - builder - .write(&amount_to_mint) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&number_of_assets) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&owner) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::MINT_UTXO_MULTIPLE_ASSETS_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: Vec = receipt - .journal - .decode() - .map_err(|e| ExecutionFailureKind::DecodeError(e.to_string()))?; - - Ok(( - digest - .into_iter() - .map(UTXO::create_utxo_from_payload) - .collect(), - receipt, - )) -} - -pub fn execute_mint_utxo( - amount_to_mint: u128, - owner: Address, - randomness: [u8; 32], -) -> anyhow::Result { - let mut builder = ExecutorEnv::builder(); - - builder.write(&amount_to_mint)?; - builder.write(owner.value())?; - builder.write(&randomness)?; - - let env = builder.build()?; - - let executor = default_executor(); - - let receipt = executor.execute(env, test_methods::MINT_UTXO_ELF)?; - - let digest: UTXOPayload = receipt.journal.decode()?; - - Ok(UTXO::create_utxo_from_payload(digest)) -} - -pub fn execute_send_utxo( - spent_utxo: UTXO, - owners_parts: Vec<(u128, Address)>, -) -> anyhow::Result<(UTXO, Vec<(UTXO, Address)>)> { - let mut builder = ExecutorEnv::builder(); - - let utxo_payload = spent_utxo.into_payload(); - - builder.write(&utxo_payload)?; - let owners_parts_with_randomness = owners_parts - .into_iter() - .map(|(amount, addr)| { - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - (amount, *addr.value(), randomness) - }) - .collect::>(); - - builder.write(&owners_parts_with_randomness)?; - - let env = builder.build()?; - - let executor = default_executor(); - - let receipt = executor.execute(env, test_methods::SEND_UTXO_ELF)?; - - let digest: (UTXOPayload, Vec<(UTXOPayload, Address)>) = receipt.journal.decode()?; - - Ok(( - UTXO::create_utxo_from_payload(digest.0), - digest - .1 - .into_iter() - .map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr)) - .collect(), - )) -} - -pub fn prove( - input_vec: Vec, - elf: &[u8], -) -> anyhow::Result<(u64, Receipt)> { - let mut builder = ExecutorEnv::builder(); - - for input in input_vec { - builder.write(&input)?; - } - - let env = builder.build()?; - - let prover = default_prover(); - - let receipt = prover.prove(env, elf)?.receipt; - - let digest = receipt.journal.decode()?; - Ok((digest, receipt)) -} - -// This only executes the program and does not generate a receipt. -pub fn execute serde::Deserialize<'de>>( - input_vec: Vec, - elf: &[u8], -) -> anyhow::Result { - let mut builder = ExecutorEnv::builder(); - - for input in input_vec { - builder.write(&input)?; - } - - let env = builder.build()?; - - let exec = default_executor(); - let session = exec.execute(env, elf)?; - - // We read the result committed to the journal by the guest code. - let result: T = session.journal.decode()?; - - Ok(result) -} - -pub fn verify(receipt: Receipt, image_id: impl Into) -> anyhow::Result<()> { - Ok(receipt.verify(image_id)?) -} - -#[cfg(test)] -mod tests { - use crate::gas_calculator::GasCalculator; - - use super::*; - use test_methods::BIG_CALCULATION_ELF; - use test_methods::{MULTIPLICATION_ELF, MULTIPLICATION_ID}; - use test_methods::{SUMMATION_ELF, SUMMATION_ID}; - - #[test] - fn prove_simple_sum() { - let message = 1; - let message_2 = 2; - - let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap(); - - verify(receipt, SUMMATION_ID).unwrap(); - assert_eq!(digest, message + message_2); - } - - #[test] - fn prove_bigger_sum() { - let message = 123476; - let message_2 = 2342384; - - let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap(); - - verify(receipt, SUMMATION_ID).unwrap(); - assert_eq!(digest, message + message_2); - } - - #[test] - fn prove_simple_multiplication() { - let message = 1; - let message_2 = 2; - - let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap(); - - verify(receipt, MULTIPLICATION_ID).unwrap(); - assert_eq!(digest, message * message_2); - } - - #[test] - fn prove_bigger_multiplication() { - let message = 3498; - let message_2 = 438563; - - let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap(); - - verify(receipt, MULTIPLICATION_ID).unwrap(); - assert_eq!(digest, message * message_2); - } - - #[test] - fn execute_simple_sum() { - let message: u64 = 1; - let message_2: u64 = 2; - - let result = execute(vec![message, message_2], SUMMATION_ELF).unwrap(); - assert_eq!(result, message + message_2); - } - - #[test] - fn execute_bigger_sum() { - let message: u64 = 123476; - let message_2: u64 = 2342384; - - let result = execute(vec![message, message_2], SUMMATION_ELF).unwrap(); - assert_eq!(result, message + message_2); - } - - #[test] - fn execute_big_calculation() { - let message: u128 = 1; - let message_2: u128 = 2; - - let result = execute(vec![message, message_2], BIG_CALCULATION_ELF).unwrap(); - assert_eq!(result, big_calculation(message, message_2)); - } - - #[test] - fn execute_big_calculation_long() { - let message: u128 = 20; - let message_2: u128 = 10; - - let result = execute(vec![message, message_2], BIG_CALCULATION_ELF).unwrap(); - assert_eq!(result, big_calculation(message, message_2)); - } - - fn big_calculation(lhs: u128, rhs: u128) -> u128 { - let mut res = 1_u128; - for _ in 0..lhs { - res *= rhs; - res += lhs; - } - - res - } - - #[test] - fn test_gas_limits_check_sufficient_funds() { - let message = 1; - let message_2 = 2; - let gas_calc = GasCalculator::new(1, 1, 1, 1, 1, 1000000, 1000000); - - let result = gas_limits_check(vec![message, message_2], SUMMATION_ELF, &gas_calc, 1000000); - assert!(result.is_ok()); - } - - #[test] - fn test_gas_limits_check_insufficient_funds() { - let message = 1; - let message_2 = 2; - let gas_calc = GasCalculator::new(1, 1, 1, 1, 1, 1000000, 1000000); - - let result = gas_limits_check(vec![message, message_2], SUMMATION_ELF, &gas_calc, 1); - assert!(matches!( - result, - Err(ExecutionFailureKind::InsufficientFundsError) - )); - } - - #[test] - fn test_execute_mint_utxo() { - let owner = Address::default(); - let amount = 123456789; - let mut randomness = [0u8; 32]; - OsRng.fill_bytes(&mut randomness); - - let utxo_exec = execute_mint_utxo(amount, owner, randomness).expect("execution failed"); - assert_eq!(utxo_exec.amount, amount); - assert_eq!(utxo_exec.owner, *owner.value()); - } - - #[test] - fn test_prove_mint_utxo() { - let owner = Address::default(); - let amount = 123456789; - - let (utxo, _) = prove_mint_utxo(amount, owner).expect("proof failed"); - assert_eq!(utxo.amount, amount); - assert_eq!(utxo.owner, *owner.value()); - } - - #[test] - fn test_prove_send_utxo() { - let owner = Address::default(); - let amount = 100; - let (input_utxo, _) = prove_mint_utxo(amount, owner).expect("mint failed"); - - let parts = vec![(40, owner), (60, owner)]; - let (outputs, _receipt) = prove_send_utxo(input_utxo, parts.clone()).expect("send failed"); - - let total: u128 = outputs.iter().map(|(utxo, _)| utxo.amount).sum(); - assert_eq!(total, amount); - assert_eq!(outputs.len(), 2); - } - - #[test] - fn test_prove_send_utxo_deshielded() { - let owner = Address::default(); - let amount = 100; - let (utxo, _) = prove_mint_utxo(amount, owner).unwrap(); - let parts = vec![(60, owner), (40, owner)]; - - let (outputs, _) = prove_send_utxo_deshielded(utxo, parts.clone()).unwrap(); - - let total: u128 = outputs.iter().map(|(amt, _)| amt).sum(); - assert_eq!(total, amount); - assert_eq!(outputs.len(), 2); - } - - #[test] - fn test_prove_send_utxo_shielded() { - let owner = Address::default(); - let amount = 100; - let parts = vec![(60, owner), (40, owner)]; - - let (outputs, _) = prove_send_utxo_shielded(owner, amount, parts.clone()).unwrap(); - - let total: u128 = outputs.iter().map(|(utxo, _)| utxo.amount).sum(); - assert_eq!(total, amount); - assert_eq!(outputs.len(), 2); - } - - #[test] - fn test_prove_send_utxo_multiple_assets_one_receiver() { - let owner = Address::default(); - let receiver = Address::default(); - - let utxos = vec![ - prove_mint_utxo(100, owner).unwrap().0, - prove_mint_utxo(50, owner).unwrap().0, - ]; - - let (to_receiver, to_change, _receipt) = - prove_send_utxo_multiple_assets_one_receiver(utxos, 1, receiver).unwrap(); - let total_to_receiver: u128 = to_receiver.iter().map(|u| u.amount).sum(); - - assert!(total_to_receiver > 0); - assert_eq!(to_receiver.len() + to_change.len(), 2); - } -} diff --git a/zkvm/test_methods/Cargo.toml b/zkvm/test_methods/Cargo.toml deleted file mode 100644 index c79f640..0000000 --- a/zkvm/test_methods/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "test-methods" -version = "0.1.0" -edition = "2021" - -[build-dependencies] -risc0-build = { version = "2.3.1" } - -[package.metadata.risc0] -methods = ["guest"] diff --git a/zkvm/test_methods/build.rs b/zkvm/test_methods/build.rs deleted file mode 100644 index 08a8a4e..0000000 --- a/zkvm/test_methods/build.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - risc0_build::embed_methods(); -} diff --git a/zkvm/test_methods/guest/Cargo.lock b/zkvm/test_methods/guest/Cargo.lock deleted file mode 100644 index af2db41..0000000 --- a/zkvm/test_methods/guest/Cargo.lock +++ /dev/null @@ -1,1348 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "anyhow" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" - -[[package]] -name = "ark-bn254" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-r1cs-std", - "ark-std", -] - -[[package]] -name = "ark-crypto-primitives" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0c292754729c8a190e50414fd1a37093c786c709899f29c9f7daccecfa855e" -dependencies = [ - "ahash", - "ark-crypto-primitives-macros", - "ark-ec", - "ark-ff", - "ark-relations", - "ark-serialize", - "ark-snark", - "ark-std", - "blake2", - "derivative", - "digest", - "fnv", - "merlin", - "sha2", -] - -[[package]] -name = "ark-crypto-primitives-macros" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "ark-ec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" -dependencies = [ - "ahash", - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std", - "educe", - "fnv", - "hashbrown", - "itertools", - "num-bigint", - "num-integer", - "num-traits", - "zeroize", -] - -[[package]] -name = "ark-ff" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" -dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "arrayvec", - "digest", - "educe", - "itertools", - "num-bigint", - "num-traits", - "paste", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" -dependencies = [ - "quote", - "syn 2.0.87", -] - -[[package]] -name = "ark-ff-macros" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "ark-groth16" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88f1d0f3a534bb54188b8dcc104307db6c56cdae574ddc3212aec0625740fc7e" -dependencies = [ - "ark-crypto-primitives", - "ark-ec", - "ark-ff", - "ark-poly", - "ark-relations", - "ark-serialize", - "ark-std", -] - -[[package]] -name = "ark-poly" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" -dependencies = [ - "ahash", - "ark-ff", - "ark-serialize", - "ark-std", - "educe", - "fnv", - "hashbrown", -] - -[[package]] -name = "ark-r1cs-std" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941551ef1df4c7a401de7068758db6503598e6f01850bdb2cfdb614a1f9dbea1" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-relations", - "ark-std", - "educe", - "num-bigint", - "num-integer", - "num-traits", - "tracing", -] - -[[package]] -name = "ark-relations" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec46ddc93e7af44bcab5230937635b06fb5744464dd6a7e7b083e80ebd274384" -dependencies = [ - "ark-ff", - "ark-std", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "ark-serialize" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" -dependencies = [ - "ark-serialize-derive", - "ark-std", - "arrayvec", - "digest", - "num-bigint", -] - -[[package]] -name = "ark-serialize-derive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "ark-snark" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d368e2848c2d4c129ce7679a7d0d2d612b6a274d3ea6a13bad4445d61b381b88" -dependencies = [ - "ark-ff", - "ark-relations", - "ark-serialize", - "ark-std", -] - -[[package]] -name = "ark-std" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" -dependencies = [ - "num-traits", - "rand", -] - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "borsh" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5327f6c99920069d1fe374aa743be1af0031dea9f250852cdf1ae6a0861ee24" -dependencies = [ - "borsh-derive", - "cfg_aliases", -] - -[[package]] -name = "borsh-derive" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10aedd8f1a81a8aafbfde924b0e3061cd6fedd6f6bbcfc6a76e6fd426d7bfe26" -dependencies = [ - "once_cell", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "bytemuck" -version = "1.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "cobs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" -dependencies = [ - "thiserror", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_more" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", - "unicode-xid", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "educe" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" -dependencies = [ - "enum-ordinalize", - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "elf" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" - -[[package]] -name = "embedded-io" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" - -[[package]] -name = "embedded-io" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" - -[[package]] -name = "enum-ordinalize" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" -dependencies = [ - "enum-ordinalize-derive", -] - -[[package]] -name = "enum-ordinalize-derive" -version = "4.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", -] - -[[package]] -name = "hashbrown" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" -dependencies = [ - "allocator-api2", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - -[[package]] -name = "include_bytes_aligned" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee796ad498c8d9a1d68e477df8f754ed784ef875de1414ebdaf169f70a6a784" - -[[package]] -name = "indexmap" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - -[[package]] -name = "libc" -version = "0.2.162" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" - -[[package]] -name = "libm" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "merlin" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" -dependencies = [ - "byteorder", - "keccak", - "rand_core", - "zeroize", -] - -[[package]] -name = "metal" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" -dependencies = [ - "bitflags 2.6.0", - "block", - "core-graphics-types", - "foreign-types", - "log", - "objc", - "paste", -] - -[[package]] -name = "no_std_strings" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b0c77c1b780822bc749a33e39aeb2c07584ab93332303babeabb645298a76e" - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pin-project-lite" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" - -[[package]] -name = "postcard" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" -dependencies = [ - "cobs", - "embedded-io 0.4.0", - "embedded-io 0.6.1", - "serde", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" - -[[package]] -name = "risc0-binfmt" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62eb7025356a233c1bc267c458a2ce56fcfc89b136d813c8a77be14ef1eaf2b1" -dependencies = [ - "anyhow", - "borsh", - "derive_more", - "elf", - "lazy_static", - "postcard", - "risc0-zkp", - "risc0-zkvm-platform", - "semver", - "serde", - "tracing", -] - -[[package]] -name = "risc0-circuit-keccak" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0094af5a57b020388a03bdd3834959c7d62723f1687be81414ade25104d93263" -dependencies = [ - "anyhow", - "bytemuck", - "paste", - "risc0-binfmt", - "risc0-circuit-recursion", - "risc0-core", - "risc0-zkp", - "tracing", -] - -[[package]] -name = "risc0-circuit-recursion" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ebded45c902c2b6939924a1cddd1d06b5d1d4ad1531e8798ebfee78f9c038d" -dependencies = [ - "anyhow", - "bytemuck", - "hex", - "metal", - "risc0-core", - "risc0-zkp", - "tracing", -] - -[[package]] -name = "risc0-circuit-rv32im" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15030849f8356f01f23c74b37dbfa4283100b594eb634109993e9e005ef45f64" -dependencies = [ - "anyhow", - "bit-vec", - "bytemuck", - "derive_more", - "paste", - "risc0-binfmt", - "risc0-core", - "risc0-zkp", - "serde", - "tracing", -] - -[[package]] -name = "risc0-core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317bbf70a8750b64d4fd7a2bdc9d7d5f30d8bb305cae486962c797ef35c8d08e" -dependencies = [ - "bytemuck", - "bytemuck_derive", - "rand_core", -] - -[[package]] -name = "risc0-groth16" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cf5d0b673d5fc67a89147c2e9c53134707dcc8137a43d1ef06b4ff68e99b74f" -dependencies = [ - "anyhow", - "ark-bn254", - "ark-ec", - "ark-groth16", - "ark-serialize", - "bytemuck", - "hex", - "num-bigint", - "num-traits", - "risc0-binfmt", - "risc0-zkp", - "serde", - "stability", -] - -[[package]] -name = "risc0-zkos-v1compat" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f76c479b69d1987cb54ac72dcc017197296fdcd6daf78fafc10cbbd3a167a7de" -dependencies = [ - "include_bytes_aligned", - "no_std_strings", -] - -[[package]] -name = "risc0-zkp" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a287e9cd6d7b3b38eeb49c62090c46a1935922309fbd997a9143ed8c43c8f3cb" -dependencies = [ - "anyhow", - "blake2", - "borsh", - "bytemuck", - "cfg-if", - "digest", - "hex", - "hex-literal", - "metal", - "paste", - "rand_core", - "risc0-core", - "risc0-zkvm-platform", - "serde", - "sha2", - "stability", - "tracing", -] - -[[package]] -name = "risc0-zkvm" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9684b333c1c5d83f29ce2a92314ccfafd9d8cdfa6c4e19c07b97015d2f1eb9d0" -dependencies = [ - "anyhow", - "borsh", - "bytemuck", - "derive_more", - "getrandom 0.2.15", - "hex", - "risc0-binfmt", - "risc0-circuit-keccak", - "risc0-circuit-recursion", - "risc0-circuit-rv32im", - "risc0-core", - "risc0-groth16", - "risc0-zkos-v1compat", - "risc0-zkp", - "risc0-zkvm-platform", - "rrs-lib", - "semver", - "serde", - "sha2", - "stability", - "tracing", -] - -[[package]] -name = "risc0-zkvm-platform" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cae9cb2c2f6cab2dfa395ea6e2576713929040c7fb0c5f4150d13e1119d18686" -dependencies = [ - "bytemuck", - "cfg-if", - "getrandom 0.2.15", - "getrandom 0.3.3", - "libm", - "stability", -] - -[[package]] -name = "rrs-lib" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4382d3af3a4ebdae7f64ba6edd9114fff92c89808004c4943b393377a25d001" -dependencies = [ - "downcast-rs", - "paste", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" -dependencies = [ - "serde", -] - -[[package]] -name = "serde" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "serde_json" -version = "1.0.134" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "stability" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" -dependencies = [ - "quote", - "syn 2.0.87", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "test" -version = "0.1.0" -dependencies = [ - "risc0-zkvm", - "serde", - "serde_json", -] - -[[package]] -name = "thiserror" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-subscriber" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" -dependencies = [ - "tracing-core", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" -dependencies = [ - "wit-bindgen-rt", -] - -[[package]] -name = "winnow" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] diff --git a/zkvm/test_methods/guest/Cargo.toml b/zkvm/test_methods/guest/Cargo.toml deleted file mode 100644 index c80f35b..0000000 --- a/zkvm/test_methods/guest/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "test" -version = "0.1.0" -edition = "2021" - -[workspace] - -[dependencies] -serde_json = "1.0.81" -risc0-zkvm = { version = "2.3.1", default-features = false, features = ['std'] } - -[dependencies.serde] -features = ["derive"] -version = "1.0.60" diff --git a/zkvm/test_methods/guest/src/bin/big_calculation.rs b/zkvm/test_methods/guest/src/bin/big_calculation.rs deleted file mode 100644 index b546857..0000000 --- a/zkvm/test_methods/guest/src/bin/big_calculation.rs +++ /dev/null @@ -1,14 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; - -fn main() { - let lhs: u128 = env::read(); - let rhs: u128 = env::read(); - let mut res = 1; - for i in 0..lhs { - res *= rhs; - res += lhs; - } - env::commit(&(res)); -} diff --git a/zkvm/test_methods/guest/src/bin/mint_utxo.rs b/zkvm/test_methods/guest/src/bin/mint_utxo.rs deleted file mode 100644 index 5123643..0000000 --- a/zkvm/test_methods/guest/src/bin/mint_utxo.rs +++ /dev/null @@ -1,32 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; -use serde::{Deserialize, Serialize}; - -type AccountAddr = [u8; 32]; - -#[derive(Serialize, Deserialize)] -pub struct UTXOPayload { - pub owner: AccountAddr, - pub asset: Vec, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: [u8; 32], -} - -fn main() { - let amount_to_mint: u128 = env::read(); - let owner: AccountAddr = env::read(); - let randomness: [u8; 32] = env::read(); - - let payload = UTXOPayload { - owner, - asset: vec![], - amount: amount_to_mint, - privacy_flag: true, - randomness, - }; - - env::commit(&(payload)); -} diff --git a/zkvm/test_methods/guest/src/bin/mint_utxo_multiple_assets.rs b/zkvm/test_methods/guest/src/bin/mint_utxo_multiple_assets.rs deleted file mode 100644 index 47ad2ac..0000000 --- a/zkvm/test_methods/guest/src/bin/mint_utxo_multiple_assets.rs +++ /dev/null @@ -1,39 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; -use serde::{Deserialize, Serialize}; - -type AccountAddr = [u8; 32]; - -#[derive(Serialize, Deserialize)] -pub struct UTXOPayload { - pub owner: AccountAddr, - pub asset: Vec, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: [u8; 32], -} - -fn main() { - let amount_to_mint: u128 = env::read(); - let number_of_assets: usize = env::read(); - let owner: AccountAddr = env::read(); - let randomness: [u8; 32] = env::read(); - - let mut asseted_utxos = vec![]; - - for i in 0..number_of_assets { - let payload = UTXOPayload { - owner, - asset: vec![i as u8], - amount: amount_to_mint, - privacy_flag: true, - randomness - }; - - asseted_utxos.push(payload); - } - - env::commit(&(asseted_utxos)); -} diff --git a/zkvm/test_methods/guest/src/bin/multiplication.rs b/zkvm/test_methods/guest/src/bin/multiplication.rs deleted file mode 100644 index 047ac07..0000000 --- a/zkvm/test_methods/guest/src/bin/multiplication.rs +++ /dev/null @@ -1,9 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; - -fn main() { - let lhs: u64 = env::read(); - let rhs: u64 = env::read(); - env::commit(&(lhs * rhs)); -} diff --git a/zkvm/test_methods/guest/src/bin/send_utxo.rs b/zkvm/test_methods/guest/src/bin/send_utxo.rs deleted file mode 100644 index 64035a9..0000000 --- a/zkvm/test_methods/guest/src/bin/send_utxo.rs +++ /dev/null @@ -1,34 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; -use serde::{Deserialize, Serialize}; - -type AccountAddr = [u8; 32]; - -#[derive(Serialize, Deserialize)] -pub struct UTXOPayload { - pub owner: AccountAddr, - pub asset: Vec, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: [u8; 32], -} - -fn main() { - let utxo_spent: UTXOPayload = env::read(); - let owners_parts: Vec<(u128, AccountAddr, [u8; 32])> = env::read(); - - let res: Vec<(UTXOPayload, AccountAddr)> = owners_parts.into_iter().map(|(amount, addr, randomness)| ( - UTXOPayload { - owner: addr.clone(), - asset: vec![], - amount, - privacy_flag: true, - randomness, - }, - addr - )).collect(); - - env::commit(&(res)); -} diff --git a/zkvm/test_methods/guest/src/bin/send_utxo_multiple_assets.rs b/zkvm/test_methods/guest/src/bin/send_utxo_multiple_assets.rs deleted file mode 100644 index e73f844..0000000 --- a/zkvm/test_methods/guest/src/bin/send_utxo_multiple_assets.rs +++ /dev/null @@ -1,41 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; -use serde::{Deserialize, Serialize}; - -type AccountAddr = [u8; 32]; - -#[derive(Clone, Serialize, Deserialize)] -pub struct UTXOPayload { - pub owner: AccountAddr, - pub asset: Vec, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: [u8; 32], -} - -fn main() { - let utxo_spent: Vec = env::read(); - let number_to_send = env::read(); - let receiver: AccountAddr = env::read(); - - let mut utxo_received = vec![]; - let mut utxo_not_spent = vec![]; - - for i in 0..utxo_spent.len() { - let mut utxo_payload = utxo_spent[i].clone(); - - if i < number_to_send { - utxo_payload.owner = receiver; - - utxo_received.push(utxo_payload); - } else { - utxo_payload.asset.push(0); - - utxo_not_spent.push(utxo_payload); - } - } - - env::commit(&(utxo_received, utxo_not_spent)); -} diff --git a/zkvm/test_methods/guest/src/bin/summation.rs b/zkvm/test_methods/guest/src/bin/summation.rs deleted file mode 100644 index cd642fd..0000000 --- a/zkvm/test_methods/guest/src/bin/summation.rs +++ /dev/null @@ -1,9 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; - -fn main() { - let data: u64 = env::read(); - let data_2: u64 = env::read(); - env::commit(&(data + data_2)); -} diff --git a/zkvm/test_methods/src/lib.rs b/zkvm/test_methods/src/lib.rs deleted file mode 100644 index 1bdb308..0000000 --- a/zkvm/test_methods/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -include!(concat!(env!("OUT_DIR"), "/methods.rs")); From 74f0c983d33bc7eae4d781af2d19ab1673578e9b Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 14 Aug 2025 14:03:48 +0300 Subject: [PATCH 12/13] fix: comments fix --- Cargo.toml | 1 - accounts/src/account_core/mod.rs | 4 +- nssa/Cargo.toml | 1 - nssa/src/address.rs | 187 ++++---------- nssa/src/gas_calculator.rs | 113 --------- nssa/src/lib.rs | 1 - sc_core/Cargo.toml | 41 ---- sc_core/src/blob_utils.rs | 125 ---------- sc_core/src/cryptography.rs | 10 - sc_core/src/lib.rs | 5 - sc_core/src/proofs_circuits.rs | 286 ---------------------- sc_core/src/public_context.rs | 186 -------------- sc_core/src/transaction_payloads_tools.rs | 100 -------- wallet/Cargo.toml | 3 - wallet/src/chain_storage/mod.rs | 19 +- wallet/src/config.rs | 15 -- wallet/src/helperfunctions.rs | 4 +- wallet/src/lib.rs | 50 +--- 18 files changed, 49 insertions(+), 1102 deletions(-) delete mode 100644 nssa/src/gas_calculator.rs delete mode 100644 sc_core/Cargo.toml delete mode 100644 sc_core/src/blob_utils.rs delete mode 100644 sc_core/src/cryptography.rs delete mode 100644 sc_core/src/lib.rs delete mode 100644 sc_core/src/proofs_circuits.rs delete mode 100644 sc_core/src/public_context.rs delete mode 100644 sc_core/src/transaction_payloads_tools.rs diff --git a/Cargo.toml b/Cargo.toml index 147f98e..fe70572 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ members = [ "wallet", "sequencer_core", "common", - "sc_core", "nssa", ] diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index da6aa27..329e1e1 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -106,7 +106,7 @@ impl AccountPublicMask { } pub fn make_tag(&self) -> Tag { - self.address.tag() + self.address.value()[0] } } @@ -199,7 +199,7 @@ impl Account { } pub fn make_tag(&self) -> Tag { - self.address.tag() + self.address.value()[0] } ///Produce account public mask diff --git a/nssa/Cargo.toml b/nssa/Cargo.toml index 7653fd7..5a579fd 100644 --- a/nssa/Cargo.toml +++ b/nssa/Cargo.toml @@ -14,7 +14,6 @@ secp256k1 = "0.31.1" rand = "0.8" hex = "0.4.3" anyhow.workspace = true -serde_json.workspace = true [dev-dependencies] test-program-methods = { path = "test_program_methods" } diff --git a/nssa/src/address.rs b/nssa/src/address.rs index 8f6d7ec..d54af10 100644 --- a/nssa/src/address.rs +++ b/nssa/src/address.rs @@ -1,5 +1,7 @@ +use std::{fmt::Display, str::FromStr}; + use anyhow::anyhow; -use serde::{Deserialize, Serialize, de::Visitor}; +use serde::{Deserialize, Serialize}; use crate::signature::PublicKey; @@ -15,10 +17,6 @@ impl Address { Self { value } } - pub fn tag(&self) -> u8 { - self.value[0] - } - pub fn value(&self) -> &[u8; 32] { &self.value } @@ -49,90 +47,30 @@ impl From<&PublicKey> for Address { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct HexString(String); - -impl HexString { - pub fn inner(&self) -> &str { - &self.0 - } -} - #[derive(Debug, thiserror::Error)] -pub enum HexStringConsistencyError { - #[error("Hex decode error")] - HexError(#[from] hex::FromHexError), - #[error("Decode slice does not fit 32 bytes")] - SizeError(#[from] anyhow::Error), +pub enum AddressError { + #[error("invalid hex")] + InvalidHex(#[from] hex::FromHexError), + #[error("invalid length: expected 32 bytes, got {0}")] + InvalidLength(usize), } -impl TryFrom<&str> for HexString { - type Error = HexStringConsistencyError; - - fn try_from(value: &str) -> Result { - let decoded_str = hex::decode(value)?; - let _: Address = decoded_str.try_into()?; - - Ok(Self(value.to_string())) +impl FromStr for Address { + type Err = AddressError; + fn from_str(s: &str) -> Result { + let bytes = hex::decode(s)?; + if bytes.len() != 32 { + return Err(AddressError::InvalidLength(bytes.len())); + } + let mut value = [0u8; 32]; + value.copy_from_slice(&bytes); + Ok(Address { value }) } } -impl Serialize for HexString { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.0) - } -} - -struct HexStringVisitor; - -impl<'de> Visitor<'de> for HexStringVisitor { - type Value = String; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("expected a valid string") - } - - fn visit_string(self, v: String) -> Result - where - E: serde::de::Error, - { - Ok(v) - } - - fn visit_str(self, v: &str) -> Result - where - E: serde::de::Error, - { - Ok(v.to_string()) - } -} - -impl<'de> Deserialize<'de> for HexString { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let str_cand = deserializer.deserialize_string(HexStringVisitor)?; - - let hex_string = - HexString::try_from(str_cand.as_str()).map_err(serde::de::Error::custom)?; - - Ok(hex_string) - } -} - -impl From for Address { - fn from(value: HexString) -> Self { - Address::try_from(hex::decode(value.inner()).unwrap()).unwrap() - } -} - -impl From
for HexString { - fn from(value: Address) -> Self { - HexString::try_from(hex::encode(value).as_str()).unwrap() +impl Display for Address { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", hex::encode(self.value)) } } @@ -141,7 +79,7 @@ impl Serialize for Address { where S: serde::Serializer, { - let hex_string: HexString = (*self).into(); + let hex_string = self.to_string(); hex_string.serialize(serializer) } @@ -152,82 +90,41 @@ impl<'de> Deserialize<'de> for Address { where D: serde::Deserializer<'de>, { - let hex_sring = HexString::deserialize(deserializer)?; + let hex_string = String::deserialize(deserializer)?; - Ok(hex_sring.into()) + Address::from_str(&hex_string).map_err(serde::de::Error::custom) } } #[cfg(test)] mod tests { - use super::*; + use crate::{Address, address::AddressError}; - #[derive(Debug, Serialize, Deserialize)] - struct Ser1 { - f1: String, - } - - #[derive(Debug, Serialize, Deserialize, PartialEq)] - struct Ser2 { - f1: HexString, - } - - #[derive(Debug, Serialize, Deserialize, PartialEq)] - struct Ser3 { - f1: Address, + #[test] + fn parse_valid_address() { + let hex_str = "00".repeat(32); // 64 hex chars = 32 bytes + let addr: Address = hex_str.parse().unwrap(); + assert_eq!(addr.value, [0u8; 32]); } #[test] - fn test_hex_ser() { - let str_for_tests = hex::encode([42; 32]); - - let hex_str_for_tests = HexString::try_from(str_for_tests.as_str()).unwrap(); - - let ser1_str = Ser1 { f1: str_for_tests }; - - let ser2_str = Ser2 { - f1: hex_str_for_tests, - }; - - let ser1_str_ser = serde_json::to_string(&ser1_str).unwrap(); - let ser2_str_ser = serde_json::to_string(&ser2_str).unwrap(); - - println!("{ser2_str_ser:#?}"); - - assert_eq!(ser1_str_ser, ser2_str_ser); + fn parse_invalid_hex() { + let hex_str = "zz".repeat(32); // invalid hex chars + let result = hex_str.parse::
().unwrap_err(); + assert!(matches!(result, AddressError::InvalidHex(_))); } #[test] - fn test_hex_deser() { - let raw_json = r#"{ - "f1": "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" - }"#; - - let str_for_tests = hex::encode([42; 32]); - - let hex_str_for_tests = HexString::try_from(str_for_tests.as_str()).unwrap(); - - let ser2_str = Ser2 { - f1: hex_str_for_tests, - }; - - let ser1_str: Ser2 = serde_json::from_str(raw_json).unwrap(); - - assert_eq!(ser1_str, ser2_str); + fn parse_wrong_length_short() { + let hex_str = "00".repeat(31); // 62 chars = 31 bytes + let result = hex_str.parse::
().unwrap_err(); + assert!(matches!(result, AddressError::InvalidLength(_))); } #[test] - fn test_addr_deser() { - let raw_json = r#"{ - "f1": "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" - }"#; - - let addr_for_tests = Address::new([42; 32]); - - let ser2_str = Ser3 { f1: addr_for_tests }; - - let ser1_str: Ser3 = serde_json::from_str(raw_json).unwrap(); - - assert_eq!(ser1_str, ser2_str); + fn parse_wrong_length_long() { + let hex_str = "00".repeat(33); // 66 chars = 33 bytes + let result = hex_str.parse::
().unwrap_err(); + assert!(matches!(result, AddressError::InvalidLength(_))); } } diff --git a/nssa/src/gas_calculator.rs b/nssa/src/gas_calculator.rs deleted file mode 100644 index ac2c737..0000000 --- a/nssa/src/gas_calculator.rs +++ /dev/null @@ -1,113 +0,0 @@ -#[derive(Debug, Clone)] -pub struct GasCalculator { - /// Gas spent per deploying one byte of data - gas_fee_per_byte_deploy: u64, - /// Gas spent per reading one byte of data in VM - gas_fee_per_input_buffer_runtime: u64, - /// Gas spent per one byte of contract data in runtime - gas_fee_per_byte_runtime: u64, - /// Cost of one gas of runtime in public balance - gas_cost_runtime: u64, - /// Cost of one gas of deployment in public balance - gas_cost_deploy: u64, - /// Gas limit for deployment - gas_limit_deploy: u64, - /// Gas limit for runtime - gas_limit_runtime: u64, -} - -impl GasCalculator { - pub fn new( - gas_fee_per_byte_deploy: u64, - gas_fee_per_input_buffer_runtime: u64, - gas_fee_per_byte_runtime: u64, - gas_cost_runtime: u64, - gas_cost_deploy: u64, - gas_limit_deploy: u64, - gas_limit_runtime: u64, - ) -> Self { - Self { - gas_fee_per_byte_deploy, - gas_fee_per_input_buffer_runtime, - gas_fee_per_byte_runtime, - gas_cost_deploy, - gas_cost_runtime, - gas_limit_deploy, - gas_limit_runtime, - } - } - - pub fn gas_fee_per_byte_deploy(&self) -> u64 { - self.gas_fee_per_byte_deploy - } - - pub fn gas_fee_per_input_buffer_runtime(&self) -> u64 { - self.gas_fee_per_input_buffer_runtime - } - - pub fn gas_fee_per_byte_runtime(&self) -> u64 { - self.gas_fee_per_byte_runtime - } - - pub fn gas_cost_runtime(&self) -> u64 { - self.gas_cost_runtime - } - - pub fn gas_cost_deploy(&self) -> u64 { - self.gas_cost_deploy - } - - pub fn gas_limit_deploy(&self) -> u64 { - self.gas_limit_deploy - } - - pub fn gas_limit_runtime(&self) -> u64 { - self.gas_limit_runtime - } - - ///Returns Option - /// - /// Some(_) - in case if `gas` < `gas_limit_deploy` - /// - /// None - else - pub fn gas_deploy(&self, elf: &[u8]) -> Option { - let gas = self.gas_fee_per_byte_deploy() * (elf.len() as u64); - - if gas < self.gas_limit_deploy() { - Some(gas) - } else { - None - } - } - - pub fn gas_runtime(&self, elf: &[u8]) -> u64 { - self.gas_fee_per_byte_runtime() * (elf.len() as u64) - } - - pub fn gas_input_buffer(&self, input_length: usize) -> u64 { - self.gas_fee_per_input_buffer_runtime() * (input_length as u64) - } - - ///Returns Option - /// - /// Some(_) - in case if `gas` < `gas_limit_runtime` - /// - /// None - else - pub fn gas_runtime_full(&self, elf: &[u8], input_length: usize) -> Option { - let gas = self.gas_runtime(elf) + self.gas_input_buffer(input_length); - - if gas < self.gas_limit_runtime() { - Some(gas) - } else { - None - } - } - - pub fn deploy_cost(&self, deploy_gas: u64) -> u64 { - deploy_gas * self.gas_cost_deploy() - } - - pub fn runtime_cost(&self, runtime_gas: u64) -> u64 { - runtime_gas * self.gas_cost_runtime() - } -} diff --git a/nssa/src/lib.rs b/nssa/src/lib.rs index e24ea89..9555b14 100644 --- a/nssa/src/lib.rs +++ b/nssa/src/lib.rs @@ -1,6 +1,5 @@ pub mod address; pub mod error; -pub mod gas_calculator; pub mod program; pub mod public_transaction; mod signature; diff --git a/sc_core/Cargo.toml b/sc_core/Cargo.toml deleted file mode 100644 index 8a615a0..0000000 --- a/sc_core/Cargo.toml +++ /dev/null @@ -1,41 +0,0 @@ -[package] -name = "sc_core" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true -rand.workspace = true -k256.workspace = true -sha2.workspace = true -bincode.workspace = true -elliptic-curve.workspace = true -hex.workspace = true -light-poseidon.workspace = true -ark-bn254.workspace = true -ark-ff.workspace = true - -risc0-zkvm = "2.3.1" - -[dependencies.accounts] -path = "../accounts" - -[dependencies.storage] -path = "../storage" - -[dependencies.utxo] -path = "../utxo" - -[dependencies.common] -path = "../common" - -[dependencies.nssa] -path = "../nssa" - -[dependencies.secp256k1-zkp] -workspace = true -features = ["std", "rand-std", "rand", "serde", "global-context"] diff --git a/sc_core/src/blob_utils.rs b/sc_core/src/blob_utils.rs deleted file mode 100644 index d1210ba..0000000 --- a/sc_core/src/blob_utils.rs +++ /dev/null @@ -1,125 +0,0 @@ -use serde::Serialize; -use storage::{ - sc_db_utils::{produce_blob_from_fit_vec, DataBlob, DataBlobChangeVariant}, - SC_DATA_BLOB_SIZE, -}; - -///Creates blob list from generic serializable state -/// -///`ToDo`: Find a way to align data in a way, to minimize read and write operations in db -pub fn produce_blob_list_from_sc_public_state( - state: &S, -) -> Result, serde_json::Error> { - let mut blob_list = vec![]; - - let ser_data = serde_json::to_vec(state)?; - - //`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust - for i in 0..=(ser_data.len() / SC_DATA_BLOB_SIZE) { - let next_chunk: Vec = if (i + 1) * SC_DATA_BLOB_SIZE < ser_data.len() { - ser_data[(i * SC_DATA_BLOB_SIZE)..((i + 1) * SC_DATA_BLOB_SIZE)].to_vec() - } else { - ser_data[(i * SC_DATA_BLOB_SIZE)..(ser_data.len())].to_vec() - }; - - blob_list.push(produce_blob_from_fit_vec(next_chunk)); - } - - Ok(blob_list) -} - -///Compare two consecutive in time blob lists to produce list of modified ids -pub fn compare_blob_lists( - blob_list_old: &[DataBlob], - blob_list_new: &[DataBlob], -) -> Vec { - let mut changed_ids = vec![]; - let mut id_end = 0; - - let old_len = blob_list_old.len(); - let new_len = blob_list_new.len(); - - if old_len > new_len { - for id in new_len..old_len { - changed_ids.push(DataBlobChangeVariant::Deleted { id }); - } - } else if new_len > old_len { - for (id, blob) in blob_list_new.iter().enumerate().take(new_len).skip(old_len) { - changed_ids.push(DataBlobChangeVariant::Created { id, blob: *blob }); - } - } - - loop { - let old_blob = blob_list_old.get(id_end); - let new_blob = blob_list_new.get(id_end); - - match (old_blob, new_blob) { - (Some(old), Some(new)) => { - if old != new { - changed_ids.push(DataBlobChangeVariant::Modified { - id: id_end, - blob_old: *old, - blob_new: *new, - }); - } - } - _ => break, - } - - id_end += 1; - } - - changed_ids -} - -#[cfg(test)] -mod tests { - use super::*; - use serde::Serialize; - - const TEST_BLOB_SIZE: usize = 256; // Define a test blob size for simplicity - static SC_DATA_BLOB_SIZE: usize = TEST_BLOB_SIZE; - - #[derive(Serialize)] - struct TestState { - a: u32, - b: u32, - } - - #[test] - fn test_produce_blob_list_from_sc_public_state() { - let state = TestState { a: 42, b: 99 }; - let result = produce_blob_list_from_sc_public_state(&state).unwrap(); - assert!(!result.is_empty()); - } - - #[test] - fn test_compare_blob_lists_created() { - let old_list: Vec = vec![]; - let new_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; - - let changes = compare_blob_lists(&old_list, &new_list); - assert_eq!(changes.len(), 1); - assert!(matches!(changes[0], DataBlobChangeVariant::Created { .. })); - } - - #[test] - fn test_compare_blob_lists_deleted() { - let old_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; - let new_list: Vec = vec![]; - - let changes = compare_blob_lists(&old_list, &new_list); - assert_eq!(changes.len(), 1); - assert!(matches!(changes[0], DataBlobChangeVariant::Deleted { .. })); - } - - #[test] - fn test_compare_blob_lists_modified() { - let old_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; - let new_list: Vec = vec![[2; SC_DATA_BLOB_SIZE].into()]; - - let changes = compare_blob_lists(&old_list, &new_list); - assert_eq!(changes.len(), 1); - assert!(matches!(changes[0], DataBlobChangeVariant::Modified { .. })); - } -} diff --git a/sc_core/src/cryptography.rs b/sc_core/src/cryptography.rs deleted file mode 100644 index d93ce0e..0000000 --- a/sc_core/src/cryptography.rs +++ /dev/null @@ -1,10 +0,0 @@ -use ark_bn254::Fr; -use light_poseidon::{Poseidon, PoseidonBytesHasher}; - -pub fn poseidon_hash(inputs: &[&[u8]]) -> anyhow::Result<[u8; 32]> { - let mut poseidon = Poseidon::::new_circom(2).unwrap(); - - let hash = poseidon.hash_bytes_be(inputs)?; - - Ok(hash) -} diff --git a/sc_core/src/lib.rs b/sc_core/src/lib.rs deleted file mode 100644 index ed70205..0000000 --- a/sc_core/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod blob_utils; -pub mod cryptography; -pub mod proofs_circuits; -pub mod public_context; -pub mod transaction_payloads_tools; diff --git a/sc_core/src/proofs_circuits.rs b/sc_core/src/proofs_circuits.rs deleted file mode 100644 index d6fbbc2..0000000 --- a/sc_core/src/proofs_circuits.rs +++ /dev/null @@ -1,286 +0,0 @@ -use bincode; -use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; -use nssa::Address; -use rand::{thread_rng, RngCore}; -use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tag, Tweak, SECP256K1}; -use sha2::{Digest, Sha256}; -use utxo::utxo_core::UTXO; - -// - -use crate::{cryptography::poseidon_hash, public_context::PublicSCContext}; - -fn hash(input: &[u8]) -> Vec { - Sha256::digest(input).to_vec() -} - -/// Generate nullifiers -/// -/// takes the input_utxo and npk -/// -/// returns the nullifiers[i], where the nullifiers[i] = poseidon_hash(in_commitments[i] || npk) -pub fn generate_nullifiers(input_utxo: &UTXO, npk: &[u8]) -> Vec { - let commitment = generate_commitment(input_utxo); - poseidon_hash(&[commitment.as_ref(), npk]).unwrap().to_vec() -} - -/// Generate commitment for UTXO -/// -/// uses the input_utxo -/// -/// returns commitment here commitment is a hash(bincode(input_utxo)) -pub fn generate_commitment(input_utxo: &UTXO) -> Vec { - let serialized = bincode::serialize(input_utxo).unwrap(); // Serialize UTXO. - hash(&serialized) -} - -/// Generate commitments for UTXO -/// -/// uses the input_utxos -/// -/// returns commitments -pub fn generate_commitments(input_utxos: &[UTXO]) -> Vec> { - input_utxos - .iter() - .map(|utxo| { - let serialized = bincode::serialize(utxo).unwrap(); // Serialize UTXO. - hash(&serialized) - }) - .collect() -} - -/// Validate inclusion proof for in_commitments -/// -/// ToDo: Solve it in more scalable way -pub fn validate_in_commitments_tree( - in_commitment: &[u8], - commitment_tree: &UTXOCommitmentsMerkleTree, -) -> bool { - let alighned_hash: [u8; 32] = in_commitment.try_into().unwrap(); - - commitment_tree.get_proof(alighned_hash).is_some() -} - -/// Check, that input utxos balances is equal to out utxo balances -pub fn check_balances_private(in_utxos: &[UTXO], out_utxos: &[UTXO]) -> bool { - let in_sum = in_utxos.iter().fold(0, |prev, utxo| prev + utxo.amount); - let out_sum = out_utxos.iter().fold(0, |prev, utxo| prev + utxo.amount); - - in_sum == out_sum -} - -pub fn private_circuit( - input_utxos: &[UTXO], - output_utxos: &[UTXO], - public_context: &PublicSCContext, -) -> (Vec>, Vec>) { - assert!(check_balances_private(input_utxos, output_utxos)); - - let in_commitments = generate_commitments(input_utxos); - - let mut in_nullifiers = vec![]; - - for in_utxo in input_utxos { - let nullifier_public_key = public_context - .account_masks - .get(&Address::new(in_utxo.owner)) - .unwrap() - .nullifier_public_key; - - let key_ser = serde_json::to_vec(&nullifier_public_key).unwrap(); - - in_nullifiers.push(generate_nullifiers(in_utxo, &key_ser)); - } - - for in_commitment in in_commitments { - assert!(validate_in_commitments_tree( - &in_commitment, - &public_context.commitments_tree, - )); - } - - (in_nullifiers, generate_commitments(output_utxos)) -} - -/// Check balances DE -/// -/// takes the input_utxos[] and output_balance, -/// -/// returns the True if the token amount in output_balance matches the sum of all input_utxos[], otherwise return False. -pub fn check_balances_de(input_utxos: &[UTXO], output_balance: u128) -> bool { - let total_input: u128 = input_utxos.iter().map(|utxo| utxo.amount).sum(); - total_input == output_balance -} - -pub fn deshielded_circuit( - input_utxos: &[UTXO], - output_balance: u128, - public_context: &PublicSCContext, -) -> Vec> { - assert!(check_balances_de(input_utxos, output_balance)); - - let in_commitments = generate_commitments(input_utxos); - - let mut in_nullifiers = vec![]; - - for in_utxo in input_utxos { - let nullifier_public_key = public_context - .account_masks - .get(&Address::new(in_utxo.owner)) - .unwrap() - .nullifier_public_key; - - let key_ser = serde_json::to_vec(&nullifier_public_key).unwrap(); - - in_nullifiers.push(generate_nullifiers(in_utxo, &key_ser)); - } - - for in_commitment in in_commitments { - assert!(validate_in_commitments_tree( - &in_commitment, - &public_context.commitments_tree, - )); - } - - in_nullifiers -} - -#[allow(unused)] -fn commitment_secrets_random(value: u64) -> CommitmentSecrets { - CommitmentSecrets { - value, - value_blinding_factor: Tweak::new(&mut thread_rng()), - generator_blinding_factor: Tweak::new(&mut thread_rng()), - } -} - -pub fn tag_random() -> Tag { - use rand::thread_rng; - use rand::RngCore; - - let mut bytes = [0u8; 32]; - thread_rng().fill_bytes(&mut bytes); - - Tag::from(bytes) -} - -pub fn commit(comm: &CommitmentSecrets, tag: Tag) -> PedersenCommitment { - let generator = Generator::new_blinded(SECP256K1, tag, comm.generator_blinding_factor); - - PedersenCommitment::new(SECP256K1, comm.value, comm.value_blinding_factor, generator) -} - -/// new_commitment for a Vec of values -pub fn pedersen_commitment_vec( - public_info_vec: Vec, -) -> (Tweak, [u8; 32], Vec) { - let mut random_val: [u8; 32] = [0; 32]; - thread_rng().fill_bytes(&mut random_val); - - let generator_blinding_factor = Tweak::new(&mut thread_rng()); - let tag = tag_random(); - - let vec_commitments = public_info_vec - .into_iter() - .map(|public_info| { - let commitment_secrets = CommitmentSecrets { - value: public_info, - value_blinding_factor: Tweak::from_slice(&random_val).unwrap(), - generator_blinding_factor, - }; - - commit(&commitment_secrets, tag) - }) - .collect(); - - (generator_blinding_factor, random_val, vec_commitments) -} - -/// Verify Pedersen commitment -/// -/// takes the public_info, secret_r and pedersen_commitment and -/// -/// checks that commitment(public_info,secret_r) is equal pedersen_commitment where the commitment is pedersen commitment. -pub fn verify_commitment( - public_info: u64, - secret_r: &[u8], - pedersen_commitment: &PedersenCommitment, -) -> bool { - let commitment_secrets = CommitmentSecrets { - value: public_info, - value_blinding_factor: Tweak::from_slice(secret_r).unwrap(), - generator_blinding_factor: Tweak::new(&mut thread_rng()), - }; - - let tag = tag_random(); - let commitment = commit(&commitment_secrets, tag); - - commitment == *pedersen_commitment -} - -/// Validate inclusion proof for pedersen_commitment -/// -/// ToDo: Solve it in more scalable way -pub fn validate_in_commitments_tree_se( - pedersen_commitment: &PedersenCommitment, - commitment_tree: &UTXOCommitmentsMerkleTree, -) -> bool { - let alighned_hash: [u8; 32] = pedersen_commitment.serialize()[0..32].try_into().unwrap(); - - commitment_tree.get_proof(alighned_hash).is_some() -} - -/// Generate nullifier SE -/// -/// takes the pedersen_commitment and npk then -/// returns a nullifier, where the nullifier = poseidon_hash(pedersen_commitment || npk) -pub fn generate_nullifiers_se(pedersen_commitment: &PedersenCommitment, npk: &[u8]) -> Vec { - let commitment_ser = pedersen_commitment.serialize().to_vec(); - - poseidon_hash(&[&commitment_ser, npk]).unwrap().to_vec() -} - -/// Check balances SE -/// -/// takes the input_balance and output_utxos[], -/// -/// returns the True if the token amount in input_balance matches the sum of all output_utxos[], otherwise return False. -pub fn check_balances_se(input_balance: u128, output_utxos: &[UTXO]) -> bool { - let total_output: u128 = output_utxos.iter().map(|utxo| utxo.amount).sum(); - total_output == input_balance -} - -pub fn shielded_circuit( - public_info: u64, - output_utxos: &[UTXO], - pedersen_commitment: PedersenCommitment, - secret_r: &[u8], - public_context: &PublicSCContext, -) -> (Vec>, Vec) { - assert!(check_balances_se(public_info as u128, output_utxos)); - - let out_commitments = generate_commitments(output_utxos); - - let nullifier_public_key = public_context - .account_masks - .get(&public_context.caller_address) - .unwrap() - .nullifier_public_key; - - let key_ser = serde_json::to_vec(&nullifier_public_key).unwrap(); - - let nullifier = generate_nullifiers_se(&pedersen_commitment, &key_ser); - - assert!(validate_in_commitments_tree_se( - &pedersen_commitment, - &public_context.commitments_tree, - )); - - assert!(verify_commitment( - public_info, - secret_r, - &pedersen_commitment - )); - - (out_commitments, nullifier) -} diff --git a/sc_core/src/public_context.rs b/sc_core/src/public_context.rs deleted file mode 100644 index cb14bbc..0000000 --- a/sc_core/src/public_context.rs +++ /dev/null @@ -1,186 +0,0 @@ -use std::collections::BTreeMap; - -use accounts::account_core::AccountPublicMask; -use common::merkle_tree_public::{merkle_tree::UTXOCommitmentsMerkleTree, TreeHashType}; -use nssa::Address; -use serde::{ser::SerializeStruct, Serialize}; - -pub const PUBLIC_SC_CONTEXT: &str = "PublicSCContext"; -pub const CALLER_ADDRESS: &str = "caller_address"; -pub const CALLER_BALANCE: &str = "caller_balance"; -pub const ACCOUNT_MASKS_KEYS_SORTED: &str = "account_masks_keys_sorted"; -pub const ACCOUNT_MASKS_VALUES_SORTED: &str = "account_masks_values_sorted"; -pub const COMMITMENT_STORE_ROOT: &str = "commitment_store_root"; -pub const PUT_TX_STORE_ROOT: &str = "put_tx_store_root"; -pub const COMMITMENT_TREE: &str = "commitments_tree"; -pub const NULLIFIERS_SET: &str = "nullifiers_set"; - -///Strucutre, representing context, given to a smart contract on a call -pub struct PublicSCContext { - pub caller_address: Address, - pub caller_balance: u64, - pub account_masks: BTreeMap, - pub comitment_store_root: TreeHashType, - pub commitments_tree: UTXOCommitmentsMerkleTree, -} - -impl Serialize for PublicSCContext { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut account_masks_keys: Vec<[u8; 32]> = self - .account_masks - .keys() - .cloned() - .map(|addr| *addr.value()) - .collect(); - account_masks_keys.sort(); - - let mut account_mask_values: Vec = - self.account_masks.values().cloned().collect(); - account_mask_values.sort_by(|left, right| left.address.cmp(&right.address)); - - let mut s = serializer.serialize_struct(PUBLIC_SC_CONTEXT, 7)?; - - s.serialize_field(CALLER_ADDRESS, &self.caller_address)?; - s.serialize_field(CALLER_BALANCE, &self.caller_balance)?; - s.serialize_field(ACCOUNT_MASKS_KEYS_SORTED, &account_masks_keys)?; - s.serialize_field(ACCOUNT_MASKS_VALUES_SORTED, &account_mask_values)?; - s.serialize_field(COMMITMENT_STORE_ROOT, &self.comitment_store_root)?; - s.serialize_field(COMMITMENT_TREE, &self.commitments_tree)?; - - s.end() - } -} - -impl PublicSCContext { - ///Produces `u64` from bytes in a vector - /// - /// Assumes, that vector of le_bytes - pub fn produce_u64_from_fit_vec(data: Vec) -> u64 { - let data_len = data.len(); - - assert!(data_len <= 8); - let mut le_bytes: [u8; 8] = [0; 8]; - - for (idx, item) in data.into_iter().enumerate() { - le_bytes[idx] = item - } - - u64::from_le_bytes(le_bytes) - } - - ///Produces vector of `u64` from context - pub fn produce_u64_list_from_context(&self) -> Result, serde_json::Error> { - let mut u64_list = vec![]; - - let ser_data = serde_json::to_vec(self)?; - - //`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust - for i in 0..=(ser_data.len() / 8) { - let next_chunk: Vec = if (i + 1) * 8 < ser_data.len() { - ser_data[(i * 8)..((i + 1) * 8)].to_vec() - } else { - ser_data[(i * 8)..(ser_data.len())].to_vec() - }; - - u64_list.push(PublicSCContext::produce_u64_from_fit_vec(next_chunk)); - } - - Ok(u64_list) - } -} - -#[cfg(test)] -mod tests { - use accounts::account_core::Account; - use common::utxo_commitment::UTXOCommitment; - - use super::*; - - fn create_test_context() -> PublicSCContext { - let caller_address = Address::new([1; 32]); - let comitment_store_root = [3; 32]; - - let commitments_tree = - UTXOCommitmentsMerkleTree::new(vec![UTXOCommitment { hash: [5; 32] }]); - - let mut account_masks = BTreeMap::new(); - - let acc_1 = Account::new(); - let acc_2 = Account::new(); - let acc_3 = Account::new(); - - account_masks.insert(acc_1.address, acc_1.make_account_public_mask()); - account_masks.insert(acc_2.address, acc_2.make_account_public_mask()); - account_masks.insert(acc_3.address, acc_3.make_account_public_mask()); - - PublicSCContext { - caller_address, - caller_balance: 100, - account_masks, - comitment_store_root, - commitments_tree, - } - } - - #[test] - fn bin_ser_stability_test() { - let test_context = create_test_context(); - - let serialization_1 = serde_json::to_vec(&test_context).unwrap(); - let serialization_2 = serde_json::to_vec(&test_context).unwrap(); - - assert_eq!(serialization_1, serialization_2); - } - - #[test] - fn correct_u64_production_from_fit_vec() { - let le_vec = vec![1, 1, 1, 1, 2, 1, 1, 1]; - - let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); - - assert_eq!(num, 72340177133043969); - } - - #[test] - fn correct_u64_production_from_small_vec() { - //7 items instead of 8 - let le_vec = vec![1, 1, 1, 1, 2, 1, 1]; - - let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); - - assert_eq!(num, 282583095116033); - } - - #[test] - fn correct_u64_production_from_small_vec_le_bytes() { - //7 items instead of 8 - let le_vec = vec![1, 1, 1, 1, 2, 1, 1]; - let le_vec_res = [1, 1, 1, 1, 2, 1, 1, 0]; - - let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); - - assert_eq!(num.to_le_bytes(), le_vec_res); - } - - #[test] - #[should_panic] - fn correct_u64_production_from_unfit_vec_should_panic() { - //9 items instead of 8 - let le_vec = vec![1, 1, 1, 1, 2, 1, 1, 1, 1]; - - PublicSCContext::produce_u64_from_fit_vec(le_vec); - } - - #[test] - fn consistent_len_of_context_commitments() { - let test_context = create_test_context(); - - let context_num_vec1 = test_context.produce_u64_list_from_context().unwrap(); - let context_num_vec2 = test_context.produce_u64_list_from_context().unwrap(); - - assert_eq!(context_num_vec1.len(), context_num_vec2.len()); - } -} diff --git a/sc_core/src/transaction_payloads_tools.rs b/sc_core/src/transaction_payloads_tools.rs deleted file mode 100644 index 543cfa8..0000000 --- a/sc_core/src/transaction_payloads_tools.rs +++ /dev/null @@ -1,100 +0,0 @@ -use accounts::{account_core::Account, key_management::ephemeral_key_holder::EphemeralKeyHolder}; -use anyhow::Result; -use common::transaction::{TransactionBody, TxKind}; -use rand::thread_rng; -use risc0_zkvm::Receipt; -use secp256k1_zkp::{CommitmentSecrets, PedersenCommitment, Tweak}; -use utxo::utxo_core::UTXO; - -use crate::proofs_circuits::{commit, generate_nullifiers, tag_random}; - -pub fn create_public_transaction_payload( - execution_input: Vec, - commitment: Vec, - tweak: Tweak, - secret_r: [u8; 32], - sc_addr: String, -) -> TransactionBody { - TransactionBody { - tx_kind: TxKind::Public, - execution_input, - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: vec![], - nullifier_created_hashes: vec![], - execution_proof_private: "".to_string(), - encoded_data: vec![], - ephemeral_pub_key: vec![], - commitment, - tweak, - secret_r, - sc_addr, - } -} - -pub fn encode_utxos_to_receivers( - utxos_receivers: Vec<(UTXO, &Account)>, -) -> Vec<(Vec, Vec)> { - let mut all_encoded_data = vec![]; - - for (utxo, receiver) in utxos_receivers { - let ephm_key_holder = EphemeralKeyHolder::new_os_random(); - - let encoded_data = Account::encrypt_data( - &ephm_key_holder, - receiver.key_holder.viewing_public_key, - &serde_json::to_vec(&utxo).unwrap(), - ); - - let encoded_data_vec = (encoded_data.0, encoded_data.1.to_vec()); - - all_encoded_data.push(encoded_data_vec); - } - - all_encoded_data -} - -pub fn generate_nullifiers_spent_utxos(utxos_spent: Vec<(UTXO, &Account)>) -> Vec> { - let mut all_nullifiers = vec![]; - - for (utxo, spender) in utxos_spent { - let nullifier = generate_nullifiers( - &utxo, - &spender - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key - .to_bytes(), - ); - - all_nullifiers.push(nullifier); - } - - all_nullifiers -} - -pub fn encode_receipt(receipt: Receipt) -> Result { - Ok(hex::encode(serde_json::to_vec(&receipt)?)) -} - -pub fn generate_secret_random_commitment( - value: u64, - account: &Account, -) -> Result { - let commitment_secrets = CommitmentSecrets { - value, - value_blinding_factor: Tweak::from_slice( - &account - .key_holder - .utxo_secret_key_holder - .viewing_secret_key - .to_bytes(), - )?, - generator_blinding_factor: Tweak::new(&mut thread_rng()), - }; - - let tag = tag_random(); - let commitment = commit(&commitment_secrets, tag); - - Ok(commitment) -} diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index a84229a..e5b01b7 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -23,9 +23,6 @@ hex.workspace = true actix-rt.workspace = true clap.workspace = true -[dependencies.sc_core] -path = "../sc_core" - [dependencies.accounts] path = "../accounts" diff --git a/wallet/src/chain_storage/mod.rs b/wallet/src/chain_storage/mod.rs index e9b466f..86bb37e 100644 --- a/wallet/src/chain_storage/mod.rs +++ b/wallet/src/chain_storage/mod.rs @@ -1,10 +1,9 @@ -use std::collections::{BTreeMap, HashMap}; +use std::collections::HashMap; use accounts::account_core::Account; use anyhow::Result; use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; use nssa::Address; -use sc_core::public_context::PublicSCContext; use serde::{Deserialize, Serialize}; use crate::config::WalletConfig; @@ -54,22 +53,6 @@ impl WalletChainStore { wallet_config: config, }) } - - pub fn produce_context(&self, caller: Address) -> PublicSCContext { - let mut account_masks = BTreeMap::new(); - - for (acc_addr, acc) in &self.acc_map { - account_masks.insert(*acc_addr, acc.make_account_public_mask()); - } - - PublicSCContext { - caller_address: caller, - caller_balance: self.acc_map.get(&caller).unwrap().balance, - account_masks, - comitment_store_root: self.utxo_commitments_store.get_root().unwrap_or([0; 32]), - commitments_tree: self.utxo_commitments_store.clone(), - } - } } #[cfg(test)] diff --git a/wallet/src/config.rs b/wallet/src/config.rs index 127bbf6..9e174f3 100644 --- a/wallet/src/config.rs +++ b/wallet/src/config.rs @@ -1,7 +1,6 @@ use std::path::PathBuf; use accounts::account_core::Account; -use nssa::gas_calculator::GasCalculator; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -22,20 +21,6 @@ pub struct GasConfig { pub gas_limit_runtime: u64, } -impl From for GasCalculator { - fn from(value: GasConfig) -> Self { - GasCalculator::new( - value.gas_fee_per_byte_deploy, - value.gas_fee_per_input_buffer_runtime, - value.gas_fee_per_byte_runtime, - value.gas_cost_runtime, - value.gas_cost_deploy, - value.gas_limit_deploy, - value.gas_limit_runtime, - ) - } -} - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WalletConfig { ///Home dir of sequencer storage diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index bfe9a95..3a3cca5 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -2,7 +2,7 @@ use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr}; use accounts::account_core::Account; use anyhow::Result; -use nssa::{address::HexString, Address}; +use nssa::Address; use crate::{config::WalletConfig, HOME_DIR_ENV_VAR}; @@ -22,7 +22,7 @@ pub fn fetch_config() -> Result { //ToDo: Replace with structures conversion in future pub fn produce_account_addr_from_hex(hex_str: String) -> Result
{ - Ok(HexString::try_from(hex_str.as_str())?.into()) + Ok(hex_str.parse()?) } ///Fetch list of accounts stored at `NSSA_WALLET_HOME_DIR/curr_accounts.json` diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index dc9c31e..40ee615 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -1,4 +1,4 @@ -use std::{fs::File, io::Write, path::PathBuf, sync::Arc}; +use std::sync::Arc; use common::{ sequencer_client::{json::SendTxResponse, SequencerClient}, @@ -15,7 +15,7 @@ use nssa::Address; use clap::{Parser, Subcommand}; use crate::helperfunctions::{ - fetch_config, fetch_persistent_accounts, get_home, produce_account_addr_from_hex, + fetch_config, fetch_persistent_accounts, produce_account_addr_from_hex, }; pub const HOME_DIR_ENV_VAR: &str = "NSSA_WALLET_HOME_DIR"; @@ -96,33 +96,6 @@ impl WalletCore { Err(ExecutionFailureKind::AmountMismatchError) } } - - ///Dumps all accounts from acc_map at `path` - /// - ///Currently storing everything in one file - /// - ///ToDo: extend storage - pub fn store_present_accounts_at_path(&self, path: PathBuf) -> Result { - let dump_path = path.join("curr_accounts.json"); - - let curr_accs: Vec = self.storage.acc_map.values().cloned().collect(); - let accs_serialized = serde_json::to_vec_pretty(&curr_accs)?; - - let mut acc_file = File::create(&dump_path).unwrap(); - acc_file.write_all(&accs_serialized).unwrap(); - - Ok(dump_path) - } - - ///Dumps all accounts from acc_map at `NSSA_WALLET_HOME_DIR` - /// - ///Currently storing everything in one file - /// - ///ToDo: extend storage - pub fn store_present_accounts_at_home(&self) -> Result { - let home = get_home()?; - self.store_present_accounts_at_path(home) - } } ///Represents CLI command for a wallet @@ -144,12 +117,6 @@ pub enum Command { #[arg(long)] amount: u128, }, - ///Dump accounts at destination - DumpAccountsOnDisc { - ///Dump path for accounts - #[arg(short, long)] - dump_path: PathBuf, - }, } ///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config @@ -183,19 +150,6 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { info!("Results of tx send is {res:#?}"); //ToDo: Insert transaction polling logic here - - let acc_storage_path = wallet_core.store_present_accounts_at_home()?; - - info!("Accounts stored at {acc_storage_path:#?}"); - } - Command::DumpAccountsOnDisc { dump_path } => { - let node_config = fetch_config()?; - - let wallet_core = WalletCore::start_from_config_update_chain(node_config).await?; - - wallet_core.store_present_accounts_at_path(dump_path.clone())?; - - info!("Accounts stored at path {dump_path:#?}"); } } From d2ab8dd4d43228e497ee22c12026828235ccd77b Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Tue, 19 Aug 2025 06:41:36 +0300 Subject: [PATCH 13/13] fix: comments fix --- nssa/src/address.rs | 15 --------------- sequencer_core/src/sequencer_store/mod.rs | 10 +--------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/nssa/src/address.rs b/nssa/src/address.rs index d54af10..93304d5 100644 --- a/nssa/src/address.rs +++ b/nssa/src/address.rs @@ -1,12 +1,9 @@ use std::{fmt::Display, str::FromStr}; -use anyhow::anyhow; use serde::{Deserialize, Serialize}; use crate::signature::PublicKey; -pub const LENGTH_MISMATCH_ERROR_MESSAGE: &str = "Slice length != 32 "; - #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct Address { value: [u8; 32], @@ -28,18 +25,6 @@ impl AsRef<[u8]> for Address { } } -impl TryFrom> for Address { - type Error = anyhow::Error; - - fn try_from(value: Vec) -> Result { - let addr_val: [u8; 32] = value - .try_into() - .map_err(|_| anyhow!(LENGTH_MISMATCH_ERROR_MESSAGE))?; - - Ok(Address::new(addr_val)) - } -} - impl From<&PublicKey> for Address { fn from(value: &PublicKey) -> Self { // TODO: Check specs diff --git a/sequencer_core/src/sequencer_store/mod.rs b/sequencer_core/src/sequencer_store/mod.rs index 3d9708d..4254ed7 100644 --- a/sequencer_core/src/sequencer_store/mod.rs +++ b/sequencer_core/src/sequencer_store/mod.rs @@ -23,15 +23,7 @@ impl SequecerChainStore { ) -> Self { let init_accs: Vec<(Address, u128)> = initial_accounts .iter() - .map(|acc_data| { - ( - hex::decode(acc_data.addr.clone()) - .unwrap() - .try_into() - .unwrap(), - acc_data.balance, - ) - }) + .map(|acc_data| (acc_data.addr.parse().unwrap(), acc_data.balance)) .collect(); let state = nssa::V01State::new_with_genesis_accounts(&init_accs);