From 6565e0af184da969dbb62b8abe98a998b7e5c5a0 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Mon, 4 Aug 2025 15:09:28 +0300 Subject: [PATCH 1/5] breaking: initial cuts --- node_core/src/chain_storage/mod.rs | 276 +---- node_core/src/lib.rs | 1561 +--------------------------- node_core/src/pre_start.rs | 71 -- node_rpc/src/process.rs | 508 +-------- 4 files changed, 22 insertions(+), 2394 deletions(-) delete mode 100644 node_core/src/pre_start.rs diff --git a/node_core/src/chain_storage/mod.rs b/node_core/src/chain_storage/mod.rs index 8e36dc5..63bbbc1 100644 --- a/node_core/src/chain_storage/mod.rs +++ b/node_core/src/chain_storage/mod.rs @@ -2,24 +2,18 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use accounts::account_core::{address::AccountAddress, Account}; use anyhow::Result; -use block_store::NodeBlockStore; use common::{ block::Block, - execution_input::PublicNativeTokenSend, merkle_tree_public::merkle_tree::{PublicTransactionMerkleTree, UTXOCommitmentsMerkleTree}, nullifier::UTXONullifier, - utxo_commitment::UTXOCommitment, }; -use k256::AffinePoint; -use log::{info, warn}; use sc_core::public_context::PublicSCContext; use serde::{Deserialize, Serialize}; -use utxo::utxo_core::UTXO; -use crate::{config::NodeConfig, ActionData}; +use crate::config::NodeConfig; pub mod accounts_store; -pub mod block_store; +//pub mod block_store; #[derive(Deserialize, Serialize)] pub struct AccMap { @@ -49,7 +43,6 @@ impl From for HashMap<[u8; 32], Account> { pub struct NodeChainStore { pub acc_map: HashMap, - pub block_store: NodeBlockStore, pub nullifier_store: HashSet, pub utxo_commitments_store: UTXOCommitmentsMerkleTree, pub pub_tx_store: PublicTransactionMerkleTree, @@ -58,30 +51,15 @@ pub struct NodeChainStore { impl NodeChainStore { pub fn new(config: NodeConfig, genesis_block: Block) -> Result<(Self, u64)> { - let mut acc_map = HashMap::new(); - let mut nullifier_store = HashSet::new(); - let mut utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); - let mut pub_tx_store = PublicTransactionMerkleTree::new(vec![]); - let mut block_id = genesis_block.block_id; - - //Sequencer should panic if unable to open db, - //as fixing this issue may require actions non-native to program scope - let block_store = - NodeBlockStore::open_db_with_genesis(&config.home.join("rocksdb"), Some(genesis_block)) - .unwrap(); - - if let Ok(temp_block_id) = block_store.get_snapshot_block_id() { - utxo_commitments_store = block_store.get_snapshot_commitment()?; - nullifier_store = block_store.get_snapshot_nullifier()?; - acc_map = block_store.get_snapshot_account()?; - pub_tx_store = block_store.get_snapshot_transaction()?; - block_id = temp_block_id; - } + let acc_map = HashMap::new(); + let nullifier_store = HashSet::new(); + let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); + let pub_tx_store = PublicTransactionMerkleTree::new(vec![]); + let block_id = genesis_block.block_id; Ok(( Self { acc_map, - block_store, nullifier_store, utxo_commitments_store, pub_tx_store, @@ -91,184 +69,6 @@ impl NodeChainStore { )) } - pub fn new_after_restart(config: NodeConfig, genesis_block: Block) -> Result<(Self, u64)> { - let mut acc_map = HashMap::new(); - let mut nullifier_store = HashSet::new(); - let mut utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); - let mut pub_tx_store = PublicTransactionMerkleTree::new(vec![]); - let mut block_id = genesis_block.block_id; - - //Sequencer should panic if unable to open db, - //as fixing this issue may require actions non-native to program scope - let block_store = NodeBlockStore::open_db_reload(&config.home.join("rocksdb")).unwrap(); - - if let Ok(temp_block_id) = block_store.get_snapshot_block_id() { - utxo_commitments_store = block_store.get_snapshot_commitment()?; - nullifier_store = block_store.get_snapshot_nullifier()?; - acc_map = block_store.get_snapshot_account()?; - pub_tx_store = block_store.get_snapshot_transaction()?; - block_id = temp_block_id; - } - - Ok(( - Self { - acc_map, - block_store, - nullifier_store, - utxo_commitments_store, - pub_tx_store, - node_config: config, - }, - block_id, - )) - } - - pub fn dissect_insert_block(&mut self, block: Block) -> Result<()> { - let block_id = block.block_id; - - for tx in &block.transactions { - if !tx.body().execution_input.is_empty() { - let public_action = - serde_json::from_slice::(&tx.body().execution_input); - - if let Ok(public_action) = public_action { - match public_action { - ActionData::MintMoneyPublicTx(action) => { - let acc_mut = self.acc_map.get_mut(&action.acc); - - if let Some(acc_mut) = acc_mut { - acc_mut.balance += action.amount as u64; - } - } - ActionData::SendMoneyDeshieldedTx(action) => { - for (balance, acc_addr) in action.receiver_data { - let acc_mut = self.acc_map.get_mut(&acc_addr); - - if let Some(acc_mut) = acc_mut { - acc_mut.balance += balance as u64; - } - } - } - ActionData::SendMoneyShieldedTx(action) => { - let acc_mut = self.acc_map.get_mut(&action.acc_sender); - - if let Some(acc_mut) = acc_mut { - acc_mut.balance = - acc_mut.balance.saturating_sub(action.amount as u64); - } - } - _ => {} - } - } else { - let native_transfer = - serde_json::from_slice::(&tx.body().execution_input); - - if let Ok(transfer) = native_transfer { - if let Some(acc_sender) = self.acc_map.get_mut(&transfer.from) { - //Can panic, we depend on sequencer maintaining chain consistency here - acc_sender.balance -= transfer.balance_to_move; - - if let Some(acc_rec) = self.acc_map.get_mut(&transfer.to) { - acc_rec.balance += transfer.balance_to_move; - } - } - } - } - } - - self.utxo_commitments_store.add_tx_multiple( - tx.body() - .utxo_commitments_created_hashes - .clone() - .into_iter() - .map(|hash| UTXOCommitment { hash }) - .collect(), - ); - - for nullifier in tx.body().nullifier_created_hashes.iter() { - self.nullifier_store.insert(UTXONullifier { - utxo_hash: *nullifier, - }); - } - - if !tx.body().encoded_data.is_empty() { - let ephemeral_public_key_sender = - serde_json::from_slice::(&tx.body().ephemeral_pub_key)?; - - for (ciphertext, nonce, tag) in tx.body().encoded_data.clone() { - let slice = nonce.as_slice(); - let nonce = - accounts::key_management::constants_types::Nonce::clone_from_slice(slice); - for (acc_id, acc) in self.acc_map.iter_mut() { - if hex::decode(acc_id).unwrap()[0] == tag { - let decoded_data_curr_acc = acc.decrypt_data( - ephemeral_public_key_sender, - ciphertext.clone(), - nonce, - ); - if let Ok(decoded_data_curr_acc) = decoded_data_curr_acc { - let decoded_utxo_try = - serde_json::from_slice::(&decoded_data_curr_acc); - if let Ok(utxo) = decoded_utxo_try { - if &utxo.owner == acc_id { - acc.utxos.insert(utxo.hash, utxo); - } - } - } - } - } - } - } - - self.pub_tx_store.add_tx(tx); - } - - self.block_store.put_block_at_id(block)?; - - //Snapshot - if block_id.is_multiple_of(self.node_config.shapshot_frequency_in_blocks) { - //Serializing all important data structures - - //If we fail serialization, it is not the reason to stop running - //Logging on warn level in this cases - let acc_map: AccMap = self.acc_map.clone().into(); - - if let Ok(accounts_ser) = serde_json::to_vec(&acc_map).inspect_err(|err| { - warn!("Failed to serialize accounts data {err:#?}"); - }) { - if let Ok(comm_ser) = - serde_json::to_vec(&self.utxo_commitments_store).inspect_err(|err| { - warn!("Failed to serialize commitments {err:#?}"); - }) - { - if let Ok(txs_ser) = serde_json::to_vec(&self.pub_tx_store).inspect_err(|err| { - warn!("Failed to serialize transactions {err:#?}"); - }) { - if let Ok(nullifiers_ser) = serde_json::to_vec(&self.nullifier_store) - .inspect_err(|err| { - warn!("Failed to serialize nullifiers {err:#?}"); - }) - { - let snapshot_trace = self.block_store.put_snapshot_at_block_id( - block_id, - accounts_ser, - comm_ser, - txs_ser, - nullifiers_ser, - ); - - info!( - "Snapshot executed at {block_id:?} with results {snapshot_trace:#?}" - ); - } - } - } - } - } - - Ok(()) - } - pub fn produce_context(&self, caller: AccountAddress) -> PublicSCContext { let mut account_masks = BTreeMap::new(); @@ -298,7 +98,6 @@ mod tests { use crate::config::GasConfig; use accounts::account_core::Account; use common::block::{Block, Data}; - use common::merkle_tree_public::TreeHashType; use common::transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind}; use secp256k1_zkp::Tweak; use std::path::PathBuf; @@ -489,6 +288,7 @@ mod tests { } } + //ToDo: Continue refactor fn create_dummy_transaction( nullifier_created_hashes: Vec<[u8; 32]>, utxo_commitments_spent_hashes: Vec<[u8; 32]>, @@ -515,6 +315,7 @@ mod tests { Transaction::new(body, SignaturePrivateKey::random(&mut rng)) } + //ToDo: Continue refactor fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block { Block { block_id, @@ -551,10 +352,6 @@ mod tests { } } - fn generate_dummy_utxo(address: TreeHashType, amount: u128) -> UTXO { - UTXO::new(address, vec![], amount, false) - } - #[test] fn test_new_initializes_correctly() { let temp_dir = tempdir().unwrap(); @@ -574,59 +371,4 @@ mod tests { [0; 32] ); } - - #[test] - fn test_new_recovers_from_snapshot() { - let temp_dir = tempdir().unwrap(); - let path = temp_dir.path().to_path_buf(); - - let config = create_sample_node_config(path); - - let nullifier_secret_const = - "261d61d294ac4bdc24f91b6f490efa263757a4a95f65871cd4f16b2ea23c3b5d"; - std::env::set_var("NULLIFIER_SECRET_CONST", nullifier_secret_const); - - let viewing_secret_const = - "6117af750b30d7a296672ec3b3b25d3489beca3cfe5770fa39f275cec395d5ce"; - std::env::set_var("VIEWING_SECRET_CONST", viewing_secret_const); - - let genesis_block = create_genesis_block(); - - // Initialize once to create DB and store fake snapshot - { - let (mut store, _) = - NodeChainStore::new(config.clone(), genesis_block.clone()).unwrap(); - - // Insert state - let mut account = Account::new(); - account - .add_new_utxo_outputs(vec![generate_dummy_utxo(account.address, 100)]) - .unwrap(); - store.acc_map.insert(account.address, account); - store.nullifier_store.insert(UTXONullifier { - utxo_hash: [2u8; 32], - }); - store - .utxo_commitments_store - .add_tx_multiple(vec![UTXOCommitment { hash: [3u8; 32] }]); - store.pub_tx_store.add_tx(&create_dummy_transaction( - vec![[9; 32]], - vec![[7; 32]], - vec![[8; 32]], - )); - - // Put block snapshot to trigger snapshot recovery on next load - let dummy_block = create_sample_block(1, 0); - - store.dissect_insert_block(dummy_block).unwrap(); - } - - // Now reload and verify snapshot is used - let (recovered_store, block_id) = - NodeChainStore::new_after_restart(config.clone(), genesis_block).unwrap(); - - assert_eq!(block_id, 1); - assert_eq!(recovered_store.acc_map.len(), 1); - assert!(recovered_store.utxo_commitments_store.get_root().is_some()); - } } diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index f613dbb..1c70a11 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -1,44 +1,30 @@ -use std::sync::{ - atomic::{AtomicU64, Ordering}, - Arc, -}; +use std::sync::{atomic::AtomicU64, Arc}; use common::{ execution_input::PublicNativeTokenSend, transaction::Transaction, ExecutionFailureKind, }; -use accounts::{ - account_core::{address::AccountAddress, Account}, - key_management::ephemeral_key_holder::EphemeralKeyHolder, -}; +use accounts::account_core::{address::AccountAddress, Account}; use anyhow::Result; use chain_storage::NodeChainStore; -use common::transaction::{TransactionBody, TxKind}; +use common::transaction::TransactionBody; use config::NodeConfig; use log::info; -use sc_core::proofs_circuits::{ - generate_commitments, generate_nullifiers, generate_nullifiers_se, pedersen_commitment_vec, -}; +use sc_core::proofs_circuits::{generate_commitments, pedersen_commitment_vec}; use sequencer_client::{json::SendTxResponse, SequencerClient}; use serde::{Deserialize, Serialize}; use storage::sc_db_utils::DataBlobChangeVariant; -use tokio::{sync::RwLock, task::JoinHandle}; +use tokio::sync::RwLock; use utxo::utxo_core::UTXO; -use zkvm::{ - gas_calculator::GasCalculator, prove_mint_utxo, prove_mint_utxo_multiple_assets, - prove_send_utxo, prove_send_utxo_deshielded, prove_send_utxo_multiple_assets_one_receiver, - prove_send_utxo_shielded, -}; +use zkvm::gas_calculator::GasCalculator; pub const BLOCK_GEN_DELAY_SECS: u64 = 20; pub mod chain_storage; pub mod config; -///Module, which includes pre start setup helperfunctions -pub mod pre_start; pub mod sequencer_client; -fn vec_u8_to_vec_u64(bytes: Vec) -> Vec { +pub fn vec_u8_to_vec_u64(bytes: Vec) -> Vec { // Pad with zeros to make sure it's a multiple of 8 let mut padded = bytes.clone(); while !padded.len().is_multiple_of(8) { @@ -89,7 +75,6 @@ pub struct NodeCore { pub storage: Arc>, pub curr_height: Arc, pub node_config: NodeConfig, - pub db_updater_handle: JoinHandle>, pub sequencer_client: Arc, pub gas_calculator: GasCalculator, } @@ -103,68 +88,18 @@ impl NodeCore { let genesis_block = client.get_block(genesis_id.genesis_id).await?.block; - let (mut storage, mut chain_height) = NodeChainStore::new(config.clone(), genesis_block)?; + let (mut storage, chain_height) = NodeChainStore::new(config.clone(), genesis_block)?; for acc in config.clone().initial_accounts { storage.acc_map.insert(acc.address, acc); } - pre_start::setup_empty_sc_states(&storage).await?; - - //Chain update loop - loop { - let next_block = chain_height + 1; - - if let Ok(block) = client.get_block(next_block).await { - storage.dissect_insert_block(block.block)?; - info!("Preprocessed block with id {next_block:?}"); - } else { - break; - } - - chain_height += 1; - } - let wrapped_storage = Arc::new(RwLock::new(storage)); let chain_height_wrapped = Arc::new(AtomicU64::new(chain_height)); - let wrapped_storage_thread = wrapped_storage.clone(); - let wrapped_chain_height_thread = chain_height_wrapped.clone(); - let client_thread = client.clone(); - - let updater_handle = tokio::spawn(async move { - loop { - let next_block = wrapped_chain_height_thread.load(Ordering::Relaxed) + 1; - - if let Ok(block) = client_thread.get_block(next_block).await { - { - let mut storage_guard = wrapped_storage_thread.write().await; - - let block_insertion_result = - storage_guard.dissect_insert_block(block.block); - - if block_insertion_result.is_err() { - info!("Block insertion failed due to {block_insertion_result:?}"); - - block_insertion_result?; - } - info!("Processed block with id {next_block:?}"); - } - - wrapped_chain_height_thread.store(next_block, Ordering::Relaxed); - } else { - tokio::time::sleep(std::time::Duration::from_secs( - config.seq_poll_timeout_secs, - )) - .await; - } - } - }); - Ok(Self { storage: wrapped_storage, curr_height: chain_height_wrapped, node_config: config.clone(), - db_updater_handle: updater_handle, sequencer_client: client.clone(), gas_calculator: GasCalculator::from(config.gas_config), }) @@ -193,760 +128,6 @@ impl NodeCore { addr } - pub async fn mint_utxo_private( - &self, - acc: AccountAddress, - amount: u128, - ) -> Result<(Transaction, [u8; 32]), ExecutionFailureKind> { - let (utxo, receipt) = prove_mint_utxo(amount, acc)?; - let result_hash = utxo.hash; - - let acc_map_read_guard = self.storage.read().await; - - let account = acc_map_read_guard.acc_map.get(&acc).unwrap(); - - let ephm_key_holder = EphemeralKeyHolder::new_os_random(); - ephm_key_holder.log(); - - let eph_pub_key = - serde_json::to_vec(&ephm_key_holder.generate_ephemeral_public_key()).unwrap(); - - let encoded_data = Account::encrypt_data( - &ephm_key_holder, - account.key_holder.viewing_public_key, - &serde_json::to_vec(&utxo).unwrap(), - ); - - let tag = account.make_tag(); - - let comm = generate_commitments(&[utxo]); - - let mint_utxo_addr_bytes: Vec = zkvm::test_methods::MINT_UTXO_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let sc_addr = hex::encode(mint_utxo_addr_bytes); - - //Sc does not change its state - let state_changes: Vec = vec![]; - let new_len = 0; - let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - - let sc_state = acc_map_read_guard - .block_store - .get_sc_sc_state(&sc_addr) - .map_err(ExecutionFailureKind::db_error)?; - - let mut vec_values_u64: Vec> = sc_state - .into_iter() - .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) - .collect(); - - let context = acc_map_read_guard.produce_context(account.address); - - //Will not panic, as PublicScContext is serializable - let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); - vec_values_u64.push(context_public_info); - - let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - - let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - let transaction_body = TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: comm - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) - .unwrap(), - encoded_data: vec![(encoded_data.0, encoded_data.1.to_vec(), tag)], - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - }; - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); - - Ok(( - Transaction::new(transaction_body, key_to_sign_transaction), - result_hash, - )) - } - - pub async fn mint_utxo_multiple_assets_private( - &self, - acc: AccountAddress, - amount: u128, - number_of_assets: usize, - ) -> Result<(Transaction, Vec<[u8; 32]>), ExecutionFailureKind> { - let (utxos, receipt) = prove_mint_utxo_multiple_assets(amount, number_of_assets, acc)?; - let result_hashes = utxos.iter().map(|utxo| utxo.hash).collect(); - - let acc_map_read_guard = self.storage.read().await; - - let account = acc_map_read_guard.acc_map.get(&acc).unwrap(); - - let ephm_key_holder = EphemeralKeyHolder::new_os_random(); - ephm_key_holder.log(); - - let eph_pub_key = - serde_json::to_vec(&ephm_key_holder.generate_ephemeral_public_key()).unwrap(); - - let encoded_data = utxos - .iter() - .map(|utxo| { - ( - Account::encrypt_data( - &ephm_key_holder, - account.key_holder.viewing_public_key, - &serde_json::to_vec(&utxo).unwrap(), - ), - account.make_tag(), - ) - }) - .map(|((ciphertext, nonce), tag)| (ciphertext, nonce.to_vec(), tag)) - .collect(); - - let comm = generate_commitments(&utxos); - - let mint_multiple_utxo_addr_bytes: Vec = - zkvm::test_methods::MINT_UTXO_MULTIPLE_ASSETS_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let sc_addr = hex::encode(mint_multiple_utxo_addr_bytes); - - //Sc does not change its state - let state_changes: Vec = vec![]; - let new_len = 0; - let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - - let sc_state = acc_map_read_guard - .block_store - .get_sc_sc_state(&sc_addr) - .map_err(ExecutionFailureKind::db_error)?; - - let mut vec_values_u64: Vec> = sc_state - .into_iter() - .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) - .collect(); - - let context = acc_map_read_guard.produce_context(account.address); - - //Will not panic, as PublicScContext is serializable - let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); - vec_values_u64.push(context_public_info); - - let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - - let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - - let transaction_body = TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: comm - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) - .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - }; - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); - - Ok(( - Transaction::new(transaction_body, key_to_sign_transaction), - result_hashes, - )) - } - - pub async fn transfer_utxo_private( - &self, - utxo: UTXO, - commitment_in: [u8; 32], - receivers: Vec<(u128, AccountAddress)>, - ) -> Result<(Transaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { - let acc_map_read_guard = self.storage.read().await; - - let account = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); - - let nullifier = generate_nullifiers( - &utxo, - &account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key - .to_bytes(), - ); - - let (resulting_utxos, receipt) = prove_send_utxo(utxo, receivers)?; - let utxo_hashes = resulting_utxos - .iter() - .map(|(utxo, addr)| (*addr, utxo.hash)) - .collect(); - - let utxos: Vec = resulting_utxos - .iter() - .map(|(utxo, _)| utxo.clone()) - .collect(); - - let ephm_key_holder = EphemeralKeyHolder::new_os_random(); - ephm_key_holder.log(); - - let eph_pub_key = - serde_json::to_vec(&ephm_key_holder.generate_ephemeral_public_key()).unwrap(); - - let encoded_data: Vec<(Vec, Vec, u8)> = utxos - .iter() - .map(|utxo_enc| { - let accout_enc = acc_map_read_guard.acc_map.get(&utxo_enc.owner).unwrap(); - - let (ciphertext, nonce) = Account::encrypt_data( - &ephm_key_holder, - accout_enc.key_holder.viewing_public_key, - &serde_json::to_vec(&utxo_enc).unwrap(), - ); - - let tag = accout_enc.make_tag(); - - (ciphertext, nonce.to_vec(), tag) - }) - .collect(); - - let commitments = generate_commitments(&utxos); - - let send_utxo_addr_bytes: Vec = zkvm::test_methods::SEND_UTXO_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let sc_addr = hex::encode(send_utxo_addr_bytes); - - //Sc does not change its state - let state_changes: Vec = vec![]; - let new_len = 0; - let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - - let sc_state = acc_map_read_guard - .block_store - .get_sc_sc_state(&sc_addr) - .map_err(ExecutionFailureKind::db_error)?; - - let mut vec_values_u64: Vec> = sc_state - .into_iter() - .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) - .collect(); - - let context = acc_map_read_guard.produce_context(account.address); - - //Will not panic, as PublicScContext is serializable - let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); - vec_values_u64.push(context_public_info); - - let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - - let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - - let transaction_body = TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes: vec![commitment_in], - utxo_commitments_created_hashes: commitments - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![nullifier.try_into().unwrap()], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) - .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - }; - - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); - - Ok(( - Transaction::new(transaction_body, key_to_sign_transaction), - utxo_hashes, - )) - } - - pub async fn transfer_utxo_multiple_assets_private( - &self, - utxos: Vec, - commitments_in: Vec<[u8; 32]>, - number_to_send: usize, - receiver: AccountAddress, - ) -> Result<(Transaction, Vec<[u8; 32]>, Vec<[u8; 32]>), ExecutionFailureKind> { - let acc_map_read_guard = self.storage.read().await; - - let account = acc_map_read_guard.acc_map.get(&utxos[0].owner).unwrap(); - - let nsk = account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key - .to_bytes() - .to_vec(); - - let nullifiers = utxos - .iter() - .map(|utxo| generate_nullifiers(utxo, &nsk)) - .map(|vecc| vecc.try_into().unwrap()) - .collect(); - - let (resulting_utxos_receiver, resulting_utxos_not_spent, receipt) = - prove_send_utxo_multiple_assets_one_receiver(utxos, number_to_send, receiver)?; - - let utxo_hashes_receiver = resulting_utxos_receiver - .iter() - .map(|utxo| utxo.hash) - .collect(); - - let utxo_hashes_not_spent = resulting_utxos_not_spent - .iter() - .map(|utxo| utxo.hash) - .collect(); - - let ephm_key_holder = EphemeralKeyHolder::new_os_random(); - ephm_key_holder.log(); - - let eph_pub_key = - serde_json::to_vec(&ephm_key_holder.generate_ephemeral_public_key()).unwrap(); - - let mut encoded_data: Vec<(Vec, Vec, u8)> = resulting_utxos_receiver - .iter() - .map(|utxo_enc| { - let accout_enc = acc_map_read_guard.acc_map.get(&utxo_enc.owner).unwrap(); - - let (ciphertext, nonce) = Account::encrypt_data( - &ephm_key_holder, - accout_enc.key_holder.viewing_public_key, - &serde_json::to_vec(&utxo_enc).unwrap(), - ); - - let tag = accout_enc.make_tag(); - - (ciphertext, nonce.to_vec(), tag) - }) - .collect(); - - let encoded_data_1: Vec<(Vec, Vec, u8)> = resulting_utxos_not_spent - .iter() - .map(|utxo_enc| { - let accout_enc = acc_map_read_guard.acc_map.get(&utxo_enc.owner).unwrap(); - - let (ciphertext, nonce) = Account::encrypt_data( - &ephm_key_holder, - accout_enc.key_holder.viewing_public_key, - &serde_json::to_vec(&utxo_enc).unwrap(), - ); - - let tag = accout_enc.make_tag(); - - (ciphertext, nonce.to_vec(), tag) - }) - .collect(); - - encoded_data.extend(encoded_data_1); - - let mut commitments = generate_commitments(&resulting_utxos_receiver); - let commitments_1 = generate_commitments(&resulting_utxos_not_spent); - - commitments.extend(commitments_1); - - let send_multiple_utxo_addr_bytes: Vec = - zkvm::test_methods::SEND_UTXO_MULTIPLE_ASSETS_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let sc_addr = hex::encode(send_multiple_utxo_addr_bytes); - - //Sc does not change its state - let state_changes: Vec = vec![]; - let new_len = 0; - let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - - let sc_state = acc_map_read_guard - .block_store - .get_sc_sc_state(&sc_addr) - .map_err(ExecutionFailureKind::db_error)?; - - let mut vec_values_u64: Vec> = sc_state - .into_iter() - .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) - .collect(); - - let context = acc_map_read_guard.produce_context(account.address); - - //Will not panic, as PublicScContext is serializable - let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); - vec_values_u64.push(context_public_info); - - let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - - let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - - let transaction_body = TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes: commitments_in, - utxo_commitments_created_hashes: commitments - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: nullifiers, - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) - .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - }; - - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); - - Ok(( - Transaction::new(transaction_body, key_to_sign_transaction), - utxo_hashes_receiver, - utxo_hashes_not_spent, - )) - } - - pub async fn transfer_balance_shielded( - &self, - acc: AccountAddress, - balance: u64, - receivers: Vec<(u128, AccountAddress)>, - ) -> Result<(Transaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { - let acc_map_read_guard = self.storage.read().await; - - let account = acc_map_read_guard.acc_map.get(&acc).unwrap(); - - // TODO: add to transaction structure and do the check. Research has to update the scheme as well. - let commitment = sc_core::transaction_payloads_tools::generate_secret_random_commitment( - balance, account, - ) - .unwrap(); - - let nullifier = generate_nullifiers_se( - &commitment, - &account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key - .to_bytes(), - ); - - let (resulting_utxos, receipt) = prove_send_utxo_shielded(acc, balance as u128, receivers)?; - let utxo_hashes = resulting_utxos - .iter() - .map(|(utxo, addr)| (*addr, utxo.hash)) - .collect(); - - let utxos: Vec = resulting_utxos - .iter() - .map(|(utxo, _)| utxo.clone()) - .collect(); - - let ephm_key_holder = EphemeralKeyHolder::new_os_random(); - ephm_key_holder.log(); - - let eph_pub_key = - serde_json::to_vec(&ephm_key_holder.generate_ephemeral_public_key()).unwrap(); - - let encoded_data: Vec<(Vec, Vec, u8)> = utxos - .iter() - .map(|utxo_enc| { - let accout_enc = acc_map_read_guard.acc_map.get(&utxo_enc.owner).unwrap(); - - let (ciphertext, nonce) = Account::encrypt_data( - &ephm_key_holder, - accout_enc.key_holder.viewing_public_key, - &serde_json::to_vec(&utxo_enc).unwrap(), - ); - - let tag = accout_enc.make_tag(); - - (ciphertext, nonce.to_vec(), tag) - }) - .collect(); - - let commitments = generate_commitments(&utxos); - - let mint_utxo_addr_bytes: Vec = zkvm::test_methods::SEND_UTXO_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let sc_addr = hex::encode(mint_utxo_addr_bytes); - - //Sc does not change its state - let state_changes: Vec = vec![]; - let new_len = 0; - let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - - let sc_state = acc_map_read_guard - .block_store - .get_sc_sc_state(&sc_addr) - .map_err(ExecutionFailureKind::db_error)?; - - let mut vec_values_u64: Vec> = sc_state - .into_iter() - .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) - .collect(); - - let context = acc_map_read_guard.produce_context(account.address); - - //Will not panic, as PublicScContext is serializable - let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); - vec_values_u64.push(context_public_info); - - let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - - let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - - let transaction_body = TransactionBody { - tx_kind: TxKind::Shielded, - execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx( - SendMoneyShieldedTx { - acc_sender: acc, - amount: balance as u128, - }, - )) - .unwrap(), - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: commitments - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![nullifier.try_into().unwrap()], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) - .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - }; - - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); - - Ok(( - Transaction::new(transaction_body, key_to_sign_transaction), - utxo_hashes, - )) - } - - pub async fn transfer_utxo_deshielded( - &self, - utxo: UTXO, - comm_gen_hash: [u8; 32], - receivers: Vec<(u128, AccountAddress)>, - ) -> Result { - let acc_map_read_guard = self.storage.read().await; - - let commitment_in = acc_map_read_guard - .utxo_commitments_store - .get_tx(comm_gen_hash) - .unwrap() - .hash; - - let account = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); - - let nullifier = generate_nullifiers( - &utxo, - &account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key - .to_bytes(), - ); - - let (resulting_balances, receipt) = prove_send_utxo_deshielded(utxo, receivers)?; - - let send_utxo_addr_bytes: Vec = zkvm::test_methods::SEND_UTXO_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let sc_addr = hex::encode(send_utxo_addr_bytes); - - //Sc does not change its state - let state_changes: Vec = vec![]; - let new_len = 0; - let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - - let sc_state = acc_map_read_guard - .block_store - .get_sc_sc_state(&sc_addr) - .map_err(ExecutionFailureKind::db_error)?; - - let mut vec_values_u64: Vec> = sc_state - .into_iter() - .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) - .collect(); - - let context = acc_map_read_guard.produce_context(account.address); - - //Will not panic, as PublicScContext is serializable - let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); - vec_values_u64.push(context_public_info); - - let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - - let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - - let transaction_body = TransactionBody { - tx_kind: TxKind::Deshielded, - execution_input: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx( - SendMoneyDeshieldedTx { - receiver_data: resulting_balances, - }, - )) - .unwrap(), - execution_output: vec![], - utxo_commitments_spent_hashes: vec![commitment_in], - utxo_commitments_created_hashes: vec![], - nullifier_created_hashes: vec![nullifier.try_into().unwrap()], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) - .unwrap(), - encoded_data: vec![], - ephemeral_pub_key: vec![], - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - }; - - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); - - Ok(Transaction::new(transaction_body, key_to_sign_transaction)) - } - - pub async fn send_private_mint_tx( - &self, - acc: AccountAddress, - amount: u128, - ) -> Result<(SendTxResponse, [u8; 32], [u8; 32]), ExecutionFailureKind> { - //Considering proof time, needs to be done before proof - let tx_roots = self.get_roots().await; - - let point_before_prove = std::time::Instant::now(); - let (tx, utxo_hash) = self.mint_utxo_private(acc, amount).await?; - tx.body().log(); - let point_after_prove = std::time::Instant::now(); - - let commitment_generated_hash = tx.body().utxo_commitments_created_hashes[0]; - - let timedelta = (point_after_prove - point_before_prove).as_millis(); - info!("Mint utxo proof spent {timedelta:?} milliseconds"); - - Ok(( - self.sequencer_client.send_tx(tx, tx_roots).await?, - utxo_hash, - commitment_generated_hash, - )) - } - - pub async fn send_private_mint_multiple_assets_tx( - &self, - acc: AccountAddress, - amount: u128, - number_of_assets: usize, - ) -> Result<(SendTxResponse, Vec<[u8; 32]>, Vec<[u8; 32]>), ExecutionFailureKind> { - //Considering proof time, needs to be done before proof - let tx_roots = self.get_roots().await; - - let point_before_prove = std::time::Instant::now(); - let (tx, utxo_hashes) = self - .mint_utxo_multiple_assets_private(acc, amount, number_of_assets) - .await?; - tx.body().log(); - let point_after_prove = std::time::Instant::now(); - - let commitment_generated_hashes = tx.body().utxo_commitments_created_hashes.clone(); - - let timedelta = (point_after_prove - point_before_prove).as_millis(); - info!("Mint utxo proof spent {timedelta:?} milliseconds"); - - Ok(( - self.sequencer_client.send_tx(tx, tx_roots).await?, - utxo_hashes, - commitment_generated_hashes, - )) - } - - // pub async fn send_public_deposit( - // &self, - // acc: AccountAddress, - // amount: u128, - // ) -> Result { - // //Considering proof time, needs to be done before proof - // let tx_roots = self.get_roots().await; - // - // let public_context = { - // let read_guard = self.storage.read().await; - // - // read_guard.produce_context(acc) - // }; - // - // let (tweak, secret_r, commitment) = pedersen_commitment_vec( - // //Will not panic, as public context is serializable - // public_context.produce_u64_list_from_context().unwrap(), - // ); - // - // let sc_addr = hex::encode([0; 32]); - // - // //Sc does not change its state - // let state_changes: Vec = vec![]; - // let new_len = 0; - // let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - // - // let tx: TransactionBody = - // sc_core::transaction_payloads_tools::create_public_transaction_payload( - // serde_json::to_vec(&ActionData::MintMoneyPublicTx(MintMoneyPublicTx { - // acc, - // amount, - // })) - // .unwrap(), - // commitment, - // tweak, - // secret_r, - // sc_addr, - // state_changes, - // ) - // .into(); - // tx.log(); - // - // Ok(self.sequencer_client.send_tx(tx, tx_roots).await?) - // } - pub async fn send_public_native_token_transfer( &self, from: AccountAddress, @@ -1010,732 +191,6 @@ impl NodeCore { } } } - - pub async fn send_private_send_tx( - &self, - utxo: UTXO, - comm_hash: [u8; 32], - receivers: Vec<(u128, AccountAddress)>, - ) -> Result<(SendTxResponse, Vec<([u8; 32], [u8; 32])>), ExecutionFailureKind> { - //Considering proof time, needs to be done before proof - let tx_roots = self.get_roots().await; - - let point_before_prove = std::time::Instant::now(); - let (tx, utxo_hashes) = self - .transfer_utxo_private(utxo, comm_hash, receivers) - .await?; - tx.body().log(); - let point_after_prove = std::time::Instant::now(); - - let timedelta = (point_after_prove - point_before_prove).as_millis(); - info!("Send private utxo proof spent {timedelta:?} milliseconds"); - - Ok(( - self.sequencer_client.send_tx(tx, tx_roots).await?, - utxo_hashes, - )) - } - - pub async fn send_private_multiple_assets_send_tx( - &self, - utxos: Vec, - comm_hashes: Vec<[u8; 32]>, - number_to_send: usize, - receiver: AccountAddress, - ) -> Result<(SendTxResponse, Vec<[u8; 32]>, Vec<[u8; 32]>), ExecutionFailureKind> { - //Considering proof time, needs to be done before proof - let tx_roots = self.get_roots().await; - - let point_before_prove = std::time::Instant::now(); - let (tx, utxo_hashes_received, utxo_hashes_not_spent) = self - .transfer_utxo_multiple_assets_private(utxos, comm_hashes, number_to_send, receiver) - .await?; - tx.body().log(); - let point_after_prove = std::time::Instant::now(); - - let timedelta = (point_after_prove - point_before_prove).as_millis(); - info!("Send private utxo proof spent {timedelta:?} milliseconds"); - - Ok(( - self.sequencer_client.send_tx(tx, tx_roots).await?, - utxo_hashes_received, - utxo_hashes_not_spent, - )) - } - - pub async fn send_shielded_send_tx( - &self, - acc: AccountAddress, - amount: u64, - receivers: Vec<(u128, AccountAddress)>, - ) -> Result<(SendTxResponse, Vec<([u8; 32], [u8; 32])>), ExecutionFailureKind> { - //Considering proof time, needs to be done before proof - let tx_roots = self.get_roots().await; - - let point_before_prove = std::time::Instant::now(); - let (tx, utxo_hashes) = self - .transfer_balance_shielded(acc, amount, receivers) - .await?; - tx.body().log(); - let point_after_prove = std::time::Instant::now(); - - let timedelta = (point_after_prove - point_before_prove).as_millis(); - info!("Send balance shielded proof spent {timedelta:?} milliseconds"); - - Ok(( - self.sequencer_client.send_tx(tx, tx_roots).await?, - utxo_hashes, - )) - } - - pub async fn send_deshielded_send_tx( - &self, - utxo: UTXO, - comm_gen_hash: [u8; 32], - receivers: Vec<(u128, AccountAddress)>, - ) -> Result { - //Considering proof time, needs to be done before proof - let tx_roots = self.get_roots().await; - - let point_before_prove = std::time::Instant::now(); - let tx = self - .transfer_utxo_deshielded(utxo, comm_gen_hash, receivers) - .await?; - tx.body().log(); - let point_after_prove = std::time::Instant::now(); - - let timedelta = (point_after_prove - point_before_prove).as_millis(); - info!("Send deshielded utxo proof spent {timedelta:?} milliseconds"); - - Ok(self.sequencer_client.send_tx(tx, tx_roots).await?) - } - - pub async fn operate_account_mint_private( - &mut self, - acc_addr: AccountAddress, - amount: u128, - ) -> Result<(UTXO, [u8; 32]), ExecutionFailureKind> { - let (resp, new_utxo_hash, comm_gen_hash) = - self.send_private_mint_tx(acc_addr, amount).await?; - info!("Response for mint private is {resp:?}"); - - info!("Awaiting new blocks"); - tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; - - let new_utxo = { - let mut write_guard = self.storage.write().await; - - let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap(); - - acc.utxos.get(&new_utxo_hash).unwrap().clone() - }; - - new_utxo.log(); - info!( - "Account address is {:?} ,new utxo owner address is {:?}", - hex::encode(acc_addr), - hex::encode(new_utxo.owner) - ); - info!( - "Account {:?} got new utxo with amount {amount:?}", - hex::encode(acc_addr) - ); - - Ok((new_utxo, comm_gen_hash)) - } - - pub async fn operate_account_mint_multiple_assets_private( - &mut self, - acc_addr: AccountAddress, - amount: u128, - number_of_assets: usize, - ) -> Result<(Vec, Vec<[u8; 32]>), ExecutionFailureKind> { - let (resp, new_utxo_hashes, comm_gen_hashes) = self - .send_private_mint_multiple_assets_tx(acc_addr, amount, number_of_assets) - .await?; - info!("Response for mint multiple assets private is {resp:?}"); - - info!("Awaiting new blocks"); - tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; - - let new_utxos = { - let mut write_guard = self.storage.write().await; - - new_utxo_hashes - .into_iter() - .map(|new_utxo_hash| { - let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap(); - - let new_utxo = acc.utxos.get(&new_utxo_hash).unwrap().clone(); - - new_utxo.log(); - info!( - "Account address is {:?} ,new utxo owner address is {:?}", - hex::encode(acc_addr), - hex::encode(new_utxo.owner) - ); - info!( - "Account {:?} got new utxo with amount {amount:?} and asset {:?}", - hex::encode(acc_addr), - new_utxo.asset - ); - - new_utxo - }) - .collect() - }; - - Ok((new_utxos, comm_gen_hashes)) - } - - pub async fn operate_account_send_deshielded_one_receiver( - &mut self, - acc_addr_rec: AccountAddress, - utxo: UTXO, - comm_gen_hash: [u8; 32], - ) -> Result<(), ExecutionFailureKind> { - let amount = utxo.amount; - - let old_balance = { - let acc_map_read_guard = self.storage.read().await; - - let acc = acc_map_read_guard.acc_map.get(&acc_addr_rec).unwrap(); - - acc.balance - }; - - info!( - "Balance of receiver {:?} now is {old_balance:?}", - hex::encode(acc_addr_rec) - ); - - let resp = self - .send_deshielded_send_tx(utxo, comm_gen_hash, vec![(amount, acc_addr_rec)]) - .await?; - info!("Response for send deshielded is {resp:?}"); - - info!("Awaiting new blocks"); - tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; - - let new_balance = { - let acc_map_read_guard = self.storage.read().await; - - let acc = acc_map_read_guard.acc_map.get(&acc_addr_rec).unwrap(); - - acc.balance - }; - - info!( - "Balance of receiver {:?} now is {:?}, delta is {:?}", - hex::encode(acc_addr_rec), - new_balance, - new_balance - old_balance - ); - - Ok(()) - } - - // pub async fn operate_account_deposit_public( - // &mut self, - // acc_addr: AccountAddress, - // amount: u128, - // ) -> Result<(), ExecutionFailureKind> { - // let old_balance = { - // let acc_map_read_guard = self.storage.read().await; - // - // let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap(); - // - // acc.balance - // }; - // - // info!( - // "Balance of {:?} now is {old_balance:?}", - // hex::encode(acc_addr) - // ); - // - // let resp = self.send_public_deposit(acc_addr, amount).await?; - // info!("Response for public deposit is {resp:?}"); - // - // info!("Awaiting new blocks"); - // tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; - // - // let new_balance = { - // let acc_map_read_guard = self.storage.read().await; - // - // let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap(); - // - // acc.balance - // }; - // - // info!( - // "Balance of {:?} now is {new_balance:?}, delta is {:?}", - // hex::encode(acc_addr), - // new_balance - old_balance - // ); - // - // Ok(()) - // } - - pub async fn operate_account_send_shielded_one_receiver( - &mut self, - acc_addr_sender: AccountAddress, - acc_addr_rec: AccountAddress, - amount: u128, - ) -> Result { - let (resp, new_utxo_hashes) = self - .send_shielded_send_tx(acc_addr_sender, amount as u64, vec![(amount, acc_addr_rec)]) - .await?; - info!("Response for send shielded is {resp:?}"); - - let new_utxo_hash = new_utxo_hashes[0].1; - - info!("Awaiting new blocks"); - tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; - - let new_utxo = { - let mut write_guard = self.storage.write().await; - - let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap(); - acc.log(); - - acc.utxos.get(&new_utxo_hash).unwrap().clone() - }; - new_utxo.log(); - info!( - "Account address is {:?} ,new utxo owner address is {:?}", - hex::encode(acc_addr_rec), - hex::encode(new_utxo.owner) - ); - info!( - "Account {:?} got new utxo with amount {amount:?}", - hex::encode(acc_addr_rec) - ); - - Ok(new_utxo) - } - - pub async fn operate_account_send_private_one_receiver( - &mut self, - acc_addr_rec: AccountAddress, - utxo: UTXO, - comm_gen_hash: [u8; 32], - ) -> Result { - let amount = utxo.amount; - - let (resp, new_utxo_hashes) = self - .send_private_send_tx(utxo, comm_gen_hash, vec![(amount, acc_addr_rec)]) - .await?; - info!("Response for send private is {resp:?}"); - - let new_utxo_hash = new_utxo_hashes[0].1; - - info!("Awaiting new blocks"); - tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; - - let new_utxo = { - let mut write_guard = self.storage.write().await; - - let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap(); - acc.log(); - - acc.utxos.get(&new_utxo_hash).unwrap().clone() - }; - new_utxo.log(); - info!( - "Account address is {:?} ,new utxo owner address is {:?}", - hex::encode(acc_addr_rec), - hex::encode(new_utxo.owner) - ); - info!( - "Account {:?} got new utxo with amount {:?}", - hex::encode(acc_addr_rec), - new_utxo.amount - ); - - Ok(new_utxo) - } - - pub async fn operate_account_send_private_multiple_assets_one_receiver( - &mut self, - acc_addr: AccountAddress, - acc_addr_rec: AccountAddress, - utxos: Vec, - comm_gen_hashes: Vec<[u8; 32]>, - number_to_send: usize, - ) -> Result<(), ExecutionFailureKind> { - let (resp, new_utxo_hashes_rec, new_utxo_hashes_not_sp) = self - .send_private_multiple_assets_send_tx( - utxos, - comm_gen_hashes, - number_to_send, - acc_addr_rec, - ) - .await?; - info!("Response for send private multiple assets is {resp:?}"); - - info!("Awaiting new blocks"); - tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; - - { - let mut write_guard = self.storage.write().await; - - for new_utxo_hash in new_utxo_hashes_rec { - let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap(); - acc.log(); - - let new_utxo = acc.utxos.get(&new_utxo_hash).unwrap().clone(); - - new_utxo.log(); - info!( - "Account address is {:?} ,new utxo owner address is {:?}", - hex::encode(acc_addr_rec), - hex::encode(new_utxo.owner) - ); - info!( - "Account {:?} got new utxo with amount {:?} and asset {:?}", - hex::encode(acc_addr_rec), - new_utxo.amount, - new_utxo.asset, - ); - } - - for new_utxo_hash in new_utxo_hashes_not_sp { - let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap(); - acc.log(); - - let new_utxo = acc.utxos.get(&new_utxo_hash).unwrap().clone(); - - new_utxo.log(); - info!( - "Account address is {:?} ,new utxo owner address is {:?}", - hex::encode(acc_addr), - hex::encode(new_utxo.owner) - ); - info!( - "Account {:?} got new utxo with amount {:?} and asset {:?}", - hex::encode(acc_addr), - new_utxo.amount, - new_utxo.asset, - ); - } - } - - Ok(()) - } - - pub async fn split_utxo( - &self, - utxo: UTXO, - commitment_in: [u8; 32], - receivers: Vec<(u128, AccountAddress)>, - visibility_list: [bool; 3], - ) -> Result<(Transaction, Vec<(AccountAddress, [u8; 32])>), ExecutionFailureKind> { - let acc_map_read_guard = self.storage.read().await; - - let account = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap(); - - let nullifier = generate_nullifiers( - &utxo, - &account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key - .to_bytes(), - ); - - let (resulting_utxos, receipt) = prove_send_utxo(utxo, receivers)?; - let utxo_hashes = resulting_utxos - .iter() - .map(|(utxo, addr)| (*addr, utxo.hash)) - .collect(); - - let utxos: Vec = resulting_utxos - .iter() - .map(|(utxo, _)| utxo.clone()) - .collect(); - - let ephm_key_holder = EphemeralKeyHolder::new_os_random(); - ephm_key_holder.log(); - - let eph_pub_key = - serde_json::to_vec(&ephm_key_holder.generate_ephemeral_public_key()).unwrap(); - - let encoded_data: Vec<(Vec, Vec, u8)> = utxos - .iter() - .map(|utxo_enc| { - let accout_enc = acc_map_read_guard.acc_map.get(&utxo_enc.owner).unwrap(); - - let (ciphertext, nonce) = Account::encrypt_data( - &ephm_key_holder, - accout_enc.key_holder.viewing_public_key, - &serde_json::to_vec(&utxo_enc).unwrap(), - ); - - let tag = accout_enc.make_tag(); - - (ciphertext, nonce.to_vec(), tag) - }) - .collect(); - - let commitments = generate_commitments(&utxos); - - let publication = ActionData::UTXOPublication(UTXOPublication { - utxos: utxos - .iter() - .enumerate() - .filter_map(|(id, item)| { - if visibility_list[id] { - Some(item.clone()) - } else { - None - } - }) - .collect(), - }); - - let send_utxo_addr_bytes: Vec = zkvm::test_methods::SEND_UTXO_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let sc_addr = hex::encode(send_utxo_addr_bytes); - - //Sc does not change its state - let state_changes: Vec = vec![]; - let new_len = 0; - let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - - let sc_state = acc_map_read_guard - .block_store - .get_sc_sc_state(&sc_addr) - .map_err(ExecutionFailureKind::db_error)?; - - let mut vec_values_u64: Vec> = sc_state - .into_iter() - .map(|slice| vec_u8_to_vec_u64(slice.to_vec())) - .collect(); - - let context = acc_map_read_guard.produce_context(account.address); - - //Will not panic, as PublicScContext is serializable - let context_public_info: Vec = context.produce_u64_list_from_context().unwrap(); - vec_values_u64.push(context_public_info); - - let vec_public_info: Vec = vec_values_u64.into_iter().flatten().collect(); - - let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - - let transaction_body = TransactionBody { - tx_kind: TxKind::Shielded, - execution_input: vec![], - execution_output: serde_json::to_vec(&publication).unwrap(), - utxo_commitments_spent_hashes: vec![commitment_in], - utxo_commitments_created_hashes: commitments - .clone() - .into_iter() - .map(|hash_data| hash_data.try_into().unwrap()) - .collect(), - nullifier_created_hashes: vec![nullifier.try_into().unwrap()], - execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt) - .unwrap(), - encoded_data, - ephemeral_pub_key: eph_pub_key.to_vec(), - commitment, - tweak, - secret_r, - sc_addr, - state_changes, - }; - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); - - Ok(( - Transaction::new(transaction_body, key_to_sign_transaction), - utxo_hashes, - )) - } - - pub async fn send_split_tx( - &self, - utxo: UTXO, - comm_hash: [u8; 32], - receivers: Vec<(u128, AccountAddress)>, - visibility_list: [bool; 3], - ) -> Result<(SendTxResponse, Vec<([u8; 32], [u8; 32])>, Vec<[u8; 32]>), ExecutionFailureKind> - { - //Considering proof time, needs to be done before proof - let tx_roots = self.get_roots().await; - - let point_before_prove = std::time::Instant::now(); - let (tx, utxo_hashes) = self - .split_utxo(utxo, comm_hash, receivers, visibility_list) - .await?; - tx.body().log(); - let point_after_prove = std::time::Instant::now(); - - let timedelta = (point_after_prove - point_before_prove).as_millis(); - info!("Send private utxo proof spent {timedelta:?} milliseconds"); - - let commitments = tx.body().utxo_commitments_created_hashes.clone(); - - Ok(( - self.sequencer_client.send_tx(tx, tx_roots).await?, - utxo_hashes, - commitments, - )) - } - - pub async fn operate_account_send_split_utxo( - &mut self, - addrs_receivers: [AccountAddress; 3], - utxo: UTXO, - comm_gen_hash: [u8; 32], - visibility_list: [bool; 3], - ) -> Result<(Vec, Vec<[u8; 32]>), ExecutionFailureKind> { - let (resp, new_utxo_hashes, commitments_hashes) = self - .send_split_tx( - utxo.clone(), - comm_gen_hash, - addrs_receivers.map(|addr| (utxo.amount / 3, addr)).to_vec(), - visibility_list, - ) - .await?; - info!("Response for send shielded is {resp:?}"); - - info!("Awaiting new blocks"); - tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await; - - let new_utxos: Vec = { - let mut write_guard = self.storage.write().await; - - new_utxo_hashes - .into_iter() - .map(|(acc_addr_rec, new_utxo_hash)| { - let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap(); - - let new_utxo = acc.utxos.get(&new_utxo_hash).unwrap().clone(); - new_utxo.log(); - - info!( - "Account address is {:?} ,new utxo owner address is {:?}", - hex::encode(acc_addr_rec), - hex::encode(new_utxo.owner) - ); - info!( - "Account {:?} got new utxo with amount {:?}", - hex::encode(acc_addr_rec), - new_utxo.amount - ); - - new_utxo - }) - .collect() - }; - - Ok((new_utxos, commitments_hashes)) - } - - ///Mint utxo, make it public - pub async fn subscenario_1(&mut self) -> Result<(), ExecutionFailureKind> { - let acc_addr = self.create_new_account().await; - - let (new_utxo, comm_gen_hash) = self.operate_account_mint_private(acc_addr, 100).await?; - - self.operate_account_send_deshielded_one_receiver(acc_addr, new_utxo, comm_gen_hash) - .await?; - - Ok(()) - } - - ///Mint utxo, privately send it to another user - pub async fn subscenario_2(&mut self) -> Result<(), ExecutionFailureKind> { - let acc_addr = self.create_new_account().await; - let acc_addr_rec = self.create_new_account().await; - - let (new_utxo, comm_gen_hash) = self.operate_account_mint_private(acc_addr, 100).await?; - - self.operate_account_send_private_one_receiver(acc_addr_rec, new_utxo, comm_gen_hash) - .await?; - - Ok(()) - } - - ///Mint utxo, deshielded send it to another user - pub async fn subscenario_3(&mut self) -> Result<(), ExecutionFailureKind> { - let acc_addr = self.create_new_account().await; - let acc_addr_rec = self.create_new_account().await; - - let (new_utxo, comm_gen_hash) = self.operate_account_mint_private(acc_addr, 100).await?; - - self.operate_account_send_deshielded_one_receiver(acc_addr_rec, new_utxo, comm_gen_hash) - .await?; - - Ok(()) - } - - ///First complex scenario. - /// Creating accounts A, B, C, D. - /// Minting UTXO for A, splitting it between B, C, D. - /// Variable `visibility_list` decides, which of actions will be visible on blockchain. - /// Variable `publication index` decides, who of B, C or D moves its UTXO into public state. - pub async fn scenario_1( - &mut self, - visibility_list: [bool; 3], - publication_index: usize, - ) -> Result<(), ExecutionFailureKind> { - let acc_addr_sender = self.create_new_account().await; - - let acc_addr_rec_1 = self.create_new_account().await; - let acc_addr_rec_2 = self.create_new_account().await; - let acc_addr_rec_3 = self.create_new_account().await; - - let addrs_receivers = [acc_addr_rec_1, acc_addr_rec_2, acc_addr_rec_3]; - - let (new_utxo, comm_gen_hash) = self - .operate_account_mint_private(acc_addr_sender, 99) - .await?; - - let (new_utxos, comm_gen_hashes) = self - .operate_account_send_split_utxo( - addrs_receivers, - new_utxo, - comm_gen_hash, - visibility_list, - ) - .await?; - - self.operate_account_send_deshielded_one_receiver( - addrs_receivers[publication_index], - new_utxos[publication_index].clone(), - comm_gen_hashes[publication_index], - ) - .await?; - - Ok(()) - } - - ///Mint number of different assets with same amount for account - pub async fn scenario_2( - &mut self, - number_of_assets: usize, - number_to_send: usize, - ) -> Result<(), ExecutionFailureKind> { - let acc_addr_sender = self.create_new_account().await; - let acc_addr_receiver = self.create_new_account().await; - - let (utxos, comm_gen_hashes) = self - .operate_account_mint_multiple_assets_private(acc_addr_sender, 100, number_of_assets) - .await?; - - self.operate_account_send_private_multiple_assets_one_receiver( - acc_addr_sender, - acc_addr_receiver, - utxos, - comm_gen_hashes, - number_to_send, - ) - .await?; - - Ok(()) - } } pub fn generate_commitments_helper(input_utxos: &[UTXO]) -> Vec<[u8; 32]> { diff --git a/node_core/src/pre_start.rs b/node_core/src/pre_start.rs deleted file mode 100644 index e79dafc..0000000 --- a/node_core/src/pre_start.rs +++ /dev/null @@ -1,71 +0,0 @@ -use anyhow::Result; -use log::info; - -use crate::chain_storage::NodeChainStore; - -///Addres of public fund transfer account, as no such binary exists for zkVM -pub const PUBLIC_DEPOSIT_ID: [u8; 32] = [0; 32]; - -///Setups public states of default smart conracts as empty -pub async fn setup_empty_sc_states(node: &NodeChainStore) -> Result<()> { - info!("Filling up public states of default smart contracts"); - - let empty_state = vec![]; - - let public_deposit_addr = hex::encode(PUBLIC_DEPOSIT_ID); - node.block_store.put_sc_sc_state( - &public_deposit_addr, - empty_state.len(), - empty_state.clone(), - )?; - info!("Public transfer state set"); - - let mint_utxo_addr_bytes: Vec = zkvm::test_methods::MINT_UTXO_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let mint_utxo_addr = hex::encode(mint_utxo_addr_bytes); - node.block_store - .put_sc_sc_state(&mint_utxo_addr, empty_state.len(), empty_state.clone())?; - info!("Mint UTXO state set"); - - let single_utxo_transfer_addr_bytes: Vec = zkvm::test_methods::SEND_UTXO_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let single_utxo_transfer_addr = hex::encode(single_utxo_transfer_addr_bytes); - node.block_store.put_sc_sc_state( - &single_utxo_transfer_addr, - empty_state.len(), - empty_state.clone(), - )?; - info!("Single UTXO transfer state set"); - - let mint_utxo_multiple_assets_addr_bytes: Vec = - zkvm::test_methods::MINT_UTXO_MULTIPLE_ASSETS_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let mint_utxo_multiple_assets_addr = hex::encode(mint_utxo_multiple_assets_addr_bytes); - node.block_store.put_sc_sc_state( - &mint_utxo_multiple_assets_addr, - empty_state.len(), - empty_state.clone(), - )?; - info!("Mint UTXO multiple assets state set"); - - let multiple_assets_utxo_transfer_addr_bytes: Vec = - zkvm::test_methods::SEND_UTXO_MULTIPLE_ASSETS_ID - .iter() - .flat_map(|num| num.to_le_bytes()) - .collect(); - let multiple_assets_utxo_transfer_addr = hex::encode(multiple_assets_utxo_transfer_addr_bytes); - node.block_store.put_sc_sc_state( - &multiple_assets_utxo_transfer_addr, - empty_state.len(), - empty_state.clone(), - )?; - info!("Multiple_assets UTXO transfer state set"); - - Ok(()) -} diff --git a/node_rpc/src/process.rs b/node_rpc/src/process.rs index 29ac787..4546639 100644 --- a/node_rpc/src/process.rs +++ b/node_rpc/src/process.rs @@ -1,7 +1,6 @@ use std::sync::atomic::Ordering; use actix_web::Error as HttpError; -use node_core::generate_commitments_helper; use serde_json::Value; use common::rpc_primitives::{ @@ -11,25 +10,12 @@ use common::rpc_primitives::{ }; use common::transaction::ActionData; -use common::rpc_primitives::requests::{ - GetBlockDataRequest, GetBlockDataResponse, GetLastBlockRequest, GetLastBlockResponse, -}; +use common::rpc_primitives::requests::{GetLastBlockRequest, GetLastBlockResponse}; -use crate::types::{ - err_rpc::cast_common_execution_error_into_rpc_error, - rpc_structs::{ - CreateAccountRequest, CreateAccountResponse, ExecuteScenarioMultipleSendRequest, - ExecuteScenarioMultipleSendResponse, ExecuteScenarioSplitRequest, - ExecuteScenarioSplitResponse, ExecuteSubscenarioRequest, ExecuteSubscenarioResponse, - ShowAccountPublicBalanceRequest, ShowAccountPublicBalanceResponse, ShowAccountUTXORequest, - ShowAccountUTXOResponse, ShowTransactionRequest, ShowTransactionResponse, - UTXOShortEssentialStruct, WriteMintPrivateUTXOMultipleAssetsRequest, - WriteMintPrivateUTXOMultipleAssetsResponse, WriteMintPrivateUTXORequest, - WriteMintPrivateUTXOResponse, WriteSendDeshieldedBalanceRequest, - WriteSendDeshieldedUTXOResponse, WriteSendPrivateUTXORequest, WriteSendPrivateUTXOResponse, - WriteSendShieldedUTXORequest, WriteSendShieldedUTXOResponse, WriteSendSplitUTXOResponse, - WriteSplitUTXORequest, - }, +use crate::types::rpc_structs::{ + CreateAccountRequest, CreateAccountResponse, ShowAccountPublicBalanceRequest, + ShowAccountPublicBalanceResponse, ShowAccountUTXORequest, ShowAccountUTXOResponse, + ShowTransactionRequest, ShowTransactionResponse, }; pub const CREATE_ACCOUNT: &str = "create_account"; @@ -71,80 +57,6 @@ impl JsonHandler { } } - async fn process_request_execute_subscenario(&self, request: Request) -> Result { - let req = ExecuteSubscenarioRequest::parse(Some(request.params))?; - - { - let mut store = self.node_chain_store.lock().await; - - match req.scenario_id { - 1 => store - .subscenario_1() - .await - .map_err(cast_common_execution_error_into_rpc_error)?, - 2 => store - .subscenario_2() - .await - .map_err(cast_common_execution_error_into_rpc_error)?, - 3 => store - .subscenario_3() - .await - .map_err(cast_common_execution_error_into_rpc_error)?, - _ => return Err(RpcErr(RpcError::invalid_params("Scenario id not found"))), - } - } - - let helperstruct = ExecuteSubscenarioResponse { - scenario_result: SUCCESS.to_string(), - }; - - respond(helperstruct) - } - - async fn process_request_execute_scenario_split( - &self, - request: Request, - ) -> Result { - let req = ExecuteScenarioSplitRequest::parse(Some(request.params))?; - - { - let mut store = self.node_chain_store.lock().await; - - store - .scenario_1(req.visibility_list, req.publication_index) - .await - .map_err(cast_common_execution_error_into_rpc_error)?; - } - - let helperstruct = ExecuteScenarioSplitResponse { - scenario_result: SUCCESS.to_string(), - }; - - respond(helperstruct) - } - - async fn process_request_execute_scenario_multiple_send( - &self, - request: Request, - ) -> Result { - let req = ExecuteScenarioMultipleSendRequest::parse(Some(request.params))?; - - { - let mut store = self.node_chain_store.lock().await; - - store - .scenario_2(req.number_of_assets, req.number_to_send) - .await - .map_err(cast_common_execution_error_into_rpc_error)?; - } - - let helperstruct = ExecuteScenarioMultipleSendResponse { - scenario_result: SUCCESS.to_string(), - }; - - respond(helperstruct) - } - async fn process_create_account(&self, request: Request) -> Result { let _req = CreateAccountRequest::parse(Some(request.params))?; @@ -161,24 +73,6 @@ impl JsonHandler { respond(helperstruct) } - async fn process_get_block_data(&self, request: Request) -> Result { - let req = GetBlockDataRequest::parse(Some(request.params))?; - - let block = { - let guard = self.node_chain_store.lock().await; - - { - let read_guard = guard.storage.read().await; - - read_guard.block_store.get_block_at_id(req.block_id)? - } - }; - - let helperstruct = GetBlockDataResponse { block }; - - respond(helperstruct) - } - async fn process_get_last_block(&self, request: Request) -> Result { let _req = GetLastBlockRequest::parse(Some(request.params))?; @@ -349,406 +243,14 @@ impl JsonHandler { respond(helperstruct) } - pub async fn process_write_mint_utxo(&self, request: Request) -> Result { - let req = WriteMintPrivateUTXORequest::parse(Some(request.params))?; - - let acc_addr_hex_dec = hex::decode(req.account_addr.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode account address from hex string".to_string()) - })?; - - let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - let (utxo, commitment_hash) = { - let mut cover_guard = self.node_chain_store.lock().await; - - cover_guard - .operate_account_mint_private(acc_addr, req.amount as u128) - .await - .map_err(cast_common_execution_error_into_rpc_error)? - }; - - let helperstruct = WriteMintPrivateUTXOResponse { - status: SUCCESS.to_string(), - utxo: UTXOShortEssentialStruct { - hash: hex::encode(utxo.hash), - commitment_hash: hex::encode(commitment_hash), - asset: utxo.asset, - }, - }; - - respond(helperstruct) - } - - pub async fn process_write_mint_utxo_multiple_assets( - &self, - request: Request, - ) -> Result { - let req = WriteMintPrivateUTXOMultipleAssetsRequest::parse(Some(request.params))?; - - let acc_addr_hex_dec = hex::decode(req.account_addr.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode account address from hex string".to_string()) - })?; - - let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - let (utxos, commitment_hashes) = { - let mut cover_guard = self.node_chain_store.lock().await; - - cover_guard - .operate_account_mint_multiple_assets_private( - acc_addr, - req.amount as u128, - req.num_of_assets, - ) - .await - .map_err(cast_common_execution_error_into_rpc_error)? - }; - - let helperstruct = WriteMintPrivateUTXOMultipleAssetsResponse { - status: SUCCESS.to_string(), - utxos: utxos - .into_iter() - .zip(commitment_hashes) - .map(|(utxo, comm_hash)| UTXOShortEssentialStruct { - hash: hex::encode(utxo.hash), - commitment_hash: hex::encode(comm_hash), - asset: utxo.asset, - }) - .collect(), - }; - - respond(helperstruct) - } - - pub async fn process_write_send_private_utxo(&self, request: Request) -> Result { - let req = WriteSendPrivateUTXORequest::parse(Some(request.params))?; - - let acc_addr_hex_dec_sender = - hex::decode(req.account_addr_sender.clone()).map_err(|_| { - RpcError::parse_error( - "Failed to decode account address from hex string".to_string(), - ) - })?; - - let acc_addr_sender: [u8; 32] = acc_addr_hex_dec_sender.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - let acc_addr_hex_dec = hex::decode(req.account_addr_receiver.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode account address from hex string".to_string()) - })?; - - let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - let utxo_hash_hex_dec = hex::decode(req.utxo_hash.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode utxo hash from hex string".to_string()) - })?; - - let utxo_hash: [u8; 32] = utxo_hash_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse utxo hash from bytes".to_string()) - })?; - - let comm_hash_hex_dec = hex::decode(req.utxo_commitment.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode commitment hash from hex string".to_string()) - })?; - - let comm_hash: [u8; 32] = comm_hash_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse commitment hash from bytes".to_string()) - })?; - - let new_utxo_rec = { - let mut cover_guard = self.node_chain_store.lock().await; - - let utxo_to_send = { - let mut under_guard = cover_guard.storage.write().await; - - let acc = under_guard - .acc_map - .get_mut(&acc_addr_sender) - .ok_or(RpcError::new_internal_error(None, ACCOUNT_NOT_FOUND))?; - - acc.utxos - .get(&utxo_hash) - .ok_or(RpcError::new_internal_error( - None, - "UTXO does not exist in tree", - ))? - .clone() - }; - - cover_guard - .operate_account_send_private_one_receiver(acc_addr, utxo_to_send, comm_hash) - .await - .map_err(cast_common_execution_error_into_rpc_error)? - }; - - let helperstruct = WriteSendPrivateUTXOResponse { - status: SUCCESS.to_string(), - utxo_result: UTXOShortEssentialStruct { - hash: hex::encode(new_utxo_rec.hash), - asset: new_utxo_rec.asset.clone(), - commitment_hash: hex::encode(generate_commitments_helper(&[new_utxo_rec])[0]), - }, - }; - - respond(helperstruct) - } - - pub async fn process_write_send_shielded_utxo( - &self, - request: Request, - ) -> Result { - let req = WriteSendShieldedUTXORequest::parse(Some(request.params))?; - - let acc_addr_hex_dec_sender = - hex::decode(req.account_addr_sender.clone()).map_err(|_| { - RpcError::parse_error( - "Failed to decode account address sender from hex string".to_string(), - ) - })?; - - let acc_addr_sender: [u8; 32] = acc_addr_hex_dec_sender.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address sender from bytes".to_string()) - })?; - - let acc_addr_hex_dec_rec = - hex::decode(req.account_addr_receiver.clone()).map_err(|_| { - RpcError::parse_error( - "Failed to decode account address receiver from hex string".to_string(), - ) - })?; - - let acc_addr_rec: [u8; 32] = acc_addr_hex_dec_rec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address receiver from bytes".to_string()) - })?; - - let new_utxo_rec = { - let mut cover_guard = self.node_chain_store.lock().await; - - cover_guard - .operate_account_send_shielded_one_receiver( - acc_addr_sender, - acc_addr_rec, - req.amount as u128, - ) - .await - .map_err(cast_common_execution_error_into_rpc_error)? - }; - - let helperstruct = WriteSendShieldedUTXOResponse { - status: SUCCESS.to_string(), - utxo_result: UTXOShortEssentialStruct { - hash: hex::encode(new_utxo_rec.hash), - asset: new_utxo_rec.asset.clone(), - commitment_hash: hex::encode(generate_commitments_helper(&[new_utxo_rec])[0]), - }, - }; - - respond(helperstruct) - } - - pub async fn process_write_send_deshielded_utxo( - &self, - request: Request, - ) -> Result { - let req = WriteSendDeshieldedBalanceRequest::parse(Some(request.params))?; - - let acc_addr_hex_dec_sender = - hex::decode(req.account_addr_sender.clone()).map_err(|_| { - RpcError::parse_error( - "Failed to decode account address from hex string".to_string(), - ) - })?; - - let acc_addr_sender: [u8; 32] = acc_addr_hex_dec_sender.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - let acc_addr_hex_dec = hex::decode(req.account_addr_receiver.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode account address from hex string".to_string()) - })?; - - let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - let utxo_hash_hex_dec = hex::decode(req.utxo_hash.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode utxo hash from hex string".to_string()) - })?; - - let utxo_hash: [u8; 32] = utxo_hash_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse utxo hash from bytes".to_string()) - })?; - - let comm_hash_hex_dec = hex::decode(req.utxo_commitment.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode commitment hash from hex string".to_string()) - })?; - - let comm_hash: [u8; 32] = comm_hash_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse commitment hash from bytes".to_string()) - })?; - - { - let mut cover_guard = self.node_chain_store.lock().await; - - let utxo_to_send = { - let mut under_guard = cover_guard.storage.write().await; - - let acc = under_guard - .acc_map - .get_mut(&acc_addr_sender) - .ok_or(RpcError::new_internal_error(None, ACCOUNT_NOT_FOUND))?; - - acc.utxos - .get(&utxo_hash) - .ok_or(RpcError::new_internal_error( - None, - "UTXO does not exist in tree", - ))? - .clone() - }; - - cover_guard - .operate_account_send_deshielded_one_receiver(acc_addr, utxo_to_send, comm_hash) - .await - .map_err(cast_common_execution_error_into_rpc_error)? - }; - - let helperstruct = WriteSendDeshieldedUTXOResponse { - status: SUCCESS.to_string(), - }; - - respond(helperstruct) - } - - pub async fn process_write_send_split_utxo(&self, request: Request) -> Result { - let req = WriteSplitUTXORequest::parse(Some(request.params))?; - - let acc_addr_hex_dec_sender = - hex::decode(req.account_addr_sender.clone()).map_err(|_| { - RpcError::parse_error( - "Failed to decode account address from hex string".to_string(), - ) - })?; - - let acc_addr_sender: [u8; 32] = acc_addr_hex_dec_sender.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - let acc_addresses = { - let mut res_addrs = vec![]; - - for item in req.account_addr_receivers { - let hex_dec_item = hex::decode(item).map_err(|_| { - RpcError::parse_error( - "Failed to decode account address from hex string".to_string(), - ) - })?; - - let dec_item = hex_dec_item.try_into().map_err(|_| { - RpcError::parse_error( - "Failed to decode account address from hex string".to_string(), - ) - })?; - - res_addrs.push(dec_item); - } - - res_addrs.try_into().unwrap() - }; - - let utxo_hash_hex_dec = hex::decode(req.utxo_hash.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode utxo hash from hex string".to_string()) - })?; - - let utxo_hash: [u8; 32] = utxo_hash_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse utxo hash from bytes".to_string()) - })?; - - let comm_hash_hex_dec = hex::decode(req.utxo_commitment.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode commitment hash from hex string".to_string()) - })?; - - let comm_hash: [u8; 32] = comm_hash_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse commitment hash from bytes".to_string()) - })?; - - let (new_utxos, commitment_hashes) = { - let mut cover_guard = self.node_chain_store.lock().await; - - let utxo_to_send = { - let mut under_guard = cover_guard.storage.write().await; - - let acc = under_guard - .acc_map - .get_mut(&acc_addr_sender) - .ok_or(RpcError::new_internal_error(None, ACCOUNT_NOT_FOUND))?; - - acc.utxos - .get(&utxo_hash) - .ok_or(RpcError::new_internal_error( - None, - "UTXO does not exist in tree", - ))? - .clone() - }; - - cover_guard - .operate_account_send_split_utxo( - acc_addresses, - utxo_to_send, - comm_hash, - req.visibility_list, - ) - .await - .map_err(cast_common_execution_error_into_rpc_error)? - }; - - let helperstruct = WriteSendSplitUTXOResponse { - status: SUCCESS.to_string(), - utxo_results: new_utxos - .into_iter() - .zip(commitment_hashes) - .map(|(utxo, comm_hash)| UTXOShortEssentialStruct { - hash: hex::encode(utxo.hash), - commitment_hash: hex::encode(comm_hash), - asset: utxo.asset, - }) - .collect(), - }; - - respond(helperstruct) - } - pub async fn process_request_internal(&self, request: Request) -> Result { match request.method.as_ref() { //Todo : Add handling of more JSON RPC methods CREATE_ACCOUNT => self.process_create_account(request).await, - EXECUTE_SUBSCENARIO => self.process_request_execute_subscenario(request).await, - GET_BLOCK => self.process_get_block_data(request).await, GET_LAST_BLOCK => self.process_get_last_block(request).await, - EXECUTE_SCENARIO_SPLIT => self.process_request_execute_scenario_split(request).await, - EXECUTE_SCENARIO_MULTIPLE_SEND => { - self.process_request_execute_scenario_multiple_send(request) - .await - } SHOW_ACCOUNT_PUBLIC_BALANCE => self.process_show_account_public_balance(request).await, SHOW_ACCOUNT_UTXO => self.process_show_account_utxo_request(request).await, SHOW_TRANSACTION => self.process_show_transaction(request).await, - WRITE_MINT_UTXO => self.process_write_mint_utxo(request).await, - WRITE_MINT_UTXO_MULTIPLE_ASSETS => { - self.process_write_mint_utxo_multiple_assets(request).await - } - WRITE_SEND_UTXO_PRIVATE => self.process_write_send_private_utxo(request).await, - WRITE_SEND_UTXO_SHIELDED => self.process_write_send_shielded_utxo(request).await, - WRITE_SEND_UTXO_DESHIELDED => self.process_write_send_deshielded_utxo(request).await, - WRITE_SPLIT_UTXO => self.process_write_send_split_utxo(request).await, _ => Err(RpcErr(RpcError::method_not_found(request.method))), } } From 4f95cef08f55ed6f7e476f229d97d9a10b101404 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Tue, 5 Aug 2025 14:59:20 +0300 Subject: [PATCH 2/5] fix: code cleanup and final removals --- Cargo.lock | 94 +----- Cargo.toml | 5 - common/Cargo.toml | 1 + common/src/block.rs | 16 +- common/src/lib.rs | 3 + common/src/test_utils.rs | 116 ++++++++ consensus/Cargo.toml | 15 - consensus/src/lib.rs | 22 -- integration_tests/Cargo.toml | 6 - integration_tests/src/lib.rs | 23 +- networking/Cargo.toml | 11 - networking/src/lib.rs | 5 - networking/src/network_protocol.rs | 19 -- networking/src/peer.rs | 18 -- networking/src/peer_manager.rs | 20 -- networking/src/rate_limiter.rs | 16 -- networking/src/tcp.rs | 11 - node_core/src/chain_storage/block_store.rs | 269 ------------------ node_core/src/chain_storage/mod.rs | 79 +---- node_core/src/config.rs | 12 + node_core/src/lib.rs | 13 +- node_rpc/Cargo.toml | 45 --- node_rpc/src/lib.rs | 45 --- node_rpc/src/net_utils.rs | 76 ----- node_rpc/src/process.rs | 257 ----------------- node_rpc/src/types/err_rpc.rs | 85 ------ node_rpc/src/types/mod.rs | 2 - node_rpc/src/types/rpc_structs.rs | 206 -------------- node_runner/Cargo.toml | 50 ---- node_runner/configs/debug/node_config.json | 253 ---------------- node_runner/src/config.rs | 14 - node_runner/src/lib.rs | 56 ---- node_runner/src/main.rs | 16 -- sequencer_core/src/lib.rs | 122 +++----- .../src/sequencer_store/block_store.rs | 37 +-- sequencer_core/src/sequencer_store/mod.rs | 4 +- sequencer_rpc/Cargo.toml | 6 - sequencer_runner/Cargo.toml | 6 - vm/Cargo.toml | 11 - vm/src/lib.rs | 1 - 40 files changed, 212 insertions(+), 1854 deletions(-) create mode 100644 common/src/test_utils.rs delete mode 100644 consensus/Cargo.toml delete mode 100644 consensus/src/lib.rs delete mode 100644 networking/Cargo.toml delete mode 100644 networking/src/lib.rs delete mode 100644 networking/src/network_protocol.rs delete mode 100644 networking/src/peer.rs delete mode 100644 networking/src/peer_manager.rs delete mode 100644 networking/src/rate_limiter.rs delete mode 100644 networking/src/tcp.rs delete mode 100644 node_core/src/chain_storage/block_store.rs delete mode 100644 node_rpc/Cargo.toml delete mode 100644 node_rpc/src/lib.rs delete mode 100644 node_rpc/src/net_utils.rs delete mode 100644 node_rpc/src/process.rs delete mode 100644 node_rpc/src/types/err_rpc.rs delete mode 100644 node_rpc/src/types/mod.rs delete mode 100644 node_rpc/src/types/rpc_structs.rs delete mode 100644 node_runner/Cargo.toml delete mode 100644 node_runner/configs/debug/node_config.json delete mode 100644 node_runner/src/config.rs delete mode 100644 node_runner/src/lib.rs delete mode 100644 node_runner/src/main.rs delete mode 100644 vm/Cargo.toml delete mode 100644 vm/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 5d64132..272ba6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1016,6 +1016,7 @@ dependencies = [ "hex", "k256", "log", + "rand 0.8.5", "reqwest 0.11.27", "risc0-zkvm", "rs_merkle", @@ -1026,19 +1027,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "consensus" -version = "0.1.0" -dependencies = [ - "anyhow", - "env_logger", - "log", - "networking", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "const-oid" version = "0.9.6" @@ -2395,8 +2383,6 @@ dependencies = [ "hex", "log", "node_core", - "node_rpc", - "node_runner", "sequencer_core", "sequencer_rpc", "sequencer_runner", @@ -2943,17 +2929,6 @@ dependencies = [ "rayon", ] -[[package]] -name = "networking" -version = "0.1.0" -dependencies = [ - "anyhow", - "env_logger", - "log", - "serde", - "serde_json", -] - [[package]] name = "no_std_strings" version = "0.1.3" @@ -2990,58 +2965,6 @@ dependencies = [ "zkvm", ] -[[package]] -name = "node_rpc" -version = "0.1.0" -dependencies = [ - "accounts", - "actix", - "actix-cors", - "actix-web", - "anyhow", - "common", - "consensus", - "env_logger", - "futures", - "hex", - "log", - "networking", - "node_core", - "serde", - "serde_json", - "storage", - "tokio", - "utxo", - "vm", - "zkvm", -] - -[[package]] -name = "node_runner" -version = "0.1.0" -dependencies = [ - "accounts", - "actix", - "actix-web", - "anyhow", - "clap", - "common", - "consensus", - "env_logger", - "hex", - "log", - "networking", - "node_core", - "node_rpc", - "serde", - "serde_json", - "storage", - "tokio", - "utxo", - "vm", - "zkvm", -] - [[package]] name = "nom" version = "7.1.3" @@ -4429,13 +4352,11 @@ dependencies = [ "actix-web", "anyhow", "common", - "consensus", "env_logger", "futures", "hex", "log", "mempool", - "networking", "sequencer_core", "serde", "serde_json", @@ -4453,11 +4374,9 @@ dependencies = [ "anyhow", "clap", "common", - "consensus", "env_logger", "log", "mempool", - "networking", "sequencer_core", "sequencer_rpc", "serde", @@ -5293,17 +5212,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "vm" -version = "0.1.0" -dependencies = [ - "anyhow", - "env_logger", - "log", - "serde", - "serde_json", -] - [[package]] name = "want" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 4ce7c9a..41c5309 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,10 @@ [workspace] resolver = "2" members = [ - "node_runner", "sequencer_runner", "storage", "accounts", "utxo", - "vm", - "networking", - "consensus", - "node_rpc", "sequencer_rpc", "mempool", "zkvm", diff --git a/common/Cargo.toml b/common/Cargo.toml index 7e4e0ab..7cf728f 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -11,6 +11,7 @@ serde.workspace = true reqwest.workspace = true risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } k256.workspace = true +rand.workspace = true rs_merkle.workspace = true sha2.workspace = true diff --git a/common/src/block.rs b/common/src/block.rs index 7757667..c566075 100644 --- a/common/src/block.rs +++ b/common/src/block.rs @@ -26,19 +26,19 @@ pub struct HashableBlockData { pub data: Data, } -impl Block { - pub fn produce_block_from_hashable_data(hashable_data: HashableBlockData) -> Self { - let data = serde_json::to_vec(&hashable_data).unwrap(); +impl From for Block { + fn from(value: HashableBlockData) -> Self { + let data = serde_json::to_vec(&value).unwrap(); let hash = OwnHasher::hash(&data); Self { - block_id: hashable_data.block_id, - prev_block_id: hashable_data.prev_block_id, + block_id: value.block_id, + prev_block_id: value.prev_block_id, hash, - transactions: hashable_data.transactions, - data: hashable_data.data, - prev_block_hash: hashable_data.prev_block_hash, + transactions: value.transactions, + data: value.data, + prev_block_hash: value.prev_block_hash, } } } diff --git a/common/src/lib.rs b/common/src/lib.rs index 1722218..91f0a08 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -10,6 +10,9 @@ pub mod rpc_primitives; pub mod transaction; pub mod utxo_commitment; +//Module for tests utility functions +pub mod test_utils; + use rpc_primitives::errors::RpcError; ///Account id on blockchain diff --git a/common/src/test_utils.rs b/common/src/test_utils.rs new file mode 100644 index 0000000..e78b291 --- /dev/null +++ b/common/src/test_utils.rs @@ -0,0 +1,116 @@ +use k256::ecdsa::SigningKey; +use secp256k1_zkp::Tweak; + +use crate::{ + block::{Block, HashableBlockData}, execution_input::PublicNativeTokenSend, transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind} +}; + +//Dummy producers + +///Produce dummy block with +/// +/// `id` - block id, provide zero for genesis +/// +/// `prev_hash` - hash of previous block, provide None for genesis +/// +/// `transactions` - vector of `Transaction` objects +/// +/// `additional_data` - vector with additional data +pub fn produce_dummy_block( + id: u64, + prev_hash: Option<[u8; 32]>, + transactions: Vec, + additional_data: Vec, +) -> Block { + let block_data = HashableBlockData { + block_id: id, + prev_block_id: id.saturating_sub(1), + prev_block_hash: prev_hash.unwrap_or_default(), + transactions, + data: additional_data, + }; + + block_data.into() +} + +pub fn produce_dummy_empty_transaction() -> Transaction { + let body = TransactionBody { + tx_kind: TxKind::Public, + execution_input: Default::default(), + execution_output: Default::default(), + utxo_commitments_spent_hashes: Default::default(), + utxo_commitments_created_hashes: Default::default(), + nullifier_created_hashes: Default::default(), + execution_proof_private: Default::default(), + encoded_data: Default::default(), + ephemeral_pub_key: Default::default(), + commitment: Default::default(), + tweak: Default::default(), + secret_r: Default::default(), + sc_addr: Default::default(), + state_changes: Default::default(), + }; + + Transaction::new(body, SignaturePrivateKey::from_slice(&[1; 32]).unwrap()) +} + +pub fn create_dummy_private_transaction_random_signer( + nullifier_created_hashes: Vec<[u8; 32]>, + utxo_commitments_spent_hashes: Vec<[u8; 32]>, + utxo_commitments_created_hashes: Vec<[u8; 32]>, + ) -> Transaction { + let mut rng = rand::thread_rng(); + + let body = TransactionBody { + tx_kind: TxKind::Private, + execution_input: vec![], + execution_output: vec![], + utxo_commitments_spent_hashes, + utxo_commitments_created_hashes, + nullifier_created_hashes, + execution_proof_private: "dummy_proof".to_string(), + encoded_data: vec![], + ephemeral_pub_key: vec![10, 11, 12], + commitment: vec![], + tweak: Tweak::new(&mut rng), + secret_r: [0; 32], + sc_addr: "sc_addr".to_string(), + state_changes: (serde_json::Value::Null, 0), + }; + Transaction::new(body, SignaturePrivateKey::random(&mut rng)) + } + +pub fn create_dummy_transaction_native_token_transfer( + from: [u8; 32], + nonce: u64, + to: [u8; 32], + balance_to_move: u64, + signing_key: SigningKey, + ) -> Transaction { + let mut rng = rand::thread_rng(); + + let native_token_transfer = PublicNativeTokenSend { + from, + nonce, + to, + balance_to_move, + }; + + let body = TransactionBody { + tx_kind: TxKind::Public, + execution_input: serde_json::to_vec(&native_token_transfer).unwrap(), + execution_output: vec![], + utxo_commitments_spent_hashes: vec![], + utxo_commitments_created_hashes: vec![], + nullifier_created_hashes: vec![], + execution_proof_private: "".to_string(), + encoded_data: vec![], + ephemeral_pub_key: vec![10, 11, 12], + commitment: vec![], + tweak: Tweak::new(&mut rng), + secret_r: [0; 32], + sc_addr: "sc_addr".to_string(), + state_changes: (serde_json::Value::Null, 0), + }; + Transaction::new(body, signing_key) + } diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml deleted file mode 100644 index 664f53d..0000000 --- a/consensus/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "consensus" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true -tokio.workspace = true - -[dependencies.networking] -path = "../networking" diff --git a/consensus/src/lib.rs b/consensus/src/lib.rs deleted file mode 100644 index 3d4e60e..0000000 --- a/consensus/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::sync::Arc; - -use networking::peer_manager::PeerManager; -use tokio::sync::Mutex; - -#[derive(Debug)] -///Entrypoint to consensus. -/// Manages consensus protocol. -pub struct ConsensusManager { - pub peer_manager: Arc>, -} - -impl ConsensusManager { - pub fn new(peer_manager: Arc>) -> Self { - Self { peer_manager } - } - - //ToDo: change block from generic value into struct, when data block will be defined - pub fn vote(&self, _block: serde_json::Value) -> bool { - todo!() - } -} diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index 0e96490..e37d014 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -30,15 +30,9 @@ path = "../sequencer_core" [dependencies.sequencer_runner] path = "../sequencer_runner" -[dependencies.node_rpc] -path = "../node_rpc" - [dependencies.node_core] path = "../node_core" -[dependencies.node_runner] -path = "../node_runner" - [dependencies.common] path = "../common" diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index a2c10c5..6438542 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -3,7 +3,6 @@ use std::{path::PathBuf, sync::Arc, time::Duration}; use actix_web::dev::ServerHandle; use anyhow::Result; use clap::Parser; -use common::rpc_primitives::RpcConfig; use log::info; use node_core::{NodeCore, config::NodeConfig}; use sequencer_core::config::SequencerConfig; @@ -31,7 +30,6 @@ pub async fn pre_test( ) -> Result<( ServerHandle, JoinHandle>, - ServerHandle, TempDir, TempDir, Arc>, @@ -43,7 +41,7 @@ pub async fn pre_test( sequencer_runner::config::from_file(home_dir_sequencer.join("sequencer_config.json")) .unwrap(); let mut node_config = - node_runner::config::from_file(home_dir_node.join("node_config.json")).unwrap(); + node_core::config::from_file(home_dir_node.join("node_config.json")).unwrap(); let (temp_dir_node, temp_dir_sequencer) = replace_home_dir_with_temp_dir_in_configs(&mut node_config, &mut sequencer_config); @@ -51,25 +49,13 @@ pub async fn pre_test( let (seq_http_server_handle, sequencer_loop_handle) = startup_sequencer(sequencer_config).await?; - let node_port = node_config.port; - let node_core = NodeCore::start_from_config_update_chain(node_config.clone()).await?; let wrapped_node_core = Arc::new(Mutex::new(node_core)); - let http_server = node_rpc::new_http_server( - RpcConfig::with_port(node_port), - node_config.clone(), - wrapped_node_core.clone(), - )?; - info!("HTTP server started"); - let node_http_server_handle = http_server.handle(); - tokio::spawn(http_server); - Ok(( seq_http_server_handle, sequencer_loop_handle, - node_http_server_handle, temp_dir_node, temp_dir_sequencer, wrapped_node_core, @@ -94,18 +80,15 @@ pub async fn post_test( residual: ( ServerHandle, JoinHandle>, - ServerHandle, TempDir, TempDir, Arc>, ), ) { - let (seq_http_server_handle, sequencer_loop_handle, node_http_server_handle, _, _, _) = - residual; + let (seq_http_server_handle, sequencer_loop_handle, _, _, _) = residual; info!("Cleanup"); - node_http_server_handle.stop(true).await; sequencer_loop_handle.abort(); seq_http_server_handle.stop(true).await; @@ -224,7 +207,7 @@ macro_rules! test_cleanup_wrap { ($home_dir:ident, $test_func:ident) => {{ let res = pre_test($home_dir.clone()).await.unwrap(); - let wrapped_node_core = res.5.clone(); + let wrapped_node_core = res.4.clone(); info!("Waiting for first block creation"); tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; diff --git a/networking/Cargo.toml b/networking/Cargo.toml deleted file mode 100644 index 5649f66..0000000 --- a/networking/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "networking" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true diff --git a/networking/src/lib.rs b/networking/src/lib.rs deleted file mode 100644 index 77025d9..0000000 --- a/networking/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod network_protocol; -pub mod peer; -pub mod peer_manager; -pub mod rate_limiter; -pub mod tcp; diff --git a/networking/src/network_protocol.rs b/networking/src/network_protocol.rs deleted file mode 100644 index 333887b..0000000 --- a/networking/src/network_protocol.rs +++ /dev/null @@ -1,19 +0,0 @@ -#[derive(Debug)] -pub enum MessageKind {} - -pub type PeerId = u64; -pub type PeerDistance = u32; - -#[derive(Debug)] -pub struct PeerAddr { - pub id: PeerId, - //Probably will be socket address in the future - pub addr: String, -} - -#[derive(Debug)] -///Structure, which contains all necessary fields for handshake -pub struct Handshake {} - -#[derive(Debug)] -pub enum HandshakeFailedReason {} diff --git a/networking/src/peer.rs b/networking/src/peer.rs deleted file mode 100644 index c7775d8..0000000 --- a/networking/src/peer.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::{ - network_protocol::{HandshakeFailedReason, PeerAddr}, - tcp::Connection, -}; - -#[derive(Debug)] -/// Structure, which stores all of the peer interaction data. -/// Created at per-peer connection basis at `PeerManager` -pub struct Peer { - pub connection: Connection, - pub peer_addr: PeerAddr, -} - -impl Peer { - pub fn handshake(&mut self) -> Result<(), HandshakeFailedReason> { - todo!(); - } -} diff --git a/networking/src/peer_manager.rs b/networking/src/peer_manager.rs deleted file mode 100644 index f75cb81..0000000 --- a/networking/src/peer_manager.rs +++ /dev/null @@ -1,20 +0,0 @@ -use anyhow::Result; - -use crate::{network_protocol::PeerId, peer::Peer}; - -#[derive(Debug)] -///Entrypoint to network module. -/// Manages connections with peers in network -pub struct PeerManager { - pub my_peer_id: PeerId, -} - -impl PeerManager { - pub async fn start_peer_manager(_num_threads: u8, my_peer_id: PeerId) -> Result { - Ok(Self { my_peer_id }) - } - - pub async fn connect(&self, _peer_id: PeerId) -> Peer { - todo!() - } -} diff --git a/networking/src/rate_limiter.rs b/networking/src/rate_limiter.rs deleted file mode 100644 index 316e5a3..0000000 --- a/networking/src/rate_limiter.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::collections::HashMap; - -use crate::network_protocol::MessageKind; - -#[derive(Debug)] -/// Object responsible to manage the rate limits of all network messages -/// for a single connection/peer. -pub struct RateLimiter { - pub limits: HashMap, -} - -impl RateLimiter { - pub fn is_allowed(&self, _message: MessageKind) -> bool { - todo!(); - } -} diff --git a/networking/src/tcp.rs b/networking/src/tcp.rs deleted file mode 100644 index 406c64f..0000000 --- a/networking/src/tcp.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::network_protocol::PeerAddr; - -#[derive(Debug)] -///Structure, representing peer connection -pub struct Connection {} - -#[derive(Debug)] -pub enum ConnectionType { - Inbound { conn: Connection }, - Outbound { conn: Connection, peer: PeerAddr }, -} diff --git a/node_core/src/chain_storage/block_store.rs b/node_core/src/chain_storage/block_store.rs deleted file mode 100644 index ba97c3c..0000000 --- a/node_core/src/chain_storage/block_store.rs +++ /dev/null @@ -1,269 +0,0 @@ -use std::collections::{HashMap, HashSet}; -use std::path::Path; - -use accounts::account_core::Account; -use anyhow::{anyhow, Result}; -use common::block::Block; -use common::merkle_tree_public::merkle_tree::HashStorageMerkleTree; -use common::nullifier::UTXONullifier; -use common::transaction::Transaction; -use common::utxo_commitment::UTXOCommitment; -use log::error; -use storage::sc_db_utils::{DataBlob, DataBlobChangeVariant}; -use storage::RocksDBIO; - -use crate::chain_storage::AccMap; - -pub struct NodeBlockStore { - dbio: RocksDBIO, -} - -impl NodeBlockStore { - ///Starting database at the start of new chain. - /// Creates files if necessary. - /// - /// ATTENTION: Will overwrite genesis block. - pub fn open_db_with_genesis(location: &Path, genesis_block: Option) -> Result { - Ok(Self { - dbio: RocksDBIO::new(location, genesis_block)?, - }) - } - - ///Reopening existing database - pub fn open_db_restart(location: &Path, genesis_block: Block) -> Result { - NodeBlockStore::db_destroy(location)?; - NodeBlockStore::open_db_with_genesis(location, Some(genesis_block)) - } - - ///Reloading existing database - pub fn open_db_reload(location: &Path) -> Result { - NodeBlockStore::open_db_with_genesis(location, None) - } - - ///Destroying existing database - fn db_destroy(location: &Path) -> Result<()> { - RocksDBIO::destroy(location).map_err(|err| anyhow!("RocksDBIO error: {}", err)) - } - - pub fn get_block_at_id(&self, id: u64) -> Result { - Ok(self.dbio.get_block(id)?) - } - - pub fn put_block_at_id(&self, block: Block) -> Result<()> { - Ok(self.dbio.put_block(block, false)?) - } - - pub fn put_sc_sc_state( - &self, - sc_addr: &str, - length: usize, - modifications: Vec, - ) -> Result<()> { - Ok(self.dbio.put_sc_sc_state(sc_addr, length, modifications)?) - } - - pub fn get_sc_sc_state(&self, sc_addr: &str) -> Result> { - Ok(self.dbio.get_sc_sc_state(sc_addr)?) - } - - pub fn get_snapshot_block_id(&self) -> Result { - Ok(self.dbio.get_snapshot_block_id()?) - } - - pub fn get_snapshot_account(&self) -> Result> { - let temp: AccMap = serde_json::from_slice(&self.dbio.get_snapshot_account()?)?; - Ok(temp.into()) - } - - pub fn get_snapshot_commitment(&self) -> Result> { - Ok(serde_json::from_slice( - &self.dbio.get_snapshot_commitment()?, - )?) - } - - pub fn get_snapshot_nullifier(&self) -> Result> { - Ok(serde_json::from_slice( - &self.dbio.get_snapshot_nullifier()?, - )?) - } - - pub fn get_snapshot_transaction(&self) -> Result> { - Ok(serde_json::from_slice( - &self.dbio.get_snapshot_transaction()?, - )?) - } - - pub fn put_snapshot_at_block_id( - &self, - id: u64, - accounts_ser: Vec, - comm_ser: Vec, - txs_ser: Vec, - nullifiers_ser: Vec, - ) -> Result<()> { - //Error notification for writing into DB error - self.dbio - .put_snapshot_block_id_db(id) - .inspect_err(|err| error!("Failed to store snapshot block id with error {err:#?}"))?; - self.dbio - .put_snapshot_account_db(accounts_ser) - .inspect_err(|err| error!("Failed to store snapshot accounts with error {err:#?}"))?; - self.dbio - .put_snapshot_commitement_db(comm_ser) - .inspect_err(|err| { - error!("Failed to store snapshot commitments with error {err:#?}") - })?; - self.dbio - .put_snapshot_transaction_db(txs_ser) - .inspect_err(|err| { - error!("Failed to store snapshot transactions with error {err:#?}") - })?; - self.dbio - .put_snapshot_nullifier_db(nullifiers_ser) - .inspect_err(|err| error!("Failed to store snapshot nullifiers with error {err:#?}"))?; - - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use common::block::Data; - use tempfile::tempdir; - - fn create_genesis_block() -> Block { - Block { - block_id: 0, - prev_block_id: 0, - prev_block_hash: [0; 32], - hash: [1; 32], - transactions: vec![], - data: Data::default(), - } - } - - fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block { - Block { - block_id, - prev_block_id, - prev_block_hash: [0; 32], - hash: [1; 32], - transactions: vec![], - data: Data::default(), - } - } - - #[test] - fn test_open_db_with_genesis() { - let temp_dir = tempdir().unwrap(); - let path = temp_dir.path(); - - let genesis_block = create_genesis_block(); - let node_store = - NodeBlockStore::open_db_with_genesis(path, Some(genesis_block.clone())).unwrap(); - - // Verify the genesis block is stored - let stored_block = node_store.get_block_at_id(0).unwrap(); - assert_eq!(stored_block.block_id, genesis_block.block_id); - assert_eq!(stored_block.hash, genesis_block.hash); - } - - #[test] - fn test_open_db_restart() { - let temp_dir = tempdir().unwrap(); - let path = temp_dir.path(); - - let genesis_block = create_genesis_block(); - { - let node_store_old = - NodeBlockStore::open_db_with_genesis(path, Some(genesis_block.clone())).unwrap(); - - let block = create_sample_block(1, 0); - node_store_old.put_block_at_id(block.clone()).unwrap(); - } - - // Check that the first block is still in the old database - { - let node_store_old = NodeBlockStore::open_db_reload(path).unwrap(); - let result = node_store_old.get_block_at_id(1); - assert!(result.is_ok()); - } - - // Restart the database - let node_store = NodeBlockStore::open_db_restart(path, genesis_block).unwrap(); - - // The block should no longer be available since no first block is set on restart - let result = node_store.get_block_at_id(1); - assert!(result.is_err()); - } - - #[test] - fn test_open_db_reload() { - let temp_dir = tempdir().unwrap(); - let path = temp_dir.path(); - - let genesis_block = create_genesis_block(); - let _ = NodeBlockStore::open_db_with_genesis(path, Some(genesis_block)).unwrap(); - - // Reload the database - let node_store = NodeBlockStore::open_db_reload(path).unwrap(); - - // The genesis block should be available on reload - let result = node_store.get_block_at_id(0); - assert!(result.is_ok()); - } - - #[test] - fn test_put_and_get_block() { - let temp_dir = tempdir().unwrap(); - let path = temp_dir.path(); - - let genesis_block = create_genesis_block(); - let node_store = NodeBlockStore::open_db_with_genesis(path, Some(genesis_block)).unwrap(); - - let block = create_sample_block(1, 0); - node_store.put_block_at_id(block.clone()).unwrap(); - - let retrieved_block = node_store.get_block_at_id(1).unwrap(); - assert_eq!(retrieved_block.block_id, block.block_id); - assert_eq!(retrieved_block.hash, block.hash); - } - - #[test] - fn test_put_snapshot_at_block_id() { - let temp_dir = tempdir().unwrap(); - let path = temp_dir.path(); - - let genesis_block = create_genesis_block(); - let node_store = NodeBlockStore::open_db_with_genesis(path, Some(genesis_block)).unwrap(); - - let id = 3; - let accounts_ser = vec![1, 2, 3, 4]; - let comm_ser = vec![5, 6, 7, 8]; - let txs_ser = vec![9, 10, 11, 12]; - let nullifiers_ser = vec![13, 14, 15, 16]; - - node_store - .put_snapshot_at_block_id( - id, - accounts_ser.clone(), - comm_ser.clone(), - txs_ser.clone(), - nullifiers_ser.clone(), - ) - .unwrap(); - - assert_eq!(node_store.dbio.get_snapshot_block_id().unwrap(), id); - assert_eq!( - node_store.dbio.get_snapshot_account().unwrap(), - accounts_ser - ); - assert_eq!(node_store.dbio.get_snapshot_commitment().unwrap(), comm_ser); - assert_eq!(node_store.dbio.get_snapshot_transaction().unwrap(), txs_ser); - assert_eq!( - node_store.dbio.get_snapshot_nullifier().unwrap(), - nullifiers_ser - ); - } -} diff --git a/node_core/src/chain_storage/mod.rs b/node_core/src/chain_storage/mod.rs index 63bbbc1..62ec130 100644 --- a/node_core/src/chain_storage/mod.rs +++ b/node_core/src/chain_storage/mod.rs @@ -3,7 +3,6 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use accounts::account_core::{address::AccountAddress, Account}; use anyhow::Result; use common::{ - block::Block, merkle_tree_public::merkle_tree::{PublicTransactionMerkleTree, UTXOCommitmentsMerkleTree}, nullifier::UTXONullifier, }; @@ -13,7 +12,6 @@ use serde::{Deserialize, Serialize}; use crate::config::NodeConfig; pub mod accounts_store; -//pub mod block_store; #[derive(Deserialize, Serialize)] pub struct AccMap { @@ -50,23 +48,21 @@ pub struct NodeChainStore { } impl NodeChainStore { - pub fn new(config: NodeConfig, genesis_block: Block) -> Result<(Self, u64)> { + pub fn new(config: NodeConfig) -> Result { let acc_map = HashMap::new(); let nullifier_store = HashSet::new(); let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); let pub_tx_store = PublicTransactionMerkleTree::new(vec![]); - let block_id = genesis_block.block_id; - Ok(( + Ok( Self { acc_map, nullifier_store, utxo_commitments_store, pub_tx_store, node_config: config, - }, - block_id, - )) + } + ) } pub fn produce_context(&self, caller: AccountAddress) -> PublicSCContext { @@ -97,9 +93,6 @@ mod tests { use super::*; use crate::config::GasConfig; use accounts::account_core::Account; - use common::block::{Block, Data}; - use common::transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind}; - use secp256k1_zkp::Tweak; use std::path::PathBuf; use tempfile::tempdir; @@ -277,55 +270,16 @@ mod tests { initial_accounts } - fn create_genesis_block() -> Block { - Block { - block_id: 0, - prev_block_id: 0, - prev_block_hash: [0; 32], - hash: [1; 32], - transactions: vec![], - data: Data::default(), - } - } - - //ToDo: Continue refactor - fn create_dummy_transaction( - nullifier_created_hashes: Vec<[u8; 32]>, - utxo_commitments_spent_hashes: Vec<[u8; 32]>, - utxo_commitments_created_hashes: Vec<[u8; 32]>, - ) -> Transaction { - let mut rng = rand::thread_rng(); - - let body = TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes, - utxo_commitments_created_hashes, - nullifier_created_hashes, - execution_proof_private: "dummy_proof".to_string(), - encoded_data: vec![], - ephemeral_pub_key: vec![10, 11, 12], - commitment: vec![], - tweak: Tweak::new(&mut rng), - secret_r: [0; 32], - sc_addr: "sc_addr".to_string(), - state_changes: (serde_json::Value::Null, 0), - }; - Transaction::new(body, SignaturePrivateKey::random(&mut rng)) - } - - //ToDo: Continue refactor - fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block { - Block { - block_id, - prev_block_id, - prev_block_hash: [0; 32], - hash: [1; 32], - transactions: vec![], - data: Data::default(), - } - } + // fn create_genesis_block() -> Block { + // Block { + // block_id: 0, + // prev_block_id: 0, + // prev_block_hash: [0; 32], + // hash: [1; 32], + // transactions: vec![], + // data: Data::default(), + // } + // } fn create_sample_node_config(home: PathBuf) -> NodeConfig { NodeConfig { @@ -359,11 +313,8 @@ mod tests { let config = create_sample_node_config(path.to_path_buf()); - let genesis_block = create_genesis_block(); + let store = NodeChainStore::new(config.clone()).unwrap(); - let (store, block_id) = NodeChainStore::new(config.clone(), genesis_block.clone()).unwrap(); - - assert_eq!(block_id, 0); assert!(store.acc_map.is_empty()); assert!(store.nullifier_store.is_empty()); assert_eq!( diff --git a/node_core/src/config.rs b/node_core/src/config.rs index e2ddf83..8aa08ad 100644 --- a/node_core/src/config.rs +++ b/node_core/src/config.rs @@ -4,6 +4,11 @@ use accounts::account_core::Account; use serde::{Deserialize, Serialize}; use zkvm::gas_calculator::GasCalculator; +use anyhow::Result; + +use std::fs::File; +use std::io::BufReader; + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GasConfig { /// Gas spent per deploying one byte of data @@ -55,3 +60,10 @@ pub struct NodeConfig { ///Initial accounts for wallet pub initial_accounts: Vec, } + +pub fn from_file(config_home: PathBuf) -> Result { + let file = File::open(config_home)?; + let reader = BufReader::new(file); + + Ok(serde_json::from_reader(reader)?) +} diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 1c70a11..cceed8c 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -1,4 +1,4 @@ -use std::sync::{atomic::AtomicU64, Arc}; +use std::sync::Arc; use common::{ execution_input::PublicNativeTokenSend, transaction::Transaction, ExecutionFailureKind, @@ -9,7 +9,6 @@ use anyhow::Result; use chain_storage::NodeChainStore; use common::transaction::TransactionBody; use config::NodeConfig; -use log::info; use sc_core::proofs_circuits::{generate_commitments, pedersen_commitment_vec}; use sequencer_client::{json::SendTxResponse, SequencerClient}; use serde::{Deserialize, Serialize}; @@ -73,7 +72,6 @@ pub enum ActionData { pub struct NodeCore { pub storage: Arc>, - pub curr_height: Arc, pub node_config: NodeConfig, pub sequencer_client: Arc, pub gas_calculator: GasCalculator, @@ -83,22 +81,15 @@ impl NodeCore { pub async fn start_from_config_update_chain(config: NodeConfig) -> Result { let client = Arc::new(SequencerClient::new(config.clone())?); - let genesis_id = client.get_genesis_id().await?; - info!("Genesis id is {genesis_id:?}"); - - let genesis_block = client.get_block(genesis_id.genesis_id).await?.block; - - let (mut storage, chain_height) = NodeChainStore::new(config.clone(), genesis_block)?; + let mut storage = NodeChainStore::new(config.clone())?; for acc in config.clone().initial_accounts { storage.acc_map.insert(acc.address, acc); } let wrapped_storage = Arc::new(RwLock::new(storage)); - let chain_height_wrapped = Arc::new(AtomicU64::new(chain_height)); Ok(Self { storage: wrapped_storage, - curr_height: chain_height_wrapped, node_config: config.clone(), sequencer_client: client.clone(), gas_calculator: GasCalculator::from(config.gas_config), diff --git a/node_rpc/Cargo.toml b/node_rpc/Cargo.toml deleted file mode 100644 index 25c5365..0000000 --- a/node_rpc/Cargo.toml +++ /dev/null @@ -1,45 +0,0 @@ -[package] -name = "node_rpc" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true -actix.workspace = true -actix-cors.workspace = true -futures.workspace = true -tokio.workspace = true -hex.workspace = true - -actix-web.workspace = true - -[dependencies.accounts] -path = "../accounts" - -[dependencies.consensus] -path = "../consensus" - -[dependencies.networking] -path = "../networking" - -[dependencies.storage] -path = "../storage" - -[dependencies.utxo] -path = "../utxo" - -[dependencies.vm] -path = "../vm" - -[dependencies.zkvm] -path = "../zkvm" - -[dependencies.node_core] -path = "../node_core" - -[dependencies.common] -path = "../common" diff --git a/node_rpc/src/lib.rs b/node_rpc/src/lib.rs deleted file mode 100644 index e4475fc..0000000 --- a/node_rpc/src/lib.rs +++ /dev/null @@ -1,45 +0,0 @@ -pub mod net_utils; -pub mod process; -pub mod types; - -use std::sync::Arc; - -use common::rpc_primitives::{ - errors::{RpcError, RpcErrorKind}, - RpcPollingConfig, -}; -use node_core::{config::NodeConfig, NodeCore}; -use serde::Serialize; -use serde_json::Value; - -pub use net_utils::*; -use tokio::sync::Mutex; - -use self::types::err_rpc::RpcErr; - -//ToDo: Add necessary fields -pub struct JsonHandler { - pub polling_config: RpcPollingConfig, - pub node_core_config: NodeConfig, - pub node_chain_store: Arc>, -} - -fn respond(val: T) -> Result { - Ok(serde_json::to_value(val)?) -} - -pub fn rpc_error_responce_inverter(err: RpcError) -> RpcError { - let mut content: Option = None; - if err.error_struct.is_some() { - content = match err.error_struct.clone().unwrap() { - RpcErrorKind::HandlerError(val) | RpcErrorKind::InternalError(val) => Some(val), - RpcErrorKind::RequestValidationError(vall) => Some(serde_json::to_value(vall).unwrap()), - }; - } - RpcError { - error_struct: None, - code: err.code, - message: err.message, - data: content, - } -} diff --git a/node_rpc/src/net_utils.rs b/node_rpc/src/net_utils.rs deleted file mode 100644 index 215106c..0000000 --- a/node_rpc/src/net_utils.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::io; -use std::sync::Arc; - -use actix_cors::Cors; -use actix_web::{http, middleware, web, App, Error as HttpError, HttpResponse, HttpServer}; -use futures::Future; -use futures::FutureExt; -use log::info; - -use common::rpc_primitives::message::Message; -use common::rpc_primitives::RpcConfig; -use node_core::config::NodeConfig; -use node_core::NodeCore; -use tokio::sync::Mutex; - -use super::JsonHandler; - -pub const SHUTDOWN_TIMEOUT_SECS: u64 = 10; - -fn rpc_handler( - message: web::Json, - handler: web::Data, -) -> impl Future> { - let response = async move { - let message = handler.process(message.0).await?; - Ok(HttpResponse::Ok().json(&message)) - }; - response.boxed() -} - -fn get_cors(cors_allowed_origins: &[String]) -> Cors { - let mut cors = Cors::permissive(); - if cors_allowed_origins != ["*".to_string()] { - for origin in cors_allowed_origins { - cors = cors.allowed_origin(origin); - } - } - cors.allowed_methods(vec!["GET", "POST"]) - .allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT]) - .allowed_header(http::header::CONTENT_TYPE) - .max_age(3600) -} - -#[allow(clippy::too_many_arguments)] -pub fn new_http_server( - config: RpcConfig, - node_config: NodeConfig, - node_chain_store: Arc>, -) -> io::Result { - let RpcConfig { - addr, - cors_allowed_origins, - polling_config, - limits_config, - } = config; - info!(target:"network", "Starting http server at {addr}"); - let handler = web::Data::new(JsonHandler { - polling_config, - node_core_config: node_config, - node_chain_store, - }); - - // HTTP server - Ok(HttpServer::new(move || { - App::new() - .wrap(get_cors(&cors_allowed_origins)) - .app_data(handler.clone()) - .app_data(web::JsonConfig::default().limit(limits_config.json_payload_max_size)) - .wrap(middleware::Logger::default()) - .service(web::resource("/").route(web::post().to(rpc_handler))) - }) - .bind(addr)? - .shutdown_timeout(SHUTDOWN_TIMEOUT_SECS) - .disable_signals() - .run()) -} diff --git a/node_rpc/src/process.rs b/node_rpc/src/process.rs deleted file mode 100644 index 4546639..0000000 --- a/node_rpc/src/process.rs +++ /dev/null @@ -1,257 +0,0 @@ -use std::sync::atomic::Ordering; - -use actix_web::Error as HttpError; -use serde_json::Value; - -use common::rpc_primitives::{ - errors::RpcError, - message::{Message, Request}, - parser::RpcRequest, -}; -use common::transaction::ActionData; - -use common::rpc_primitives::requests::{GetLastBlockRequest, GetLastBlockResponse}; - -use crate::types::rpc_structs::{ - CreateAccountRequest, CreateAccountResponse, ShowAccountPublicBalanceRequest, - ShowAccountPublicBalanceResponse, ShowAccountUTXORequest, ShowAccountUTXOResponse, - ShowTransactionRequest, ShowTransactionResponse, -}; - -pub const CREATE_ACCOUNT: &str = "create_account"; -pub const EXECUTE_SUBSCENARIO: &str = "execute_subscenario"; -pub const GET_BLOCK: &str = "get_block"; -pub const GET_LAST_BLOCK: &str = "get_last_block"; -pub const EXECUTE_SCENARIO_SPLIT: &str = "execute_scenario_split"; -pub const EXECUTE_SCENARIO_MULTIPLE_SEND: &str = "execute_scenario_multiple_send"; -pub const SHOW_ACCOUNT_PUBLIC_BALANCE: &str = "show_account_public_balance"; -pub const SHOW_ACCOUNT_UTXO: &str = "show_account_utxo"; -pub const SHOW_TRANSACTION: &str = "show_transaction"; -pub const WRITE_MINT_UTXO: &str = "write_mint_utxo"; -pub const WRITE_MINT_UTXO_MULTIPLE_ASSETS: &str = "write_mint_utxo_multiple_assets"; -pub const WRITE_SEND_UTXO_PRIVATE: &str = "write_send_utxo_private"; -pub const WRITE_SEND_UTXO_SHIELDED: &str = "write_send_utxo_shielded"; -pub const WRITE_SEND_UTXO_DESHIELDED: &str = "write_send_utxo_deshielded"; -pub const WRITE_SPLIT_UTXO: &str = "write_split_utxo"; - -pub const SUCCESS: &str = "success"; - -pub const ACCOUNT_NOT_FOUND: &str = "Account not found"; -pub const TRANSACTION_NOT_FOUND: &str = "Transaction not found"; - -use super::{respond, types::err_rpc::RpcErr, JsonHandler}; - -impl JsonHandler { - pub async fn process(&self, message: Message) -> Result { - let id = message.id(); - if let Message::Request(request) = message { - let message_inner = self - .process_request_internal(request) - .await - .map_err(|e| e.0); - Ok(Message::response(id, message_inner)) - } else { - Ok(Message::error(RpcError::parse_error( - "JSON RPC Request format was expected".to_owned(), - ))) - } - } - - async fn process_create_account(&self, request: Request) -> Result { - let _req = CreateAccountRequest::parse(Some(request.params))?; - - let acc_addr = { - let mut guard = self.node_chain_store.lock().await; - - guard.create_new_account().await - }; - - let helperstruct = CreateAccountResponse { - status: hex::encode(acc_addr), - }; - - respond(helperstruct) - } - - async fn process_get_last_block(&self, request: Request) -> Result { - let _req = GetLastBlockRequest::parse(Some(request.params))?; - - let last_block = { - let guard = self.node_chain_store.lock().await; - - guard.curr_height.load(Ordering::Relaxed) - }; - - let helperstruct = GetLastBlockResponse { last_block }; - - respond(helperstruct) - } - - async fn process_show_account_public_balance(&self, request: Request) -> Result { - let req = ShowAccountPublicBalanceRequest::parse(Some(request.params))?; - - let acc_addr_hex_dec = hex::decode(req.account_addr.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode account address from hex string".to_string()) - })?; - - let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - let balance = { - let cover_guard = self.node_chain_store.lock().await; - - { - let under_guard = cover_guard.storage.read().await; - - let acc = under_guard - .acc_map - .get(&acc_addr) - .ok_or(RpcError::new_internal_error(None, ACCOUNT_NOT_FOUND))?; - - acc.balance - } - }; - - let helperstruct = ShowAccountPublicBalanceResponse { - addr: req.account_addr, - balance, - }; - - respond(helperstruct) - } - - async fn process_show_account_utxo_request(&self, request: Request) -> Result { - let req = ShowAccountUTXORequest::parse(Some(request.params))?; - - let acc_addr_hex_dec = hex::decode(req.account_addr.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode account address from hex string".to_string()) - })?; - - let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| { - RpcError::parse_error("Failed to parse account address from bytes".to_string()) - })?; - - let utxo_hash_hex_dec = hex::decode(req.utxo_hash.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode hash from hex string".to_string()) - })?; - - let utxo_hash: [u8; 32] = utxo_hash_hex_dec - .try_into() - .map_err(|_| RpcError::parse_error("Failed to parse hash from bytes".to_string()))?; - - let (asset, amount) = { - let cover_guard = self.node_chain_store.lock().await; - - { - let mut under_guard = cover_guard.storage.write().await; - - let acc = under_guard - .acc_map - .get_mut(&acc_addr) - .ok_or(RpcError::new_internal_error(None, ACCOUNT_NOT_FOUND))?; - - let utxo = acc - .utxos - .get(&utxo_hash) - .ok_or(RpcError::new_internal_error( - None, - "UTXO does not exist in the tree", - ))?; - - (utxo.asset.clone(), utxo.amount) - } - }; - - let helperstruct = ShowAccountUTXOResponse { - hash: req.utxo_hash, - asset, - amount, - }; - - respond(helperstruct) - } - - async fn process_show_transaction(&self, request: Request) -> Result { - let req = ShowTransactionRequest::parse(Some(request.params))?; - - let tx_hash_hex_dec = hex::decode(req.tx_hash.clone()).map_err(|_| { - RpcError::parse_error("Failed to decode hash from hex string".to_string()) - })?; - - let tx_hash: [u8; 32] = tx_hash_hex_dec - .try_into() - .map_err(|_| RpcError::parse_error("Failed to parse hash from bytes".to_string()))?; - - let helperstruct = { - let cover_guard = self.node_chain_store.lock().await; - - { - let under_guard = cover_guard.storage.read().await; - - let tx = under_guard - .pub_tx_store - .get_tx(tx_hash) - .ok_or(RpcError::new_internal_error(None, TRANSACTION_NOT_FOUND))?; - - ShowTransactionResponse { - hash: req.tx_hash, - tx_kind: tx.body().tx_kind, - public_input: if let Ok(action) = - serde_json::from_slice::(&tx.body().execution_input) - { - action.into_hexed_print() - } else { - "".to_string() - }, - public_output: if let Ok(action) = - serde_json::from_slice::(&tx.body().execution_output) - { - action.into_hexed_print() - } else { - "".to_string() - }, - utxo_commitments_created_hashes: tx - .body() - .utxo_commitments_created_hashes - .iter() - .map(hex::encode) - .collect::>(), - utxo_commitments_spent_hashes: tx - .body() - .utxo_commitments_spent_hashes - .iter() - .map(hex::encode) - .collect::>(), - utxo_nullifiers_created_hashes: tx - .body() - .nullifier_created_hashes - .iter() - .map(hex::encode) - .collect::>(), - encoded_data: tx - .body() - .encoded_data - .iter() - .map(|val| (hex::encode(val.0.clone()), hex::encode(val.1.clone()))) - .collect::>(), - ephemeral_pub_key: hex::encode(tx.body().ephemeral_pub_key.clone()), - } - } - }; - - respond(helperstruct) - } - - pub async fn process_request_internal(&self, request: Request) -> Result { - match request.method.as_ref() { - //Todo : Add handling of more JSON RPC methods - CREATE_ACCOUNT => self.process_create_account(request).await, - GET_LAST_BLOCK => self.process_get_last_block(request).await, - SHOW_ACCOUNT_PUBLIC_BALANCE => self.process_show_account_public_balance(request).await, - SHOW_ACCOUNT_UTXO => self.process_show_account_utxo_request(request).await, - SHOW_TRANSACTION => self.process_show_transaction(request).await, - _ => Err(RpcErr(RpcError::method_not_found(request.method))), - } - } -} diff --git a/node_rpc/src/types/err_rpc.rs b/node_rpc/src/types/err_rpc.rs deleted file mode 100644 index 0e75f7a..0000000 --- a/node_rpc/src/types/err_rpc.rs +++ /dev/null @@ -1,85 +0,0 @@ -use common::{ExecutionFailureKind, SequencerClientError}; -use log::debug; - -use common::rpc_primitives::errors::{RpcError, RpcParseError}; - -pub struct RpcErr(pub RpcError); - -pub type RpcErrInternal = anyhow::Error; - -pub trait RpcErrKind: 'static { - fn into_rpc_err(self) -> RpcError; -} - -impl From for RpcErr { - fn from(e: T) -> Self { - Self(e.into_rpc_err()) - } -} - -macro_rules! standard_rpc_err_kind { - ($type_name:path) => { - impl RpcErrKind for $type_name { - fn into_rpc_err(self) -> RpcError { - self.into() - } - } - }; -} -standard_rpc_err_kind!(RpcError); -standard_rpc_err_kind!(RpcParseError); - -impl RpcErrKind for serde_json::Error { - fn into_rpc_err(self) -> RpcError { - RpcError::serialization_error(&self.to_string()) - } -} - -impl RpcErrKind for RpcErrInternal { - fn into_rpc_err(self) -> RpcError { - RpcError::new_internal_error(None, &format!("{self:#?}")) - } -} - -#[allow(clippy::needless_pass_by_value)] -pub fn from_rpc_err_into_anyhow_err(rpc_err: RpcError) -> anyhow::Error { - debug!("Rpc error cast to anyhow error : err {rpc_err:?}"); - anyhow::anyhow!(format!("{rpc_err:#?}")) -} - -pub fn cast_seq_client_error_into_rpc_error(seq_cli_err: SequencerClientError) -> RpcError { - let error_string = seq_cli_err.to_string(); - - match seq_cli_err { - SequencerClientError::SerdeError(_) => RpcError::serialization_error(&error_string), - SequencerClientError::HTTPError(_) => RpcError::new_internal_error(None, &error_string), - SequencerClientError::InternalError(err) => RpcError::new_internal_error( - err.error.data, - &serde_json::to_string(&err.error.error_struct).unwrap_or(String::default()), - ), - } -} - -pub fn cast_common_execution_error_into_rpc_error(comm_exec_err: ExecutionFailureKind) -> RpcError { - let error_string = comm_exec_err.to_string(); - - match comm_exec_err { - ExecutionFailureKind::BuilderError(_) => RpcError::new_internal_error(None, &error_string), - ExecutionFailureKind::WriteError(_) => RpcError::new_internal_error(None, &error_string), - ExecutionFailureKind::DBError(_) => RpcError::new_internal_error(None, &error_string), - ExecutionFailureKind::DecodeError(_) => RpcError::new_internal_error(None, &error_string), - ExecutionFailureKind::ProveError(_) => RpcError::new_internal_error(None, &error_string), - ExecutionFailureKind::AmountMismatchError => { - RpcError::new_internal_error(None, &error_string) - } - ExecutionFailureKind::InsufficientGasError => { - RpcError::new_internal_error(None, &error_string) - } - ExecutionFailureKind::InsufficientFundsError => { - RpcError::new_internal_error(None, &error_string) - } - ExecutionFailureKind::SequencerClientError(seq_cli_err) => { - cast_seq_client_error_into_rpc_error(seq_cli_err) - } - } -} diff --git a/node_rpc/src/types/mod.rs b/node_rpc/src/types/mod.rs deleted file mode 100644 index 4901b7f..0000000 --- a/node_rpc/src/types/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod err_rpc; -pub mod rpc_structs; diff --git a/node_rpc/src/types/rpc_structs.rs b/node_rpc/src/types/rpc_structs.rs deleted file mode 100644 index 3ae8694..0000000 --- a/node_rpc/src/types/rpc_structs.rs +++ /dev/null @@ -1,206 +0,0 @@ -use common::parse_request; -use common::rpc_primitives::errors::RpcParseError; -use common::rpc_primitives::parser::parse_params; -use common::rpc_primitives::parser::RpcRequest; -use common::transaction::TxKind; -use serde::{Deserialize, Serialize}; -use serde_json::Value; - -#[derive(Serialize, Deserialize, Debug)] -pub struct ExecuteSubscenarioRequest { - pub scenario_id: u64, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ExecuteScenarioSplitRequest { - pub visibility_list: [bool; 3], - pub publication_index: usize, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ExecuteScenarioMultipleSendRequest { - pub number_of_assets: usize, - pub number_to_send: usize, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ShowAccountPublicBalanceRequest { - pub account_addr: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ShowAccountUTXORequest { - pub account_addr: String, - pub utxo_hash: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ShowTransactionRequest { - pub tx_hash: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteDepositPublicBalanceRequest { - pub account_addr: String, - pub amount: u64, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteMintPrivateUTXORequest { - pub account_addr: String, - pub amount: u64, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteMintPrivateUTXOMultipleAssetsRequest { - pub account_addr: String, - pub num_of_assets: usize, - pub amount: u64, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteSendPrivateUTXORequest { - pub account_addr_sender: String, - pub account_addr_receiver: String, - pub utxo_hash: String, - pub utxo_commitment: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteSendShieldedUTXORequest { - pub account_addr_sender: String, - pub account_addr_receiver: String, - pub amount: u64, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteSendDeshieldedBalanceRequest { - pub account_addr_sender: String, - pub account_addr_receiver: String, - pub utxo_hash: String, - pub utxo_commitment: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteSplitUTXORequest { - pub account_addr_sender: String, - pub account_addr_receivers: [String; 3], - pub visibility_list: [bool; 3], - pub utxo_hash: String, - pub utxo_commitment: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct CreateAccountRequest {} - -// parse_request!(GetGenesisIdRequest); -parse_request!(ExecuteSubscenarioRequest); -parse_request!(ExecuteScenarioSplitRequest); -parse_request!(ExecuteScenarioMultipleSendRequest); -// parse_request!(GetLastBlockRequest); - -parse_request!(ShowAccountPublicBalanceRequest); -parse_request!(ShowAccountUTXORequest); -parse_request!(ShowTransactionRequest); - -parse_request!(WriteDepositPublicBalanceRequest); -parse_request!(WriteMintPrivateUTXORequest); -parse_request!(WriteMintPrivateUTXOMultipleAssetsRequest); -parse_request!(WriteSendPrivateUTXORequest); -parse_request!(WriteSendShieldedUTXORequest); -parse_request!(WriteSendDeshieldedBalanceRequest); -parse_request!(WriteSplitUTXORequest); -parse_request!(CreateAccountRequest); - -#[derive(Serialize, Deserialize, Debug)] -pub struct ExecuteSubscenarioResponse { - pub scenario_result: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ExecuteScenarioSplitResponse { - pub scenario_result: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ExecuteScenarioMultipleSendResponse { - pub scenario_result: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ShowAccountPublicBalanceResponse { - pub addr: String, - pub balance: u64, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ShowAccountUTXOResponse { - pub hash: String, - pub asset: Vec, - pub amount: u128, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ShowTransactionResponse { - pub hash: String, - pub tx_kind: TxKind, - pub public_input: String, - pub public_output: String, - pub utxo_commitments_created_hashes: Vec, - pub utxo_commitments_spent_hashes: Vec, - pub utxo_nullifiers_created_hashes: Vec, - pub encoded_data: Vec<(String, String)>, - pub ephemeral_pub_key: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteDepositPublicBalanceResponse { - pub status: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct UTXOShortEssentialStruct { - pub hash: String, - pub commitment_hash: String, - pub asset: Vec, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteMintPrivateUTXOResponse { - pub status: String, - pub utxo: UTXOShortEssentialStruct, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteMintPrivateUTXOMultipleAssetsResponse { - pub status: String, - pub utxos: Vec, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteSendPrivateUTXOResponse { - pub status: String, - pub utxo_result: UTXOShortEssentialStruct, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteSendShieldedUTXOResponse { - pub status: String, - pub utxo_result: UTXOShortEssentialStruct, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteSendDeshieldedUTXOResponse { - pub status: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WriteSendSplitUTXOResponse { - pub status: String, - pub utxo_results: Vec, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct CreateAccountResponse { - pub status: String, -} diff --git a/node_runner/Cargo.toml b/node_runner/Cargo.toml deleted file mode 100644 index d63c39a..0000000 --- a/node_runner/Cargo.toml +++ /dev/null @@ -1,50 +0,0 @@ -[package] -name = "node_runner" -version = "0.1.0" -edition = "2021" - -[dependencies] -hex.workspace = true -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true -actix.workspace = true - -actix-web.workspace = true -tokio.workspace = true - -[dependencies.clap] -features = ["derive", "env"] -workspace = true - -[dependencies.accounts] -path = "../accounts" - -[dependencies.consensus] -path = "../consensus" - -[dependencies.networking] -path = "../networking" - -[dependencies.storage] -path = "../storage" - -[dependencies.utxo] -path = "../utxo" - -[dependencies.vm] -path = "../vm" - -[dependencies.zkvm] -path = "../zkvm" - -[dependencies.node_rpc] -path = "../node_rpc" - -[dependencies.node_core] -path = "../node_core" - -[dependencies.common] -path = "../common" diff --git a/node_runner/configs/debug/node_config.json b/node_runner/configs/debug/node_config.json deleted file mode 100644 index 6c39f15..0000000 --- a/node_runner/configs/debug/node_config.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "home": ".", - "override_rust_log": null, - "sequencer_addr": "http://127.0.0.1:3040", - "seq_poll_timeout_secs": 10, - "port": 3041, - "gas_config": { - "gas_fee_per_byte_deploy": 100, - "gas_fee_per_input_buffer_runtime": 1000, - "gas_fee_per_byte_runtime": 10, - "gas_cost_runtime": 100, - "gas_cost_deploy": 1000, - "gas_limit_deploy": 30000000, - "gas_limit_runtime": 30000000 - }, - "shapshot_frequency_in_blocks": 10, - "initial_accounts": [ - { - "address": [ - 13, - 150, - 223, - 204, - 65, - 64, - 25, - 56, - 12, - 157, - 222, - 12, - 211, - 220, - 229, - 170, - 201, - 15, - 181, - 68, - 59, - 248, - 113, - 16, - 135, - 65, - 174, - 175, - 222, - 85, - 42, - 215 - ], - "balance": 10000, - "key_holder": { - "address": [ - 13, - 150, - 223, - 204, - 65, - 64, - 25, - 56, - 12, - 157, - 222, - 12, - 211, - 220, - 229, - 170, - 201, - 15, - 181, - 68, - 59, - 248, - 113, - 16, - 135, - 65, - 174, - 175, - 222, - 85, - 42, - 215 - ], - "nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718", - "pub_account_signing_key": [ - 133, - 143, - 177, - 187, - 252, - 66, - 237, - 236, - 234, - 252, - 244, - 138, - 5, - 151, - 3, - 99, - 217, - 231, - 112, - 217, - 77, - 211, - 58, - 218, - 176, - 68, - 99, - 53, - 152, - 228, - 198, - 190 - ], - "top_secret_key_holder": { - "secret_spending_key": "7BC46784DB1BC67825D8F029436846712BFDF9B5D79EA3AB11D39A52B9B229D4" - }, - "utxo_secret_key_holder": { - "nullifier_secret_key": "BB54A8D3C9C51B82C431082D1845A74677B0EF829A11B517E1D9885DE3139506", - "viewing_secret_key": "AD923E92F6A5683E30140CEAB2702AFB665330C1EE4EFA70FAF29767B6B52BAF" - }, - "viewing_public_key": "0361220C5D277E7A1709340FD31A52600C1432B9C45B9BCF88A43581D58824A8B6" - }, - "utxos": {} - }, - { - "address": [ - 151, - 72, - 112, - 233, - 190, - 141, - 10, - 192, - 138, - 168, - 59, - 63, - 199, - 167, - 166, - 134, - 41, - 29, - 135, - 50, - 80, - 138, - 186, - 152, - 179, - 96, - 128, - 243, - 156, - 44, - 243, - 100 - ], - "balance": 20000, - "key_holder": { - "address": [ - 151, - 72, - 112, - 233, - 190, - 141, - 10, - 192, - 138, - 168, - 59, - 63, - 199, - 167, - 166, - 134, - 41, - 29, - 135, - 50, - 80, - 138, - 186, - 152, - 179, - 96, - 128, - 243, - 156, - 44, - 243, - 100 - ], - "nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271", - "pub_account_signing_key": [ - 54, - 90, - 62, - 225, - 71, - 225, - 228, - 148, - 143, - 53, - 210, - 23, - 137, - 158, - 171, - 156, - 48, - 7, - 139, - 52, - 117, - 242, - 214, - 7, - 99, - 29, - 122, - 184, - 59, - 116, - 144, - 107 - ], - "top_secret_key_holder": { - "secret_spending_key": "80A186737C8D38B4288A03F0F589957D9C040D79C19F3E0CC4BA80F8494E5179" - }, - "utxo_secret_key_holder": { - "nullifier_secret_key": "746928E63F0984F6F4818933493CE9C067562D9CB932FDC06D82C86CDF6D7122", - "viewing_secret_key": "89176CF4BC9E673807643FD52110EF99D4894335AFB10D881AC0B5041FE1FCB7" - }, - "viewing_public_key": "026072A8F83FEC3472E30CDD4767683F30B91661D25B1040AD9A5FC2E01D659F99" - }, - "utxos": {} - } - ] -} \ No newline at end of file diff --git a/node_runner/src/config.rs b/node_runner/src/config.rs deleted file mode 100644 index 988b0f2..0000000 --- a/node_runner/src/config.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::path::PathBuf; - -use anyhow::Result; -use node_core::config::NodeConfig; - -use std::fs::File; -use std::io::BufReader; - -pub fn from_file(config_home: PathBuf) -> Result { - let file = File::open(config_home)?; - let reader = BufReader::new(file); - - Ok(serde_json::from_reader(reader)?) -} diff --git a/node_runner/src/lib.rs b/node_runner/src/lib.rs deleted file mode 100644 index cbede4e..0000000 --- a/node_runner/src/lib.rs +++ /dev/null @@ -1,56 +0,0 @@ -use std::{path::PathBuf, sync::Arc}; - -use anyhow::Result; -use clap::Parser; -use common::rpc_primitives::RpcConfig; -use consensus::ConsensusManager; -use log::info; -use networking::peer_manager::PeerManager; -use node_core::NodeCore; -use node_rpc::new_http_server; -use tokio::sync::Mutex; - -pub mod config; - -#[derive(Parser, Debug)] -#[clap(version)] -struct Args { - /// Path to configs - home_dir: PathBuf, -} - -pub async fn main_runner() -> Result<()> { - env_logger::init(); - - let args = Args::parse(); - let Args { home_dir } = args; - - let app_config = config::from_file(home_dir.join("node_config.json"))?; - - let port = app_config.port; - - let node_core = NodeCore::start_from_config_update_chain(app_config.clone()).await?; - let wrapped_node_core = Arc::new(Mutex::new(node_core)); - - let http_server = new_http_server( - RpcConfig::with_port(port), - app_config.clone(), - wrapped_node_core.clone(), - )?; - info!("HTTP server started"); - let _http_server_handle = http_server.handle(); - tokio::spawn(http_server); - - let peer_manager = PeerManager::start_peer_manager(4, 0).await?; - info!("Peer manager mock started"); - - let peer_manager_shared = Arc::new(Mutex::new(peer_manager)); - - let _consensus_manager = ConsensusManager::new(peer_manager_shared.clone()); - info!("Consensus manger mock started"); - - #[allow(clippy::empty_loop)] - loop { - //ToDo: Insert activity into main loop - } -} diff --git a/node_runner/src/main.rs b/node_runner/src/main.rs deleted file mode 100644 index 2bc288d..0000000 --- a/node_runner/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -use anyhow::Result; - -use node_runner::main_runner; - -pub const NUM_THREADS: usize = 4; - -fn main() -> Result<()> { - actix::System::with_tokio_rt(|| { - tokio::runtime::Builder::new_multi_thread() - .worker_threads(NUM_THREADS) - .enable_all() - .build() - .unwrap() - }) - .block_on(main_runner()) -} diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 80ac760..6f3f27e 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -3,7 +3,7 @@ use std::fmt::Display; use accounts::account_core::address::{self, AccountAddress}; use anyhow::Result; use common::{ - block::{Block, HashableBlockData}, + block::HashableBlockData, execution_input::PublicNativeTokenSend, merkle_tree_public::TreeHashType, nullifier::UTXONullifier, @@ -321,7 +321,7 @@ impl SequencerCore { prev_block_hash, }; - let block = Block::produce_block_from_hashable_data(hashable_data); + let block = hashable_data.into(); self.store.block_store.put_block_at_id(block)?; @@ -336,11 +336,8 @@ mod tests { use crate::config::AccountInitialData; use super::*; - - use common::transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind}; use k256::{ecdsa::SigningKey, FieldBytes}; use mempool_transaction::MempoolTransaction; - use secp256k1_zkp::Tweak; fn setup_sequencer_config_variable_initial_accounts( initial_accounts: Vec, @@ -386,67 +383,6 @@ mod tests { setup_sequencer_config_variable_initial_accounts(initial_accounts) } - fn create_dummy_transaction( - nullifier_created_hashes: Vec<[u8; 32]>, - utxo_commitments_spent_hashes: Vec<[u8; 32]>, - utxo_commitments_created_hashes: Vec<[u8; 32]>, - ) -> Transaction { - let mut rng = rand::thread_rng(); - - let body = TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes, - utxo_commitments_created_hashes, - nullifier_created_hashes, - execution_proof_private: "dummy_proof".to_string(), - encoded_data: vec![], - ephemeral_pub_key: vec![10, 11, 12], - commitment: vec![], - tweak: Tweak::new(&mut rng), - secret_r: [0; 32], - sc_addr: "sc_addr".to_string(), - state_changes: (serde_json::Value::Null, 0), - }; - Transaction::new(body, SignaturePrivateKey::random(&mut rng)) - } - - fn create_dummy_transaction_native_token_transfer( - from: [u8; 32], - nonce: u64, - to: [u8; 32], - balance_to_move: u64, - signing_key: SigningKey, - ) -> Transaction { - let mut rng = rand::thread_rng(); - - let native_token_transfer = PublicNativeTokenSend { - from, - nonce, - to, - balance_to_move, - }; - - let body = TransactionBody { - tx_kind: TxKind::Public, - execution_input: serde_json::to_vec(&native_token_transfer).unwrap(), - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: vec![], - nullifier_created_hashes: vec![], - execution_proof_private: "".to_string(), - encoded_data: vec![], - ephemeral_pub_key: vec![10, 11, 12], - commitment: vec![], - tweak: Tweak::new(&mut rng), - secret_r: [0; 32], - sc_addr: "sc_addr".to_string(), - state_changes: (serde_json::Value::Null, 0), - }; - Transaction::new(body, signing_key) - } - fn create_signing_key_for_account1() -> SigningKey { let pub_sign_key_acc1 = [ 133, 143, 177, 187, 252, 66, 237, 236, 234, 252, 244, 138, 5, 151, 3, 99, 217, 231, @@ -468,7 +404,11 @@ mod tests { } fn common_setup(sequencer: &mut SequencerCore) { - let tx = create_dummy_transaction(vec![[9; 32]], vec![[7; 32]], vec![[8; 32]]); + let tx = common::test_utils::create_dummy_private_transaction_random_signer( + vec![[9; 32]], + vec![[7; 32]], + vec![[8; 32]], + ); let mempool_tx = MempoolTransaction { auth_tx: tx.into_authenticated().unwrap(), }; @@ -581,7 +521,11 @@ mod tests { common_setup(&mut sequencer); - let tx = create_dummy_transaction(vec![[91; 32]], vec![[71; 32]], vec![[81; 32]]); + let tx = common::test_utils::create_dummy_private_transaction_random_signer( + vec![[91; 32]], + vec![[71; 32]], + vec![[81; 32]], + ); let tx_roots = sequencer.get_tree_roots(); let result = sequencer.transaction_pre_check(tx, tx_roots); @@ -606,7 +550,9 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = create_dummy_transaction_native_token_transfer(acc1, 0, acc2, 10, sign_key1); + let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + acc1, 0, acc2, 10, sign_key1, + ); let tx_roots = sequencer.get_tree_roots(); let result = sequencer.transaction_pre_check(tx, tx_roots); @@ -631,7 +577,9 @@ mod tests { let sign_key2 = create_signing_key_for_account2(); - let tx = create_dummy_transaction_native_token_transfer(acc1, 0, acc2, 10, sign_key2); + let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + acc1, 0, acc2, 10, sign_key2, + ); let tx_roots = sequencer.get_tree_roots(); let result = sequencer.transaction_pre_check(tx, tx_roots); @@ -659,7 +607,9 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = create_dummy_transaction_native_token_transfer(acc1, 0, acc2, 10000000, sign_key1); + let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + acc1, 0, acc2, 10000000, sign_key1, + ); let tx_roots = sequencer.get_tree_roots(); let result = sequencer.transaction_pre_check(tx, tx_roots); @@ -693,7 +643,9 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = create_dummy_transaction_native_token_transfer(acc1, 0, acc2, 100, sign_key1); + let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + acc1, 0, acc2, 100, sign_key1, + ); sequencer .execute_check_transaction_on_state(&tx.into_authenticated().unwrap().into()) @@ -716,7 +668,11 @@ mod tests { common_setup(&mut sequencer); - let tx = create_dummy_transaction(vec![[92; 32]], vec![[72; 32]], vec![[82; 32]]); + let tx = common::test_utils::create_dummy_private_transaction_random_signer( + vec![[92; 32]], + vec![[72; 32]], + vec![[82; 32]], + ); let tx_roots = sequencer.get_tree_roots(); // Fill the mempool @@ -740,7 +696,11 @@ mod tests { common_setup(&mut sequencer); - let tx = create_dummy_transaction(vec![[93; 32]], vec![[73; 32]], vec![[83; 32]]); + let tx = common::test_utils::create_dummy_private_transaction_random_signer( + vec![[93; 32]], + vec![[73; 32]], + vec![[83; 32]], + ); let tx_roots = sequencer.get_tree_roots(); let result = sequencer.push_tx_into_mempool_pre_check(tx, tx_roots); @@ -754,7 +714,11 @@ mod tests { let mut sequencer = SequencerCore::start_from_config(config); let genesis_height = sequencer.chain_height; - let tx = create_dummy_transaction(vec![[94; 32]], vec![[7; 32]], vec![[8; 32]]); + let tx = common::test_utils::create_dummy_private_transaction_random_signer( + vec![[94; 32]], + vec![[7; 32]], + vec![[8; 32]], + ); let tx_mempool = MempoolTransaction { auth_tx: tx.into_authenticated().unwrap(), }; @@ -783,7 +747,9 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = create_dummy_transaction_native_token_transfer(acc1, 0, acc2, 100, sign_key1); + let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + acc1, 0, acc2, 100, sign_key1, + ); let tx_mempool_original = MempoolTransaction { auth_tx: tx.clone().into_authenticated().unwrap(), @@ -828,7 +794,9 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = create_dummy_transaction_native_token_transfer(acc1, 0, acc2, 100, sign_key1); + let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + acc1, 0, acc2, 100, sign_key1, + ); // The transaction should be included the first time let tx_mempool_original = MempoolTransaction { diff --git a/sequencer_core/src/sequencer_store/block_store.rs b/sequencer_core/src/sequencer_store/block_store.rs index dbefdc2..6467539 100644 --- a/sequencer_core/src/sequencer_store/block_store.rs +++ b/sequencer_core/src/sequencer_store/block_store.rs @@ -76,40 +76,8 @@ fn block_to_transactions_map(block: &Block) -> HashMap { #[cfg(test)] mod tests { use super::*; - use common::transaction::{SignaturePrivateKey, TransactionBody}; use tempfile::tempdir; - fn create_dummy_block_with_transaction(block_id: u64) -> (Block, Transaction) { - let body = TransactionBody { - tx_kind: common::transaction::TxKind::Public, - execution_input: Default::default(), - execution_output: Default::default(), - utxo_commitments_spent_hashes: Default::default(), - utxo_commitments_created_hashes: Default::default(), - nullifier_created_hashes: Default::default(), - execution_proof_private: Default::default(), - encoded_data: Default::default(), - ephemeral_pub_key: Default::default(), - commitment: Default::default(), - tweak: Default::default(), - secret_r: Default::default(), - sc_addr: Default::default(), - state_changes: Default::default(), - }; - let tx = Transaction::new(body, SignaturePrivateKey::from_slice(&[1; 32]).unwrap()); - ( - Block { - block_id, - prev_block_id: block_id - 1, - prev_block_hash: [0; 32], - hash: [1; 32], - transactions: vec![tx.clone()], - data: vec![], - }, - tx, - ) - } - #[test] fn test_get_transaction_by_hash() { let temp_dir = tempdir().unwrap(); @@ -125,7 +93,10 @@ mod tests { // Start an empty node store let mut node_store = SequecerBlockStore::open_db_with_genesis(path, Some(genesis_block)).unwrap(); - let (block, tx) = create_dummy_block_with_transaction(1); + + let tx = common::test_utils::produce_dummy_empty_transaction(); + let block = common::test_utils::produce_dummy_block(1, None, vec![tx.clone()], vec![]); + // Try retrieve a tx that's not in the chain yet. let retrieved_tx = node_store.get_transaction_by_hash(tx.body().hash()); assert_eq!(None, retrieved_tx); diff --git a/sequencer_core/src/sequencer_store/mod.rs b/sequencer_core/src/sequencer_store/mod.rs index a85fd23..3a1ff36 100644 --- a/sequencer_core/src/sequencer_store/mod.rs +++ b/sequencer_core/src/sequencer_store/mod.rs @@ -3,7 +3,7 @@ use std::{collections::HashSet, path::Path}; use accounts_store::SequencerAccountsStore; use block_store::SequecerBlockStore; use common::{ - block::{Block, HashableBlockData}, + block::HashableBlockData, merkle_tree_public::merkle_tree::{PublicTransactionMerkleTree, UTXOCommitmentsMerkleTree}, nullifier::UTXONullifier, }; @@ -63,7 +63,7 @@ impl SequecerChainStore { prev_block_hash, }; - let genesis_block = Block::produce_block_from_hashable_data(hashable_data); + let genesis_block = hashable_data.into(); //Sequencer should panic if unable to open db, //as fixing this issue may require actions non-native to program scope diff --git a/sequencer_rpc/Cargo.toml b/sequencer_rpc/Cargo.toml index fb33c2d..3e9662a 100644 --- a/sequencer_rpc/Cargo.toml +++ b/sequencer_rpc/Cargo.toml @@ -24,12 +24,6 @@ path = "../mempool" [dependencies.accounts] path = "../accounts" -[dependencies.consensus] -path = "../consensus" - -[dependencies.networking] -path = "../networking" - [dependencies.sequencer_core] path = "../sequencer_core" diff --git a/sequencer_runner/Cargo.toml b/sequencer_runner/Cargo.toml index 286ee76..b42fcb6 100644 --- a/sequencer_runner/Cargo.toml +++ b/sequencer_runner/Cargo.toml @@ -22,12 +22,6 @@ workspace = true [dependencies.mempool] path = "../mempool" -[dependencies.consensus] -path = "../consensus" - -[dependencies.networking] -path = "../networking" - [dependencies.sequencer_rpc] path = "../sequencer_rpc" diff --git a/vm/Cargo.toml b/vm/Cargo.toml deleted file mode 100644 index b69c32f..0000000 --- a/vm/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "vm" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true diff --git a/vm/src/lib.rs b/vm/src/lib.rs deleted file mode 100644 index c94d4d0..0000000 --- a/vm/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -//ToDo: Add vm module From 7be870369c597d05f699825c7182edfba6915fe0 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Tue, 5 Aug 2025 15:44:52 +0300 Subject: [PATCH 3/5] fix: fmt --- common/src/test_utils.rs | 112 +++++++++++++++-------------- node_core/src/chain_storage/mod.rs | 16 ++--- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/common/src/test_utils.rs b/common/src/test_utils.rs index e78b291..78ea39a 100644 --- a/common/src/test_utils.rs +++ b/common/src/test_utils.rs @@ -2,7 +2,9 @@ use k256::ecdsa::SigningKey; use secp256k1_zkp::Tweak; use crate::{ - block::{Block, HashableBlockData}, execution_input::PublicNativeTokenSend, transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind} + block::{Block, HashableBlockData}, + execution_input::PublicNativeTokenSend, + transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind}, }; //Dummy producers @@ -55,62 +57,62 @@ pub fn produce_dummy_empty_transaction() -> Transaction { } pub fn create_dummy_private_transaction_random_signer( - nullifier_created_hashes: Vec<[u8; 32]>, - utxo_commitments_spent_hashes: Vec<[u8; 32]>, - utxo_commitments_created_hashes: Vec<[u8; 32]>, - ) -> Transaction { - let mut rng = rand::thread_rng(); + nullifier_created_hashes: Vec<[u8; 32]>, + utxo_commitments_spent_hashes: Vec<[u8; 32]>, + utxo_commitments_created_hashes: Vec<[u8; 32]>, +) -> Transaction { + let mut rng = rand::thread_rng(); - let body = TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes, - utxo_commitments_created_hashes, - nullifier_created_hashes, - execution_proof_private: "dummy_proof".to_string(), - encoded_data: vec![], - ephemeral_pub_key: vec![10, 11, 12], - commitment: vec![], - tweak: Tweak::new(&mut rng), - secret_r: [0; 32], - sc_addr: "sc_addr".to_string(), - state_changes: (serde_json::Value::Null, 0), - }; - Transaction::new(body, SignaturePrivateKey::random(&mut rng)) - } + let body = TransactionBody { + tx_kind: TxKind::Private, + execution_input: vec![], + execution_output: vec![], + utxo_commitments_spent_hashes, + utxo_commitments_created_hashes, + nullifier_created_hashes, + execution_proof_private: "dummy_proof".to_string(), + encoded_data: vec![], + ephemeral_pub_key: vec![10, 11, 12], + commitment: vec![], + tweak: Tweak::new(&mut rng), + secret_r: [0; 32], + sc_addr: "sc_addr".to_string(), + state_changes: (serde_json::Value::Null, 0), + }; + Transaction::new(body, SignaturePrivateKey::random(&mut rng)) +} pub fn create_dummy_transaction_native_token_transfer( - from: [u8; 32], - nonce: u64, - to: [u8; 32], - balance_to_move: u64, - signing_key: SigningKey, - ) -> Transaction { - let mut rng = rand::thread_rng(); + from: [u8; 32], + nonce: u64, + to: [u8; 32], + balance_to_move: u64, + signing_key: SigningKey, +) -> Transaction { + let mut rng = rand::thread_rng(); - let native_token_transfer = PublicNativeTokenSend { - from, - nonce, - to, - balance_to_move, - }; + let native_token_transfer = PublicNativeTokenSend { + from, + nonce, + to, + balance_to_move, + }; - let body = TransactionBody { - tx_kind: TxKind::Public, - execution_input: serde_json::to_vec(&native_token_transfer).unwrap(), - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: vec![], - nullifier_created_hashes: vec![], - execution_proof_private: "".to_string(), - encoded_data: vec![], - ephemeral_pub_key: vec![10, 11, 12], - commitment: vec![], - tweak: Tweak::new(&mut rng), - secret_r: [0; 32], - sc_addr: "sc_addr".to_string(), - state_changes: (serde_json::Value::Null, 0), - }; - Transaction::new(body, signing_key) - } + let body = TransactionBody { + tx_kind: TxKind::Public, + execution_input: serde_json::to_vec(&native_token_transfer).unwrap(), + execution_output: vec![], + utxo_commitments_spent_hashes: vec![], + utxo_commitments_created_hashes: vec![], + nullifier_created_hashes: vec![], + execution_proof_private: "".to_string(), + encoded_data: vec![], + ephemeral_pub_key: vec![10, 11, 12], + commitment: vec![], + tweak: Tweak::new(&mut rng), + secret_r: [0; 32], + sc_addr: "sc_addr".to_string(), + state_changes: (serde_json::Value::Null, 0), + }; + Transaction::new(body, signing_key) +} diff --git a/node_core/src/chain_storage/mod.rs b/node_core/src/chain_storage/mod.rs index 62ec130..ba20504 100644 --- a/node_core/src/chain_storage/mod.rs +++ b/node_core/src/chain_storage/mod.rs @@ -54,15 +54,13 @@ impl NodeChainStore { let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); let pub_tx_store = PublicTransactionMerkleTree::new(vec![]); - Ok( - Self { - acc_map, - nullifier_store, - utxo_commitments_store, - pub_tx_store, - node_config: config, - } - ) + Ok(Self { + acc_map, + nullifier_store, + utxo_commitments_store, + pub_tx_store, + node_config: config, + }) } pub fn produce_context(&self, caller: AccountAddress) -> PublicSCContext { From c5097ab8790852dfdce41cc6d5b0fb7621bd85f7 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 6 Aug 2025 14:56:58 +0300 Subject: [PATCH 4/5] fix: cli added --- Cargo.lock | 174 ++++++++++-------- Cargo.toml | 2 +- ci_scripts/test-ubuntu.sh | 1 + .../configs/debug/node/node_config.json | 11 -- integration_tests/src/lib.rs | 123 +++++-------- node_core/Cargo.toml | 1 + node_core/src/chain_storage/mod.rs | 27 --- node_core/src/config.rs | 18 -- node_core/src/lib.rs | 75 +++++++- node_core/src/main.rs | 22 +++ 10 files changed, 243 insertions(+), 211 deletions(-) create mode 100644 node_core/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 272ba6c..539c8da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,6 +365,56 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "anstream" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + [[package]] name = "anyhow" version = "1.0.98" @@ -627,17 +677,6 @@ dependencies = [ "critical-section", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "auto_ops" version = "0.3.0" @@ -961,42 +1000,43 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.25" +version = "4.5.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882" dependencies = [ - "atty", - "bitflags 1.3.2", + "clap_builder", "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966" +dependencies = [ + "anstream", + "anstyle", "clap_lex", - "indexmap 1.9.3", - "once_cell", - "strsim 0.10.0", - "termcolor", - "textwrap", + "strsim", ] [[package]] name = "clap_derive" -version = "3.2.25" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ - "heck 0.4.1", - "proc-macro-error", + "heck 0.5.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.104", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "cobs" @@ -1007,6 +1047,12 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "common" version = "0.1.0" @@ -1237,7 +1283,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.11.1", + "strsim", "syn 2.0.104", ] @@ -1927,7 +1973,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.10.0", + "indexmap", "slab", "tokio", "tokio-util", @@ -2005,15 +2051,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.5.2" @@ -2340,16 +2377,6 @@ 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", -] - [[package]] name = "indexmap" version = "2.10.0" @@ -2435,11 +2462,17 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.5.2", + "hermit-abi", "libc", "windows-sys 0.59.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.10.5" @@ -2943,6 +2976,7 @@ dependencies = [ "actix-rt", "anyhow", "bincode", + "clap", "common", "elliptic-curve", "env_logger", @@ -3085,6 +3119,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + [[package]] name = "opaque-debug" version = "0.3.1" @@ -3141,12 +3181,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - [[package]] name = "parking_lot" version = "0.12.4" @@ -4610,12 +4644,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -4754,12 +4782,6 @@ dependencies = [ "risc0-build", ] -[[package]] -name = "textwrap" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" - [[package]] name = "thiserror" version = "1.0.69" @@ -4956,7 +4978,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.10.0", + "indexmap", "serde", "serde_spanned", "toml_datetime", @@ -4969,7 +4991,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.10.0", + "indexmap", "serde", "serde_spanned", "toml_datetime", @@ -5167,6 +5189,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "utxo" version = "0.1.0" @@ -5821,7 +5849,7 @@ dependencies = [ "crossbeam-utils", "displaydoc", "flate2", - "indexmap 2.10.0", + "indexmap", "memchr", "thiserror 2.0.12", "zopfli", diff --git a/Cargo.toml b/Cargo.toml index 41c5309..a7d82a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,7 @@ version = "=4.1.0" [workspace.dependencies.clap] features = ["derive", "env"] -version = "3.1.6" +version = "4.5.42" [workspace.dependencies.tokio-retry] version = "0.3.0" diff --git a/ci_scripts/test-ubuntu.sh b/ci_scripts/test-ubuntu.sh index 47d79fa..34b97b7 100644 --- a/ci_scripts/test-ubuntu.sh +++ b/ci_scripts/test-ubuntu.sh @@ -6,4 +6,5 @@ source env.sh cargo test --release cd integration_tests +export HOME_DIR=$(pwd)/configs/debug/node/ cargo run $(pwd)/configs/debug all \ No newline at end of file diff --git a/integration_tests/configs/debug/node/node_config.json b/integration_tests/configs/debug/node/node_config.json index ec27ac4..ef07b4f 100644 --- a/integration_tests/configs/debug/node/node_config.json +++ b/integration_tests/configs/debug/node/node_config.json @@ -3,17 +3,6 @@ "override_rust_log": null, "sequencer_addr": "http://127.0.0.1:3040", "seq_poll_timeout_secs": 10, - "port": 3041, - "gas_config": { - "gas_fee_per_byte_deploy": 100, - "gas_fee_per_input_buffer_runtime": 1000, - "gas_fee_per_byte_runtime": 10, - "gas_cost_runtime": 100, - "gas_cost_deploy": 1000, - "gas_limit_deploy": 30000000, - "gas_limit_runtime": 30000000 - }, - "shapshot_frequency_in_blocks": 10, "initial_accounts": [ { "address": [ diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index 6438542..7678f4f 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -1,14 +1,14 @@ -use std::{path::PathBuf, sync::Arc, time::Duration}; +use std::{path::PathBuf, time::Duration}; use actix_web::dev::ServerHandle; use anyhow::Result; use clap::Parser; use log::info; -use node_core::{NodeCore, config::NodeConfig}; +use node_core::{Command, fetch_config, sequencer_client::SequencerClient}; use sequencer_core::config::SequencerConfig; use sequencer_runner::startup_sequencer; use tempfile::TempDir; -use tokio::{sync::Mutex, task::JoinHandle}; +use tokio::task::JoinHandle; #[derive(Parser, Debug)] #[clap(version)] @@ -27,65 +27,38 @@ pub const TIME_TO_WAIT_FOR_BLOCK_SECONDS: u64 = 12; #[allow(clippy::type_complexity)] pub async fn pre_test( home_dir: PathBuf, -) -> Result<( - ServerHandle, - JoinHandle>, - TempDir, - TempDir, - Arc>, -)> { +) -> Result<(ServerHandle, JoinHandle>, TempDir)> { let home_dir_sequencer = home_dir.join("sequencer"); - let home_dir_node = home_dir.join("node"); let mut sequencer_config = sequencer_runner::config::from_file(home_dir_sequencer.join("sequencer_config.json")) .unwrap(); - let mut node_config = - node_core::config::from_file(home_dir_node.join("node_config.json")).unwrap(); - let (temp_dir_node, temp_dir_sequencer) = - replace_home_dir_with_temp_dir_in_configs(&mut node_config, &mut sequencer_config); + let temp_dir_sequencer = replace_home_dir_with_temp_dir_in_configs(&mut sequencer_config); let (seq_http_server_handle, sequencer_loop_handle) = startup_sequencer(sequencer_config).await?; - let node_core = NodeCore::start_from_config_update_chain(node_config.clone()).await?; - - let wrapped_node_core = Arc::new(Mutex::new(node_core)); - Ok(( seq_http_server_handle, sequencer_loop_handle, - temp_dir_node, temp_dir_sequencer, - wrapped_node_core, )) } pub fn replace_home_dir_with_temp_dir_in_configs( - node_config: &mut NodeConfig, sequencer_config: &mut SequencerConfig, -) -> (TempDir, TempDir) { - let temp_dir_node = tempfile::tempdir().unwrap(); +) -> TempDir { let temp_dir_sequencer = tempfile::tempdir().unwrap(); - node_config.home = temp_dir_node.path().to_path_buf(); sequencer_config.home = temp_dir_sequencer.path().to_path_buf(); - (temp_dir_node, temp_dir_sequencer) + temp_dir_sequencer } #[allow(clippy::type_complexity)] -pub async fn post_test( - residual: ( - ServerHandle, - JoinHandle>, - TempDir, - TempDir, - Arc>, - ), -) { - let (seq_http_server_handle, sequencer_loop_handle, _, _, _) = residual; +pub async fn post_test(residual: (ServerHandle, JoinHandle>, TempDir)) { + let (seq_http_server_handle, sequencer_loop_handle, _) = residual; info!("Cleanup"); @@ -96,28 +69,28 @@ pub async fn post_test( //So they are dropped and tempdirs will be dropped too, } -pub async fn test_success(wrapped_node_core: Arc>) { - let acc_sender = hex::decode(ACC_SENDER).unwrap().try_into().unwrap(); - let acc_receiver = hex::decode(ACC_RECEIVER).unwrap().try_into().unwrap(); +pub async fn test_success() { + let command = Command::SendNativeTokenTransfer { + from: ACC_SENDER.to_string(), + to: ACC_RECEIVER.to_string(), + amount: 100, + }; - let guard = wrapped_node_core.lock().await; + let node_config = fetch_config().unwrap(); - let _res = guard - .send_public_native_token_transfer(acc_sender, 0, acc_receiver, 100) - .await - .unwrap(); + let seq_client = SequencerClient::new(node_config).unwrap(); + + node_core::execute_subcommand(command).await.unwrap(); info!("Waiting for next block creation"); tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; info!("Checking correct balance move"); - let acc_1_balance = guard - .sequencer_client + let acc_1_balance = seq_client .get_account_balance(ACC_SENDER.to_string()) .await .unwrap(); - let acc_2_balance = guard - .sequencer_client + let acc_2_balance = seq_client .get_account_balance(ACC_RECEIVER.to_string()) .await .unwrap(); @@ -131,30 +104,30 @@ pub async fn test_success(wrapped_node_core: Arc>) { info!("Success!"); } -pub async fn test_success_move_to_another_account(wrapped_node_core: Arc>) { - let acc_sender = hex::decode(ACC_SENDER).unwrap().try_into().unwrap(); - let acc_receiver_new_acc = [42; 32]; +pub async fn test_success_move_to_another_account() { + let hex_acc_receiver_new_acc = hex::encode([42; 32]); - let hex_acc_receiver_new_acc = hex::encode(acc_receiver_new_acc); + let command = Command::SendNativeTokenTransfer { + from: ACC_SENDER.to_string(), + to: hex_acc_receiver_new_acc.clone(), + amount: 100, + }; - let guard = wrapped_node_core.lock().await; + let node_config = fetch_config().unwrap(); - let _res = guard - .send_public_native_token_transfer(acc_sender, 0, acc_receiver_new_acc, 100) - .await - .unwrap(); + let seq_client = SequencerClient::new(node_config).unwrap(); + + node_core::execute_subcommand(command).await.unwrap(); info!("Waiting for next block creation"); tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; info!("Checking correct balance move"); - let acc_1_balance = guard - .sequencer_client + let acc_1_balance = seq_client .get_account_balance(ACC_SENDER.to_string()) .await .unwrap(); - let acc_2_balance = guard - .sequencer_client + let acc_2_balance = seq_client .get_account_balance(hex_acc_receiver_new_acc) .await .unwrap(); @@ -168,28 +141,28 @@ pub async fn test_success_move_to_another_account(wrapped_node_core: Arc>) { - let acc_sender = hex::decode(ACC_SENDER).unwrap().try_into().unwrap(); - let acc_receiver = hex::decode(ACC_RECEIVER).unwrap().try_into().unwrap(); +pub async fn test_failure() { + let command = Command::SendNativeTokenTransfer { + from: ACC_SENDER.to_string(), + to: ACC_RECEIVER.to_string(), + amount: 1000000, + }; - let guard = wrapped_node_core.lock().await; + let node_config = fetch_config().unwrap(); - let _res = guard - .send_public_native_token_transfer(acc_sender, 0, acc_receiver, 100000) - .await - .unwrap(); + let seq_client = SequencerClient::new(node_config).unwrap(); + + node_core::execute_subcommand(command).await.unwrap(); info!("Waiting for next block creation"); tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; info!("Checking correct balance move"); - let acc_1_balance = guard - .sequencer_client + let acc_1_balance = seq_client .get_account_balance(ACC_SENDER.to_string()) .await .unwrap(); - let acc_2_balance = guard - .sequencer_client + let acc_2_balance = seq_client .get_account_balance(ACC_RECEIVER.to_string()) .await .unwrap(); @@ -207,12 +180,10 @@ macro_rules! test_cleanup_wrap { ($home_dir:ident, $test_func:ident) => {{ let res = pre_test($home_dir.clone()).await.unwrap(); - let wrapped_node_core = res.4.clone(); - info!("Waiting for first block creation"); tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; - $test_func(wrapped_node_core.clone()).await; + $test_func().await; post_test(res).await; }}; diff --git a/node_core/Cargo.toml b/node_core/Cargo.toml index 969e4ec..a9c8b23 100644 --- a/node_core/Cargo.toml +++ b/node_core/Cargo.toml @@ -21,6 +21,7 @@ tempfile.workspace = true risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } hex.workspace = true actix-rt.workspace = true +clap.workspace = true [dependencies.sc_core] path = "../sc_core" diff --git a/node_core/src/chain_storage/mod.rs b/node_core/src/chain_storage/mod.rs index ba20504..446df2f 100644 --- a/node_core/src/chain_storage/mod.rs +++ b/node_core/src/chain_storage/mod.rs @@ -89,7 +89,6 @@ impl NodeChainStore { #[cfg(test)] mod tests { use super::*; - use crate::config::GasConfig; use accounts::account_core::Account; use std::path::PathBuf; use tempfile::tempdir; @@ -268,42 +267,16 @@ mod tests { initial_accounts } - // fn create_genesis_block() -> Block { - // Block { - // block_id: 0, - // prev_block_id: 0, - // prev_block_hash: [0; 32], - // hash: [1; 32], - // transactions: vec![], - // data: Data::default(), - // } - // } - fn create_sample_node_config(home: PathBuf) -> NodeConfig { NodeConfig { home, override_rust_log: None, sequencer_addr: "http://127.0.0.1".to_string(), seq_poll_timeout_secs: 1, - port: 8000, - gas_config: create_sample_gas_config(), - shapshot_frequency_in_blocks: 1, initial_accounts: create_initial_accounts(), } } - fn create_sample_gas_config() -> GasConfig { - GasConfig { - gas_fee_per_byte_deploy: 0, - gas_fee_per_input_buffer_runtime: 0, - gas_fee_per_byte_runtime: 0, - gas_cost_runtime: 0, - gas_cost_deploy: 0, - gas_limit_deploy: 0, - gas_limit_runtime: 0, - } - } - #[test] fn test_new_initializes_correctly() { let temp_dir = tempdir().unwrap(); diff --git a/node_core/src/config.rs b/node_core/src/config.rs index 8aa08ad..29a22f9 100644 --- a/node_core/src/config.rs +++ b/node_core/src/config.rs @@ -4,11 +4,6 @@ use accounts::account_core::Account; use serde::{Deserialize, Serialize}; use zkvm::gas_calculator::GasCalculator; -use anyhow::Result; - -use std::fs::File; -use std::io::BufReader; - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GasConfig { /// Gas spent per deploying one byte of data @@ -51,19 +46,6 @@ pub struct NodeConfig { pub sequencer_addr: String, ///Sequencer polling duration for new blocks in seconds pub seq_poll_timeout_secs: u64, - ///Port to listen - pub port: u16, - ///Gas config - pub gas_config: GasConfig, - ///Frequency of snapshots - pub shapshot_frequency_in_blocks: u64, ///Initial accounts for wallet pub initial_accounts: Vec, } - -pub fn from_file(config_home: PathBuf) -> Result { - let file = File::open(config_home)?; - let reader = BufReader::new(file); - - Ok(serde_json::from_reader(reader)?) -} diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index cceed8c..c94776f 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -1,22 +1,25 @@ -use std::sync::Arc; +use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr, sync::Arc}; use common::{ execution_input::PublicNativeTokenSend, transaction::Transaction, ExecutionFailureKind, }; use accounts::account_core::{address::AccountAddress, Account}; -use anyhow::Result; +use anyhow::{anyhow, Result}; use chain_storage::NodeChainStore; use common::transaction::TransactionBody; use config::NodeConfig; +use log::info; use sc_core::proofs_circuits::{generate_commitments, pedersen_commitment_vec}; use sequencer_client::{json::SendTxResponse, SequencerClient}; use serde::{Deserialize, Serialize}; use storage::sc_db_utils::DataBlobChangeVariant; use tokio::sync::RwLock; use utxo::utxo_core::UTXO; -use zkvm::gas_calculator::GasCalculator; +use clap::{Parser, Subcommand}; + +pub const HOME_DIR_ENV_VAR: &str = "HOME_DIR"; pub const BLOCK_GEN_DELAY_SECS: u64 = 20; pub mod chain_storage; @@ -74,7 +77,6 @@ pub struct NodeCore { pub storage: Arc>, pub node_config: NodeConfig, pub sequencer_client: Arc, - pub gas_calculator: GasCalculator, } impl NodeCore { @@ -92,7 +94,6 @@ impl NodeCore { storage: wrapped_storage, node_config: config.clone(), sequencer_client: client.clone(), - gas_calculator: GasCalculator::from(config.gas_config), }) } @@ -190,3 +191,67 @@ pub fn generate_commitments_helper(input_utxos: &[UTXO]) -> Vec<[u8; 32]> { .map(|comm_raw| comm_raw.try_into().unwrap()) .collect() } + +///Represents CLI command for a wallet +#[derive(Subcommand, Debug, Clone)] +pub enum Command { + SendNativeTokenTransfer { + #[arg(long)] + from: String, + #[arg(long)] + to: String, + #[arg(long)] + amount: u64, + }, +} + +#[derive(Parser, Debug)] +#[clap(version)] +pub struct Args { + /// Wallet command + #[command(subcommand)] + pub command: Command, +} + +pub fn get_home() -> Result { + Ok(PathBuf::from_str(&std::env::var(HOME_DIR_ENV_VAR)?)?) +} + +pub fn fetch_config() -> Result { + let config_home = get_home()?; + let file = File::open(config_home.join("node_config.json"))?; + let reader = BufReader::new(file); + + Ok(serde_json::from_reader(reader)?) +} + +//ToDo: Replace with structures in future +pub fn produce_account_addr_from_hex(hex_str: String) -> Result<[u8; 32]> { + hex::decode(hex_str)? + .try_into() + .map_err(|_| anyhow!("Failed conversion to 32 bytes")) +} + +pub async fn execute_subcommand(command: Command) -> Result<()> { + //env_logger::init(); + + match command { + Command::SendNativeTokenTransfer { from, to, amount } => { + let node_config = fetch_config()?; + + let from = produce_account_addr_from_hex(from)?; + let to = produce_account_addr_from_hex(to)?; + + let wallet_core = NodeCore::start_from_config_update_chain(node_config).await?; + + //ToDo: Nonce management + let res = wallet_core + .send_public_native_token_transfer(from, 0, to, amount) + .await?; + + info!("Results of tx send is {res:#?}"); + } + } + + Ok(()) +} diff --git a/node_core/src/main.rs b/node_core/src/main.rs new file mode 100644 index 0000000..c8a8049 --- /dev/null +++ b/node_core/src/main.rs @@ -0,0 +1,22 @@ +use anyhow::Result; +use clap::Parser; +use node_core::{execute_subcommand, Args}; +use tokio::runtime::Builder; + +pub const NUM_THREADS: usize = 2; + +fn main() -> Result<()> { + let runtime = Builder::new_multi_thread() + .worker_threads(NUM_THREADS) + .enable_all() + .build() + .unwrap(); + + let args = Args::parse(); + + runtime.block_on(async move { + execute_subcommand(args.command).await.unwrap(); + }); + + Ok(()) +} From 17b6851d00c0cffbabfe8c68c594d89689963c4f Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Thu, 7 Aug 2025 14:07:34 +0300 Subject: [PATCH 5/5] fix: cleanup --- Cargo.lock | 63 +++++----- Cargo.toml | 2 +- ci_scripts/test-ubuntu.sh | 2 +- common/src/lib.rs | 1 + .../src/sequencer_client/json.rs | 3 +- .../src/sequencer_client/mod.rs | 43 ++----- common/src/test_utils.rs | 3 - common/src/transaction.rs | 5 - integration_tests/Cargo.toml | 4 +- integration_tests/src/lib.rs | 15 +-- sc_core/src/transaction_payloads_tools.rs | 2 - sequencer_rpc/src/process.rs | 6 +- {node_core => wallet}/Cargo.toml | 5 +- .../src/chain_storage/accounts_store.rs | 0 .../src/chain_storage/mod.rs | 0 {node_core => wallet}/src/config.rs | 0 wallet/src/helperfunctions.rs | 43 +++++++ {node_core => wallet}/src/lib.rs | 112 +++--------------- {node_core => wallet}/src/main.rs | 4 +- wallet/src/requests_structs.rs | 33 ++++++ 20 files changed, 160 insertions(+), 186 deletions(-) rename {node_core => common}/src/sequencer_client/json.rs (96%) rename {node_core => common}/src/sequencer_client/mod.rs (79%) rename {node_core => wallet}/Cargo.toml (93%) rename {node_core => wallet}/src/chain_storage/accounts_store.rs (100%) rename {node_core => wallet}/src/chain_storage/mod.rs (100%) rename {node_core => wallet}/src/config.rs (100%) create mode 100644 wallet/src/helperfunctions.rs rename {node_core => wallet}/src/lib.rs (61%) rename {node_core => wallet}/src/main.rs (86%) create mode 100644 wallet/src/requests_structs.rs diff --git a/Cargo.lock b/Cargo.lock index 539c8da..9417564 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2409,7 +2409,6 @@ dependencies = [ "env_logger", "hex", "log", - "node_core", "sequencer_core", "sequencer_rpc", "sequencer_runner", @@ -2418,6 +2417,7 @@ dependencies = [ "tempfile", "tokio", "toml 0.7.8", + "wallet", ] [[package]] @@ -2968,37 +2968,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5b0c77c1b780822bc749a33e39aeb2c07584ab93332303babeabb645298a76e" -[[package]] -name = "node_core" -version = "0.1.0" -dependencies = [ - "accounts", - "actix-rt", - "anyhow", - "bincode", - "clap", - "common", - "elliptic-curve", - "env_logger", - "hex", - "k256", - "log", - "rand 0.8.5", - "reqwest 0.11.27", - "risc0-zkvm", - "sc_core", - "secp256k1-zkp", - "serde", - "serde_json", - "sha2", - "storage", - "tempfile", - "thiserror 1.0.69", - "tokio", - "utxo", - "zkvm", -] - [[package]] name = "nom" version = "7.1.3" @@ -5240,6 +5209,36 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "wallet" +version = "0.1.0" +dependencies = [ + "accounts", + "actix-rt", + "anyhow", + "bincode", + "clap", + "common", + "elliptic-curve", + "env_logger", + "hex", + "k256", + "log", + "rand 0.8.5", + "reqwest 0.11.27", + "risc0-zkvm", + "sc_core", + "secp256k1-zkp", + "serde", + "serde_json", + "sha2", + "tempfile", + "thiserror 1.0.69", + "tokio", + "utxo", + "zkvm", +] + [[package]] name = "want" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index a7d82a2..b6ecaed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ "sequencer_rpc", "mempool", "zkvm", - "node_core", + "wallet", "sequencer_core", "common", "sc_core", diff --git a/ci_scripts/test-ubuntu.sh b/ci_scripts/test-ubuntu.sh index 34b97b7..90aa19e 100644 --- a/ci_scripts/test-ubuntu.sh +++ b/ci_scripts/test-ubuntu.sh @@ -6,5 +6,5 @@ source env.sh cargo test --release cd integration_tests -export HOME_DIR=$(pwd)/configs/debug/node/ +export NSSA_WALLET_HOME_DIR=$(pwd)/configs/debug/node/ 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 91f0a08..560bcd2 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -7,6 +7,7 @@ pub mod execution_input; pub mod merkle_tree_public; pub mod nullifier; pub mod rpc_primitives; +pub mod sequencer_client; pub mod transaction; pub mod utxo_commitment; diff --git a/node_core/src/sequencer_client/json.rs b/common/src/sequencer_client/json.rs similarity index 96% rename from node_core/src/sequencer_client/json.rs rename to common/src/sequencer_client/json.rs index ad1d746..3fbb3c6 100644 --- a/node_core/src/sequencer_client/json.rs +++ b/common/src/sequencer_client/json.rs @@ -1,6 +1,7 @@ -use common::transaction::Transaction; use serde::{Deserialize, Serialize}; +use crate::transaction::Transaction; + //Requests #[derive(Serialize, Deserialize, Debug)] diff --git a/node_core/src/sequencer_client/mod.rs b/common/src/sequencer_client/mod.rs similarity index 79% rename from node_core/src/sequencer_client/mod.rs rename to common/src/sequencer_client/mod.rs index 834e862..796ff1e 100644 --- a/node_core/src/sequencer_client/mod.rs +++ b/common/src/sequencer_client/mod.rs @@ -1,35 +1,32 @@ -use accounts::account_core::Account; -use anyhow::Result; -use common::rpc_primitives::requests::{ +use super::rpc_primitives::requests::{ GetAccountBalanceRequest, GetAccountBalanceResponse, GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse, GetInitialTestnetAccountsRequest, - RegisterAccountRequest, RegisterAccountResponse, }; -use common::transaction::Transaction; -use common::{SequencerClientError, SequencerRpcError}; +use anyhow::Result; use json::{SendTxRequest, SendTxResponse, SequencerRpcRequest, SequencerRpcResponse}; use reqwest::Client; use serde_json::Value; -use crate::config::NodeConfig; use crate::sequencer_client::json::AccountInitialData; +use crate::transaction::Transaction; +use crate::{SequencerClientError, SequencerRpcError}; pub mod json; #[derive(Clone)] pub struct SequencerClient { pub client: reqwest::Client, - pub config: NodeConfig, + pub sequencer_addr: String, } impl SequencerClient { - pub fn new(config: NodeConfig) -> Result { + pub fn new(sequencer_addr: String) -> Result { Ok(Self { client: Client::builder() //Add more fiedls if needed .timeout(std::time::Duration::from_secs(60)) .build()?, - config, + sequencer_addr, }) } @@ -40,7 +37,7 @@ impl SequencerClient { ) -> Result { let request = SequencerRpcRequest::from_payload_version_2_0(method.to_string(), payload); - let call_builder = self.client.post(&self.config.sequencer_addr); + let call_builder = self.client.post(&self.sequencer_addr); let call_res = call_builder.json(&request).send().await?; @@ -56,6 +53,7 @@ impl SequencerClient { } } + ///Get block data at `block_id` from sequencer pub async fn get_block( &self, block_id: u64, @@ -71,6 +69,7 @@ impl SequencerClient { Ok(resp_deser) } + ///Get account public balance for `address`. `address` must be a valid hex-string for 32 bytes. pub async fn get_account_balance( &self, address: String, @@ -88,6 +87,7 @@ impl SequencerClient { Ok(resp_deser) } + ///Send transaction to sequencer pub async fn send_tx( &self, transaction: Transaction, @@ -107,25 +107,7 @@ impl SequencerClient { Ok(resp_deser) } - pub async fn register_account( - &self, - account: &Account, - ) -> Result { - let acc_req = RegisterAccountRequest { - address: account.address, - }; - - let req = serde_json::to_value(acc_req)?; - - let resp = self - .call_method_with_payload("register_account", req) - .await?; - - let resp_deser = serde_json::from_value(resp)?; - - Ok(resp_deser) - } - + ///Get genesis id from sequencer pub async fn get_genesis_id(&self) -> Result { let genesis_req = GetGenesisIdRequest {}; @@ -141,6 +123,7 @@ impl SequencerClient { Ok(resp_deser) } + ///Get initial testnet accounts from sequencer pub async fn get_initial_testnet_accounts( &self, ) -> Result, SequencerClientError> { diff --git a/common/src/test_utils.rs b/common/src/test_utils.rs index 78ea39a..0e6bf5c 100644 --- a/common/src/test_utils.rs +++ b/common/src/test_utils.rs @@ -50,7 +50,6 @@ pub fn produce_dummy_empty_transaction() -> Transaction { tweak: Default::default(), secret_r: Default::default(), sc_addr: Default::default(), - state_changes: Default::default(), }; Transaction::new(body, SignaturePrivateKey::from_slice(&[1; 32]).unwrap()) @@ -77,7 +76,6 @@ pub fn create_dummy_private_transaction_random_signer( tweak: Tweak::new(&mut rng), secret_r: [0; 32], sc_addr: "sc_addr".to_string(), - state_changes: (serde_json::Value::Null, 0), }; Transaction::new(body, SignaturePrivateKey::random(&mut rng)) } @@ -112,7 +110,6 @@ pub fn create_dummy_transaction_native_token_transfer( tweak: Tweak::new(&mut rng), secret_r: [0; 32], sc_addr: "sc_addr".to_string(), - state_changes: (serde_json::Value::Null, 0), }; Transaction::new(body, signing_key) } diff --git a/common/src/transaction.rs b/common/src/transaction.rs index 2ba78e9..afc4559 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -58,10 +58,6 @@ pub struct TransactionBody { pub secret_r: [u8; 32], ///Hex-encoded address of a smart contract account called pub sc_addr: String, - ///Recorded changes in state of smart contract - /// - /// First value represents vector of changes, second is new length of a state - pub state_changes: (serde_json::Value, usize), } #[derive(Debug, Serialize, Deserialize)] @@ -325,7 +321,6 @@ mod tests { tweak: Tweak::from_slice(&[7; SECRET_KEY_SIZE]).unwrap(), secret_r: [8; 32], sc_addr: "someAddress".to_string(), - state_changes: (serde_json::Value::Null, 10), } } diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index e37d014..10c49fb 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -30,8 +30,8 @@ path = "../sequencer_core" [dependencies.sequencer_runner] path = "../sequencer_runner" -[dependencies.node_core] -path = "../node_core" +[dependencies.wallet] +path = "../wallet" [dependencies.common] path = "../common" diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index 7678f4f..f863f54 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -3,12 +3,13 @@ use std::{path::PathBuf, time::Duration}; use actix_web::dev::ServerHandle; use anyhow::Result; use clap::Parser; +use common::sequencer_client::SequencerClient; use log::info; -use node_core::{Command, fetch_config, sequencer_client::SequencerClient}; use sequencer_core::config::SequencerConfig; use sequencer_runner::startup_sequencer; use tempfile::TempDir; use tokio::task::JoinHandle; +use wallet::{Command, helperfunctions::fetch_config}; #[derive(Parser, Debug)] #[clap(version)] @@ -78,9 +79,9 @@ pub async fn test_success() { let node_config = fetch_config().unwrap(); - let seq_client = SequencerClient::new(node_config).unwrap(); + let seq_client = SequencerClient::new(node_config.sequencer_addr.clone()).unwrap(); - node_core::execute_subcommand(command).await.unwrap(); + wallet::execute_subcommand(command).await.unwrap(); info!("Waiting for next block creation"); tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; @@ -115,9 +116,9 @@ pub async fn test_success_move_to_another_account() { let node_config = fetch_config().unwrap(); - let seq_client = SequencerClient::new(node_config).unwrap(); + let seq_client = SequencerClient::new(node_config.sequencer_addr.clone()).unwrap(); - node_core::execute_subcommand(command).await.unwrap(); + wallet::execute_subcommand(command).await.unwrap(); info!("Waiting for next block creation"); tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; @@ -150,9 +151,9 @@ pub async fn test_failure() { let node_config = fetch_config().unwrap(); - let seq_client = SequencerClient::new(node_config).unwrap(); + let seq_client = SequencerClient::new(node_config.sequencer_addr.clone()).unwrap(); - node_core::execute_subcommand(command).await.unwrap(); + wallet::execute_subcommand(command).await.unwrap(); info!("Waiting for next block creation"); tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; diff --git a/sc_core/src/transaction_payloads_tools.rs b/sc_core/src/transaction_payloads_tools.rs index fa0e28e..543cfa8 100644 --- a/sc_core/src/transaction_payloads_tools.rs +++ b/sc_core/src/transaction_payloads_tools.rs @@ -14,7 +14,6 @@ pub fn create_public_transaction_payload( tweak: Tweak, secret_r: [u8; 32], sc_addr: String, - state_changes: (serde_json::Value, usize), ) -> TransactionBody { TransactionBody { tx_kind: TxKind::Public, @@ -30,7 +29,6 @@ pub fn create_public_transaction_payload( tweak, secret_r, sc_addr, - state_changes, } } diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index 77c6e8b..4e7c011 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -287,7 +287,6 @@ mod tests { tweak: Default::default(), secret_r: Default::default(), sc_addr: Default::default(), - state_changes: Default::default(), }; let tx = Transaction::new(tx_body, SignaturePrivateKey::from_slice(&[1; 32]).unwrap()); @@ -499,7 +498,7 @@ mod tests { let request = serde_json::json!({ "jsonrpc": "2.0", "method": "get_transaction_by_hash", - "params": { "hash": "a5210ef33912a448cfe6eda43878c144df81f7bdf51d19b5ddf97be11806a6ed"}, + "params": { "hash": "2c69b9639bcf8d58509204e18f1d5962029bf26840915f2bf2bb434501ad3c38"}, "id": 1 }); @@ -518,14 +517,13 @@ mod tests { "nullifier_created_hashes": [], "sc_addr": "", "secret_r": vec![0; 32], - "state_changes": [null, 0], "tweak": "0".repeat(64), "tx_kind": "Shielded", "utxo_commitments_created_hashes": [], "utxo_commitments_spent_hashes": [], }, "public_key": "3056301006072A8648CE3D020106052B8104000A034200041B84C5567B126440995D3ED5AABA0565D71E1834604819FF9C17F5E9D5DD078F70BEAF8F588B541507FED6A642C5AB42DFDF8120A7F639DE5122D47A69A8E8D1", - "signature": "A4E0D6A25BE829B006124F0DFD766427967AA3BEA96C29219E79BB2CC871891F384748C27E28718A4450AA78709FBF1A57DB33BCD575A2C819D2A439C2D878E6" + "signature": "D75783642EA6E7D5E13AE8CCD3C2D3F82728C0A778A80C9F2976C739CD9F7F3F240B0532954D87761DE299A6CB9E6606295786BA5D0F5CACAB3F3626724528B1" } } }); diff --git a/node_core/Cargo.toml b/wallet/Cargo.toml similarity index 93% rename from node_core/Cargo.toml rename to wallet/Cargo.toml index a9c8b23..a3166fc 100644 --- a/node_core/Cargo.toml +++ b/wallet/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "node_core" +name = "wallet" version = "0.1.0" edition = "2021" @@ -29,9 +29,6 @@ path = "../sc_core" [dependencies.accounts] path = "../accounts" -[dependencies.storage] -path = "../storage" - [dependencies.utxo] path = "../utxo" diff --git a/node_core/src/chain_storage/accounts_store.rs b/wallet/src/chain_storage/accounts_store.rs similarity index 100% rename from node_core/src/chain_storage/accounts_store.rs rename to wallet/src/chain_storage/accounts_store.rs diff --git a/node_core/src/chain_storage/mod.rs b/wallet/src/chain_storage/mod.rs similarity index 100% rename from node_core/src/chain_storage/mod.rs rename to wallet/src/chain_storage/mod.rs diff --git a/node_core/src/config.rs b/wallet/src/config.rs similarity index 100% rename from node_core/src/config.rs rename to wallet/src/config.rs diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs new file mode 100644 index 0000000..8f6af22 --- /dev/null +++ b/wallet/src/helperfunctions.rs @@ -0,0 +1,43 @@ +use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr}; + +use anyhow::{anyhow, Result}; + +use crate::{config::NodeConfig, HOME_DIR_ENV_VAR}; + +pub fn vec_u8_to_vec_u64(bytes: Vec) -> Vec { + // Pad with zeros to make sure it's a multiple of 8 + let mut padded = bytes.clone(); + while !padded.len().is_multiple_of(8) { + padded.push(0); + } + + padded + .chunks(8) + .map(|chunk| { + let mut array = [0u8; 8]; + array.copy_from_slice(chunk); + u64::from_le_bytes(array) + }) + .collect() +} + +///Get home dir for wallet. Env var `NSSA_WALLET_HOME_DIR` must be set before execution to succeed. +pub fn get_home() -> Result { + Ok(PathBuf::from_str(&std::env::var(HOME_DIR_ENV_VAR)?)?) +} + +///Fetch config from `NSSA_WALLET_HOME_DIR` +pub fn fetch_config() -> Result { + let config_home = get_home()?; + let file = File::open(config_home.join("node_config.json"))?; + let reader = BufReader::new(file); + + Ok(serde_json::from_reader(reader)?) +} + +//ToDo: Replace with structures conversion in future +pub fn produce_account_addr_from_hex(hex_str: String) -> Result<[u8; 32]> { + hex::decode(hex_str)? + .try_into() + .map_err(|_| anyhow!("Failed conversion to 32 bytes")) +} diff --git a/node_core/src/lib.rs b/wallet/src/lib.rs similarity index 61% rename from node_core/src/lib.rs rename to wallet/src/lib.rs index c94776f..81cf14e 100644 --- a/node_core/src/lib.rs +++ b/wallet/src/lib.rs @@ -1,77 +1,32 @@ -use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr, sync::Arc}; +use std::sync::Arc; use common::{ - execution_input::PublicNativeTokenSend, transaction::Transaction, ExecutionFailureKind, + execution_input::PublicNativeTokenSend, + sequencer_client::{json::SendTxResponse, SequencerClient}, + transaction::Transaction, + ExecutionFailureKind, }; use accounts::account_core::{address::AccountAddress, Account}; -use anyhow::{anyhow, Result}; +use anyhow::Result; use chain_storage::NodeChainStore; use common::transaction::TransactionBody; use config::NodeConfig; use log::info; -use sc_core::proofs_circuits::{generate_commitments, pedersen_commitment_vec}; -use sequencer_client::{json::SendTxResponse, SequencerClient}; -use serde::{Deserialize, Serialize}; -use storage::sc_db_utils::DataBlobChangeVariant; +use sc_core::proofs_circuits::pedersen_commitment_vec; use tokio::sync::RwLock; -use utxo::utxo_core::UTXO; use clap::{Parser, Subcommand}; -pub const HOME_DIR_ENV_VAR: &str = "HOME_DIR"; +use crate::helperfunctions::{fetch_config, produce_account_addr_from_hex}; + +pub const HOME_DIR_ENV_VAR: &str = "NSSA_WALLET_HOME_DIR"; pub const BLOCK_GEN_DELAY_SECS: u64 = 20; pub mod chain_storage; pub mod config; -pub mod sequencer_client; - -pub fn vec_u8_to_vec_u64(bytes: Vec) -> Vec { - // Pad with zeros to make sure it's a multiple of 8 - let mut padded = bytes.clone(); - while !padded.len().is_multiple_of(8) { - padded.push(0); - } - - padded - .chunks(8) - .map(|chunk| { - let mut array = [0u8; 8]; - array.copy_from_slice(chunk); - u64::from_le_bytes(array) - }) - .collect() -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct MintMoneyPublicTx { - pub acc: AccountAddress, - pub amount: u128, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SendMoneyShieldedTx { - pub acc_sender: AccountAddress, - pub amount: u128, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SendMoneyDeshieldedTx { - pub receiver_data: Vec<(u128, AccountAddress)>, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct UTXOPublication { - pub utxos: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum ActionData { - MintMoneyPublicTx(MintMoneyPublicTx), - SendMoneyShieldedTx(SendMoneyShieldedTx), - SendMoneyDeshieldedTx(SendMoneyDeshieldedTx), - UTXOPublication(UTXOPublication), -} +pub mod helperfunctions; +pub mod requests_structs; pub struct NodeCore { pub storage: Arc>, @@ -81,7 +36,7 @@ pub struct NodeCore { impl NodeCore { pub async fn start_from_config_update_chain(config: NodeConfig) -> Result { - let client = Arc::new(SequencerClient::new(config.clone())?); + let client = Arc::new(SequencerClient::new(config.sequencer_addr.clone())?); let mut storage = NodeChainStore::new(config.clone())?; for acc in config.clone().initial_accounts { @@ -142,11 +97,6 @@ impl NodeCore { let sc_addr = hex::encode([0; 32]); - //Native contract does not change its state - let state_changes: Vec = vec![]; - let new_len = 0; - let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - let tx: TransactionBody = sc_core::transaction_payloads_tools::create_public_transaction_payload( serde_json::to_vec(&PublicNativeTokenSend { @@ -160,7 +110,6 @@ impl NodeCore { tweak, secret_r, sc_addr, - state_changes, ); tx.log(); @@ -185,56 +134,33 @@ impl NodeCore { } } -pub fn generate_commitments_helper(input_utxos: &[UTXO]) -> Vec<[u8; 32]> { - generate_commitments(input_utxos) - .into_iter() - .map(|comm_raw| comm_raw.try_into().unwrap()) - .collect() -} - ///Represents CLI command for a wallet #[derive(Subcommand, Debug, Clone)] +#[clap(about)] pub enum Command { SendNativeTokenTransfer { + ///from - valid 32 byte hex string #[arg(long)] from: String, + ///to - valid 32 byte hex string #[arg(long)] to: String, + ///amount - amount of balance to move #[arg(long)] amount: u64, }, } +///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config #[derive(Parser, Debug)] -#[clap(version)] +#[clap(version, about)] pub struct Args { /// Wallet command #[command(subcommand)] pub command: Command, } -pub fn get_home() -> Result { - Ok(PathBuf::from_str(&std::env::var(HOME_DIR_ENV_VAR)?)?) -} - -pub fn fetch_config() -> Result { - let config_home = get_home()?; - let file = File::open(config_home.join("node_config.json"))?; - let reader = BufReader::new(file); - - Ok(serde_json::from_reader(reader)?) -} - -//ToDo: Replace with structures in future -pub fn produce_account_addr_from_hex(hex_str: String) -> Result<[u8; 32]> { - hex::decode(hex_str)? - .try_into() - .map_err(|_| anyhow!("Failed conversion to 32 bytes")) -} - pub async fn execute_subcommand(command: Command) -> Result<()> { - //env_logger::init(); - match command { Command::SendNativeTokenTransfer { from, to, amount } => { let node_config = fetch_config()?; diff --git a/node_core/src/main.rs b/wallet/src/main.rs similarity index 86% rename from node_core/src/main.rs rename to wallet/src/main.rs index c8a8049..f8c91f8 100644 --- a/node_core/src/main.rs +++ b/wallet/src/main.rs @@ -1,7 +1,7 @@ use anyhow::Result; use clap::Parser; -use node_core::{execute_subcommand, Args}; use tokio::runtime::Builder; +use wallet::{execute_subcommand, Args}; pub const NUM_THREADS: usize = 2; @@ -14,6 +14,8 @@ fn main() -> Result<()> { let args = Args::parse(); + env_logger::init(); + runtime.block_on(async move { execute_subcommand(args.command).await.unwrap(); }); diff --git a/wallet/src/requests_structs.rs b/wallet/src/requests_structs.rs new file mode 100644 index 0000000..e7bb935 --- /dev/null +++ b/wallet/src/requests_structs.rs @@ -0,0 +1,33 @@ +use accounts::account_core::address::AccountAddress; +use serde::{Deserialize, Serialize}; +use utxo::utxo_core::UTXO; + +#[derive(Debug, Serialize, Deserialize)] +pub struct MintMoneyPublicTx { + pub acc: AccountAddress, + pub amount: u128, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct SendMoneyShieldedTx { + pub acc_sender: AccountAddress, + pub amount: u128, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct SendMoneyDeshieldedTx { + pub receiver_data: Vec<(u128, AccountAddress)>, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct UTXOPublication { + pub utxos: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum ActionData { + MintMoneyPublicTx(MintMoneyPublicTx), + SendMoneyShieldedTx(SendMoneyShieldedTx), + SendMoneyDeshieldedTx(SendMoneyDeshieldedTx), + UTXOPublication(UTXOPublication), +}