diff --git a/client/tests/integration_tests/add_account.rs b/client/tests/integration_tests/add_account.rs index 17bde93163d..fd2fd4fe634 100644 --- a/client/tests/integration_tests/add_account.rs +++ b/client/tests/integration_tests/add_account.rs @@ -12,6 +12,7 @@ use test_network::{Peer as TestPeer, *}; fn client_add_account_with_name_length_more_than_limit_should_not_commit_transaction() -> Result<()> { let (_rt, _peer, mut test_client) = ::start_test_with_runtime(); + wait_for_genesis_committed(vec![test_client.clone()], 0); let pipeline_time = Configuration::pipeline_time(); diff --git a/client/tests/integration_tests/add_asset.rs b/client/tests/integration_tests/add_asset.rs index 3102c7e9626..466e4f9e5e3 100644 --- a/client/tests/integration_tests/add_asset.rs +++ b/client/tests/integration_tests/add_asset.rs @@ -11,11 +11,10 @@ use test_network::{Peer as TestPeer, *}; #[test] fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount() -> Result<()> { let (_rt, _peer, mut test_client) = ::start_test_with_runtime(); + wait_for_genesis_committed(vec![test_client.clone()], 0); let pipeline_time = Configuration::pipeline_time(); // Given - thread::sleep(pipeline_time); - let account_id = AccountId::new("alice", "wonderland"); let asset_definition_id = AssetDefinitionId::new("xor", "wonderland"); let create_asset = RegisterBox::new(IdentifiableBox::from(AssetDefinition::new_quantity( diff --git a/client/tests/integration_tests/add_domain.rs b/client/tests/integration_tests/add_domain.rs index 0bd88627613..8595bdd278c 100644 --- a/client/tests/integration_tests/add_domain.rs +++ b/client/tests/integration_tests/add_domain.rs @@ -12,10 +12,10 @@ use test_network::{Peer as TestPeer, *}; fn client_add_domain_with_name_length_more_than_limit_should_not_commit_transaction() -> Result<()> { let (_rt, _peer, mut test_client) = ::start_test_with_runtime(); + wait_for_genesis_committed(vec![test_client.clone()], 0); let pipeline_time = Configuration::pipeline_time(); // Given - thread::sleep(pipeline_time); let normal_domain_name = "sora"; let create_domain = RegisterBox::new(IdentifiableBox::from(Domain::new(normal_domain_name))); diff --git a/client/tests/integration_tests/asset_propagation.rs b/client/tests/integration_tests/asset_propagation.rs index 5048a1160cb..5686d5e7281 100644 --- a/client/tests/integration_tests/asset_propagation.rs +++ b/client/tests/integration_tests/asset_propagation.rs @@ -13,10 +13,9 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount_on_a ) -> Result<()> { // Given let (_rt, network, mut iroha_client) = ::start_test_with_runtime(4, 1); + wait_for_genesis_committed(network.clients(), 0); let pipeline_time = Configuration::pipeline_time(); - thread::sleep(pipeline_time * 5); - let create_domain = RegisterBox::new(IdentifiableBox::Domain(Domain::new("domain").into())); let account_id = AccountId::new("account", "domain"); let create_account = RegisterBox::new(IdentifiableBox::NewAccount( diff --git a/client/tests/integration_tests/config.rs b/client/tests/integration_tests/config.rs index 650445fa527..9edc4a56ad0 100644 --- a/client/tests/integration_tests/config.rs +++ b/client/tests/integration_tests/config.rs @@ -6,12 +6,14 @@ use test_network::{Peer as TestPeer, *}; #[test] fn get_config() { // The underscored variables must not be dropped until end of closure. - let (_dont_drop, _dont_drop_either, cl) = ::start_test_with_runtime(); + let (_dont_drop, _dont_drop_either, test_client) = ::start_test_with_runtime(); + wait_for_genesis_committed(vec![test_client.clone()], 0); - let field = cl.get_config_docs(&["torii"]).unwrap().unwrap(); + let field = test_client.get_config_docs(&["torii"]).unwrap().unwrap(); assert!(field.contains("IROHA_TORII")); - let cfg: Configuration = serde_json::from_value(cl.get_config_value().unwrap()).unwrap(); + let cfg: Configuration = + serde_json::from_value(test_client.get_config_value().unwrap()).unwrap(); let test = Configuration::test(); assert_eq!(cfg.block_sync, test.block_sync); assert_eq!(cfg.network, test.network); diff --git a/client/tests/integration_tests/events.rs b/client/tests/integration_tests/events.rs index e3919d0c5b8..a5aae14cff7 100644 --- a/client/tests/integration_tests/events.rs +++ b/client/tests/integration_tests/events.rs @@ -15,29 +15,23 @@ const PEER_COUNT: usize = 7; #[test] fn transaction_event_should_be_sent_to_all_peers_from_all_peers() -> Result<()> { - let asset_definition_id = AssetDefinitionId::new("xor", "wonderland"); - let create_asset = RegisterBox::new(IdentifiableBox::AssetDefinition( - AssetDefinition::new_quantity(asset_definition_id).into(), - )); - test_with_instruction_and_status(create_asset, true)?; + test_with_instruction_and_status(None, true)?; let fail = FailBox::new("Failing transaction to test Rejected event."); - test_with_instruction_and_status(fail, false) + test_with_instruction_and_status(Some(fail.into()), false) } -#[allow(clippy::needless_range_loop)] +#[allow(clippy::needless_range_loop, clippy::needless_pass_by_value)] fn test_with_instruction_and_status( - instruction: impl Into, + instruction: Option, should_be_committed: bool, ) -> Result<()> { - let instruction: Instruction = instruction.into(); + let (_rt, network, _) = ::start_test_with_runtime(PEER_COUNT.try_into().unwrap(), 1); + wait_for_genesis_committed(network.clients(), 0); + for submitting_peer in 0..PEER_COUNT { - let (_rt, network, _) = - ::start_test_with_runtime(PEER_COUNT.try_into().unwrap(), 1); let pipeline_time = Configuration::pipeline_time(); // Given - thread::sleep(pipeline_time * 4); - let committed_event_received = Arc::new(RwLock::new([false; PEER_COUNT])); let validating_event_received = Arc::new(RwLock::new([false; PEER_COUNT])); let rejected_event_received = Arc::new(RwLock::new([false; PEER_COUNT])); @@ -46,8 +40,10 @@ fn test_with_instruction_and_status( &peers[submitting_peer].api_address, &peers[submitting_peer].status_address, ); - let transaction = submitter_client - .build_transaction(vec![instruction.clone()], UnlimitedMetadata::new())?; + let transaction = submitter_client.build_transaction( + instruction.clone().into_iter().collect(), + UnlimitedMetadata::new(), + )?; for receiving_peer in 0..PEER_COUNT { let committed_event_received_clone = committed_event_received.clone(); let validating_event_received_clone = validating_event_received.clone(); diff --git a/client/tests/integration_tests/multiple_blocks_created.rs b/client/tests/integration_tests/multiple_blocks_created.rs index 5a923eb7786..8891c5376ba 100644 --- a/client/tests/integration_tests/multiple_blocks_created.rs +++ b/client/tests/integration_tests/multiple_blocks_created.rs @@ -14,10 +14,9 @@ const N_BLOCKS: usize = 510; fn long_multiple_blocks_created() { // Given let (_rt, network, mut iroha_client) = ::start_test_with_runtime(4, 1); + wait_for_genesis_committed(network.clients(), 0); let pipeline_time = Configuration::pipeline_time(); - thread::sleep(pipeline_time * 2); - let create_domain = RegisterBox::new(IdentifiableBox::Domain(Domain::new("domain").into())); let account_id = AccountId::new("account", "domain"); let create_account = RegisterBox::new(IdentifiableBox::NewAccount( diff --git a/client/tests/integration_tests/multisignature_account.rs b/client/tests/integration_tests/multisignature_account.rs index cba96a9387b..9576559763a 100644 --- a/client/tests/integration_tests/multisignature_account.rs +++ b/client/tests/integration_tests/multisignature_account.rs @@ -11,8 +11,8 @@ use test_network::{Peer as TestPeer, *}; #[test] fn transaction_signed_by_new_signatory_of_account_should_pass() -> Result<()> { let (_rt, peer, mut iroha_client) = ::start_test_with_runtime(); + wait_for_genesis_committed(vec![iroha_client.clone()], 0); let pipeline_time = Configuration::pipeline_time(); - thread::sleep(pipeline_time); // Given let account_id = AccountId::new("alice", "wonderland"); diff --git a/client/tests/integration_tests/multisignature_transaction.rs b/client/tests/integration_tests/multisignature_transaction.rs index f471ab3e190..697abadbcdc 100644 --- a/client/tests/integration_tests/multisignature_transaction.rs +++ b/client/tests/integration_tests/multisignature_transaction.rs @@ -14,10 +14,9 @@ use test_network::*; #[test] fn multisignature_transactions_should_wait_for_all_signatures() { let (_rt, network, _) = ::start_test_with_runtime(4, 1); + wait_for_genesis_committed(network.clients(), 0); let pipeline_time = Configuration::pipeline_time(); - thread::sleep(pipeline_time * 3); - let create_domain = RegisterBox::new(IdentifiableBox::Domain(Domain::new("domain").into())); let account_id = AccountId::new("account", "domain"); let key_pair_1 = KeyPair::generate().expect("Failed to generate KeyPair."); diff --git a/client/tests/integration_tests/offline_peers.rs b/client/tests/integration_tests/offline_peers.rs index 1cac7360a45..129a1e80d99 100644 --- a/client/tests/integration_tests/offline_peers.rs +++ b/client/tests/integration_tests/offline_peers.rs @@ -1,9 +1,6 @@ #![allow(clippy::restriction)] -use std::thread; - use iroha_client::client; -use iroha_core::config::Configuration; use iroha_data_model::prelude::*; use test_network::*; use tokio::runtime::Runtime; @@ -12,10 +9,8 @@ use tokio::runtime::Runtime; fn genesis_block_is_commited_with_some_offline_peers() { // Given let rt = Runtime::test(); - let (_network, mut iroha_client) = rt.block_on(::start_test_with_offline(4, 1, 1)); - let pipeline_time = Configuration::pipeline_time(); - - thread::sleep(pipeline_time * 8); + let (network, mut iroha_client) = rt.block_on(::start_test_with_offline(4, 1, 1)); + wait_for_genesis_committed(network.clients(), 1); //When let alice_id = AccountId::new("alice", "wonderland"); diff --git a/client/tests/integration_tests/pagination.rs b/client/tests/integration_tests/pagination.rs index 47bce7f36ae..3dafb5a0b31 100644 --- a/client/tests/integration_tests/pagination.rs +++ b/client/tests/integration_tests/pagination.rs @@ -10,6 +10,7 @@ use test_network::{Peer as TestPeer, *}; #[test] fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount() { let (_rt, _peer, mut iroha_client) = ::start_test_with_runtime(); + wait_for_genesis_committed(vec![iroha_client.clone()], 0); let pipeline_time = Configuration::pipeline_time(); let register = ('a'..'z') diff --git a/client/tests/integration_tests/permissions.rs b/client/tests/integration_tests/permissions.rs index fe9bce6ded0..88a89b3da69 100644 --- a/client/tests/integration_tests/permissions.rs +++ b/client/tests/integration_tests/permissions.rs @@ -32,6 +32,7 @@ fn permissions_disallow_asset_transfer() { public_blockchain::default_permissions(), AllowAll.into(), )); + wait_for_genesis_committed(vec![iroha_client.clone()], 0); let pipeline_time = Configuration::pipeline_time(); // Given diff --git a/client/tests/integration_tests/restart_peer.rs b/client/tests/integration_tests/restart_peer.rs index eafa7b9c570..c77312fc788 100644 --- a/client/tests/integration_tests/restart_peer.rs +++ b/client/tests/integration_tests/restart_peer.rs @@ -23,16 +23,14 @@ fn restarted_peer_should_have_the_same_asset_amount() -> Result<()> { // Given let rt = Runtime::test(); rt.block_on(peer.start_with_config_permissions_dir(configuration.clone(), AllowAll, &temp_dir)); - - // Wait for genesis to be committed. - thread::sleep(pipeline_time * 2); + let mut iroha_client = Client::test(&peer.api_address, &peer.status_address); + wait_for_genesis_committed(vec![iroha_client.clone()], 0); let account_id = AccountId::from_str("alice@wonderland").unwrap(); let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").unwrap(); let create_asset = RegisterBox::new(IdentifiableBox::AssetDefinition( AssetDefinition::new_quantity(asset_definition_id.clone()).into(), )); - let mut iroha_client = Client::test(&peer.api_address, &peer.status_address); iroha_client.submit(create_asset)?; thread::sleep(pipeline_time * 2); //When diff --git a/client/tests/integration_tests/status.rs b/client/tests/integration_tests/status.rs index 1832269498d..1f2cd1b8d0d 100644 --- a/client/tests/integration_tests/status.rs +++ b/client/tests/integration_tests/status.rs @@ -4,7 +4,7 @@ use std::thread; use iroha_core::config::Configuration; use iroha_data_model::prelude::*; -use test_network::{Network as TestNetwork, TestConfiguration}; +use test_network::{Network as TestNetwork, *}; #[test] fn test_status() { @@ -12,8 +12,8 @@ fn test_status() { let mut status; let (rt, network, mut client) = ::start_test_with_runtime(N_PEERS as u32, 1); + wait_for_genesis_committed(network.clients(), 0); let pipeline_time = Configuration::pipeline_time(); - thread::sleep(pipeline_time * 2); // Confirm all peers connected status = client.get_status().unwrap(); diff --git a/client/tests/integration_tests/transfer_asset.rs b/client/tests/integration_tests/transfer_asset.rs index e004fae6387..250d261acd3 100644 --- a/client/tests/integration_tests/transfer_asset.rs +++ b/client/tests/integration_tests/transfer_asset.rs @@ -10,11 +10,9 @@ use test_network::{Peer as TestPeer, *}; #[test] fn client_can_transfer_asset_to_another_account() { let (_rt, _peer, mut iroha_client) = ::start_test_with_runtime(); + wait_for_genesis_committed(vec![iroha_client.clone()], 0); let pipeline_time = Configuration::pipeline_time(); - // Given - thread::sleep(pipeline_time); - let create_domain = RegisterBox::new(IdentifiableBox::Domain(Domain::new("domain").into())); let account1_id = AccountId::new("account1", "domain"); let account2_id = AccountId::new("account2", "domain"); diff --git a/client/tests/integration_tests/tx_history.rs b/client/tests/integration_tests/tx_history.rs index 3698a048eed..a47e661b17f 100644 --- a/client/tests/integration_tests/tx_history.rs +++ b/client/tests/integration_tests/tx_history.rs @@ -10,11 +10,11 @@ use test_network::{Peer as TestPeer, *}; #[test] fn client_has_rejected_and_acepted_txs_should_return_tx_history() { let (_rt, _peer, mut iroha_client) = ::start_test_with_runtime(); + wait_for_genesis_committed(vec![iroha_client.clone()], 0); + let pipeline_time = Configuration::pipeline_time(); // Given - thread::sleep(pipeline_time); - let account_id = AccountId::new("alice", "wonderland"); let asset_definition_id = AssetDefinitionId::new("xor", "wonderland"); let create_asset = RegisterBox::new(IdentifiableBox::AssetDefinition( diff --git a/client/tests/integration_tests/tx_rollback.rs b/client/tests/integration_tests/tx_rollback.rs index 0142aec1a90..3bfa68b3b6b 100644 --- a/client/tests/integration_tests/tx_rollback.rs +++ b/client/tests/integration_tests/tx_rollback.rs @@ -10,10 +10,9 @@ use test_network::{Peer as TestPeer, *}; #[test] fn client_sends_transaction_with_invalid_instruction_should_not_see_any_changes() { let (_rt, _peer, mut iroha_client) = ::start_test_with_runtime(); - let pipeline_time = Configuration::pipeline_time(); + wait_for_genesis_committed(vec![iroha_client.clone()], 0); - // Given - thread::sleep(pipeline_time); + let pipeline_time = Configuration::pipeline_time(); //When let account_id = AccountId::new("alice", "wonderland"); diff --git a/client/tests/integration_tests/unregister_peer.rs b/client/tests/integration_tests/unregister_peer.rs index bc5acc170ed..4fdabb981f6 100644 --- a/client/tests/integration_tests/unregister_peer.rs +++ b/client/tests/integration_tests/unregister_peer.rs @@ -10,6 +10,8 @@ use test_network::*; fn network_stable_after_add_and_after_remove_peer() -> Result<()> { // Given a network let (rt, network, mut genesis_client, pipeline_time, account_id, asset_definition_id) = init()?; + wait_for_genesis_committed(network.clients(), 0); + // When assets are minted mint( &asset_definition_id, diff --git a/client/tests/integration_tests/unstable_network.rs b/client/tests/integration_tests/unstable_network.rs index 9d3fb6527c5..017feae96d6 100644 --- a/client/tests/integration_tests/unstable_network.rs +++ b/client/tests/integration_tests/unstable_network.rs @@ -2,13 +2,15 @@ use std::{thread, time::Duration}; -use iroha_client::client; +use iroha_client::client::{self, Client}; +use iroha_config::logger; use iroha_core::config::Configuration; use iroha_data_model::prelude::*; +use iroha_logger::Level; use test_network::*; use tokio::runtime::Runtime; -const MAXIMUM_TRANSACTIONS_IN_BLOCK: u32 = 1; +const MAXIMUM_TRANSACTIONS_IN_BLOCK: u32 = 5; #[test] fn unstable_network_4_peers_1_fault() { @@ -29,7 +31,6 @@ fn unstable_network_4_peers_1_fault() { } #[test] -#[ignore = "This test fails after reducing the amount of gossipping"] fn unstable_network_7_peers_1_fault() { let n_peers = 7; let n_transactions = 20; @@ -59,16 +60,24 @@ fn unstable_network( drop(iroha_logger::install_panic_hook()); let rt = Runtime::test(); // Given - let (_network, mut iroha_client) = - rt.block_on(::start_test_with_offline_and_set_n_shifts( - n_peers, - MAXIMUM_TRANSACTIONS_IN_BLOCK, - n_offline_peers, - u64::from(n_peers), - )); + let (network, mut iroha_client) = rt.block_on(async { + let mut configuration = Configuration::test(); + configuration.queue.maximum_transactions_in_block = MAXIMUM_TRANSACTIONS_IN_BLOCK; + configuration.sumeragi.n_topology_shifts_before_reshuffle = u64::from(n_peers); + configuration.logger.max_log_level = Level(logger::Level::ERROR).into(); + let network = + ::new_with_offline_peers(Some(configuration), n_peers, n_offline_peers) + .await + .expect("Failed to init peers"); + let client = Client::test( + &network.genesis.api_address, + &network.genesis.status_address, + ); + (network, client) + }); + wait_for_genesis_committed(network.clients(), n_offline_peers); let pipeline_time = Configuration::pipeline_time(); - thread::sleep(pipeline_time * n_peers); let account_id = AccountId::new("alice", "wonderland"); let asset_definition_id = AssetDefinitionId::new("rose", "wonderland"); diff --git a/core/src/genesis.rs b/core/src/genesis.rs index 3c20c9e67a9..ea089e55e77 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -66,11 +66,15 @@ pub trait GenesisNetworkTrait: let genesis_topology = self .wait_for_peers(sumeragi.peer_id.clone(), sumeragi.topology.clone(), network) .await?; + time::sleep(Duration::from_millis(self.genesis_submission_delay_ms())).await; iroha_logger::info!("Initializing iroha using the genesis block."); sumeragi .start_genesis_round(self.deref().clone(), genesis_topology) .await } + + /// See [`GenesisConfiguration`] docs. + fn genesis_submission_delay_ms(&self) -> u64; } /// [`GenesisNetwork`] contains initial transactions and genesis setup related parameters. @@ -82,6 +86,9 @@ pub struct GenesisNetwork { pub wait_for_peers_retry_count: u64, /// Period in milliseconds in which to retry connecting to peers, while waiting for them to submit genesis. pub wait_for_peers_retry_period_ms: u64, + /// Delay before genesis block submission after minimum number of peers were discovered to be online. + /// Used to ensure that other peers had time to connect to each other. + pub genesis_submission_delay_ms: u64, } impl Deref for GenesisNetwork { @@ -180,6 +187,7 @@ impl GenesisNetworkTrait for GenesisNetwork { .collect(), wait_for_peers_retry_count: genesis_config.wait_for_peers_retry_count, wait_for_peers_retry_period_ms: genesis_config.wait_for_peers_retry_period_ms, + genesis_submission_delay_ms: genesis_config.genesis_submission_delay_ms, })) } @@ -204,6 +212,10 @@ impl GenesisNetworkTrait for GenesisNetwork { } Err(eyre!("Waiting for peers failed.")) } + + fn genesis_submission_delay_ms(&self) -> u64 { + self.genesis_submission_delay_ms + } } /// `RawGenesisBlock` is an initial block of the network @@ -287,6 +299,7 @@ pub mod config { const DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT: u64 = 100; const DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS: u64 = 500; + const DEFAULT_GENESIS_SUBMISSION_DELAY_MS: u64 = 1000; #[derive(Clone, Deserialize, Serialize, Debug, Configurable, PartialEq, Eq)] #[serde(rename_all = "UPPERCASE")] @@ -305,6 +318,10 @@ pub mod config { /// Period in milliseconds in which to retry connecting to peers, while waiting for them to submit genesis. #[serde(default = "default_wait_for_peers_retry_period_ms")] pub wait_for_peers_retry_period_ms: u64, + /// Delay before genesis block submission after minimum number of peers were discovered to be online. + /// Used to ensure that other peers had time to connect to each other. + #[serde(default = "default_genesis_submission_delay_ms")] + pub genesis_submission_delay_ms: u64, } impl Default for GenesisConfiguration { @@ -314,6 +331,7 @@ pub mod config { account_private_key: None, wait_for_peers_retry_count: DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT, wait_for_peers_retry_period_ms: DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS, + genesis_submission_delay_ms: DEFAULT_GENESIS_SUBMISSION_DELAY_MS, } } } @@ -325,6 +343,10 @@ pub mod config { const fn default_wait_for_peers_retry_period_ms() -> u64 { DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS } + + const fn default_genesis_submission_delay_ms() -> u64 { + DEFAULT_GENESIS_SUBMISSION_DELAY_MS + } } #[cfg(test)] diff --git a/core/src/torii/tests.rs b/core/src/torii/tests.rs index 51baa494803..ad70165861d 100644 --- a/core/src/torii/tests.rs +++ b/core/src/torii/tests.rs @@ -15,7 +15,10 @@ use crate::{ }; async fn create_torii() -> (Torii, KeyPair) { - let config = get_config(get_trusted_peers(None), None); + let mut config = get_config(get_trusted_peers(None), None); + config.torii.p2p_addr = format!("127.0.0.1:{}", unique_port::get_unique_free_port().unwrap()); + config.torii.api_url = format!("127.0.0.1:{}", unique_port::get_unique_free_port().unwrap()); + config.torii.status_url = format!("127.0.0.1:{}", unique_port::get_unique_free_port().unwrap()); let (events, _) = tokio::sync::broadcast::channel(100); let wsv = Arc::new(WorldStateView::new(World::with( ('a'..'z') diff --git a/core/test_network/src/lib.rs b/core/test_network/src/lib.rs index 7a5eca15bbe..d5edd4844b3 100644 --- a/core/test_network/src/lib.rs +++ b/core/test_network/src/lib.rs @@ -298,8 +298,6 @@ where } futures.collect::<()>().await; - time::sleep(Duration::from_millis(500) * (n_peers + 1)).await; - Ok(Self { genesis, peers }) } @@ -308,6 +306,12 @@ where std::iter::once(&self.genesis).chain(self.peers.values()) } + pub fn clients(&self) -> Vec { + self.peers() + .map(|peer| Client::test(&peer.api_address, &peer.status_address)) + .collect() + } + /// Get peer by its Id. pub fn peer_by_id(&self, id: &PeerId) -> Option<&Peer> { self.peers.get(id).or(if self.genesis.id == *id { @@ -337,6 +341,37 @@ where } } +/// Wait for peers to have committed genesis block. +/// +/// # Panics +/// When unsuccessful after `MAX_RETRIES`. +pub fn wait_for_genesis_committed(clients: Vec, offline_peers: u32) { + const POLL_PERIOD: Duration = Duration::from_millis(1000); + const MAX_RETRIES: u32 = 60 * 3; // 3 minutes + + for _ in 0..MAX_RETRIES { + let without_genesis_peers = clients.iter().fold(0u32, |acc, client| { + if let Ok(status) = client.get_status() { + if status.blocks < 1 { + acc + 1 + } else { + acc + } + } else { + acc + 1 + } + }); + if without_genesis_peers <= offline_peers { + return; + } + thread::sleep(POLL_PERIOD); + } + panic!( + "Failed to wait for online peers to commit genesis block. Total wait time: {:?}", + POLL_PERIOD * MAX_RETRIES + ); +} + impl Drop for Peer where W: WorldTrait, @@ -393,12 +428,8 @@ where ..configuration.torii }, logger: LoggerConfiguration { - #[cfg(profile = "bench")] - max_log_level: Level(logger::Level::ERROR).into(), - #[cfg(not(profile = "bench"))] - max_log_level: Level(logger::Level::INFO).into(), compact_mode: false, - ..LoggerConfiguration::default() + ..configuration.logger }, public_key: self.key_pair.public_key.clone(), private_key: self.key_pair.private_key.clone(), @@ -575,10 +606,6 @@ where ) .await; let client = Client::test(&peer.api_address, &peer.status_address); - time::sleep(Duration::from_millis( - configuration.sumeragi.pipeline_time_ms(), - )) - .await; (peer, client) } } diff --git a/core/test_network/tests/sumeragi_with_mock.rs b/core/test_network/tests/sumeragi_with_mock.rs index f990d7e8fbc..08b03ff294f 100644 --- a/core/test_network/tests/sumeragi_with_mock.rs +++ b/core/test_network/tests/sumeragi_with_mock.rs @@ -71,6 +71,10 @@ pub mod utils { ) -> Result { unreachable!() } + + fn genesis_submission_delay_ms(&self) -> u64 { + 0 + } } } diff --git a/docs/source/references/config.md b/docs/source/references/config.md index 9af615205b6..ecb22dd673e 100644 --- a/docs/source/references/config.md +++ b/docs/source/references/config.md @@ -61,7 +61,8 @@ The following is the default configuration used by Iroha. "ACCOUNT_PUBLIC_KEY": null, "ACCOUNT_PRIVATE_KEY": null, "WAIT_FOR_PEERS_RETRY_COUNT": 100, - "WAIT_FOR_PEERS_RETRY_PERIOD_MS": 500 + "WAIT_FOR_PEERS_RETRY_PERIOD_MS": 500, + "GENESIS_SUBMISSION_DELAY_MS": 1000 }, "WSV": { "ASSET_METADATA_LIMITS": { @@ -152,6 +153,7 @@ Has type `GenesisConfiguration`. Can be configured via environment variable `IRO { "ACCOUNT_PRIVATE_KEY": null, "ACCOUNT_PUBLIC_KEY": null, + "GENESIS_SUBMISSION_DELAY_MS": 1000, "WAIT_FOR_PEERS_RETRY_COUNT": 100, "WAIT_FOR_PEERS_RETRY_PERIOD_MS": 500 } @@ -177,6 +179,16 @@ Has type `Option`. Can be configured via environment variable `IROHA_ null ``` +### `genesis.genesis_submission_delay_ms` + +Delay before genesis block submission after minimum number of peers were discovered to be online. + +Has type `u64`. Can be configured via environment variable `IROHA_GENESIS_GENESIS_SUBMISSION_DELAY_MS` + +```json +1000 +``` + ### `genesis.wait_for_peers_retry_count` Number of attempts to connect to peers, while waiting for them to submit genesis.