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,