mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-07 15:53:14 +00:00
Merge pull request #96 from vacp2p/Pravdyvy/integration-tests
Integration tests
This commit is contained in:
commit
ebec84b3c0
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -16,7 +16,7 @@ name: General
|
|||||||
jobs:
|
jobs:
|
||||||
ubuntu-latest-pipeline:
|
ubuntu-latest-pipeline:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 120
|
||||||
|
|
||||||
name: ubuntu-latest-pipeline
|
name: ubuntu-latest-pipeline
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
492
Cargo.lock
generated
492
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,7 @@ members = [
|
|||||||
"sequencer_core",
|
"sequencer_core",
|
||||||
"common",
|
"common",
|
||||||
"sc_core",
|
"sc_core",
|
||||||
|
"integration_tests",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
|||||||
@ -4,4 +4,6 @@ curl -L https://risczero.com/install | bash
|
|||||||
/home/runner/.risc0/bin/rzup install
|
/home/runner/.risc0/bin/rzup install
|
||||||
source env.sh
|
source env.sh
|
||||||
|
|
||||||
cargo test --release
|
cargo test --release
|
||||||
|
cd integration_tests
|
||||||
|
cargo run $(pwd)/configs/debug all
|
||||||
46
integration_tests/Cargo.toml
Normal file
46
integration_tests/Cargo.toml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
[package]
|
||||||
|
name = "integration_tests"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
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
|
||||||
|
toml.workspace = true
|
||||||
|
hex.workspace = true
|
||||||
|
tempfile.workspace = true
|
||||||
|
|
||||||
|
[dependencies.clap]
|
||||||
|
features = ["derive", "env"]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies.sequencer_rpc]
|
||||||
|
path = "../sequencer_rpc"
|
||||||
|
|
||||||
|
[dependencies.sequencer_core]
|
||||||
|
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"
|
||||||
|
|
||||||
|
[dependencies.accounts]
|
||||||
|
path = "../accounts"
|
||||||
253
integration_tests/configs/debug/node/node_config.json
Normal file
253
integration_tests/configs/debug/node/node_config.json
Normal file
@ -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": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
268
integration_tests/src/lib.rs
Normal file
268
integration_tests/src/lib.rs
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
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;
|
||||||
|
use sequencer_runner::startup_sequencer;
|
||||||
|
use tempfile::TempDir;
|
||||||
|
use tokio::{sync::Mutex, task::JoinHandle};
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[clap(version)]
|
||||||
|
struct Args {
|
||||||
|
/// Path to configs
|
||||||
|
home_dir: PathBuf,
|
||||||
|
/// Test name
|
||||||
|
test_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const ACC_SENDER: &str = "0d96dfcc414019380c9dde0cd3dce5aac90fb5443bf871108741aeafde552ad7";
|
||||||
|
pub const ACC_RECEIVER: &str = "974870e9be8d0ac08aa83b3fc7a7a686291d8732508aba98b36080f39c2cf364";
|
||||||
|
|
||||||
|
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<Result<()>>,
|
||||||
|
ServerHandle,
|
||||||
|
TempDir,
|
||||||
|
TempDir,
|
||||||
|
Arc<Mutex<NodeCore>>,
|
||||||
|
)> {
|
||||||
|
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_runner::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 (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,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
pub async fn post_test(
|
||||||
|
residual: (
|
||||||
|
ServerHandle,
|
||||||
|
JoinHandle<Result<()>>,
|
||||||
|
ServerHandle,
|
||||||
|
TempDir,
|
||||||
|
TempDir,
|
||||||
|
Arc<Mutex<NodeCore>>,
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
let (seq_http_server_handle, sequencer_loop_handle, node_http_server_handle, _, _, _) =
|
||||||
|
residual;
|
||||||
|
|
||||||
|
info!("Cleanup");
|
||||||
|
|
||||||
|
node_http_server_handle.stop(true).await;
|
||||||
|
sequencer_loop_handle.abort();
|
||||||
|
seq_http_server_handle.stop(true).await;
|
||||||
|
|
||||||
|
//At this point all of the references to node_core and sequencer_core must be lost.
|
||||||
|
//So they are dropped and tempdirs will be dropped too,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn test_success(wrapped_node_core: Arc<Mutex<NodeCore>>) {
|
||||||
|
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, 0, acc_receiver, 100)
|
||||||
|
.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
|
||||||
|
.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:#?}");
|
||||||
|
|
||||||
|
assert_eq!(acc_1_balance.balance, 9900);
|
||||||
|
assert_eq!(acc_2_balance.balance, 20100);
|
||||||
|
|
||||||
|
info!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn test_success_move_to_another_account(wrapped_node_core: Arc<Mutex<NodeCore>>) {
|
||||||
|
let acc_sender = hex::decode(ACC_SENDER).unwrap().try_into().unwrap();
|
||||||
|
let acc_receiver_new_acc = [42; 32];
|
||||||
|
|
||||||
|
let hex_acc_receiver_new_acc = hex::encode(acc_receiver_new_acc);
|
||||||
|
|
||||||
|
let guard = wrapped_node_core.lock().await;
|
||||||
|
|
||||||
|
let _res = guard
|
||||||
|
.send_public_native_token_transfer(acc_sender, 0, acc_receiver_new_acc, 100)
|
||||||
|
.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
|
||||||
|
.get_account_balance(ACC_SENDER.to_string())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let acc_2_balance = guard
|
||||||
|
.sequencer_client
|
||||||
|
.get_account_balance(hex_acc_receiver_new_acc)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
info!("Balance of sender : {acc_1_balance:#?}");
|
||||||
|
info!("Balance of receiver : {acc_2_balance:#?}");
|
||||||
|
|
||||||
|
assert_eq!(acc_1_balance.balance, 9900);
|
||||||
|
assert_eq!(acc_2_balance.balance, 100);
|
||||||
|
|
||||||
|
info!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn test_failure(wrapped_node_core: Arc<Mutex<NodeCore>>) {
|
||||||
|
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, 0, acc_receiver, 100000)
|
||||||
|
.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
|
||||||
|
.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:#?}");
|
||||||
|
|
||||||
|
assert_eq!(acc_1_balance.balance, 10000);
|
||||||
|
assert_eq!(acc_2_balance.balance, 20000);
|
||||||
|
|
||||||
|
info!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
post_test(res).await;
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn main_tests_runner() -> Result<()> {
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let args = Args::parse();
|
||||||
|
let Args {
|
||||||
|
home_dir,
|
||||||
|
test_name,
|
||||||
|
} = args;
|
||||||
|
|
||||||
|
match test_name.as_str() {
|
||||||
|
"test_success_move_to_another_account" => {
|
||||||
|
test_cleanup_wrap!(home_dir, test_success_move_to_another_account);
|
||||||
|
}
|
||||||
|
"test_success" => {
|
||||||
|
test_cleanup_wrap!(home_dir, test_success);
|
||||||
|
}
|
||||||
|
"test_failure" => {
|
||||||
|
test_cleanup_wrap!(home_dir, test_failure);
|
||||||
|
}
|
||||||
|
"all" => {
|
||||||
|
test_cleanup_wrap!(home_dir, test_success_move_to_another_account);
|
||||||
|
test_cleanup_wrap!(home_dir, test_success);
|
||||||
|
test_cleanup_wrap!(home_dir, test_failure);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
anyhow::bail!("Unknown test name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
16
integration_tests/src/main.rs
Normal file
16
integration_tests/src/main.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use integration_tests::main_tests_runner;
|
||||||
|
|
||||||
|
pub const NUM_THREADS: usize = 8;
|
||||||
|
|
||||||
|
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_tests_runner())
|
||||||
|
}
|
||||||
@ -103,12 +103,8 @@ impl NodeCore {
|
|||||||
|
|
||||||
let genesis_block = client.get_block(genesis_id.genesis_id).await?.block;
|
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<Account> =
|
|
||||||
initial_accounts_ser.into_iter().map(Into::into).collect();
|
|
||||||
|
|
||||||
let (mut storage, mut chain_height) = NodeChainStore::new(config.clone(), genesis_block)?;
|
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);
|
storage.acc_map.insert(acc.address, acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,8 +947,6 @@ impl NodeCore {
|
|||||||
// Ok(self.sequencer_client.send_tx(tx, tx_roots).await?)
|
// Ok(self.sequencer_client.send_tx(tx, tx_roots).await?)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// ToDo: Currently untested due to need for end-to-end integration tests.
|
|
||||||
// Add integration tests to cover this functionality
|
|
||||||
pub async fn send_public_native_token_transfer(
|
pub async fn send_public_native_token_transfer(
|
||||||
&self,
|
&self,
|
||||||
from: AccountAddress,
|
from: AccountAddress,
|
||||||
|
|||||||
@ -46,3 +46,11 @@ pub struct SequencerRpcResponse {
|
|||||||
pub result: serde_json::Value,
|
pub result: serde_json::Value,
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
///Helperstruct for account serialization
|
||||||
|
pub struct AccountInitialData {
|
||||||
|
///Hex encoded `AccountAddress`
|
||||||
|
pub addr: String,
|
||||||
|
pub balance: u64,
|
||||||
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
use accounts::account_core::{Account, AccountForSerialization};
|
use accounts::account_core::Account;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use common::rpc_primitives::requests::{
|
use common::rpc_primitives::requests::{
|
||||||
GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
|
GetAccountBalanceRequest, GetAccountBalanceResponse, GetBlockDataRequest, GetBlockDataResponse,
|
||||||
GetInitialTestnetAccountsRequest, RegisterAccountRequest, RegisterAccountResponse,
|
GetGenesisIdRequest, GetGenesisIdResponse, GetInitialTestnetAccountsRequest,
|
||||||
|
RegisterAccountRequest, RegisterAccountResponse,
|
||||||
};
|
};
|
||||||
use common::transaction::Transaction;
|
use common::transaction::Transaction;
|
||||||
use common::{SequencerClientError, SequencerRpcError};
|
use common::{SequencerClientError, SequencerRpcError};
|
||||||
@ -11,6 +12,7 @@ use reqwest::Client;
|
|||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::config::NodeConfig;
|
use crate::config::NodeConfig;
|
||||||
|
use crate::sequencer_client::json::AccountInitialData;
|
||||||
|
|
||||||
pub mod json;
|
pub mod json;
|
||||||
|
|
||||||
@ -69,6 +71,23 @@ impl SequencerClient {
|
|||||||
Ok(resp_deser)
|
Ok(resp_deser)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_account_balance(
|
||||||
|
&self,
|
||||||
|
address: String,
|
||||||
|
) -> Result<GetAccountBalanceResponse, SequencerClientError> {
|
||||||
|
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(
|
pub async fn send_tx(
|
||||||
&self,
|
&self,
|
||||||
transaction: Transaction,
|
transaction: Transaction,
|
||||||
@ -124,7 +143,7 @@ impl SequencerClient {
|
|||||||
|
|
||||||
pub async fn get_initial_testnet_accounts(
|
pub async fn get_initial_testnet_accounts(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Vec<AccountForSerialization>, SequencerClientError> {
|
) -> Result<Vec<AccountInitialData>, SequencerClientError> {
|
||||||
let acc_req = GetInitialTestnetAccountsRequest {};
|
let acc_req = GetInitialTestnetAccountsRequest {};
|
||||||
|
|
||||||
let req = serde_json::to_value(acc_req).unwrap();
|
let req = serde_json::to_value(acc_req).unwrap();
|
||||||
|
|||||||
@ -94,6 +94,10 @@ impl SequencerAccountsStore {
|
|||||||
} else {
|
} else {
|
||||||
self.register_account(*account_addr);
|
self.register_account(*account_addr);
|
||||||
|
|
||||||
|
let acc = self.accounts.get_mut(account_addr).unwrap();
|
||||||
|
|
||||||
|
acc.balance = new_balance;
|
||||||
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,7 +299,7 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(ret, 0);
|
assert_eq!(ret, 0);
|
||||||
assert!(seq_acc_store.contains_account(&[1; 32]));
|
assert!(seq_acc_store.contains_account(&[1; 32]));
|
||||||
assert_eq!(seq_acc_store.get_account_balance(&[1; 32]), 0);
|
assert_eq!(seq_acc_store.get_account_balance(&[1; 32]), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
use std::{path::PathBuf, sync::Arc};
|
use std::{path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
|
use actix_web::dev::ServerHandle;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use common::rpc_primitives::RpcConfig;
|
use common::rpc_primitives::RpcConfig;
|
||||||
use log::info;
|
use log::info;
|
||||||
use sequencer_core::SequencerCore;
|
use sequencer_core::{config::SequencerConfig, SequencerCore};
|
||||||
use sequencer_rpc::new_http_server;
|
use sequencer_rpc::new_http_server;
|
||||||
use tokio::sync::Mutex;
|
use tokio::{sync::Mutex, task::JoinHandle};
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
|
||||||
@ -19,50 +20,62 @@ struct Args {
|
|||||||
home_dir: PathBuf,
|
home_dir: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn startup_sequencer(
|
||||||
|
app_config: SequencerConfig,
|
||||||
|
) -> Result<(ServerHandle, JoinHandle<Result<()>>)> {
|
||||||
|
let block_timeout = app_config.block_create_timeout_millis;
|
||||||
|
let port = app_config.port;
|
||||||
|
|
||||||
|
let sequencer_core = SequencerCore::start_from_config(app_config);
|
||||||
|
|
||||||
|
info!("Sequencer core set up");
|
||||||
|
|
||||||
|
let seq_core_wrapped = Arc::new(Mutex::new(sequencer_core));
|
||||||
|
|
||||||
|
let http_server = new_http_server(RpcConfig::with_port(port), seq_core_wrapped.clone())?;
|
||||||
|
info!("HTTP server started");
|
||||||
|
let http_server_handle = http_server.handle();
|
||||||
|
tokio::spawn(http_server);
|
||||||
|
|
||||||
|
info!("Starting main sequencer loop");
|
||||||
|
|
||||||
|
let main_loop_handle = tokio::spawn(async move {
|
||||||
|
loop {
|
||||||
|
tokio::time::sleep(std::time::Duration::from_millis(block_timeout)).await;
|
||||||
|
|
||||||
|
info!("Collecting transactions from mempool, block creation");
|
||||||
|
|
||||||
|
let id = {
|
||||||
|
let mut state = seq_core_wrapped.lock().await;
|
||||||
|
|
||||||
|
state.produce_new_block_with_mempool_transactions()?
|
||||||
|
};
|
||||||
|
|
||||||
|
info!("Block with id {id} created");
|
||||||
|
|
||||||
|
info!("Waiting for new transactions");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok((http_server_handle, main_loop_handle))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn main_runner() -> Result<()> {
|
pub async fn main_runner() -> Result<()> {
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let Args { home_dir } = args;
|
let Args { home_dir } = args;
|
||||||
|
|
||||||
let app_config = config::from_file(home_dir.join("sequencer_config.json"))?;
|
let app_config = config::from_file(home_dir.join("sequencer_config.json"))?;
|
||||||
|
|
||||||
let block_timeout = app_config.block_create_timeout_millis;
|
|
||||||
let port = app_config.port;
|
|
||||||
|
|
||||||
if let Some(ref rust_log) = app_config.override_rust_log {
|
if let Some(ref rust_log) = app_config.override_rust_log {
|
||||||
info!("RUST_LOG env var set to {rust_log:?}");
|
info!("RUST_LOG env var set to {rust_log:?}");
|
||||||
|
|
||||||
std::env::set_var(RUST_LOG, rust_log);
|
std::env::set_var(RUST_LOG, rust_log);
|
||||||
}
|
}
|
||||||
|
|
||||||
env_logger::init();
|
//ToDo: Add restart on failures
|
||||||
|
let (_, _) = startup_sequencer(app_config).await?;
|
||||||
|
|
||||||
let sequencer_core = SequencerCore::start_from_config(app_config);
|
Ok(())
|
||||||
|
|
||||||
info!("Sequncer core set up");
|
|
||||||
|
|
||||||
let seq_core_wrapped = Arc::new(Mutex::new(sequencer_core));
|
|
||||||
|
|
||||||
let http_server = new_http_server(RpcConfig::with_port(port), seq_core_wrapped.clone())?;
|
|
||||||
info!("HTTP server started");
|
|
||||||
let _http_server_handle = http_server.handle();
|
|
||||||
tokio::spawn(http_server);
|
|
||||||
|
|
||||||
info!("Starting main sequencer loop");
|
|
||||||
|
|
||||||
#[allow(clippy::empty_loop)]
|
|
||||||
loop {
|
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(block_timeout)).await;
|
|
||||||
|
|
||||||
info!("Collecting transactions from mempool, block creation");
|
|
||||||
|
|
||||||
let id = {
|
|
||||||
let mut state = seq_core_wrapped.lock().await;
|
|
||||||
|
|
||||||
state.produce_new_block_with_mempool_transactions()?
|
|
||||||
};
|
|
||||||
|
|
||||||
info!("Block with id {id} created");
|
|
||||||
|
|
||||||
info!("Waiting for new transactions");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user