From 6df4a04f841cb88945042dfce2ec8a9b9dd26186 Mon Sep 17 00:00:00 2001 From: Oleksandr Pravdyvyi Date: Wed, 30 Jul 2025 14:01:40 +0300 Subject: [PATCH] feat: first scenario implemented --- Cargo.lock | 1 + integration_tests/Cargo.toml | 1 + .../configs/debug/node/node_config.json | 253 ++++++++++++++++++ .../configs/debug/node_config.json | 17 -- .../debug/sequencer/sequencer_config.json | 19 ++ .../configs/debug/sequencer_config.json | 19 -- integration_tests/src/lib.rs | 72 ++++- node_core/src/lib.rs | 6 +- node_core/src/sequencer_client/json.rs | 8 + node_core/src/sequencer_client/mod.rs | 23 +- sequencer_core/src/lib.rs | 5 + 11 files changed, 370 insertions(+), 54 deletions(-) create mode 100644 integration_tests/configs/debug/node/node_config.json delete mode 100644 integration_tests/configs/debug/node_config.json create mode 100644 integration_tests/configs/debug/sequencer/sequencer_config.json delete mode 100644 integration_tests/configs/debug/sequencer_config.json diff --git a/Cargo.lock b/Cargo.lock index bf0838b..de96e5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2389,6 +2389,7 @@ dependencies = [ "clap", "common", "env_logger", + "hex", "log", "node_core", "node_rpc", diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index fcc7cc6..9558b9f 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -14,6 +14,7 @@ actix.workspace = true actix-web.workspace = true tokio.workspace = true toml.workspace = true +hex.workspace = true [dependencies.clap] features = ["derive", "env"] diff --git a/integration_tests/configs/debug/node/node_config.json b/integration_tests/configs/debug/node/node_config.json new file mode 100644 index 0000000..ec27ac4 --- /dev/null +++ b/integration_tests/configs/debug/node/node_config.json @@ -0,0 +1,253 @@ +{ + "home": "./node", + "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/integration_tests/configs/debug/node_config.json b/integration_tests/configs/debug/node_config.json deleted file mode 100644 index c948b82..0000000 --- a/integration_tests/configs/debug/node_config.json +++ /dev/null @@ -1,17 +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 -} \ No newline at end of file diff --git a/integration_tests/configs/debug/sequencer/sequencer_config.json b/integration_tests/configs/debug/sequencer/sequencer_config.json new file mode 100644 index 0000000..9eb086a --- /dev/null +++ b/integration_tests/configs/debug/sequencer/sequencer_config.json @@ -0,0 +1,19 @@ +{ + "home": "./sequencer", + "override_rust_log": null, + "genesis_id": 1, + "is_genesis_random": true, + "max_num_tx_in_block": 20, + "block_create_timeout_millis": 10000, + "port": 3040, + "initial_accounts": [ + { + "addr": "0d96dfcc414019380c9dde0cd3dce5aac90fb5443bf871108741aeafde552ad7", + "balance": 10000 + }, + { + "addr": "974870e9be8d0ac08aa83b3fc7a7a686291d8732508aba98b36080f39c2cf364", + "balance": 20000 + } + ] +} \ No newline at end of file diff --git a/integration_tests/configs/debug/sequencer_config.json b/integration_tests/configs/debug/sequencer_config.json deleted file mode 100644 index 18d1b72..0000000 --- a/integration_tests/configs/debug/sequencer_config.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "home": ".", - "override_rust_log": null, - "genesis_id": 1, - "is_genesis_random": true, - "max_num_tx_in_block": 20, - "block_create_timeout_millis": 10000, - "port": 3040, - "initial_accounts": [ - { - "addr": "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c", - "balance": 10 - }, - { - "addr": "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31", - "balance": 100 - } - ] -} \ No newline at end of file diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index af98f4d..375a523 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, sync::Arc}; +use std::{path::PathBuf, sync::Arc, time::Duration}; use anyhow::Result; use clap::Parser; @@ -15,14 +15,23 @@ struct Args { home_dir: PathBuf, } +pub const ACC_SENDER: &str = "0d96dfcc414019380c9dde0cd3dce5aac90fb5443bf871108741aeafde552ad7"; +pub const ACC_RECEIVER: &str = "974870e9be8d0ac08aa83b3fc7a7a686291d8732508aba98b36080f39c2cf364"; + pub async fn main_tests_runner() -> Result<()> { env_logger::init(); let args = Args::parse(); let Args { home_dir } = args; - let sequencer_config = sequencer_runner::config::from_file(home_dir.join("sequencer_config.json"))?; - let node_config = node_runner::config::from_file(home_dir.join("node_config.json"))?; + let home_dir_sequencer = home_dir.join("sequencer"); + let home_dir_node = home_dir.join("node"); + + let sequencer_config = + sequencer_runner::config::from_file(home_dir_sequencer.join("sequencer_config.json")) + .unwrap(); + let node_config = + node_runner::config::from_file(home_dir_node.join("node_config.json")).unwrap(); let block_timeout = sequencer_config.block_create_timeout_millis; let sequencer_port = sequencer_config.port; @@ -33,14 +42,17 @@ pub async fn main_tests_runner() -> Result<()> { let seq_core_wrapped = Arc::new(Mutex::new(sequencer_core)); - let http_server = sequencer_rpc::new_http_server(RpcConfig::with_port(sequencer_port), seq_core_wrapped.clone())?; + let http_server = sequencer_rpc::new_http_server( + RpcConfig::with_port(sequencer_port), + seq_core_wrapped.clone(), + )?; info!("HTTP server started"); - let _http_server_handle = http_server.handle(); + let seq_http_server_handle = http_server.handle(); tokio::spawn(http_server); info!("Starting main sequencer loop"); - let _sequencer_loop_handle: JoinHandle> = tokio::spawn(async move { + let sequencer_loop_handle: JoinHandle> = tokio::spawn(async move { loop { tokio::time::sleep(std::time::Duration::from_millis(block_timeout)).await; @@ -69,9 +81,51 @@ pub async fn main_tests_runner() -> Result<()> { wrapped_node_core.clone(), )?; info!("HTTP server started"); - let _http_server_handle = http_server.handle(); + let node_http_server_handle = http_server.handle(); tokio::spawn(http_server); - #[allow(clippy::empty_loop)] - loop {} + info!("Waiting for first block creation"); + tokio::time::sleep(Duration::from_secs(12)).await; + + let acc_sender = hex::decode(ACC_SENDER).unwrap().try_into().unwrap(); + let acc_receiver = hex::decode(ACC_RECEIVER).unwrap().try_into().unwrap(); + + { + let guard = wrapped_node_core.lock().await; + + let res = guard + .send_public_native_token_transfer(acc_sender, acc_receiver, 100) + .await + .unwrap(); + + info!("Res of tx_send is {res:#?}"); + + info!("Waiting for next block creation"); + tokio::time::sleep(Duration::from_secs(12)).await; + + info!("Checking correct balance move"); + let acc_1_balance = guard + .sequencer_client + .get_account_balance(ACC_SENDER.to_string()) + .await + .unwrap(); + let acc_2_balance = guard + .sequencer_client + .get_account_balance(ACC_RECEIVER.to_string()) + .await + .unwrap(); + + info!("Balance of sender : {acc_1_balance:#?}"); + info!("Balance of receiver : {acc_2_balance:#?}"); + } + + info!("Success!"); + + info!("Cleanup"); + + node_http_server_handle.stop(true).await; + sequencer_loop_handle.abort(); + seq_http_server_handle.stop(true).await; + + Ok(()) } diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index a8ca0b9..1d5259f 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -103,12 +103,8 @@ impl NodeCore { let genesis_block = client.get_block(genesis_id.genesis_id).await?.block; - let initial_accounts_ser = client.get_initial_testnet_accounts().await?; - let initial_accounts: Vec = - initial_accounts_ser.into_iter().map(Into::into).collect(); - let (mut storage, mut chain_height) = NodeChainStore::new(config.clone(), genesis_block)?; - for acc in initial_accounts { + for acc in config.clone().initial_accounts { storage.acc_map.insert(acc.address, acc); } diff --git a/node_core/src/sequencer_client/json.rs b/node_core/src/sequencer_client/json.rs index df94ca2..ad1d746 100644 --- a/node_core/src/sequencer_client/json.rs +++ b/node_core/src/sequencer_client/json.rs @@ -46,3 +46,11 @@ pub struct SequencerRpcResponse { pub result: serde_json::Value, pub id: u64, } + +#[derive(Debug, Serialize, Deserialize, Clone)] +///Helperstruct for account serialization +pub struct AccountInitialData { + ///Hex encoded `AccountAddress` + pub addr: String, + pub balance: u64, +} diff --git a/node_core/src/sequencer_client/mod.rs b/node_core/src/sequencer_client/mod.rs index e24b840..018d4ef 100644 --- a/node_core/src/sequencer_client/mod.rs +++ b/node_core/src/sequencer_client/mod.rs @@ -1,8 +1,7 @@ -use accounts::account_core::{Account, AccountForSerialization}; +use accounts::account_core::Account; use anyhow::Result; use common::rpc_primitives::requests::{ - GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse, - GetInitialTestnetAccountsRequest, RegisterAccountRequest, RegisterAccountResponse, + GetAccountBalanceRequest, GetAccountBalanceResponse, GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse, GetInitialTestnetAccountsRequest, RegisterAccountRequest, RegisterAccountResponse }; use common::transaction::Transaction; use common::{SequencerClientError, SequencerRpcError}; @@ -11,6 +10,7 @@ use reqwest::Client; use serde_json::Value; use crate::config::NodeConfig; +use crate::sequencer_client::json::AccountInitialData; pub mod json; @@ -69,6 +69,21 @@ impl SequencerClient { Ok(resp_deser) } + pub async fn get_account_balance( + &self, + address: String, + ) -> Result { + let block_req = GetAccountBalanceRequest { address }; + + let req = serde_json::to_value(block_req)?; + + let resp = self.call_method_with_payload("get_account_balance", req).await?; + + let resp_deser = serde_json::from_value(resp)?; + + Ok(resp_deser) + } + pub async fn send_tx( &self, transaction: Transaction, @@ -124,7 +139,7 @@ impl SequencerClient { pub async fn get_initial_testnet_accounts( &self, - ) -> Result, SequencerClientError> { + ) -> Result, SequencerClientError> { let acc_req = GetInitialTestnetAccountsRequest {}; let req = serde_json::to_value(acc_req).unwrap(); diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 3786a2b..5a6fd4d 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -478,6 +478,9 @@ mod tests { assert_eq!(sequencer.sequencer_config.max_num_tx_in_block, 10); assert_eq!(sequencer.sequencer_config.port, 8080); + println!("Initial_acc1 {:#?}", config.initial_accounts[0].addr.clone()); + println!("Initial_acc1 {:#?}", config.initial_accounts[1].addr.clone()); + let acc1_addr = hex::decode(config.initial_accounts[0].addr.clone()) .unwrap() .try_into() @@ -487,6 +490,8 @@ mod tests { .try_into() .unwrap(); + assert_eq!(2,3); + assert!(sequencer.store.acc_store.contains_account(&acc1_addr)); assert!(sequencer.store.acc_store.contains_account(&acc2_addr));