From 6cada5bd099579a76a47d99137b3c846bb2bc712 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 13 Aug 2025 16:23:00 +0300 Subject: [PATCH 01/26] fix: nonces fix --- accounts/src/account_core/mod.rs | 8 -------- wallet/src/lib.rs | 12 +----------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs index f586019..1926649 100644 --- a/accounts/src/account_core/mod.rs +++ b/accounts/src/account_core/mod.rs @@ -25,7 +25,6 @@ pub struct Account { pub key_holder: AddressKeyHolder, pub address: AccountAddress, pub balance: u64, - pub nonce: u64, pub utxos: HashMap, } @@ -34,7 +33,6 @@ pub struct AccountForSerialization { pub key_holder: AddressKeyHolder, pub address: AccountAddress, pub balance: u64, - pub nonce: u64, pub utxos: HashMap, } @@ -44,7 +42,6 @@ impl From for AccountForSerialization { key_holder: value.key_holder, address: value.address, balance: value.balance, - nonce: value.nonce, utxos: value .utxos .into_iter() @@ -60,7 +57,6 @@ impl From for Account { key_holder: value.key_holder, address: value.address, balance: value.balance, - nonce: value.nonce, utxos: value .utxos .into_iter() @@ -124,14 +120,12 @@ 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, } } @@ -140,14 +134,12 @@ 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/wallet/src/lib.rs b/wallet/src/lib.rs index 9c17751..875da65 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -112,15 +112,6 @@ 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 @@ -198,7 +189,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) @@ -207,7 +198,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 0c7456d7a05897c2b16eaa037702627f5636e1bf Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 20 Aug 2025 17:16:51 +0300 Subject: [PATCH 02/26] fix: first batch of wallet methods --- common/src/sequencer_client/mod.rs | 19 ++++++++ key_protocol/src/key_management/mod.rs | 55 ----------------------- key_protocol/src/key_protocol_core/mod.rs | 27 +++++------ wallet/src/chain_storage/mod.rs | 27 ++++++----- wallet/src/helperfunctions.rs | 15 +++++++ wallet/src/lib.rs | 55 ++++++++++++++++++++--- 6 files changed, 109 insertions(+), 89 deletions(-) diff --git a/common/src/sequencer_client/mod.rs b/common/src/sequencer_client/mod.rs index a131033..196713f 100644 --- a/common/src/sequencer_client/mod.rs +++ b/common/src/sequencer_client/mod.rs @@ -7,6 +7,7 @@ use json::{SendTxRequest, SendTxResponse, SequencerRpcRequest, SequencerRpcRespo use reqwest::Client; use serde_json::Value; +use crate::rpc_primitives::requests::{GetTransactionByHashRequest, GetTransactionByHashResponse}; use crate::sequencer_client::json::AccountInitialData; use crate::{SequencerClientError, SequencerRpcError}; @@ -137,4 +138,22 @@ impl SequencerClient { Ok(resp_deser) } + + ///Get tx data for `tx_hash` from sequencer + pub async fn get_transaction_by_hash( + &self, + tx_hash: String, + ) -> Result { + let block_req = GetTransactionByHashRequest { hash: tx_hash }; + + let req = serde_json::to_value(block_req)?; + + let resp = self + .call_method_with_payload("get_transaction_by_hash", req) + .await?; + + let resp_deser = serde_json::from_value(resp)?; + + Ok(resp_deser) + } } diff --git a/key_protocol/src/key_management/mod.rs b/key_protocol/src/key_management/mod.rs index bc6d14c..5702b38 100644 --- a/key_protocol/src/key_management/mod.rs +++ b/key_protocol/src/key_management/mod.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit}; use constants_types::{CipherText, Nonce}; use elliptic_curve::point::AffineCoordinates; @@ -20,8 +18,6 @@ pub mod secret_holders; pub struct KeyChain { top_secret_key_holder: TopSecretKeyHolder, pub utxo_secret_key_holder: UTXOSecretKeyHolder, - ///Map for all users accounts - pub_account_signing_keys: HashMap, pub nullifer_public_key: PublicKey, pub viewing_public_key: PublicKey, } @@ -43,47 +39,9 @@ impl KeyChain { utxo_secret_key_holder, nullifer_public_key, viewing_public_key, - pub_account_signing_keys: HashMap::new(), } } - pub fn new_os_random_with_accounts(accounts: HashMap) -> Self { - //Currently dropping SeedHolder at the end of initialization. - //Now entirely sure if we need it in the future. - let seed_holder = SeedHolder::new_os_random(); - let top_secret_key_holder = seed_holder.produce_top_secret_key_holder(); - - let utxo_secret_key_holder = top_secret_key_holder.produce_utxo_secret_holder(); - - let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key(); - let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key(); - - Self { - top_secret_key_holder, - utxo_secret_key_holder, - nullifer_public_key, - viewing_public_key, - pub_account_signing_keys: accounts, - } - } - - pub fn generate_new_private_key(&mut self) -> nssa::Address { - let private_key = nssa::PrivateKey::new_os_random(); - let address = nssa::Address::from(&nssa::PublicKey::new_from_private_key(&private_key)); - - self.pub_account_signing_keys.insert(address, private_key); - - address - } - - /// Returns the signing key for public transaction signatures - pub fn get_pub_account_signing_key( - &self, - address: &nssa::Address, - ) -> Option<&nssa::PrivateKey> { - self.pub_account_signing_keys.get(address) - } - pub fn calculate_shared_secret_receiver( &self, ephemeral_public_key_sender: AffinePoint, @@ -341,19 +299,6 @@ mod tests { assert_eq!(decrypted_data, plaintext); } - #[test] - fn test_get_public_account_signing_key() { - let mut address_key_holder = KeyChain::new_os_random(); - - let address = address_key_holder.generate_new_private_key(); - - let is_private_key_generated = address_key_holder - .get_pub_account_signing_key(&address) - .is_some(); - - assert!(is_private_key_generated); - } - #[test] fn key_generation_test() { let seed_holder = SeedHolder::new_os_random(); diff --git a/key_protocol/src/key_protocol_core/mod.rs b/key_protocol/src/key_protocol_core/mod.rs index 3b8092e..5362095 100644 --- a/key_protocol/src/key_protocol_core/mod.rs +++ b/key_protocol/src/key_protocol_core/mod.rs @@ -15,7 +15,8 @@ pub type PublicKey = AffinePoint; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NSSAUserData { pub key_holder: KeyChain, - pub accounts: HashMap, + ///Map for all users accounts + pub accounts: HashMap, } ///A strucure, which represents all the visible(public) information @@ -56,21 +57,22 @@ impl NSSAUserData { } pub fn new_with_accounts( - accounts_keys: HashMap, - accounts: HashMap, + accounts_data: HashMap, ) -> Self { - let key_holder = KeyChain::new_os_random_with_accounts(accounts_keys); + let key_holder = KeyChain::new_os_random(); Self { key_holder, - accounts, + accounts: accounts_data, } } pub fn generate_new_account(&mut self) -> nssa::Address { - let address = self.key_holder.generate_new_private_key(); - self.accounts - .insert(address, nssa_core::account::Account::default()); + let private_key = nssa::PrivateKey::new_os_random(); + let address = nssa::Address::from(&nssa::PublicKey::new_from_private_key(&private_key)); + let account = nssa_core::account::Account::default(); + + self.accounts.insert(address, (private_key, account)); address } @@ -78,16 +80,16 @@ impl NSSAUserData { pub fn get_account_balance(&self, address: &nssa::Address) -> u128 { self.accounts .get(address) - .map(|acc| acc.balance) + .map(|(_, acc)| acc.balance) .unwrap_or(0) } pub fn get_account(&self, address: &nssa::Address) -> Option<&nssa_core::account::Account> { - self.accounts.get(address) + self.accounts.get(address).map(|(_, acc)| acc) } pub fn get_account_signing_key(&self, address: &nssa::Address) -> Option<&nssa::PrivateKey> { - self.key_holder.get_pub_account_signing_key(address) + self.accounts.get(address).map(|(key, _)| key) } pub fn encrypt_data( @@ -111,8 +113,7 @@ impl NSSAUserData { pub fn update_account_balance(&mut self, address: nssa::Address, new_balance: u128) { self.accounts .entry(address) - .and_modify(|acc| acc.balance = new_balance) - .or_default(); + .and_modify(|(_, acc)| acc.balance = new_balance); } //ToDo: Part of a private keys update diff --git a/wallet/src/chain_storage/mod.rs b/wallet/src/chain_storage/mod.rs index 40c9ddc..daa51bf 100644 --- a/wallet/src/chain_storage/mod.rs +++ b/wallet/src/chain_storage/mod.rs @@ -14,24 +14,23 @@ pub struct WalletChainStore { impl WalletChainStore { pub fn new(config: WalletConfig) -> Result { - let accounts: HashMap = config - .initial_accounts - .clone() - .into_iter() - .map(|init_acc_data| (init_acc_data.address, init_acc_data.account)) - .collect(); - - let accounts_keys: HashMap = config - .initial_accounts - .clone() - .into_iter() - .map(|init_acc_data| (init_acc_data.address, init_acc_data.pub_sign_key)) - .collect(); + let accounts_data: HashMap = + config + .initial_accounts + .clone() + .into_iter() + .map(|init_acc_data| { + ( + init_acc_data.address, + (init_acc_data.pub_sign_key, init_acc_data.account), + ) + }) + .collect(); let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); Ok(Self { - user_data: NSSAUserData::new_with_accounts(accounts_keys, accounts), + user_data: NSSAUserData::new_with_accounts(accounts_data), utxo_commitments_store, wallet_config: config, }) diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index 51b9d9d..e41c325 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::Result; +use key_protocol::key_protocol_core::NSSAUserData; use nssa::Address; use crate::{ @@ -47,3 +48,17 @@ pub fn fetch_persistent_accounts() -> Result> { }, } } + +pub fn produce_data_for_storage(user_data: &NSSAUserData) -> Vec { + let mut vec_for_storage = vec![]; + + for (addr, (key, account)) in &user_data.accounts { + vec_for_storage.push(InitialAccountData { + address: *addr, + account: account.clone(), + pub_sign_key: key.clone(), + }); + } + + vec_for_storage +} diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 2c4b711..c6d0704 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::{ sequencer_client::{json::SendTxResponse, SequencerClient}, @@ -14,7 +14,8 @@ use nssa::Address; use clap::{Parser, Subcommand}; use crate::helperfunctions::{ - fetch_config, fetch_persistent_accounts, produce_account_addr_from_hex, + fetch_config, fetch_persistent_accounts, get_home, produce_account_addr_from_hex, + produce_data_for_storage, }; pub const HOME_DIR_ENV_VAR: &str = "NSSA_WALLET_HOME_DIR"; @@ -35,6 +36,9 @@ impl WalletCore { let mut storage = WalletChainStore::new(config)?; + //Updating user data with stored accounts + //We do not store/update any key data connected to private executions + //ToDo: Add this into persistent data let persistent_accounts = fetch_persistent_accounts()?; for acc in persistent_accounts { storage @@ -48,7 +52,20 @@ impl WalletCore { }) } - pub async fn create_new_account(&mut self) -> Address { + pub fn store_persistent_accounts(&self) -> Result { + let home = get_home()?; + let accs_path = home.join("curr_accounts.json"); + let accs = serde_json::to_vec(&produce_data_for_storage(&self.storage.user_data))?; + + let mut accs_file = File::create(accs_path.as_path())?; + accs_file.write_all(&accs)?; + + info!("Stored accounts data at {accs_path:#?}"); + + Ok(accs_path) + } + + pub fn create_new_account(&mut self) -> Address { self.storage.user_data.generate_new_account() } @@ -114,6 +131,13 @@ pub enum Command { #[arg(long)] amount: u128, }, + ///Register new account + RegisterAccount {}, + ///Fetch transaction by `hash` + FetchTx { + #[arg(short, long)] + tx_hash: String, + }, } ///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config @@ -126,6 +150,9 @@ pub struct Args { } pub async fn execute_subcommand(command: Command) -> Result<()> { + let wallet_config = fetch_config()?; + let mut wallet_core = WalletCore::start_from_config_update_chain(wallet_config).await?; + match command { Command::SendNativeTokenTransfer { from, @@ -133,13 +160,9 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { to, amount, } => { - let wallet_config = fetch_config()?; - 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 res = wallet_core .send_public_native_token_transfer(from, nonce, to, amount) .await?; @@ -148,7 +171,25 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { //ToDo: Insert transaction polling logic here } + Command::RegisterAccount {} => { + let addr = wallet_core.create_new_account(); + + let key = wallet_core.storage.user_data.get_account_signing_key(&addr); + + info!("Generated new account with addr {addr:#?}"); + info!("With key {key:#?}"); + } + Command::FetchTx { tx_hash } => { + let tx_obj = wallet_core + .sequencer_client + .get_transaction_by_hash(tx_hash) + .await?; + + info!("Transaction object {tx_obj:#?}"); + } } + wallet_core.store_persistent_accounts()?; + Ok(()) } From 914cbfb9dc8361d7230f385d03c4065060115440 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 21 Aug 2025 15:58:31 +0300 Subject: [PATCH 03/26] fix: complete cli intefaces --- common/src/rpc_primitives/requests.rs | 12 +++++ common/src/sequencer_client/json.rs | 2 +- common/src/sequencer_client/mod.rs | 59 +++++++++++++++------- key_protocol/src/key_protocol_core/mod.rs | 6 +++ sequencer_rpc/src/process.rs | 43 ++++++++++++++-- wallet/Cargo.toml | 1 + wallet/src/chain_storage/mod.rs | 5 +- wallet/src/config.rs | 10 +++- wallet/src/lib.rs | 60 +++++++++++++++++++++-- wallet/src/poller.rs | 55 +++++++++++++++++++++ 10 files changed, 223 insertions(+), 30 deletions(-) create mode 100644 wallet/src/poller.rs diff --git a/common/src/rpc_primitives/requests.rs b/common/src/rpc_primitives/requests.rs index 2e67f16..674c077 100644 --- a/common/src/rpc_primitives/requests.rs +++ b/common/src/rpc_primitives/requests.rs @@ -43,6 +43,11 @@ pub struct GetTransactionByHashRequest { pub hash: String, } +#[derive(Serialize, Deserialize, Debug)] +pub struct GetAccountsNoncesRequest { + pub addresses: Vec, +} + parse_request!(HelloRequest); parse_request!(RegisterAccountRequest); parse_request!(SendTxRequest); @@ -52,6 +57,7 @@ parse_request!(GetLastBlockRequest); parse_request!(GetInitialTestnetAccountsRequest); parse_request!(GetAccountBalanceRequest); parse_request!(GetTransactionByHashRequest); +parse_request!(GetAccountsNoncesRequest); #[derive(Serialize, Deserialize, Debug)] pub struct HelloResponse { @@ -66,6 +72,7 @@ pub struct RegisterAccountResponse { #[derive(Serialize, Deserialize, Debug)] pub struct SendTxResponse { pub status: String, + pub tx_hash: String, } #[derive(Serialize, Deserialize, Debug)] @@ -88,6 +95,11 @@ pub struct GetAccountBalanceResponse { pub balance: u128, } +#[derive(Serialize, Deserialize, Debug)] +pub struct GetAccountsNoncesResponse { + pub nonces: Vec, +} + #[derive(Serialize, Deserialize, Debug)] pub struct GetTransactionByHashResponse { pub transaction: Option, diff --git a/common/src/sequencer_client/json.rs b/common/src/sequencer_client/json.rs index 71b1719..59895bf 100644 --- a/common/src/sequencer_client/json.rs +++ b/common/src/sequencer_client/json.rs @@ -12,7 +12,7 @@ pub struct SendTxRequest { #[derive(Serialize, Deserialize, Debug)] pub struct SendTxResponse { pub status: String, - pub additional_data: Option, + pub tx_hash: String, } //General diff --git a/common/src/sequencer_client/mod.rs b/common/src/sequencer_client/mod.rs index 196713f..ad66d82 100644 --- a/common/src/sequencer_client/mod.rs +++ b/common/src/sequencer_client/mod.rs @@ -7,7 +7,10 @@ use json::{SendTxRequest, SendTxResponse, SequencerRpcRequest, SequencerRpcRespo use reqwest::Client; use serde_json::Value; -use crate::rpc_primitives::requests::{GetTransactionByHashRequest, GetTransactionByHashResponse}; +use crate::rpc_primitives::requests::{ + GetAccountsNoncesRequest, GetAccountsNoncesResponse, GetTransactionByHashRequest, + GetTransactionByHashResponse, +}; use crate::sequencer_client::json::AccountInitialData; use crate::{SequencerClientError, SequencerRpcError}; @@ -87,6 +90,42 @@ impl SequencerClient { Ok(resp_deser) } + ///Get accounts nonces for `addresses`. `addresses` must be a list of valid hex-strings for 32 bytes. + pub async fn get_accounts_nonces( + &self, + addresses: Vec, + ) -> Result { + let block_req = GetAccountsNoncesRequest { addresses }; + + let req = serde_json::to_value(block_req)?; + + let resp = self + .call_method_with_payload("get_accounts_nonces", req) + .await?; + + let resp_deser = serde_json::from_value(resp)?; + + Ok(resp_deser) + } + + ///Get transaction details for `hash`. + pub async fn get_transaction_by_hash( + &self, + hash: String, + ) -> Result { + let block_req = GetTransactionByHashRequest { hash }; + + let req = serde_json::to_value(block_req)?; + + let resp = self + .call_method_with_payload("get_transaction_by_hash", req) + .await?; + + let resp_deser = serde_json::from_value(resp)?; + + Ok(resp_deser) + } + ///Send transaction to sequencer pub async fn send_tx( &self, @@ -138,22 +177,4 @@ impl SequencerClient { Ok(resp_deser) } - - ///Get tx data for `tx_hash` from sequencer - pub async fn get_transaction_by_hash( - &self, - tx_hash: String, - ) -> Result { - let block_req = GetTransactionByHashRequest { hash: tx_hash }; - - let req = serde_json::to_value(block_req)?; - - let resp = self - .call_method_with_payload("get_transaction_by_hash", req) - .await?; - - let resp_deser = serde_json::from_value(resp)?; - - Ok(resp_deser) - } } diff --git a/key_protocol/src/key_protocol_core/mod.rs b/key_protocol/src/key_protocol_core/mod.rs index 5362095..facc5a2 100644 --- a/key_protocol/src/key_protocol_core/mod.rs +++ b/key_protocol/src/key_protocol_core/mod.rs @@ -116,6 +116,12 @@ impl NSSAUserData { .and_modify(|(_, acc)| acc.balance = new_balance); } + pub fn increment_account_nonce(&mut self, address: nssa::Address) { + self.accounts + .entry(address) + .and_modify(|(_, acc)| acc.nonce += 1); + } + //ToDo: Part of a private keys update // pub fn make_tag(&self) -> Tag { // self.address.value()[0] diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index 2d5a29a..83f1e1c 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -12,7 +12,8 @@ use common::{ message::{Message, Request}, parser::RpcRequest, requests::{ - GetAccountBalanceRequest, GetAccountBalanceResponse, GetInitialTestnetAccountsRequest, + GetAccountBalanceRequest, GetAccountBalanceResponse, GetAccountsNoncesRequest, + GetAccountsNoncesResponse, GetInitialTestnetAccountsRequest, GetTransactionByHashRequest, GetTransactionByHashResponse, }, }, @@ -33,10 +34,11 @@ pub const GET_GENESIS: &str = "get_genesis"; pub const GET_LAST_BLOCK: &str = "get_last_block"; pub const GET_ACCOUNT_BALANCE: &str = "get_account_balance"; pub const GET_TRANSACTION_BY_HASH: &str = "get_transaction_by_hash"; +pub const GET_ACCOUNTS_NONCES: &str = "get_accounts_nonces"; pub const HELLO_FROM_SEQUENCER: &str = "HELLO_FROM_SEQUENCER"; -pub const SUCCESS: &str = "Success"; +pub const TRANSACTION_SUBMITTED: &str = "Transaction submitted"; pub const GET_INITIAL_TESTNET_ACCOUNTS: &str = "get_initial_testnet_accounts"; @@ -72,6 +74,7 @@ impl JsonHandler { let send_tx_req = SendTxRequest::parse(Some(request.params))?; let tx = nssa::PublicTransaction::from_bytes(&send_tx_req.transaction) .map_err(|e| RpcError::serialization_error(&e.to_string()))?; + let tx_hash = hex::encode(tx.hash()); { let mut state = self.sequencer_state.lock().await; @@ -80,7 +83,8 @@ impl JsonHandler { } let helperstruct = SendTxResponse { - status: SUCCESS.to_string(), + status: TRANSACTION_SUBMITTED.to_string(), + tx_hash, }; respond(helperstruct) @@ -171,6 +175,38 @@ impl JsonHandler { respond(helperstruct) } + /// Returns the nonces of the accounts at the given addresses. + /// Each address must be a valid hex string of the correct length. + async fn process_get_accounts_nonces(&self, request: Request) -> Result { + let get_account_nonces_req = GetAccountsNoncesRequest::parse(Some(request.params))?; + let mut addresses = vec![]; + for address_raw in get_account_nonces_req.addresses { + let address_bytes = hex::decode(address_raw) + .map_err(|_| RpcError::invalid_params("invalid hex".to_string()))?; + + let address = nssa::Address::new( + address_bytes + .try_into() + .map_err(|_| RpcError::invalid_params("invalid length".to_string()))?, + ); + + addresses.push(address); + } + + let nonces = { + let state = self.sequencer_state.lock().await; + + addresses + .into_iter() + .map(|addr| state.store.state.get_account_by_address(&addr).nonce) + .collect() + }; + + let helperstruct = GetAccountsNoncesResponse { nonces }; + + respond(helperstruct) + } + /// Returns the transaction corresponding to the given hash, if it exists in the blockchain. /// The hash must be a valid hex string of the correct length. async fn process_get_transaction_by_hash(&self, request: Request) -> Result { @@ -205,6 +241,7 @@ impl JsonHandler { GET_LAST_BLOCK => self.process_get_last_block(request).await, GET_INITIAL_TESTNET_ACCOUNTS => self.get_initial_testnet_accounts(request).await, GET_ACCOUNT_BALANCE => self.process_get_account_balance(request).await, + GET_ACCOUNTS_NONCES => self.process_get_accounts_nonces(request).await, GET_TRANSACTION_BY_HASH => self.process_get_transaction_by_hash(request).await, _ => Err(RpcErr(RpcError::method_not_found(request.method))), } diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index 4a67791..c3ddd3b 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -23,6 +23,7 @@ hex.workspace = true actix-rt.workspace = true clap.workspace = true nssa-core = { path = "../nssa/core" } +base64.workspace = true [dependencies.key_protocol] path = "../key_protocol" diff --git a/wallet/src/chain_storage/mod.rs b/wallet/src/chain_storage/mod.rs index daa51bf..16195f5 100644 --- a/wallet/src/chain_storage/mod.rs +++ b/wallet/src/chain_storage/mod.rs @@ -78,7 +78,10 @@ mod tests { home, override_rust_log: None, sequencer_addr: "http://127.0.0.1".to_string(), - seq_poll_timeout_secs: 1, + seq_poll_timeout_millis: 12000, + seq_poll_max_blocks: 5, + seq_poll_max_retries: 10, + seq_poll_retry_delay_millis: 500, initial_accounts: create_initial_accounts(), } } diff --git a/wallet/src/config.rs b/wallet/src/config.rs index 21bd912..e6737f9 100644 --- a/wallet/src/config.rs +++ b/wallet/src/config.rs @@ -34,8 +34,14 @@ pub struct WalletConfig { pub override_rust_log: Option, ///Sequencer URL pub sequencer_addr: String, - ///Sequencer polling duration for new blocks in seconds - pub seq_poll_timeout_secs: u64, + ///Sequencer polling duration for new blocks in milliseconds + pub seq_poll_timeout_millis: u64, + ///Sequencer polling max number of blocks + pub seq_poll_max_blocks: usize, + ///Sequencer polling max number error retries + pub seq_poll_max_retries: u64, + ///Sequencer polling error retry delay in milliseconds + pub seq_poll_retry_delay_millis: u64, ///Initial accounts for wallet pub initial_accounts: Vec, } diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index c6d0704..bc34e20 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -1,5 +1,6 @@ use std::{fs::File, io::Write, path::PathBuf, sync::Arc}; +use base64::Engine; use common::{ sequencer_client::{json::SendTxResponse, SequencerClient}, ExecutionFailureKind, @@ -13,9 +14,12 @@ use nssa::Address; use clap::{Parser, Subcommand}; -use crate::helperfunctions::{ - fetch_config, fetch_persistent_accounts, get_home, produce_account_addr_from_hex, - produce_data_for_storage, +use crate::{ + helperfunctions::{ + fetch_config, fetch_persistent_accounts, get_home, produce_account_addr_from_hex, + produce_data_for_storage, + }, + poller::TxPoller, }; pub const HOME_DIR_ENV_VAR: &str = "NSSA_WALLET_HOME_DIR"; @@ -24,15 +28,24 @@ pub const BLOCK_GEN_DELAY_SECS: u64 = 20; pub mod chain_storage; pub mod config; pub mod helperfunctions; +pub mod poller; pub struct WalletCore { pub storage: WalletChainStore, + pub poller: TxPoller, pub sequencer_client: Arc, } impl WalletCore { pub async fn start_from_config_update_chain(config: WalletConfig) -> Result { let client = Arc::new(SequencerClient::new(config.sequencer_addr.clone())?); + let tx_poller = TxPoller { + polling_delay_millis: config.seq_poll_timeout_millis, + polling_max_blocks_to_query: config.seq_poll_max_blocks, + polling_max_error_attempts: config.seq_poll_max_retries, + polling_error_delay_millis: config.seq_poll_retry_delay_millis, + client: client.clone(), + }; let mut storage = WalletChainStore::new(config)?; @@ -48,6 +61,7 @@ impl WalletCore { Ok(Self { storage, + poller: tx_poller, sequencer_client: client.clone(), }) } @@ -110,6 +124,38 @@ impl WalletCore { Err(ExecutionFailureKind::AmountMismatchError) } } + + pub async fn poll_public_native_token_transfer( + &self, + hash: String, + ) -> Result { + let transaction_encoded = self.poller.poll_tx(hash).await?; + let tx_base64_decode = + base64::engine::general_purpose::STANDARD.decode(transaction_encoded)?; + let pub_tx = nssa::PublicTransaction::from_bytes(&tx_base64_decode)?; + + Ok(pub_tx) + } + + pub fn execute_native_token_transfer( + &mut self, + from: Address, + to: Address, + balance_to_move: u128, + ) { + self.storage.user_data.increment_account_nonce(from); + self.storage.user_data.increment_account_nonce(to); + + let from_bal = self.storage.user_data.get_account_balance(&from); + let to_bal = self.storage.user_data.get_account_balance(&to); + + self.storage + .user_data + .update_account_balance(from, from_bal - balance_to_move); + self.storage + .user_data + .update_account_balance(to, to_bal + balance_to_move); + } } ///Represents CLI command for a wallet @@ -169,7 +215,13 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { info!("Results of tx send is {res:#?}"); - //ToDo: Insert transaction polling logic here + let transfer_tx = wallet_core + .poll_public_native_token_transfer(res.tx_hash) + .await?; + + info!("Transaction data is {transfer_tx:#?}"); + + wallet_core.execute_native_token_transfer(from, to, amount); } Command::RegisterAccount {} => { let addr = wallet_core.create_new_account(); diff --git a/wallet/src/poller.rs b/wallet/src/poller.rs new file mode 100644 index 0000000..ae0a793 --- /dev/null +++ b/wallet/src/poller.rs @@ -0,0 +1,55 @@ +use std::sync::Arc; + +use anyhow::Result; +use common::sequencer_client::SequencerClient; +use log::{info, warn}; + +#[derive(Clone)] +pub struct TxPoller { + pub polling_max_blocks_to_query: usize, + pub polling_max_error_attempts: u64, + pub polling_error_delay_millis: u64, + pub polling_delay_millis: u64, + pub client: Arc, +} + +impl TxPoller { + pub async fn poll_tx(&self, tx_hash: String) -> Result { + let max_blocks_to_query = self.polling_max_blocks_to_query; + + info!("Starting poll for transaction {tx_hash:#?}"); + for poll_id in 1..max_blocks_to_query { + info!("Poll {poll_id}"); + + let mut try_error_counter = 0; + + let tx_obj = loop { + let tx_obj = self + .client + .get_transaction_by_hash(tx_hash.clone()) + .await + .inspect_err(|err| { + warn!("Failed to get transaction by hash {tx_hash:#?} with error: {err:#?}") + }); + + if let Ok(tx_obj) = tx_obj { + break tx_obj; + } else { + try_error_counter += 1; + } + + if try_error_counter > self.polling_max_error_attempts { + anyhow::bail!("Number of retries exceeded"); + } + }; + + if tx_obj.transaction.is_some() { + return Ok(tx_obj.transaction.unwrap()); + } + + tokio::time::sleep(std::time::Duration::from_millis(self.polling_delay_millis)).await; + } + + anyhow::bail!("Transaction not found in preconfigured amount of blocks"); + } +} From 41af90e2ebf979ca8885fe5281bbab498781ad95 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Fri, 22 Aug 2025 15:58:43 +0300 Subject: [PATCH 04/26] fix: tests addded-fixed --- .../configs/debug/wallet/wallet_config.json | 5 +- integration_tests/src/lib.rs | 51 +++++++++++++++---- sequencer_core/src/lib.rs | 10 +++- sequencer_rpc/src/process.rs | 48 +++++++++++++++++ wallet/src/chain_storage/mod.rs | 8 ++- wallet/src/helperfunctions.rs | 1 + wallet/src/lib.rs | 13 +++-- wallet/src/poller.rs | 1 + 8 files changed, 117 insertions(+), 20 deletions(-) diff --git a/integration_tests/configs/debug/wallet/wallet_config.json b/integration_tests/configs/debug/wallet/wallet_config.json index d888119..e1edc05 100644 --- a/integration_tests/configs/debug/wallet/wallet_config.json +++ b/integration_tests/configs/debug/wallet/wallet_config.json @@ -2,7 +2,10 @@ "home": "./node", "override_rust_log": null, "sequencer_addr": "http://127.0.0.1:3040", - "seq_poll_timeout_secs": 10, + "seq_poll_timeout_millis": 12000, + "seq_poll_max_blocks": 5, + "seq_poll_max_retries": 5, + "seq_poll_retry_delay_millis": 500, "initial_accounts": [ { "address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index 812e44f..b6bf8a6 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -4,12 +4,15 @@ use actix_web::dev::ServerHandle; use anyhow::Result; use clap::Parser; use common::sequencer_client::SequencerClient; -use log::info; +use log::{info, warn}; use sequencer_core::config::SequencerConfig; use sequencer_runner::startup_sequencer; use tempfile::TempDir; use tokio::task::JoinHandle; -use wallet::{Command, helperfunctions::fetch_config}; +use wallet::{ + Command, + helperfunctions::{fetch_config, fetch_persistent_accounts}, +}; #[derive(Parser, Debug)] #[clap(version)] @@ -66,6 +69,14 @@ pub async fn post_test(residual: (ServerHandle, JoinHandle>, TempDir) sequencer_loop_handle.abort(); seq_http_server_handle.stop(true).await; + let wallet_home = wallet::helperfunctions::get_home().unwrap(); + let persistent_data_home = wallet_home.join("curr_accounts.json"); + + //Removing persistent accounts after run to not affect other executions + //Not necessary an error, if fails as there is tests for failure scenario + let _ = std::fs::remove_file(persistent_data_home) + .inspect_err(|err| warn!("Failed to remove persistent data with err {err:#?}")); + //At this point all of the references to sequencer_core must be lost. //So they are dropped and tempdirs will be dropped too, } @@ -107,14 +118,7 @@ pub async fn test_success() { } pub async fn test_success_move_to_another_account() { - let hex_acc_receiver_new_acc = hex::encode([42; 32]); - - let command = Command::SendNativeTokenTransfer { - from: ACC_SENDER.to_string(), - nonce: 0, - to: hex_acc_receiver_new_acc.clone(), - amount: 100, - }; + let command = Command::RegisterAccount {}; let wallet_config = fetch_config().unwrap(); @@ -122,6 +126,31 @@ pub async fn test_success_move_to_another_account() { wallet::execute_subcommand(command).await.unwrap(); + let persistent_accounts = fetch_persistent_accounts().unwrap(); + + let mut new_persistent_account_addr = String::new(); + + for per_acc in persistent_accounts { + if (per_acc.address.to_string() != ACC_RECEIVER) + && (per_acc.address.to_string() != ACC_SENDER) + { + new_persistent_account_addr = per_acc.address.to_string(); + } + } + + if new_persistent_account_addr == String::new() { + panic!("Failed to produce new account, not present in persistent accounts"); + } + + let command = Command::SendNativeTokenTransfer { + from: ACC_SENDER.to_string(), + nonce: 0, + to: new_persistent_account_addr.clone(), + 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; @@ -131,7 +160,7 @@ pub async fn test_success_move_to_another_account() { .await .unwrap(); let acc_2_balance = seq_client - .get_account_balance(hex_acc_receiver_new_acc) + .get_account_balance(new_persistent_account_addr) .await .unwrap(); diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index b56b34cc..2137c8b 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -3,6 +3,7 @@ use std::fmt::Display; use anyhow::Result; use common::{block::HashableBlockData, merkle_tree_public::TreeHashType}; use config::SequencerConfig; +use log::warn; use mempool::MemPool; use sequencer_store::SequecerChainStore; use serde::{Deserialize, Serialize}; @@ -78,7 +79,9 @@ impl SequencerCore { return Err(TransactionMalformationErrorKind::MempoolFullForRound); } - let authenticated_tx = self.transaction_pre_check(transaction)?; + let authenticated_tx = self + .transaction_pre_check(transaction) + .inspect_err(|err| warn!("Error at pre_check {err:#?}"))?; self.mempool.push_item(authenticated_tx); @@ -89,7 +92,10 @@ impl SequencerCore { &mut self, tx: nssa::PublicTransaction, ) -> Result { - self.store.state.transition_from_public_transaction(&tx)?; + self.store + .state + .transition_from_public_transaction(&tx) + .inspect_err(|err| warn!("Error at transition {err:#?}"))?; Ok(tx) } diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index 83f1e1c..d994210 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -457,6 +457,54 @@ mod tests { assert_eq!(response, expected_response); } + #[actix_web::test] + async fn test_get_accounts_nonces_for_non_existent_account() { + let (json_handler, _, _) = components_for_tests(); + let request = serde_json::json!({ + "jsonrpc": "2.0", + "method": "get_accounts_nonces", + "params": { "addresses": ["efac".repeat(16)] }, + "id": 1 + }); + let expected_response = serde_json::json!({ + "id": 1, + "jsonrpc": "2.0", + "result": { + "nonces": [ 0 ] + } + }); + + let response = call_rpc_handler_with_json(json_handler, request).await; + + assert_eq!(response, expected_response); + } + + #[actix_web::test] + async fn test_get_accounts_nonces_for_existent_account() { + let (json_handler, initial_accounts, _) = components_for_tests(); + + let acc_1_addr = initial_accounts[0].addr.clone(); + let acc_2_addr = initial_accounts[1].addr.clone(); + + let request = serde_json::json!({ + "jsonrpc": "2.0", + "method": "get_accounts_nonces", + "params": { "addresses": [acc_1_addr, acc_2_addr] }, + "id": 1 + }); + let expected_response = serde_json::json!({ + "id": 1, + "jsonrpc": "2.0", + "result": { + "nonces": [ 1, 0 ] + } + }); + + let response = call_rpc_handler_with_json(json_handler, request).await; + + assert_eq!(response, expected_response); + } + #[actix_web::test] async fn test_get_transaction_by_hash_for_non_existent_hash() { let (json_handler, _, _) = components_for_tests(); diff --git a/wallet/src/chain_storage/mod.rs b/wallet/src/chain_storage/mod.rs index 16195f5..a6b59ce 100644 --- a/wallet/src/chain_storage/mod.rs +++ b/wallet/src/chain_storage/mod.rs @@ -4,7 +4,7 @@ use anyhow::Result; use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; use key_protocol::key_protocol_core::NSSAUserData; -use crate::config::WalletConfig; +use crate::config::{InitialAccountData, WalletConfig}; pub struct WalletChainStore { pub user_data: NSSAUserData, @@ -35,6 +35,12 @@ impl WalletChainStore { wallet_config: config, }) } + + pub(crate) fn insert_account_data(&mut self, acc_data: InitialAccountData) { + self.user_data + .accounts + .insert(acc_data.address, (acc_data.pub_sign_key, acc_data.account)); + } } #[cfg(test)] diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index e41c325..ad89491 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -49,6 +49,7 @@ pub fn fetch_persistent_accounts() -> Result> { } } +///Produces a list of accounts for storage pub fn produce_data_for_storage(user_data: &NSSAUserData) -> Vec { let mut vec_for_storage = vec![]; diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index bc34e20..336e195 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -54,9 +54,7 @@ impl WalletCore { //ToDo: Add this into persistent data let persistent_accounts = fetch_persistent_accounts()?; for acc in persistent_accounts { - storage - .user_data - .update_account_balance(acc.address, acc.account.balance); + storage.insert_account_data(acc); } Ok(Self { @@ -66,10 +64,13 @@ impl WalletCore { }) } + ///Stre persistent accounts at home pub fn store_persistent_accounts(&self) -> Result { let home = get_home()?; let accs_path = home.join("curr_accounts.json"); - let accs = serde_json::to_vec(&produce_data_for_storage(&self.storage.user_data))?; + + let data = produce_data_for_storage(&self.storage.user_data); + let accs = serde_json::to_vec_pretty(&data)?; let mut accs_file = File::create(accs_path.as_path())?; accs_file.write_all(&accs)?; @@ -125,6 +126,7 @@ impl WalletCore { } } + ///Poll transactions pub async fn poll_public_native_token_transfer( &self, hash: String, @@ -137,6 +139,7 @@ impl WalletCore { Ok(pub_tx) } + ///Execute native token transfer at wallet accounts pub fn execute_native_token_transfer( &mut self, from: Address, @@ -219,7 +222,7 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { .poll_public_native_token_transfer(res.tx_hash) .await?; - info!("Transaction data is {transfer_tx:#?}"); + info!("Transaction data is {transfer_tx:?}"); wallet_core.execute_native_token_transfer(from, to, amount); } diff --git a/wallet/src/poller.rs b/wallet/src/poller.rs index ae0a793..8fd219f 100644 --- a/wallet/src/poller.rs +++ b/wallet/src/poller.rs @@ -5,6 +5,7 @@ use common::sequencer_client::SequencerClient; use log::{info, warn}; #[derive(Clone)] +///Helperstruct to poll transactions pub struct TxPoller { pub polling_max_blocks_to_query: usize, pub polling_max_error_attempts: u64, From fedf63b75992347b46024050b74d87ed0e2a9961 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Fri, 22 Aug 2025 16:36:38 +0300 Subject: [PATCH 05/26] fix: risk0 bump --- nssa/Cargo.toml | 2 +- nssa/core/Cargo.toml | 2 +- nssa/program_methods/Cargo.toml | 2 +- nssa/program_methods/guest/Cargo.lock | 692 +++++++++++++++------ nssa/program_methods/guest/Cargo.toml | 2 +- nssa/test_program_methods/Cargo.toml | 2 +- nssa/test_program_methods/guest/Cargo.toml | 2 +- wallet/Cargo.toml | 2 +- 8 files changed, 520 insertions(+), 186 deletions(-) diff --git a/nssa/Cargo.toml b/nssa/Cargo.toml index 5a579fd..87a0c4e 100644 --- a/nssa/Cargo.toml +++ b/nssa/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] thiserror = "2.0.12" -risc0-zkvm = "2.3.1" +risc0-zkvm = "3.0.1" nssa-core = { path = "core" } program-methods = { path = "program_methods" } serde = "1.0.219" diff --git a/nssa/core/Cargo.toml b/nssa/core/Cargo.toml index feb907d..121e60b 100644 --- a/nssa/core/Cargo.toml +++ b/nssa/core/Cargo.toml @@ -4,5 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] -risc0-zkvm = "2.3.1" +risc0-zkvm = "3.0.1" serde = { version = "1.0", default-features = false } diff --git a/nssa/program_methods/Cargo.toml b/nssa/program_methods/Cargo.toml index ea7e36b..76a62ee 100644 --- a/nssa/program_methods/Cargo.toml +++ b/nssa/program_methods/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [build-dependencies] -risc0-build = { version = "2.3.1" } +risc0-build = { version = "3.0.1" } [package.metadata.risc0] methods = ["guest"] diff --git a/nssa/program_methods/guest/Cargo.lock b/nssa/program_methods/guest/Cargo.lock index 1d3063f..f9df542 100644 --- a/nssa/program_methods/guest/Cargo.lock +++ b/nssa/program_methods/guest/Cargo.lock @@ -44,6 +44,21 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" version = "1.0.98" @@ -303,6 +318,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + [[package]] name = "bincode" version = "1.3.3" @@ -356,15 +377,15 @@ dependencies = [ [[package]] name = "bonsai-sdk" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bce8d6acc5286a16e94c29e9c885d1869358885e08a6feeb6bc54e36fe20055" +checksum = "21055e2f49cbbdbfe9f8f96d597c5527b0c6ab7933341fdc2f147180e48a988e" dependencies = [ "duplicate", "maybe-async", "reqwest", "serde", - "thiserror 1.0.69", + "thiserror", ] [[package]] @@ -460,7 +481,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -484,13 +505,26 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + [[package]] name = "cobs" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -580,6 +614,27 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "derivative" version = "2.2.0" @@ -657,23 +712,23 @@ dependencies = [ [[package]] name = "dirs" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.48.0", + "windows-sys 0.60.2", ] [[package]] @@ -701,14 +756,21 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "duplicate" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de78e66ac9061e030587b2a2e75cc88f22304913c907b11307bca737141230cb" +checksum = "97af9b5f014e228b33e77d75ee0e6e87960124f0f4b16337b586a6bec91867b1" dependencies = [ - "heck 0.4.1", - "proc-macro-error", + "heck", + "proc-macro2", + "proc-macro2-diagnostics", ] +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "educe" version = "0.6.0" @@ -802,6 +864,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.5.0" @@ -945,12 +1013,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", -] +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" @@ -959,23 +1024,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ "allocator-api2", + "foldhash", ] [[package]] name = "hashlink" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.15.4", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -1094,6 +1154,30 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icu_collections" version = "2.0.0" @@ -1213,6 +1297,17 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee796ad498c8d9a1d68e477df8f754ed784ef875de1414ebdaf169f70a6a784" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.10.0" @@ -1221,6 +1316,7 @@ checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown 0.15.4", + "serde", ] [[package]] @@ -1459,6 +1555,29 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" version = "0.1.46" @@ -1468,6 +1587,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1475,6 +1605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1513,6 +1644,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1531,6 +1671,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "postcard" version = "1.1.3" @@ -1552,6 +1713,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1570,30 +1737,6 @@ dependencies = [ "toml_edit", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.95" @@ -1603,6 +1746,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "version_check", + "yansi", +] + [[package]] name = "programs" version = "0.1.0" @@ -1611,6 +1767,20 @@ dependencies = [ "risc0-zkvm", ] +[[package]] +name = "proptest" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" +dependencies = [ + "bitflags 2.9.1", + "num-traits", + "rand 0.9.2", + "rand_chacha 0.9.0", + "rand_xorshift", + "unarray", +] + [[package]] name = "prost" version = "0.13.5" @@ -1648,7 +1818,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2 0.5.10", - "thiserror 2.0.12", + "thiserror", "tokio", "tracing", "web-time", @@ -1669,7 +1839,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.12", + "thiserror", "tinyvec", "tracing", "web-time", @@ -1749,6 +1919,9 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] [[package]] name = "rand_core" @@ -1760,14 +1933,43 @@ dependencies = [ ] [[package]] -name = "redox_users" -version = "0.4.6" +name = "rand_xorshift" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 1.0.69", + "thiserror", +] + +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", ] [[package]] @@ -1857,18 +2059,21 @@ dependencies = [ [[package]] name = "risc0-binfmt" -version = "2.0.2" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62eb7025356a233c1bc267c458a2ce56fcfc89b136d813c8a77be14ef1eaf2b1" +checksum = "e2af322c052ae9973054f67434bc953eae44dbac68054d304b46848634d2a45d" dependencies = [ "anyhow", "borsh", + "bytemuck", "derive_more", "elf", "lazy_static", "postcard", + "rand 0.9.2", "risc0-zkp", "risc0-zkvm-platform", + "ruint", "semver", "serde", "tracing", @@ -1876,9 +2081,9 @@ dependencies = [ [[package]] name = "risc0-build" -version = "2.3.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ffc0f135e6c1e9851e7e19438d03ff41a9d49199ee4f6c17b8bb30b4f83910" +checksum = "b042a8a6fdd02793c0acb526fbd3f0d92abe664f1158be38d45a92def57385b2" dependencies = [ "anyhow", "cargo_metadata", @@ -1900,9 +2105,9 @@ dependencies = [ [[package]] name = "risc0-circuit-keccak" -version = "3.0.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0094af5a57b020388a03bdd3834959c7d62723f1687be81414ade25104d93263" +checksum = "966ba960d718123e16c603d6919a0c5d7cd2f872d428639ab5650108520f133a" dependencies = [ "anyhow", "bytemuck", @@ -1916,9 +2121,9 @@ dependencies = [ [[package]] name = "risc0-circuit-recursion" -version = "3.0.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ebded45c902c2b6939924a1cddd1d06b5d1d4ad1531e8798ebfee78f9c038d" +checksum = "30f6afac63cfd291aaa7f40edf976db5452698e66cd79f16ccbf7c0eb5a5d94e" dependencies = [ "anyhow", "bytemuck", @@ -1931,9 +2136,9 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im" -version = "3.0.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15030849f8356f01f23c74b37dbfa4283100b594eb634109993e9e005ef45f64" +checksum = "8fdd0865593941a6800c65a7c3b48be8700f73eb597681f6f594c7465839ce8a" dependencies = [ "anyhow", "bit-vec", @@ -1949,24 +2154,24 @@ dependencies = [ [[package]] name = "risc0-core" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317bbf70a8750b64d4fd7a2bdc9d7d5f30d8bb305cae486962c797ef35c8d08e" +checksum = "80f2723fedace48c6c5a505bd8f97ac4e1712bc4cb769083e10536d862b66987" dependencies = [ "bytemuck", - "bytemuck_derive", - "rand_core 0.6.4", + "rand_core 0.9.3", ] [[package]] name = "risc0-groth16" -version = "2.0.2" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cf5d0b673d5fc67a89147c2e9c53134707dcc8137a43d1ef06b4ff68e99b74f" +checksum = "b68a622c69d0b97f511ee43db1d7f7f00b4dacead9c8aceae03fc5383f4764c1" dependencies = [ "anyhow", "ark-bn254", "ark-ec", + "ark-ff", "ark-groth16", "ark-serialize", "bytemuck", @@ -1976,14 +2181,13 @@ dependencies = [ "risc0-binfmt", "risc0-zkp", "serde", - "stability", ] [[package]] name = "risc0-zkos-v1compat" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f76c479b69d1987cb54ac72dcc017197296fdcd6daf78fafc10cbbd3a167a7de" +checksum = "328c9f0ec5f6eb8b7624347b5dcf82729f304adbc364399825f3ab6f8588189c" dependencies = [ "include_bytes_aligned", "no_std_strings", @@ -1991,9 +2195,9 @@ dependencies = [ [[package]] name = "risc0-zkp" -version = "2.0.2" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a287e9cd6d7b3b38eeb49c62090c46a1935922309fbd997a9143ed8c43c8f3cb" +checksum = "2c246f34b86a165308e37a064afa86e66ee7b8525f02bcf03f2124aaeedba04f" dependencies = [ "anyhow", "blake2", @@ -2005,7 +2209,7 @@ dependencies = [ "hex-literal", "metal", "paste", - "rand_core 0.6.4", + "rand_core 0.9.3", "risc0-core", "risc0-zkvm-platform", "serde", @@ -2016,9 +2220,9 @@ dependencies = [ [[package]] name = "risc0-zkvm" -version = "2.3.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9684b333c1c5d83f29ce2a92314ccfafd9d8cdfa6c4e19c07b97015d2f1eb9d0" +checksum = "0fdf8d11f9e61cfd3e577fb6e6e11cc34ca247831c2555ee0a6a53deba9702d2" dependencies = [ "anyhow", "bincode", @@ -2027,7 +2231,6 @@ dependencies = [ "bytemuck", "bytes", "derive_more", - "getrandom 0.2.16", "hex", "lazy-regex", "prost", @@ -2053,9 +2256,9 @@ dependencies = [ [[package]] name = "risc0-zkvm-platform" -version = "2.0.3" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cae9cb2c2f6cab2dfa395ea6e2576713929040c7fb0c5f4150d13e1119d18686" +checksum = "06fc0e464f4ac44c3f1fd17b479e09e3ccbd1c40219837d750580b03030dca60" dependencies = [ "bytemuck", "cfg-if", @@ -2075,6 +2278,48 @@ dependencies = [ "paste", ] +[[package]] +name = "rsa" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "ruint" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecb38f82477f20c5c3d62ef52d7c4e536e38ea9b73fb570a20c5cae0e14bcf6" +dependencies = [ + "borsh", + "proptest", + "rand 0.8.5", + "rand 0.9.2", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rustc-demangle" version = "0.1.26" @@ -2149,19 +2394,47 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "rzup" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "400558bf12d4292a7804093b60a437ba8b0219ea7d53716b2c010a0d31e5f4a8" +checksum = "76c6dfdbd72b2b0a537ad1e6256a3ce493ac87b9e89815465e393ee6595968e2" dependencies = [ + "hex", + "rsa", "semver", "serde", + "serde_with", + "sha2", "strum", "tempfile", - "thiserror 2.0.12", + "thiserror", "toml", "yaml-rust2", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "semver" version = "1.0.26" @@ -2224,6 +2497,38 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.10.0", + "schemars 0.9.0", + "schemars 1.0.4", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "sha2" version = "0.10.9" @@ -2241,6 +2546,16 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "slab" version = "0.4.10" @@ -2279,6 +2594,16 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stability" version = "0.2.1" @@ -2303,23 +2628,22 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.26.3" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.26.4" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "rustversion", "syn 2.0.104", ] @@ -2384,33 +2708,13 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - [[package]] name = "thiserror" version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.12", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", + "thiserror-impl", ] [[package]] @@ -2424,6 +2728,37 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.8.1" @@ -2516,7 +2851,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap", + "indexmap 2.10.0", "serde", "serde_spanned", "toml_datetime", @@ -2629,6 +2964,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-ident" version = "1.0.18" @@ -2813,6 +3154,41 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "windows-link" version = "0.1.3" @@ -2820,12 +3196,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-result" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-targets 0.48.5", + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", ] [[package]] @@ -2855,21 +3240,6 @@ dependencies = [ "windows-targets 0.53.3", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -2903,12 +3273,6 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -2921,12 +3285,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -2939,12 +3297,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -2969,12 +3321,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -2987,12 +3333,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -3005,12 +3345,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -3023,12 +3357,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -3067,15 +3395,21 @@ checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "yaml-rust2" -version = "0.9.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1a1c0bc9823338a3bdf8c61f994f23ac004c6fa32c08cd152984499b445e8d" +checksum = "4ce2a4ff45552406d02501cea6c18d8a7e50228e7736a872951fe2fe75c91be7" dependencies = [ "arraydeque", "encoding_rs", "hashlink", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yoke" version = "0.8.0" diff --git a/nssa/program_methods/guest/Cargo.toml b/nssa/program_methods/guest/Cargo.toml index 4b377c8..b5336d6 100644 --- a/nssa/program_methods/guest/Cargo.toml +++ b/nssa/program_methods/guest/Cargo.toml @@ -6,5 +6,5 @@ edition = "2021" [workspace] [dependencies] -risc0-zkvm = { version = "2.3.1", default-features = false, features = ['std'] } +risc0-zkvm = { version = "3.0.1", default-features = false, features = ['std'] } nssa-core = { path = "../../core" } diff --git a/nssa/test_program_methods/Cargo.toml b/nssa/test_program_methods/Cargo.toml index dded508..ed5d215 100644 --- a/nssa/test_program_methods/Cargo.toml +++ b/nssa/test_program_methods/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [build-dependencies] -risc0-build = { version = "2.3.1" } +risc0-build = { version = "3.0.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 4b377c8..b5336d6 100644 --- a/nssa/test_program_methods/guest/Cargo.toml +++ b/nssa/test_program_methods/guest/Cargo.toml @@ -6,5 +6,5 @@ edition = "2021" [workspace] [dependencies] -risc0-zkvm = { version = "2.3.1", default-features = false, features = ['std'] } +risc0-zkvm = { version = "3.0.1", default-features = false, features = ['std'] } nssa-core = { path = "../../core" } diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index c3ddd3b..4cad557 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -18,7 +18,7 @@ reqwest.workspace = true thiserror.workspace = true tokio.workspace = true tempfile.workspace = true -risc0-zkvm = "2.3.1" +risc0-zkvm = "3.0.1" hex.workspace = true actix-rt.workspace = true clap.workspace = true From ab35d37766195cbf387bde57e33ce7a0d970b1a3 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Tue, 26 Aug 2025 09:16:46 +0300 Subject: [PATCH 06/26] fix: suggestions fix --- wallet/src/helperfunctions.rs | 16 ++++++++++++++++ wallet/src/lib.rs | 1 - 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index ad89491..db6b10f 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -63,3 +63,19 @@ pub fn produce_data_for_storage(user_data: &NSSAUserData) -> Vec Date: Tue, 2 Sep 2025 09:01:33 +0300 Subject: [PATCH 07/26] fix: update to pr 104 --- ci_scripts/test-ubuntu.sh | 1 + common/src/lib.rs | 2 + integration_tests/src/lib.rs | 5 - key_protocol/src/key_management/mod.rs | 42 +++++++ key_protocol/src/key_protocol_core/mod.rs | 2 +- wallet/src/chain_storage/mod.rs | 9 +- wallet/src/config.rs | 6 + wallet/src/helperfunctions.rs | 11 +- wallet/src/lib.rs | 134 ++++++++++++---------- 9 files changed, 137 insertions(+), 75 deletions(-) diff --git a/ci_scripts/test-ubuntu.sh b/ci_scripts/test-ubuntu.sh index db14402..0d22626 100644 --- a/ci_scripts/test-ubuntu.sh +++ b/ci_scripts/test-ubuntu.sh @@ -7,4 +7,5 @@ source env.sh cargo test --release cd integration_tests export NSSA_WALLET_HOME_DIR=$(pwd)/configs/debug/wallet/ +export RUST_LOG=info cargo run $(pwd)/configs/debug all \ No newline at end of file diff --git a/common/src/lib.rs b/common/src/lib.rs index 01ae261..3b2ddff 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -66,6 +66,8 @@ pub enum ExecutionFailureKind { ProveError(anyhow::Error), #[error("Failed to decode data from VM: {0:?}")] DecodeError(String), + #[error("Failed to get account data from sequencer")] + SequencerError, #[error("Inputs amounts does not match outputs")] AmountMismatchError, #[error("Accounts key not found")] diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index b6bf8a6..9b7b970 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -84,7 +84,6 @@ pub async fn post_test(residual: (ServerHandle, JoinHandle>, TempDir) pub async fn test_success() { let command = Command::SendNativeTokenTransfer { from: ACC_SENDER.to_string(), - nonce: 0, to: ACC_RECEIVER.to_string(), amount: 100, }; @@ -144,7 +143,6 @@ pub async fn test_success_move_to_another_account() { let command = Command::SendNativeTokenTransfer { from: ACC_SENDER.to_string(), - nonce: 0, to: new_persistent_account_addr.clone(), amount: 100, }; @@ -176,7 +174,6 @@ pub async fn test_success_move_to_another_account() { pub async fn test_failure() { let command = Command::SendNativeTokenTransfer { from: ACC_SENDER.to_string(), - nonce: 0, to: ACC_RECEIVER.to_string(), amount: 1000000, }; @@ -214,7 +211,6 @@ pub async fn test_failure() { 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, }; @@ -248,7 +244,6 @@ pub async fn test_success_two_transactions() { let command = Command::SendNativeTokenTransfer { from: ACC_SENDER.to_string(), - nonce: 1, to: ACC_RECEIVER.to_string(), amount: 100, }; diff --git a/key_protocol/src/key_management/mod.rs b/key_protocol/src/key_management/mod.rs index 5702b38..2c38375 100644 --- a/key_protocol/src/key_management/mod.rs +++ b/key_protocol/src/key_management/mod.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit}; use constants_types::{CipherText, Nonce}; use elliptic_curve::point::AffineCoordinates; @@ -18,6 +20,8 @@ pub mod secret_holders; pub struct KeyChain { top_secret_key_holder: TopSecretKeyHolder, pub utxo_secret_key_holder: UTXOSecretKeyHolder, + ///Map for all users accounts + pub pub_account_signing_keys: HashMap, pub nullifer_public_key: PublicKey, pub viewing_public_key: PublicKey, } @@ -39,9 +43,47 @@ impl KeyChain { utxo_secret_key_holder, nullifer_public_key, viewing_public_key, + pub_account_signing_keys: HashMap::new(), } } + pub fn new_os_random_with_accounts(accounts: HashMap) -> Self { + //Currently dropping SeedHolder at the end of initialization. + //Now entirely sure if we need it in the future. + let seed_holder = SeedHolder::new_os_random(); + let top_secret_key_holder = seed_holder.produce_top_secret_key_holder(); + + let utxo_secret_key_holder = top_secret_key_holder.produce_utxo_secret_holder(); + + let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key(); + let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key(); + + Self { + top_secret_key_holder, + utxo_secret_key_holder, + nullifer_public_key, + viewing_public_key, + pub_account_signing_keys: accounts, + } + } + + pub fn generate_new_private_key(&mut self) -> nssa::Address { + let private_key = nssa::PrivateKey::new_os_random(); + let address = nssa::Address::from(&nssa::PublicKey::new_from_private_key(&private_key)); + + self.pub_account_signing_keys.insert(address, private_key); + + address + } + + /// Returns the signing key for public transaction signatures + pub fn get_pub_account_signing_key( + &self, + address: &nssa::Address, + ) -> Option<&nssa::PrivateKey> { + self.pub_account_signing_keys.get(address) + } + pub fn calculate_shared_secret_receiver( &self, ephemeral_public_key_sender: AffinePoint, diff --git a/key_protocol/src/key_protocol_core/mod.rs b/key_protocol/src/key_protocol_core/mod.rs index e836d5f..67cb52c 100644 --- a/key_protocol/src/key_protocol_core/mod.rs +++ b/key_protocol/src/key_protocol_core/mod.rs @@ -49,7 +49,7 @@ impl NSSAUserData { } pub fn get_account_signing_key(&self, address: &nssa::Address) -> Option<&nssa::PrivateKey> { - self.accounts.get(address).map(|(key, _)| key) + self.key_holder.get_pub_account_signing_key(address) } } diff --git a/wallet/src/chain_storage/mod.rs b/wallet/src/chain_storage/mod.rs index 9a9ddb6..6f4201c 100644 --- a/wallet/src/chain_storage/mod.rs +++ b/wallet/src/chain_storage/mod.rs @@ -4,7 +4,7 @@ use anyhow::Result; use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; use key_protocol::key_protocol_core::NSSAUserData; -use crate::config::{InitialAccountData, WalletConfig}; +use crate::config::{PersistentAccountData, WalletConfig}; pub struct WalletChainStore { pub user_data: NSSAUserData, @@ -30,10 +30,11 @@ impl WalletChainStore { }) } - pub(crate) fn insert_account_data(&mut self, acc_data: InitialAccountData) { + pub(crate) fn insert_account_data(&mut self, acc_data: PersistentAccountData) { self.user_data - .accounts - .insert(acc_data.address, (acc_data.pub_sign_key, acc_data.account)); + .key_holder + .pub_account_signing_keys + .insert(acc_data.address, acc_data.pub_sign_key); } } diff --git a/wallet/src/config.rs b/wallet/src/config.rs index e6737f9..b6355ce 100644 --- a/wallet/src/config.rs +++ b/wallet/src/config.rs @@ -8,6 +8,12 @@ pub struct InitialAccountData { pub pub_sign_key: nssa::PrivateKey, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PersistentAccountData { + pub address: nssa::Address, + pub pub_sign_key: nssa::PrivateKey, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GasConfig { /// Gas spent per deploying one byte of data diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index db6b10f..0ad9aed 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -5,7 +5,7 @@ use key_protocol::key_protocol_core::NSSAUserData; use nssa::Address; use crate::{ - config::{InitialAccountData, WalletConfig}, + config::{PersistentAccountData, WalletConfig}, HOME_DIR_ENV_VAR, }; @@ -31,7 +31,7 @@ pub fn produce_account_addr_from_hex(hex_str: String) -> Result
{ ///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> { +pub fn fetch_persistent_accounts() -> Result> { let home = get_home()?; let accs_path = home.join("curr_accounts.json"); @@ -50,13 +50,12 @@ pub fn fetch_persistent_accounts() -> Result> { } ///Produces a list of accounts for storage -pub fn produce_data_for_storage(user_data: &NSSAUserData) -> Vec { +pub fn produce_data_for_storage(user_data: &NSSAUserData) -> Vec { let mut vec_for_storage = vec![]; - for (addr, (key, account)) in &user_data.accounts { - vec_for_storage.push(InitialAccountData { + for (addr, key) in &user_data.key_holder.pub_account_signing_keys { + vec_for_storage.push(PersistentAccountData { address: *addr, - account: account.clone(), pub_sign_key: key.clone(), }); } diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 05ec118..7ce7955 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::{fs::File, io::Write, path::PathBuf, str::FromStr, sync::Arc}; use base64::Engine; use common::{ @@ -47,7 +47,12 @@ impl WalletCore { client: client.clone(), }; - let storage = WalletChainStore::new(config)?; + let mut storage = WalletChainStore::new(config)?; + + let persistent_accounts = fetch_persistent_accounts()?; + for pers_acc_data in persistent_accounts { + storage.insert_account_data(pers_acc_data); + } Ok(Self { storage, @@ -88,45 +93,65 @@ impl WalletCore { pub async fn send_public_native_token_transfer( &self, from: Address, - nonce: u128, to: Address, balance_to_move: u128, ) -> Result { - let account = self.search_for_initial_account(from); + if let Ok(balance) = self.get_account_balance(from).await { + if balance >= balance_to_move { + if let Ok(nonces) = self.get_accounts_nonces(vec![from]).await { + let addresses = vec![from, to]; + 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 { - if account.balance >= balance_to_move { - 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 = self.storage.user_data.get_account_signing_key(&from); - let signing_key = self.storage.user_data.get_account_signing_key(&from); + if let Some(signing_key) = signing_key { + let witness_set = nssa::public_transaction::WitnessSet::for_message( + &message, + &[signing_key], + ); - if let Some(signing_key) = 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?) + Ok(self.sequencer_client.send_tx(tx).await?) + } else { + Err(ExecutionFailureKind::KeyNotFoundError) + } } else { - Err(ExecutionFailureKind::KeyNotFoundError) + Err(ExecutionFailureKind::SequencerError) } } else { Err(ExecutionFailureKind::InsufficientFundsError) } } else { - Err(ExecutionFailureKind::AmountMismatchError) + Err(ExecutionFailureKind::SequencerError) } } + ///Get account balance + pub async fn get_account_balance(&self, acc: Address) -> Result { + Ok(self + .sequencer_client + .get_account_balance(acc.to_string()) + .await? + .balance) + } + + ///Get accounts nonces + pub async fn get_accounts_nonces(&self, accs: Vec
) -> Result> { + Ok(self + .sequencer_client + .get_accounts_nonces(accs.into_iter().map(|acc| acc.to_string()).collect()) + .await? + .nonces) + } + ///Poll transactions pub async fn poll_public_native_token_transfer( &self, @@ -139,27 +164,6 @@ impl WalletCore { Ok(pub_tx) } - - ///Execute native token transfer at wallet accounts - pub fn execute_native_token_transfer( - &mut self, - from: Address, - to: Address, - balance_to_move: u128, - ) { - self.storage.user_data.increment_account_nonce(from); - self.storage.user_data.increment_account_nonce(to); - - let from_bal = self.storage.user_data.get_account_balance(&from); - let to_bal = self.storage.user_data.get_account_balance(&to); - - self.storage - .user_data - .update_account_balance(from, from_bal - balance_to_move); - self.storage - .user_data - .update_account_balance(to, to_bal + balance_to_move); - } } ///Represents CLI command for a wallet @@ -171,9 +175,6 @@ pub enum Command { ///from - valid 32 byte hex string #[arg(long)] from: String, - ///nonce - u128 integer - #[arg(long)] - nonce: u128, ///to - valid 32 byte hex string #[arg(long)] to: String, @@ -188,6 +189,16 @@ pub enum Command { #[arg(short, long)] tx_hash: String, }, + ///Get account `addr` balance + GetAccountBalance { + #[arg(short, long)] + addr: String, + }, + ///Get account `addr` nonce + GetAccountNonce { + #[arg(short, long)] + addr: String, + }, } ///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config @@ -201,20 +212,15 @@ pub struct Args { pub async fn execute_subcommand(command: Command) -> Result<()> { let wallet_config = fetch_config()?; - let mut wallet_core = WalletCore::start_from_config_update_chain(wallet_config).await?; + let mut wallet_core = WalletCore::start_from_config_update_chain(wallet_config)?; match command { - Command::SendNativeTokenTransfer { - from, - nonce, - to, - amount, - } => { + Command::SendNativeTokenTransfer { from, to, amount } => { let from = produce_account_addr_from_hex(from)?; let to = produce_account_addr_from_hex(to)?; let res = wallet_core - .send_public_native_token_transfer(from, nonce, to, amount) + .send_public_native_token_transfer(from, to, amount) .await?; info!("Results of tx send is {res:#?}"); @@ -224,8 +230,6 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { .await?; info!("Transaction data is {transfer_tx:?}"); - - wallet_core.execute_native_token_transfer(from, to, amount); } Command::RegisterAccount {} => { let addr = wallet_core.create_new_account(); @@ -243,6 +247,18 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { info!("Transaction object {tx_obj:#?}"); } + Command::GetAccountBalance { addr } => { + let addr = Address::from_str(&addr)?; + + let balance = wallet_core.get_account_balance(addr).await?; + info!("Accounts {addr:#?} balance is {balance}"); + } + Command::GetAccountNonce { addr } => { + let addr = Address::from_str(&addr)?; + + let nonce = wallet_core.get_accounts_nonces(vec![addr]).await?[0]; + info!("Accounts {addr:#?} nonce is {nonce}"); + } } wallet_core.store_persistent_accounts()?; From 1d627ce5b961a49a138881ee65a7b1ad5fc07fa7 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 4 Sep 2025 13:33:17 +0300 Subject: [PATCH 08/26] fix: suggestions 1 --- common/src/rpc_primitives/requests.rs | 14 ++++ sequencer_rpc/src/process.rs | 100 +++++++++++++++++++++++--- wallet/src/lib.rs | 68 ++++++++---------- wallet/src/poller.rs | 12 ++++ 4 files changed, 145 insertions(+), 49 deletions(-) diff --git a/common/src/rpc_primitives/requests.rs b/common/src/rpc_primitives/requests.rs index 674c077..a4c18d7 100644 --- a/common/src/rpc_primitives/requests.rs +++ b/common/src/rpc_primitives/requests.rs @@ -48,6 +48,11 @@ pub struct GetAccountsNoncesRequest { pub addresses: Vec, } +#[derive(Serialize, Deserialize, Debug)] +pub struct GetAccountDataRequest { + pub address: String, +} + parse_request!(HelloRequest); parse_request!(RegisterAccountRequest); parse_request!(SendTxRequest); @@ -58,6 +63,7 @@ parse_request!(GetInitialTestnetAccountsRequest); parse_request!(GetAccountBalanceRequest); parse_request!(GetTransactionByHashRequest); parse_request!(GetAccountsNoncesRequest); +parse_request!(GetAccountDataRequest); #[derive(Serialize, Deserialize, Debug)] pub struct HelloResponse { @@ -104,3 +110,11 @@ pub struct GetAccountsNoncesResponse { pub struct GetTransactionByHashResponse { pub transaction: Option, } + +#[derive(Serialize, Deserialize, Debug)] +pub struct GetAccountDataResponse { + pub balance: u128, + pub nonce: u128, + pub program_owner: [u32; 8], + pub data: Vec, +} diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index d994210..5d7b4be 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -12,9 +12,10 @@ use common::{ message::{Message, Request}, parser::RpcRequest, requests::{ - GetAccountBalanceRequest, GetAccountBalanceResponse, GetAccountsNoncesRequest, - GetAccountsNoncesResponse, GetInitialTestnetAccountsRequest, - GetTransactionByHashRequest, GetTransactionByHashResponse, + GetAccountBalanceRequest, GetAccountBalanceResponse, GetAccountDataRequest, + GetAccountDataResponse, GetAccountsNoncesRequest, GetAccountsNoncesResponse, + GetInitialTestnetAccountsRequest, GetTransactionByHashRequest, + GetTransactionByHashResponse, }, }, }; @@ -35,6 +36,7 @@ pub const GET_LAST_BLOCK: &str = "get_last_block"; pub const GET_ACCOUNT_BALANCE: &str = "get_account_balance"; pub const GET_TRANSACTION_BY_HASH: &str = "get_transaction_by_hash"; pub const GET_ACCOUNTS_NONCES: &str = "get_accounts_nonces"; +pub const GET_ACCOUNT_DATA: &str = "get_account_data"; pub const HELLO_FROM_SEQUENCER: &str = "HELLO_FROM_SEQUENCER"; @@ -181,14 +183,9 @@ impl JsonHandler { let get_account_nonces_req = GetAccountsNoncesRequest::parse(Some(request.params))?; let mut addresses = vec![]; for address_raw in get_account_nonces_req.addresses { - let address_bytes = hex::decode(address_raw) - .map_err(|_| RpcError::invalid_params("invalid hex".to_string()))?; - - let address = nssa::Address::new( - address_bytes - .try_into() - .map_err(|_| RpcError::invalid_params("invalid length".to_string()))?, - ); + let address = address_raw + .parse::() + .map_err(|e| RpcError::invalid_params(e.to_string()))?; addresses.push(address); } @@ -207,6 +204,32 @@ impl JsonHandler { respond(helperstruct) } + ///Returns account struct for give address. + /// Address must be a valid hex string of the correct length. + async fn process_get_account_data(&self, request: Request) -> Result { + let get_account_nonces_req = GetAccountDataRequest::parse(Some(request.params))?; + + let address = get_account_nonces_req + .address + .parse::() + .map_err(|e| RpcError::invalid_params(e.to_string()))?; + + let account = { + let state = self.sequencer_state.lock().await; + + state.store.state.get_account_by_address(&address) + }; + + let helperstruct = GetAccountDataResponse { + balance: account.balance, + nonce: account.nonce, + program_owner: account.program_owner, + data: account.data, + }; + + respond(helperstruct) + } + /// Returns the transaction corresponding to the given hash, if it exists in the blockchain. /// The hash must be a valid hex string of the correct length. async fn process_get_transaction_by_hash(&self, request: Request) -> Result { @@ -242,6 +265,7 @@ impl JsonHandler { GET_INITIAL_TESTNET_ACCOUNTS => self.get_initial_testnet_accounts(request).await, GET_ACCOUNT_BALANCE => self.process_get_account_balance(request).await, GET_ACCOUNTS_NONCES => self.process_get_accounts_nonces(request).await, + GET_ACCOUNT_DATA => self.process_get_account_data(request).await, GET_TRANSACTION_BY_HASH => self.process_get_transaction_by_hash(request).await, _ => Err(RpcErr(RpcError::method_not_found(request.method))), } @@ -505,6 +529,60 @@ mod tests { assert_eq!(response, expected_response); } + #[actix_web::test] + async fn test_get_account_data_for_non_existent_account() { + let (json_handler, _, _) = components_for_tests(); + let request = serde_json::json!({ + "jsonrpc": "2.0", + "method": "get_account_data", + "params": { "address": "efac".repeat(16) }, + "id": 1 + }); + let expected_response = serde_json::json!({ + "id": 1, + "jsonrpc": "2.0", + "result": { + "balance": 0, + "nonce": 0, + "program_owner": [ 0, 0, 0, 0, 0, 0, 0, 0], + "data": [], + } + }); + + let response = call_rpc_handler_with_json(json_handler, request).await; + + assert_eq!(response, expected_response); + } + + #[actix_web::test] + async fn test_get_account_data_for_existent_account() { + let (json_handler, initial_accounts, _) = components_for_tests(); + + let acc_1_addr = initial_accounts[0].addr.clone(); + + let request = serde_json::json!({ + "jsonrpc": "2.0", + "method": "get_account_data", + "params": { "address": acc_1_addr }, + "id": 1 + }); + + let expected_response = serde_json::json!({ + "id": 1, + "jsonrpc": "2.0", + "result": { + "balance": 9990, + "nonce": 1, + "program_owner": [ 1793544791, 852173979, 3315478100u32, 4158236927u32, 146723505, 3793635251u32, 999304864, 2535706995u32], + "data": [], + } + }); + + let response = call_rpc_handler_with_json(json_handler, request).await; + + assert_eq!(response, expected_response); + } + #[actix_web::test] async fn test_get_transaction_by_hash_for_non_existent_hash() { let (json_handler, _, _) = components_for_tests(); diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 7ce7955..8d4efc8 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -39,13 +39,7 @@ pub struct WalletCore { impl WalletCore { pub fn start_from_config_update_chain(config: WalletConfig) -> Result { let client = Arc::new(SequencerClient::new(config.sequencer_addr.clone())?); - let tx_poller = TxPoller { - polling_delay_millis: config.seq_poll_timeout_millis, - polling_max_blocks_to_query: config.seq_poll_max_blocks, - polling_max_error_attempts: config.seq_poll_max_retries, - polling_error_delay_millis: config.seq_poll_retry_delay_millis, - client: client.clone(), - }; + let tx_poller = TxPoller::new(config.clone(), client.clone()); let mut storage = WalletChainStore::new(config)?; @@ -61,7 +55,7 @@ impl WalletCore { }) } - ///Stre persistent accounts at home + ///Store persistent accounts at home pub fn store_persistent_accounts(&self) -> Result { let home = get_home()?; let accs_path = home.join("curr_accounts.json"); @@ -96,41 +90,39 @@ impl WalletCore { to: Address, balance_to_move: u128, ) -> Result { - if let Ok(balance) = self.get_account_balance(from).await { - if balance >= balance_to_move { - if let Ok(nonces) = self.get_accounts_nonces(vec![from]).await { - let addresses = vec![from, to]; - 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 Ok(balance) = self.get_account_balance(from).await else { + return Err(ExecutionFailureKind::SequencerError); + }; - let signing_key = self.storage.user_data.get_account_signing_key(&from); + if balance >= balance_to_move { + let Ok(nonces) = self.get_accounts_nonces(vec![from]).await else { + return Err(ExecutionFailureKind::SequencerError); + }; - if let Some(signing_key) = signing_key { - let witness_set = nssa::public_transaction::WitnessSet::for_message( - &message, - &[signing_key], - ); + let addresses = vec![from, to]; + 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 tx = nssa::PublicTransaction::new(message, witness_set); + let signing_key = self.storage.user_data.get_account_signing_key(&from); - Ok(self.sequencer_client.send_tx(tx).await?) - } else { - Err(ExecutionFailureKind::KeyNotFoundError) - } - } else { - Err(ExecutionFailureKind::SequencerError) - } - } else { - Err(ExecutionFailureKind::InsufficientFundsError) - } + let Some(signing_key) = signing_key else { + return Err(ExecutionFailureKind::KeyNotFoundError); + }; + + let witness_set = + nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); + + let tx = nssa::PublicTransaction::new(message, witness_set); + + Ok(self.sequencer_client.send_tx(tx).await?) } else { - Err(ExecutionFailureKind::SequencerError) + Err(ExecutionFailureKind::InsufficientFundsError) } } diff --git a/wallet/src/poller.rs b/wallet/src/poller.rs index 8fd219f..279197f 100644 --- a/wallet/src/poller.rs +++ b/wallet/src/poller.rs @@ -4,6 +4,8 @@ use anyhow::Result; use common::sequencer_client::SequencerClient; use log::{info, warn}; +use crate::config::WalletConfig; + #[derive(Clone)] ///Helperstruct to poll transactions pub struct TxPoller { @@ -15,6 +17,16 @@ pub struct TxPoller { } impl TxPoller { + pub fn new(config: WalletConfig, client: Arc) -> Self { + Self { + polling_delay_millis: config.seq_poll_timeout_millis, + polling_max_blocks_to_query: config.seq_poll_max_blocks, + polling_max_error_attempts: config.seq_poll_max_retries, + polling_error_delay_millis: config.seq_poll_retry_delay_millis, + client: client.clone(), + } + } + pub async fn poll_tx(&self, tx_hash: String) -> Result { let max_blocks_to_query = self.polling_max_blocks_to_query; From ee91d7d79c6d733a77caa4c38755f68a10a49c76 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 4 Sep 2025 14:18:44 +0300 Subject: [PATCH 09/26] fix: ci fix 1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2b98867..b2905de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ futures = "0.3" actix-rt = "*" lazy_static = "1.5.0" env_logger = "0.10" -log = "0.4" +log = "0.4.28" lru = "0.7.8" thiserror = "2.0.12" rs_merkle = "1.4" From 7052bccfbc965f5f3c4c8c58f6c9e428848bb12a Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 4 Sep 2025 14:38:41 +0300 Subject: [PATCH 10/26] fix: try edition 2024 --- common/Cargo.toml | 2 +- common/src/merkle_tree_public/hasher.rs | 2 +- common/src/merkle_tree_public/merkle_tree.rs | 4 ++-- common/src/rpc_primitives/errors.rs | 6 ++--- common/src/rpc_primitives/message.rs | 2 +- common/src/rpc_primitives/requests.rs | 2 +- common/src/transaction.rs | 22 ++++++++++--------- key_protocol/Cargo.toml | 2 +- .../key_management/ephemeral_key_holder.rs | 6 ++--- key_protocol/src/key_management/mod.rs | 4 ++-- .../src/key_management/secret_holders.rs | 4 ++-- key_protocol/src/key_protocol_core/mod.rs | 4 +++- mempool/Cargo.toml | 2 +- nssa/program_methods/Cargo.toml | 2 +- nssa/program_methods/guest/Cargo.toml | 2 +- nssa/test_program_methods/Cargo.toml | 2 +- nssa/test_program_methods/guest/Cargo.toml | 2 +- rustfmt.toml | 2 +- sequencer_core/Cargo.toml | 2 +- sequencer_core/src/sequencer_store/mod.rs | 2 +- sequencer_rpc/Cargo.toml | 2 +- sequencer_rpc/src/lib.rs | 2 +- sequencer_rpc/src/net_utils.rs | 4 ++-- sequencer_rpc/src/process.rs | 12 +++++----- sequencer_runner/Cargo.toml | 2 +- sequencer_runner/src/lib.rs | 6 +++-- storage/Cargo.toml | 2 +- storage/src/lib.rs | 2 +- storage/src/sc_db_utils.rs | 2 +- wallet/Cargo.toml | 2 +- wallet/src/helperfunctions.rs | 10 ++++++--- wallet/src/lib.rs | 2 +- wallet/src/main.rs | 2 +- 33 files changed, 68 insertions(+), 58 deletions(-) diff --git a/common/Cargo.toml b/common/Cargo.toml index 4e29b1e..54923a3 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "common" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] anyhow.workspace = true diff --git a/common/src/merkle_tree_public/hasher.rs b/common/src/merkle_tree_public/hasher.rs index b23388f..ed9443a 100644 --- a/common/src/merkle_tree_public/hasher.rs +++ b/common/src/merkle_tree_public/hasher.rs @@ -1,5 +1,5 @@ use rs_merkle::Hasher; -use sha2::{digest::FixedOutput, Digest, Sha256}; +use sha2::{Digest, Sha256, digest::FixedOutput}; use super::TreeHashType; diff --git a/common/src/merkle_tree_public/merkle_tree.rs b/common/src/merkle_tree_public/merkle_tree.rs index e2eb715..8911344 100644 --- a/common/src/merkle_tree_public/merkle_tree.rs +++ b/common/src/merkle_tree_public/merkle_tree.rs @@ -2,14 +2,14 @@ use std::{collections::HashMap, fmt, marker::PhantomData}; use rs_merkle::{MerkleProof, MerkleTree}; use serde::{ + Deserialize, Deserializer, Serialize, de::{SeqAccess, Visitor}, ser::SerializeSeq, - Deserialize, Deserializer, Serialize, }; use crate::{transaction::Transaction, utxo_commitment::UTXOCommitment}; -use super::{hasher::OwnHasher, tree_leav_item::TreeLeavItem, TreeHashType}; +use super::{TreeHashType, hasher::OwnHasher, tree_leav_item::TreeLeavItem}; #[derive(Clone)] pub struct HashStorageMerkleTree { diff --git a/common/src/rpc_primitives/errors.rs b/common/src/rpc_primitives/errors.rs index 6bbf207..fc52dd0 100644 --- a/common/src/rpc_primitives/errors.rs +++ b/common/src/rpc_primitives/errors.rs @@ -1,4 +1,4 @@ -use serde_json::{to_value, Value}; +use serde_json::{Value, to_value}; use std::fmt; #[derive(serde::Serialize)] @@ -65,7 +65,7 @@ impl RpcError { return Self::server_error(Some(format!( "Failed to serialize invalid parameters error: {:?}", err.to_string() - ))) + ))); } }; RpcError::new(-32_602, "Invalid params".to_owned(), Some(value)) @@ -178,7 +178,7 @@ impl From for RpcError { let error_data = match to_value(&e) { Ok(value) => value, Err(_err) => { - return RpcError::new_internal_error(None, "Failed to serialize ServerError") + return RpcError::new_internal_error(None, "Failed to serialize ServerError"); } }; RpcError::new_internal_error(Some(error_data), e.to_string().as_str()) diff --git a/common/src/rpc_primitives/message.rs b/common/src/rpc_primitives/message.rs index c6bdc58..e8e4186 100644 --- a/common/src/rpc_primitives/message.rs +++ b/common/src/rpc_primitives/message.rs @@ -315,10 +315,10 @@ impl From for Vec { #[cfg(test)] mod tests { + use serde_json::Value; use serde_json::de::from_slice; use serde_json::json; use serde_json::ser::to_vec; - use serde_json::Value; use super::*; diff --git a/common/src/rpc_primitives/requests.rs b/common/src/rpc_primitives/requests.rs index a4c18d7..a566ee2 100644 --- a/common/src/rpc_primitives/requests.rs +++ b/common/src/rpc_primitives/requests.rs @@ -1,8 +1,8 @@ use crate::parse_request; use super::errors::RpcParseError; -use super::parser::parse_params; use super::parser::RpcRequest; +use super::parser::parse_params; use serde::{Deserialize, Serialize}; use serde_json::Value; diff --git a/common/src/transaction.rs b/common/src/transaction.rs index afc4559..1d0ccec 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -1,12 +1,12 @@ use k256::ecdsa::{ - signature::{Signer, Verifier}, Signature, SigningKey, VerifyingKey, + signature::{Signer, Verifier}, }; use log::info; use secp256k1_zkp::{PedersenCommitment, Tweak}; use serde::{Deserialize, Serialize}; -use sha2::{digest::FixedOutput, Digest}; +use sha2::{Digest, digest::FixedOutput}; use crate::merkle_tree_public::TreeHashType; @@ -297,9 +297,9 @@ impl AuthenticatedTransaction { #[cfg(test)] mod tests { use super::*; - use k256::{ecdsa::signature::Signer, FieldBytes}; - use secp256k1_zkp::{constants::SECRET_KEY_SIZE, Tweak}; - use sha2::{digest::FixedOutput, Digest}; + use k256::{FieldBytes, ecdsa::signature::Signer}; + use secp256k1_zkp::{Tweak, constants::SECRET_KEY_SIZE}; + use sha2::{Digest, digest::FixedOutput}; use crate::{ merkle_tree_public::TreeHashType, @@ -378,11 +378,13 @@ mod tests { assert_eq!(authenticated_tx.transaction(), &transaction); assert_eq!(hash, &transaction.body.hash()); - assert!(authenticated_tx - .transaction() - .public_key - .verify(&transaction.body.to_bytes(), &signature) - .is_ok()); + assert!( + authenticated_tx + .transaction() + .public_key + .verify(&transaction.body.to_bytes(), &signature) + .is_ok() + ); } #[test] diff --git a/key_protocol/Cargo.toml b/key_protocol/Cargo.toml index 2f2bb07..3150dfe 100644 --- a/key_protocol/Cargo.toml +++ b/key_protocol/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "key_protocol" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] anyhow.workspace = true diff --git a/key_protocol/src/key_management/ephemeral_key_holder.rs b/key_protocol/src/key_management/ephemeral_key_holder.rs index ecfb09e..b304292 100644 --- a/key_protocol/src/key_management/ephemeral_key_holder.rs +++ b/key_protocol/src/key_management/ephemeral_key_holder.rs @@ -1,9 +1,9 @@ -use aes_gcm::{aead::Aead, AeadCore, Aes256Gcm, KeyInit}; -use elliptic_curve::point::AffineCoordinates; +use aes_gcm::{AeadCore, Aes256Gcm, KeyInit, aead::Aead}; use elliptic_curve::PrimeField; +use elliptic_curve::point::AffineCoordinates; use k256::{AffinePoint, FieldBytes, Scalar}; use log::info; -use rand::{rngs::OsRng, RngCore}; +use rand::{RngCore, rngs::OsRng}; use super::constants_types::{CipherText, Nonce}; diff --git a/key_protocol/src/key_management/mod.rs b/key_protocol/src/key_management/mod.rs index 2c38375..1a037ef 100644 --- a/key_protocol/src/key_management/mod.rs +++ b/key_protocol/src/key_management/mod.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit}; +use aes_gcm::{Aes256Gcm, KeyInit, aead::Aead}; use constants_types::{CipherText, Nonce}; use elliptic_curve::point::AffineCoordinates; use k256::AffinePoint; @@ -136,8 +136,8 @@ impl KeyChain { #[cfg(test)] mod tests { use aes_gcm::{ - aead::{Aead, KeyInit, OsRng}, Aes256Gcm, + aead::{Aead, KeyInit, OsRng}, }; use constants_types::{CipherText, Nonce}; use constants_types::{NULLIFIER_SECRET_CONST, VIEWING_SECRET_CONST}; diff --git a/key_protocol/src/key_management/secret_holders.rs b/key_protocol/src/key_management/secret_holders.rs index 47342ec..c6b2948 100644 --- a/key_protocol/src/key_management/secret_holders.rs +++ b/key_protocol/src/key_management/secret_holders.rs @@ -1,9 +1,9 @@ use common::merkle_tree_public::TreeHashType; use elliptic_curve::PrimeField; use k256::{AffinePoint, FieldBytes, Scalar}; -use rand::{rngs::OsRng, RngCore}; +use rand::{RngCore, rngs::OsRng}; use serde::{Deserialize, Serialize}; -use sha2::{digest::FixedOutput, Digest}; +use sha2::{Digest, digest::FixedOutput}; use super::constants_types::{NULLIFIER_SECRET_CONST, VIEWING_SECRET_CONST}; diff --git a/key_protocol/src/key_protocol_core/mod.rs b/key_protocol/src/key_protocol_core/mod.rs index 67cb52c..7757183 100644 --- a/key_protocol/src/key_protocol_core/mod.rs +++ b/key_protocol/src/key_protocol_core/mod.rs @@ -36,7 +36,9 @@ impl NSSAUserData { accounts_keys: HashMap, ) -> Result { if !Self::valid_key_transaction_pairing_check(&accounts_keys) { - anyhow::bail!("Key transaction pairing check not satisfied, there is addresses, which is not derived from keys"); + anyhow::bail!( + "Key transaction pairing check not satisfied, there is addresses, which is not derived from keys" + ); } let key_holder = KeyChain::new_os_random_with_accounts(accounts_keys); diff --git a/mempool/Cargo.toml b/mempool/Cargo.toml index ff8b855..16327ac 100644 --- a/mempool/Cargo.toml +++ b/mempool/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "mempool" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] anyhow.workspace = true diff --git a/nssa/program_methods/Cargo.toml b/nssa/program_methods/Cargo.toml index af52307..40dab21 100644 --- a/nssa/program_methods/Cargo.toml +++ b/nssa/program_methods/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "program-methods" version = "0.1.0" -edition = "2021" +edition = "2024" [build-dependencies] risc0-build = { version = "3.0.3" } diff --git a/nssa/program_methods/guest/Cargo.toml b/nssa/program_methods/guest/Cargo.toml index 0d47ccd..da4dbe8 100644 --- a/nssa/program_methods/guest/Cargo.toml +++ b/nssa/program_methods/guest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "programs" version = "0.1.0" -edition = "2021" +edition = "2024" [workspace] diff --git a/nssa/test_program_methods/Cargo.toml b/nssa/test_program_methods/Cargo.toml index 50d6ca2..0317d2b 100644 --- a/nssa/test_program_methods/Cargo.toml +++ b/nssa/test_program_methods/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "test-program-methods" version = "0.1.0" -edition = "2021" +edition = "2024" [build-dependencies] risc0-build = { version = "3.0.3" } diff --git a/nssa/test_program_methods/guest/Cargo.toml b/nssa/test_program_methods/guest/Cargo.toml index 0d47ccd..da4dbe8 100644 --- a/nssa/test_program_methods/guest/Cargo.toml +++ b/nssa/test_program_methods/guest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "programs" version = "0.1.0" -edition = "2021" +edition = "2024" [workspace] diff --git a/rustfmt.toml b/rustfmt.toml index 3a26366..f216078 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1 +1 @@ -edition = "2021" +edition = "2024" diff --git a/sequencer_core/Cargo.toml b/sequencer_core/Cargo.toml index 2e3570b..ecfb323 100644 --- a/sequencer_core/Cargo.toml +++ b/sequencer_core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sequencer_core" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] hex.workspace = true diff --git a/sequencer_core/src/sequencer_store/mod.rs b/sequencer_core/src/sequencer_store/mod.rs index 4254ed7..bb0a7c1 100644 --- a/sequencer_core/src/sequencer_store/mod.rs +++ b/sequencer_core/src/sequencer_store/mod.rs @@ -3,7 +3,7 @@ use std::path::Path; use block_store::SequecerBlockStore; use common::block::HashableBlockData; use nssa::{self, Address}; -use rand::{rngs::OsRng, RngCore}; +use rand::{RngCore, rngs::OsRng}; use crate::config::AccountInitialData; diff --git a/sequencer_rpc/Cargo.toml b/sequencer_rpc/Cargo.toml index c6ce004..a0111f6 100644 --- a/sequencer_rpc/Cargo.toml +++ b/sequencer_rpc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sequencer_rpc" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] anyhow.workspace = true diff --git a/sequencer_rpc/src/lib.rs b/sequencer_rpc/src/lib.rs index 1112dbd..2973c42 100644 --- a/sequencer_rpc/src/lib.rs +++ b/sequencer_rpc/src/lib.rs @@ -5,8 +5,8 @@ pub mod types; use std::sync::Arc; use common::rpc_primitives::{ - errors::{RpcError, RpcErrorKind}, RpcPollingConfig, + errors::{RpcError, RpcErrorKind}, }; use sequencer_core::SequencerCore; use serde::Serialize; diff --git a/sequencer_rpc/src/net_utils.rs b/sequencer_rpc/src/net_utils.rs index c421f17..b373823 100644 --- a/sequencer_rpc/src/net_utils.rs +++ b/sequencer_rpc/src/net_utils.rs @@ -2,13 +2,13 @@ use std::io; use std::sync::Arc; use actix_cors::Cors; -use actix_web::{http, middleware, web, App, Error as HttpError, HttpResponse, HttpServer}; +use actix_web::{App, Error as HttpError, HttpResponse, HttpServer, http, middleware, web}; use futures::Future; use futures::FutureExt; use log::info; -use common::rpc_primitives::message::Message; use common::rpc_primitives::RpcConfig; +use common::rpc_primitives::message::Message; use sequencer_core::SequencerCore; use tokio::sync::Mutex; diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index 5d7b4be..ad05843 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -1,5 +1,5 @@ use actix_web::Error as HttpError; -use base64::{engine::general_purpose, Engine}; +use base64::{Engine, engine::general_purpose}; use nssa; use sequencer_core::config::AccountInitialData; use serde_json::Value; @@ -26,7 +26,7 @@ use common::rpc_primitives::requests::{ SendTxResponse, }; -use super::{respond, types::err_rpc::RpcErr, JsonHandler}; +use super::{JsonHandler, respond, types::err_rpc::RpcErr}; pub const HELLO: &str = "hello"; pub const SEND_TX: &str = "send_tx"; @@ -276,13 +276,13 @@ impl JsonHandler { mod tests { use std::sync::Arc; - use crate::{rpc_handler, JsonHandler}; - use base64::{engine::general_purpose, Engine}; + use crate::{JsonHandler, rpc_handler}; + use base64::{Engine, engine::general_purpose}; use common::rpc_primitives::RpcPollingConfig; use sequencer_core::{ - config::{AccountInitialData, SequencerConfig}, SequencerCore, + config::{AccountInitialData, SequencerConfig}, }; use serde_json::Value; use tempfile::tempdir; @@ -368,7 +368,7 @@ mod tests { } async fn call_rpc_handler_with_json(handler: JsonHandler, request_json: Value) -> Value { - use actix_web::{test, web, App}; + use actix_web::{App, test, web}; let app = test::init_service( App::new() diff --git a/sequencer_runner/Cargo.toml b/sequencer_runner/Cargo.toml index b42fcb6..a610f8d 100644 --- a/sequencer_runner/Cargo.toml +++ b/sequencer_runner/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sequencer_runner" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] anyhow.workspace = true diff --git a/sequencer_runner/src/lib.rs b/sequencer_runner/src/lib.rs index 625350b..b682a18 100644 --- a/sequencer_runner/src/lib.rs +++ b/sequencer_runner/src/lib.rs @@ -5,7 +5,7 @@ use anyhow::Result; use clap::Parser; use common::rpc_primitives::RpcConfig; use log::info; -use sequencer_core::{config::SequencerConfig, SequencerCore}; +use sequencer_core::{SequencerCore, config::SequencerConfig}; use sequencer_rpc::new_http_server; use tokio::{sync::Mutex, task::JoinHandle}; @@ -71,7 +71,9 @@ pub async fn main_runner() -> Result<()> { if let Some(ref rust_log) = app_config.override_rust_log { info!("RUST_LOG env var set to {rust_log:?}"); - std::env::set_var(RUST_LOG, rust_log); + unsafe { + std::env::set_var(RUST_LOG, rust_log); + } } //ToDo: Add restart on failures diff --git a/storage/Cargo.toml b/storage/Cargo.toml index c4fd3a9..d756dd3 100644 --- a/storage/Cargo.toml +++ b/storage/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "storage" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] anyhow.workspace = true diff --git a/storage/src/lib.rs b/storage/src/lib.rs index 0dd12b7..9ead317 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -5,7 +5,7 @@ use error::DbError; use rocksdb::{ BoundColumnFamily, ColumnFamilyDescriptor, DBWithThreadMode, MultiThreaded, Options, }; -use sc_db_utils::{produce_blob_from_fit_vec, DataBlob, DataBlobChangeVariant}; +use sc_db_utils::{DataBlob, DataBlobChangeVariant, produce_blob_from_fit_vec}; pub mod error; pub mod sc_db_utils; diff --git a/storage/src/sc_db_utils.rs b/storage/src/sc_db_utils.rs index c86828e..af982cf 100644 --- a/storage/src/sc_db_utils.rs +++ b/storage/src/sc_db_utils.rs @@ -1,4 +1,4 @@ -use serde::{de::Error, Deserialize, Serialize}; +use serde::{Deserialize, Serialize, de::Error}; use crate::SC_DATA_BLOB_SIZE; diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index b973e1c..6078f68 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "wallet" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] anyhow.workspace = true diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index 0ad9aed..8a7b7b6 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -5,8 +5,8 @@ use key_protocol::key_protocol_core::NSSAUserData; use nssa::Address; use crate::{ - config::{PersistentAccountData, WalletConfig}, HOME_DIR_ENV_VAR, + config::{PersistentAccountData, WalletConfig}, }; ///Get home dir for wallet. Env var `NSSA_WALLET_HOME_DIR` must be set before execution to succeed. @@ -69,12 +69,16 @@ mod tests { #[test] fn test_get_home_get_env_var() { - std::env::set_var(HOME_DIR_ENV_VAR, "/path/to/configs"); + unsafe { + std::env::set_var(HOME_DIR_ENV_VAR, "/path/to/configs"); + } let home = get_home().unwrap(); assert_eq!(PathBuf::from_str("/path/to/configs").unwrap(), home); - std::env::remove_var(HOME_DIR_ENV_VAR); + unsafe { + std::env::remove_var(HOME_DIR_ENV_VAR); + } } } diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 8d4efc8..3814925 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -2,8 +2,8 @@ use std::{fs::File, io::Write, path::PathBuf, str::FromStr, sync::Arc}; use base64::Engine; use common::{ - sequencer_client::{json::SendTxResponse, SequencerClient}, ExecutionFailureKind, + sequencer_client::{SequencerClient, json::SendTxResponse}, }; use anyhow::Result; diff --git a/wallet/src/main.rs b/wallet/src/main.rs index f8c91f8..b296400 100644 --- a/wallet/src/main.rs +++ b/wallet/src/main.rs @@ -1,7 +1,7 @@ use anyhow::Result; use clap::Parser; use tokio::runtime::Builder; -use wallet::{execute_subcommand, Args}; +use wallet::{Args, execute_subcommand}; pub const NUM_THREADS: usize = 2; From 762a0d760e6915a9e04359a817e91af01da2a6b8 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 4 Sep 2025 14:54:48 +0300 Subject: [PATCH 11/26] fix: resolver 3 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b2905de..02192ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -resolver = "2" +resolver = "3" members = [ "integration_tests", "sequencer_runner", From d402cfca52b1d562a3df0a8bc16dca0592995eb8 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 4 Sep 2025 15:12:01 +0300 Subject: [PATCH 12/26] fix: direct log dependency --- sequencer_core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sequencer_core/Cargo.toml b/sequencer_core/Cargo.toml index ecfb323..d818916 100644 --- a/sequencer_core/Cargo.toml +++ b/sequencer_core/Cargo.toml @@ -8,7 +8,7 @@ hex.workspace = true anyhow.workspace = true serde_json.workspace = true env_logger.workspace = true -log.workspace = true +log = "0.4.28" serde.workspace = true rand.workspace = true elliptic-curve.workspace = true From 57045fa8e1c2e2de19ccd0ad66a0bf2a6ff1e90c Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 4 Sep 2025 15:15:14 +0300 Subject: [PATCH 13/26] fix: merge upfix --- sequencer_core/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/sequencer_core/Cargo.toml b/sequencer_core/Cargo.toml index cf98855..1c56f11 100644 --- a/sequencer_core/Cargo.toml +++ b/sequencer_core/Cargo.toml @@ -9,6 +9,7 @@ anyhow.workspace = true serde.workspace = true rand.workspace = true tempfile.workspace = true +log.workspace = true [dependencies.storage] path = "../storage" From b1d3b71df734f8890d9ba93313048cbc7dec30ee Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 4 Sep 2025 16:46:20 +0300 Subject: [PATCH 14/26] fix: tests fix --- sequencer_rpc/src/process.rs | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index ad05843..2f55dd2 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -554,35 +554,6 @@ mod tests { assert_eq!(response, expected_response); } - #[actix_web::test] - async fn test_get_account_data_for_existent_account() { - let (json_handler, initial_accounts, _) = components_for_tests(); - - let acc_1_addr = initial_accounts[0].addr.clone(); - - let request = serde_json::json!({ - "jsonrpc": "2.0", - "method": "get_account_data", - "params": { "address": acc_1_addr }, - "id": 1 - }); - - let expected_response = serde_json::json!({ - "id": 1, - "jsonrpc": "2.0", - "result": { - "balance": 9990, - "nonce": 1, - "program_owner": [ 1793544791, 852173979, 3315478100u32, 4158236927u32, 146723505, 3793635251u32, 999304864, 2535706995u32], - "data": [], - } - }); - - let response = call_rpc_handler_with_json(json_handler, request).await; - - assert_eq!(response, expected_response); - } - #[actix_web::test] async fn test_get_transaction_by_hash_for_non_existent_hash() { let (json_handler, _, _) = components_for_tests(); From 4e122abbcefc2f0aecc00652d957a95b1bcfdc96 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:03:49 -0400 Subject: [PATCH 15/26] added comments for Merkle tree --- nssa/src/merkle_tree/mod.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nssa/src/merkle_tree/mod.rs b/nssa/src/merkle_tree/mod.rs index 2306efd..a27501c 100644 --- a/nssa/src/merkle_tree/mod.rs +++ b/nssa/src/merkle_tree/mod.rs @@ -39,11 +39,11 @@ impl MerkleTree { if tree_depth == capacity_depth { 0 } else { + // 2^(capacity_depth - tree_depth) - 1 (1 << (capacity_depth - tree_depth)) - 1 } } - - /// Number of levels required to hold all values + /// Number of levels required to hold all nodes fn depth(&self) -> usize { self.length.next_power_of_two().trailing_zeros() as usize } @@ -57,6 +57,7 @@ impl MerkleTree { } pub fn with_capacity(capacity: usize) -> Self { + //adjust capacity to ensure power of two let capacity = capacity.next_power_of_two(); let total_depth = capacity.trailing_zeros() as usize; @@ -75,6 +76,8 @@ impl MerkleTree { } } + /// reallocate storage of Merkle tree for double capacity. + /// current tree is embedded into the new tree as a subtree fn reallocate_to_double_capacity(&mut self) { let old_capacity = self.capacity; let new_capacity = old_capacity << 1; @@ -102,9 +105,11 @@ impl MerkleTree { let mut node_index = new_index + self.capacity - 1; let mut node_hash = hash_value(&value); + //add new node to nodes self.set_node(node_index, node_hash); self.length += 1; + //updates Merkle path of the newly inserted node for _ in 0..self.depth() { let parent_index = (node_index - 1) >> 1; let left_child = self.get_node((parent_index << 1) + 1); @@ -129,6 +134,7 @@ impl MerkleTree { while node_index != root_index { let parent_index = (node_index - 1) >> 1; + //left children have odd indices, and right children have even indices let is_left_child = node_index & 1 == 1; let sibling_index = if is_left_child { node_index + 1 From 5eeb92538409c94bb3adb7346fa9e1dbbd2a9333 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:21:46 -0400 Subject: [PATCH 16/26] added comments related to commitments --- nssa/core/src/commitment.rs | 4 ++++ nssa/src/state.rs | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/nssa/core/src/commitment.rs b/nssa/core/src/commitment.rs index bc22c8f..8e66941 100644 --- a/nssa/core/src/commitment.rs +++ b/nssa/core/src/commitment.rs @@ -8,6 +8,8 @@ use crate::{NullifierPublicKey, account::Account}; pub struct Commitment(pub(super) [u8; 32]); impl Commitment { + //generate new commitment to a private account owned by user with npk. + //hash(npk || program_owner || balance || nonce || data) pub fn new(npk: &NullifierPublicKey, account: &Account) -> Self { let mut bytes = Vec::new(); bytes.extend_from_slice(&npk.to_byte_array()); @@ -34,6 +36,8 @@ pub type CommitmentSetDigest = [u8; 32]; pub type MembershipProof = (usize, Vec<[u8; 32]>); +/// computes the resulting digest/root hash for a membership proof +/// and its corresponding commitment. pub fn compute_digest_for_path( commitment: &Commitment, proof: &MembershipProof, diff --git a/nssa/src/state.rs b/nssa/src/state.rs index f975804..e27b00c 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -21,6 +21,7 @@ impl CommitmentSet { self.merkle_tree.root() } + /// queries the CommitmentSet for membership proof of commitment pub fn get_proof_for(&self, commitment: &Commitment) -> Option { let index = *self.commitments.get(commitment)?; @@ -29,6 +30,7 @@ impl CommitmentSet { .map(|path| (index, path)) } + /// appends a list of commitments to the CommitmentSet. pub(crate) fn extend(&mut self, commitments: &[Commitment]) { for commitment in commitments.iter().cloned() { let index = self.merkle_tree.insert(commitment.to_byte_array()); @@ -41,6 +43,9 @@ impl CommitmentSet { self.commitments.contains_key(commitment) } + /// Initializes a CommitmentState with a given capacity. + /// if capacity is not a power_of_two, then capacity is taken + /// to be the next power_of_two. pub(crate) fn with_capacity(capacity: usize) -> CommitmentSet { Self { merkle_tree: MerkleTree::with_capacity(capacity), From 45b31d304c114660513415db69a4f89fcddf81a7 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:26:56 -0400 Subject: [PATCH 17/26] Update nssa/src/merkle_tree/mod.rs Co-authored-by: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> --- nssa/src/merkle_tree/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nssa/src/merkle_tree/mod.rs b/nssa/src/merkle_tree/mod.rs index a27501c..ebc13e0 100644 --- a/nssa/src/merkle_tree/mod.rs +++ b/nssa/src/merkle_tree/mod.rs @@ -57,7 +57,7 @@ impl MerkleTree { } pub fn with_capacity(capacity: usize) -> Self { - //adjust capacity to ensure power of two + // Adjust capacity to ensure power of two let capacity = capacity.next_power_of_two(); let total_depth = capacity.trailing_zeros() as usize; From 6e7520bfeacfd0c5a9a98b0dd48db788d31214d0 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:27:03 -0400 Subject: [PATCH 18/26] Update nssa/src/merkle_tree/mod.rs Co-authored-by: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> --- nssa/src/merkle_tree/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nssa/src/merkle_tree/mod.rs b/nssa/src/merkle_tree/mod.rs index ebc13e0..5944525 100644 --- a/nssa/src/merkle_tree/mod.rs +++ b/nssa/src/merkle_tree/mod.rs @@ -76,8 +76,8 @@ impl MerkleTree { } } - /// reallocate storage of Merkle tree for double capacity. - /// current tree is embedded into the new tree as a subtree + /// Reallocates storage of Merkle tree for double capacity. + /// The current tree is embedded into the new tree as a subtree fn reallocate_to_double_capacity(&mut self) { let old_capacity = self.capacity; let new_capacity = old_capacity << 1; From 73c11600ba2c26e6c5d1d1231cf5683f6a64d232 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:27:43 -0400 Subject: [PATCH 19/26] Update nssa/src/merkle_tree/mod.rs Co-authored-by: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> --- nssa/src/merkle_tree/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nssa/src/merkle_tree/mod.rs b/nssa/src/merkle_tree/mod.rs index 5944525..8ce8560 100644 --- a/nssa/src/merkle_tree/mod.rs +++ b/nssa/src/merkle_tree/mod.rs @@ -105,7 +105,7 @@ impl MerkleTree { let mut node_index = new_index + self.capacity - 1; let mut node_hash = hash_value(&value); - //add new node to nodes + // Insert the new node at the bottom layer self.set_node(node_index, node_hash); self.length += 1; From 1e7c3e155501af8b9f6fb58143a4f09ff18b605a Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:27:55 -0400 Subject: [PATCH 20/26] Update nssa/src/merkle_tree/mod.rs Co-authored-by: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> --- nssa/src/merkle_tree/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nssa/src/merkle_tree/mod.rs b/nssa/src/merkle_tree/mod.rs index 8ce8560..0caff55 100644 --- a/nssa/src/merkle_tree/mod.rs +++ b/nssa/src/merkle_tree/mod.rs @@ -134,7 +134,7 @@ impl MerkleTree { while node_index != root_index { let parent_index = (node_index - 1) >> 1; - //left children have odd indices, and right children have even indices + // Left children have odd indices, and right children have even indices let is_left_child = node_index & 1 == 1; let sibling_index = if is_left_child { node_index + 1 From 26acdbed6169a3a2b8a9cd4e8754f4b42b9ab56a Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:28:13 -0400 Subject: [PATCH 21/26] Update nssa/src/merkle_tree/mod.rs Co-authored-by: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> --- nssa/src/merkle_tree/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nssa/src/merkle_tree/mod.rs b/nssa/src/merkle_tree/mod.rs index 0caff55..7b30d78 100644 --- a/nssa/src/merkle_tree/mod.rs +++ b/nssa/src/merkle_tree/mod.rs @@ -109,7 +109,7 @@ impl MerkleTree { self.set_node(node_index, node_hash); self.length += 1; - //updates Merkle path of the newly inserted node + // Update upper levels for the newly inserted node for _ in 0..self.depth() { let parent_index = (node_index - 1) >> 1; let left_child = self.get_node((parent_index << 1) + 1); From 5dea03027aa83e3d7beea5fcc44bcc45dca4556f Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:38:34 -0400 Subject: [PATCH 22/26] minor corrections --- nssa/core/src/commitment.rs | 7 +++---- nssa/src/state.rs | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/nssa/core/src/commitment.rs b/nssa/core/src/commitment.rs index 8e66941..760aa91 100644 --- a/nssa/core/src/commitment.rs +++ b/nssa/core/src/commitment.rs @@ -8,8 +8,8 @@ use crate::{NullifierPublicKey, account::Account}; pub struct Commitment(pub(super) [u8; 32]); impl Commitment { - //generate new commitment to a private account owned by user with npk. - //hash(npk || program_owner || balance || nonce || data) + // Generates the commitment to a private account owned by user for npk: + // hash(npk || program_owner || balance || nonce || data) pub fn new(npk: &NullifierPublicKey, account: &Account) -> Self { let mut bytes = Vec::new(); bytes.extend_from_slice(&npk.to_byte_array()); @@ -36,8 +36,7 @@ pub type CommitmentSetDigest = [u8; 32]; pub type MembershipProof = (usize, Vec<[u8; 32]>); -/// computes the resulting digest/root hash for a membership proof -/// and its corresponding commitment. +/// Computes the resulting digest for the given membership proof and corresponding commitment pub fn compute_digest_for_path( commitment: &Commitment, proof: &MembershipProof, diff --git a/nssa/src/state.rs b/nssa/src/state.rs index e27b00c..77495e9 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -21,7 +21,7 @@ impl CommitmentSet { self.merkle_tree.root() } - /// queries the CommitmentSet for membership proof of commitment + /// Queries the CommitmentSet for a membership proof of commitment pub fn get_proof_for(&self, commitment: &Commitment) -> Option { let index = *self.commitments.get(commitment)?; @@ -30,7 +30,7 @@ impl CommitmentSet { .map(|path| (index, path)) } - /// appends a list of commitments to the CommitmentSet. + /// Inserts a list of commitments to the CommitmentSet. pub(crate) fn extend(&mut self, commitments: &[Commitment]) { for commitment in commitments.iter().cloned() { let index = self.merkle_tree.insert(commitment.to_byte_array()); @@ -44,7 +44,7 @@ impl CommitmentSet { } /// Initializes a CommitmentState with a given capacity. - /// if capacity is not a power_of_two, then capacity is taken + /// If the capacity is not a power_of_two, then capacity is taken /// to be the next power_of_two. pub(crate) fn with_capacity(capacity: usize) -> CommitmentSet { Self { From 49019eaee270e880f4ae98dfd85923fe59393f9c Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 20:48:11 -0400 Subject: [PATCH 23/26] Update nssa/core/src/commitment.rs Co-authored-by: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> --- nssa/core/src/commitment.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nssa/core/src/commitment.rs b/nssa/core/src/commitment.rs index 760aa91..1eb8c98 100644 --- a/nssa/core/src/commitment.rs +++ b/nssa/core/src/commitment.rs @@ -8,8 +8,8 @@ use crate::{NullifierPublicKey, account::Account}; pub struct Commitment(pub(super) [u8; 32]); impl Commitment { - // Generates the commitment to a private account owned by user for npk: - // hash(npk || program_owner || balance || nonce || data) + /// Generates the commitment to a private account owned by user for npk: + /// SHA256(npk || program_owner || balance || nonce || data) pub fn new(npk: &NullifierPublicKey, account: &Account) -> Self { let mut bytes = Vec::new(); bytes.extend_from_slice(&npk.to_byte_array()); From 4ae2af21a578f73ddc0fe7cca340ca89ca3792c6 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 20:48:26 -0400 Subject: [PATCH 24/26] Update nssa/src/state.rs Co-authored-by: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> --- nssa/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 77495e9..1817445 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -43,7 +43,7 @@ impl CommitmentSet { self.commitments.contains_key(commitment) } - /// Initializes a CommitmentState with a given capacity. + /// Initializes an empty `CommitmentSet` with a given capacity. /// If the capacity is not a power_of_two, then capacity is taken /// to be the next power_of_two. pub(crate) fn with_capacity(capacity: usize) -> CommitmentSet { From 4a0a99e26486b72493910ae933c06661aec48c8f Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 20:48:47 -0400 Subject: [PATCH 25/26] Update nssa/src/state.rs Co-authored-by: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> --- nssa/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 1817445..8641e14 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -30,7 +30,7 @@ impl CommitmentSet { .map(|path| (index, path)) } - /// Inserts a list of commitments to the CommitmentSet. + /// Inserts a list of commitments to the `CommitmentSet`. pub(crate) fn extend(&mut self, commitments: &[Commitment]) { for commitment in commitments.iter().cloned() { let index = self.merkle_tree.insert(commitment.to_byte_array()); From c055941738f8b9d9263c5e3262b16e7865e59c33 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Fri, 5 Sep 2025 20:48:56 -0400 Subject: [PATCH 26/26] Update nssa/src/state.rs Co-authored-by: Sergio Chouhy <41742639+schouhy@users.noreply.github.com> --- nssa/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 8641e14..f980370 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -21,7 +21,7 @@ impl CommitmentSet { self.merkle_tree.root() } - /// Queries the CommitmentSet for a membership proof of commitment + /// Queries the `CommitmentSet` for a membership proof of commitment pub fn get_proof_for(&self, commitment: &Commitment) -> Option { let index = *self.commitments.get(commitment)?;