From 1727eadccf36255e518882cbde91b74aef7c256f Mon Sep 17 00:00:00 2001 From: dkijania Date: Tue, 2 Mar 2021 07:52:30 +0100 Subject: [PATCH 1/4] rename sanity_module into transaction --- testing/jormungandr-integration-tests/src/non_functional/mod.rs | 2 +- .../src/non_functional/{sanity.rs => transaction.rs} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename testing/jormungandr-integration-tests/src/non_functional/{sanity.rs => transaction.rs} (100%) diff --git a/testing/jormungandr-integration-tests/src/non_functional/mod.rs b/testing/jormungandr-integration-tests/src/non_functional/mod.rs index 5bf3edfe2e..7853c7818d 100644 --- a/testing/jormungandr-integration-tests/src/non_functional/mod.rs +++ b/testing/jormungandr-integration-tests/src/non_functional/mod.rs @@ -10,7 +10,7 @@ pub mod explorer; Run some transaction for ~15 minutes or specified no of transactions (100) */ #[cfg(feature = "sanity-non-functional")] -pub mod sanity; +pub mod transaction; /* Long running test for self node (48 h) */ diff --git a/testing/jormungandr-integration-tests/src/non_functional/sanity.rs b/testing/jormungandr-integration-tests/src/non_functional/transaction.rs similarity index 100% rename from testing/jormungandr-integration-tests/src/non_functional/sanity.rs rename to testing/jormungandr-integration-tests/src/non_functional/transaction.rs From 9ad765acb461f48a98bc4351ce17e7ab6d1a2838 Mon Sep 17 00:00:00 2001 From: dkijania Date: Tue, 2 Mar 2021 07:53:06 +0100 Subject: [PATCH 2/4] remove cfg from voting module split will be done deeper in module hierarchy --- testing/jormungandr-integration-tests/src/non_functional/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/testing/jormungandr-integration-tests/src/non_functional/mod.rs b/testing/jormungandr-integration-tests/src/non_functional/mod.rs index 7853c7818d..d7c1c8e75b 100644 --- a/testing/jormungandr-integration-tests/src/non_functional/mod.rs +++ b/testing/jormungandr-integration-tests/src/non_functional/mod.rs @@ -35,7 +35,6 @@ pub mod fragment; #[cfg(feature = "sanity-non-functional")] pub mod bootstrap; -#[cfg(feature = "sanity-non-functional")] pub mod voting; use crate::common::{ From 83c4eab82bec7e906475f6d4dd26fab551361de9 Mon Sep 17 00:00:00 2001 From: dkijania Date: Tue, 2 Mar 2021 07:53:33 +0100 Subject: [PATCH 3/4] added soak module, which should hold long running tests --- .../src/non_functional/voting/private/soak.rs | 17 +++++++++++++++++ .../src/non_functional/voting/public/soak.rs | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 testing/jormungandr-integration-tests/src/non_functional/voting/private/soak.rs create mode 100644 testing/jormungandr-integration-tests/src/non_functional/voting/public/soak.rs diff --git a/testing/jormungandr-integration-tests/src/non_functional/voting/private/soak.rs b/testing/jormungandr-integration-tests/src/non_functional/voting/private/soak.rs new file mode 100644 index 0000000000..0c1cca7ba6 --- /dev/null +++ b/testing/jormungandr-integration-tests/src/non_functional/voting/private/soak.rs @@ -0,0 +1,17 @@ +use crate::non_functional::voting::{ + config::{adversary_noise_config, PrivateVotingLoadTestConfig}, + private::{adversary_private_vote_load_scenario, private_vote_load_scenario}, +}; + +#[test] +pub fn private_vote_load_long_test() { + let quick_config = PrivateVotingLoadTestConfig::long(); + private_vote_load_scenario(quick_config) +} + +#[test] +pub fn adversary_private_vote_load_long_test() { + let long_config = PrivateVotingLoadTestConfig::long(); + let adversary_noise_config = adversary_noise_config(30, long_config.test_duration()); + adversary_private_vote_load_scenario(long_config, adversary_noise_config) +} diff --git a/testing/jormungandr-integration-tests/src/non_functional/voting/public/soak.rs b/testing/jormungandr-integration-tests/src/non_functional/voting/public/soak.rs new file mode 100644 index 0000000000..fb4ddadccc --- /dev/null +++ b/testing/jormungandr-integration-tests/src/non_functional/voting/public/soak.rs @@ -0,0 +1,17 @@ +use crate::non_functional::voting::{ + config::{adversary_noise_config, PublicVotingLoadTestConfig}, + public::{adversary_public_vote_load_scenario, public_vote_load_scenario}, +}; + +#[test] +pub fn public_vote_load_long_test() { + let long_config = PublicVotingLoadTestConfig::long(); + public_vote_load_scenario(long_config) +} + +#[test] +pub fn adversary_public_vote_load_long_test() { + let long_config = PublicVotingLoadTestConfig::long(); + let adversary_noise_config = adversary_noise_config(30, long_config.test_duration()); + adversary_public_vote_load_scenario(long_config, adversary_noise_config) +} From a8e8786c74b1fd9c3933891d752ed14f48084a00 Mon Sep 17 00:00:00 2001 From: dkijania Date: Tue, 2 Mar 2021 07:53:44 +0100 Subject: [PATCH 4/4] adjust tests after split --- .../src/non_functional/voting/private/load.rs | 193 +-------- .../src/non_functional/voting/private/mod.rs | 383 ++++++++++++++++++ .../non_functional/voting/private/noise.rs | 229 +---------- .../src/non_functional/voting/public/load.rs | 149 +------ .../src/non_functional/voting/public/mod.rs | 305 ++++++++++++++ .../src/non_functional/voting/public/noise.rs | 187 +-------- 6 files changed, 697 insertions(+), 749 deletions(-) diff --git a/testing/jormungandr-integration-tests/src/non_functional/voting/private/load.rs b/testing/jormungandr-integration-tests/src/non_functional/voting/private/load.rs index 4680cc3671..e1fcb1e885 100644 --- a/testing/jormungandr-integration-tests/src/non_functional/voting/private/load.rs +++ b/testing/jormungandr-integration-tests/src/non_functional/voting/private/load.rs @@ -1,197 +1,8 @@ -use crate::common::jormungandr::{ConfigurationBuilder, Starter}; -use crate::non_functional::voting::config::PrivateVotingLoadTestConfig; -use assert_fs::TempDir; -use chain_core::property::BlockDate; -use chain_impl_mockchain::testing::data::CommitteeMembersManager; -use chain_impl_mockchain::{ - certificate::{VoteAction, VoteTallyPayload}, - ledger::governance::TreasuryGovernanceAction, - testing::decrypt_tally, - value::Value, -}; -use jormungandr_lib::interfaces::BlockDate as BlockDateLib; -use jormungandr_testing_utils::testing::VoteCastsGenerator; -use jormungandr_testing_utils::testing::{ - benchmark_consumption, FragmentStatusProvider, VotePlanBuilder, -}; -use jormungandr_testing_utils::{ - testing::{ - node::time::{wait_for_date, wait_for_epoch}, - vote_plan_cert, FragmentSender, FragmentSenderSetup, - }, - wallet::Wallet, -}; -use jortestkit::{load, measurement::Status}; -use rand::rngs::OsRng; +use crate::non_functional::voting::private::private_vote_load_scenario; +use crate::non_functional::voting::private::PrivateVotingLoadTestConfig; #[test] pub fn private_vote_load_quick_test() { let quick_config = PrivateVotingLoadTestConfig::quick(); private_vote_load_scenario(quick_config) } - -#[test] -pub fn private_vote_load_long_test() { - let quick_config = PrivateVotingLoadTestConfig::long(); - private_vote_load_scenario(quick_config) -} - -pub fn private_vote_load_scenario(quick_config: PrivateVotingLoadTestConfig) { - let temp_dir = TempDir::new().unwrap().into_persistent(); - let mut rng = OsRng; - let members = CommitteeMembersManager::new( - &mut rng, - quick_config.tally_threshold(), - quick_config.members_count(), - ); - - let committee_keys = members - .members() - .iter() - .map(|committee_member| committee_member.public_key()) - .collect::>(); - - let voters: Vec = std::iter::from_fn(|| Some(Wallet::new_account(&mut rng))) - .take(quick_config.wallets_count()) - .collect(); - - let mut rng = OsRng; - let mut committee = Wallet::new_account(&mut rng); - - let vote_plan = VotePlanBuilder::new() - .proposals_count(quick_config.proposals_count()) - .action_type(VoteAction::Treasury { - action: TreasuryGovernanceAction::TransferToRewards { - value: Value(quick_config.rewards_increase()), - }, - }) - .with_vote_start(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[0].into(), - 0, - )) - .with_tally_start(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[1].into(), - 0, - )) - .with_tally_end(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[2].into(), - 0, - )) - .private() - .member_public_keys(committee_keys) - .build(); - - let vote_plan_cert = vote_plan_cert(&committee, &vote_plan).into(); - - let config = ConfigurationBuilder::new() - .with_fund(committee.to_initial_fund(quick_config.initial_fund_per_wallet())) - .with_funds_split_if_needed( - voters - .iter() - .map(|x| x.to_initial_fund(quick_config.initial_fund_per_wallet())) - .collect(), - ) - .with_committees(&[&committee.clone()]) - .with_slots_per_epoch(quick_config.slots_in_epoch()) - .with_certs(vec![vote_plan_cert]) - .with_explorer() - .with_slot_duration(quick_config.slot_duration()) - .with_block_content_max_size(quick_config.block_content_max_size()) - .with_treasury(1_000.into()) - .build(&temp_dir); - - let jormungandr = Starter::new().config(config.clone()).start().unwrap(); - - let transaction_sender = FragmentSender::new( - jormungandr.genesis_block_hash(), - jormungandr.fees(), - FragmentSenderSetup::no_verify(), - ); - - let benchmark_consumption_monitor = benchmark_consumption(&quick_config.measurement_name()) - .target(quick_config.target_resources_usage()) - .for_process("Node", jormungandr.pid() as usize) - .start_async(std::time::Duration::from_secs(30)); - - let votes_generator = VoteCastsGenerator::new( - voters, - vote_plan.clone(), - jormungandr.to_remote(), - transaction_sender.clone(), - ); - - let stats = load::start_async( - votes_generator, - FragmentStatusProvider::new(jormungandr.to_remote()), - quick_config.configuration(), - &quick_config.measurement_name(), - ); - - stats.print_summary(&quick_config.measurement_name()); - assert_eq!( - stats - .measure( - &quick_config.measurement_name(), - quick_config.tx_target_success_rate() - ) - .status(), - Status::Green - ); - - wait_for_epoch( - quick_config.voting_timing()[1].into(), - jormungandr.explorer().clone(), - ); - - transaction_sender - .send_encrypted_tally(&mut committee, &vote_plan, &jormungandr) - .unwrap(); - - wait_for_date( - BlockDateLib::new( - quick_config.voting_timing()[1].into(), - (quick_config.slots_in_epoch() / 2).into(), - ), - jormungandr.explorer().clone(), - ); - - let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); - let vote_plan_status = active_vote_plans - .iter() - .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) - .unwrap(); - - let shares = decrypt_tally(&vote_plan_status.clone().into(), &members); - - transaction_sender - .send_vote_tally( - &mut committee, - &vote_plan, - &jormungandr, - VoteTallyPayload::Private { inner: shares }, - ) - .unwrap(); - - wait_for_epoch( - quick_config.voting_timing()[2].into(), - jormungandr.explorer().clone(), - ); - let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); - - let vote_plan_status = active_vote_plans - .iter() - .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) - .unwrap(); - - for proposal in vote_plan_status.proposals.iter() { - assert!( - proposal.tally.is_some(), - "Proposal is not tallied {:?}", - proposal - ); - } - - benchmark_consumption_monitor.stop(); - - jormungandr.assert_no_errors_in_log(); -} diff --git a/testing/jormungandr-integration-tests/src/non_functional/voting/private/mod.rs b/testing/jormungandr-integration-tests/src/non_functional/voting/private/mod.rs index 29528a69ec..6df2167f84 100644 --- a/testing/jormungandr-integration-tests/src/non_functional/voting/private/mod.rs +++ b/testing/jormungandr-integration-tests/src/non_functional/voting/private/mod.rs @@ -1,2 +1,385 @@ +#[cfg(feature = "sanity-non-functional")] mod load; +#[cfg(feature = "sanity-non-functional")] mod noise; +#[cfg(feature = "soak-non-functional")] +mod soak; + +use crate::common::jormungandr::{ConfigurationBuilder, Starter}; +use crate::non_functional::voting::config::PrivateVotingLoadTestConfig; +use assert_fs::TempDir; +use chain_core::property::BlockDate; +use chain_impl_mockchain::testing::data::CommitteeMembersManager; +use chain_impl_mockchain::{ + certificate::{VoteAction, VoteTallyPayload}, + ledger::governance::TreasuryGovernanceAction, + testing::decrypt_tally, + value::Value, +}; +use jormungandr_lib::interfaces::BlockDate as BlockDateLib; +use jormungandr_testing_utils::testing::fragments::AdversaryFragmentGenerator; +use jormungandr_testing_utils::testing::AdversaryFragmentSender; +use jormungandr_testing_utils::testing::AdversaryFragmentSenderSetup; +use jormungandr_testing_utils::testing::VoteCastsGenerator; +use jormungandr_testing_utils::testing::{ + benchmark_consumption, FragmentStatusProvider, VotePlanBuilder, +}; +use jormungandr_testing_utils::{ + testing::{ + node::time::{wait_for_date, wait_for_epoch}, + vote_plan_cert, FragmentSender, FragmentSenderSetup, + }, + wallet::Wallet, +}; +use jortestkit::load::Configuration; +use jortestkit::measurement::Status; +use rand::rngs::OsRng; + +pub fn private_vote_load_scenario(quick_config: PrivateVotingLoadTestConfig) { + let temp_dir = TempDir::new().unwrap().into_persistent(); + let mut rng = OsRng; + let members = CommitteeMembersManager::new( + &mut rng, + quick_config.tally_threshold(), + quick_config.members_count(), + ); + + let committee_keys = members + .members() + .iter() + .map(|committee_member| committee_member.public_key()) + .collect::>(); + + let voters: Vec = std::iter::from_fn(|| Some(Wallet::new_account(&mut rng))) + .take(quick_config.wallets_count()) + .collect(); + + let mut rng = OsRng; + let mut committee = Wallet::new_account(&mut rng); + + let vote_plan = VotePlanBuilder::new() + .proposals_count(quick_config.proposals_count()) + .action_type(VoteAction::Treasury { + action: TreasuryGovernanceAction::TransferToRewards { + value: Value(quick_config.rewards_increase()), + }, + }) + .with_vote_start(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[0].into(), + 0, + )) + .with_tally_start(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[1].into(), + 0, + )) + .with_tally_end(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[2].into(), + 0, + )) + .private() + .member_public_keys(committee_keys) + .build(); + + let vote_plan_cert = vote_plan_cert(&committee, &vote_plan).into(); + + let config = ConfigurationBuilder::new() + .with_fund(committee.to_initial_fund(quick_config.initial_fund_per_wallet())) + .with_funds_split_if_needed( + voters + .iter() + .map(|x| x.to_initial_fund(quick_config.initial_fund_per_wallet())) + .collect(), + ) + .with_committees(&[&committee.clone()]) + .with_slots_per_epoch(quick_config.slots_in_epoch()) + .with_certs(vec![vote_plan_cert]) + .with_explorer() + .with_slot_duration(quick_config.slot_duration()) + .with_block_content_max_size(quick_config.block_content_max_size()) + .with_treasury(1_000.into()) + .build(&temp_dir); + + let jormungandr = Starter::new().config(config.clone()).start().unwrap(); + + let transaction_sender = FragmentSender::new( + jormungandr.genesis_block_hash(), + jormungandr.fees(), + FragmentSenderSetup::no_verify(), + ); + + let benchmark_consumption_monitor = benchmark_consumption(&quick_config.measurement_name()) + .target(quick_config.target_resources_usage()) + .for_process("Node", jormungandr.pid() as usize) + .start_async(std::time::Duration::from_secs(30)); + + let votes_generator = VoteCastsGenerator::new( + voters, + vote_plan.clone(), + jormungandr.to_remote(), + transaction_sender.clone(), + ); + + let stats = jortestkit::load::start_async( + votes_generator, + FragmentStatusProvider::new(jormungandr.to_remote()), + quick_config.configuration(), + &quick_config.measurement_name(), + ); + + stats.print_summary(&quick_config.measurement_name()); + assert_eq!( + stats + .measure( + &quick_config.measurement_name(), + quick_config.tx_target_success_rate() + ) + .status(), + Status::Green + ); + + wait_for_epoch( + quick_config.voting_timing()[1].into(), + jormungandr.explorer().clone(), + ); + + transaction_sender + .send_encrypted_tally(&mut committee, &vote_plan, &jormungandr) + .unwrap(); + + wait_for_date( + BlockDateLib::new( + quick_config.voting_timing()[1].into(), + (quick_config.slots_in_epoch() / 2).into(), + ), + jormungandr.explorer().clone(), + ); + + let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); + let vote_plan_status = active_vote_plans + .iter() + .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) + .unwrap(); + + let shares = decrypt_tally(&vote_plan_status.clone().into(), &members); + + transaction_sender + .send_vote_tally( + &mut committee, + &vote_plan, + &jormungandr, + VoteTallyPayload::Private { inner: shares }, + ) + .unwrap(); + + wait_for_epoch( + quick_config.voting_timing()[2].into(), + jormungandr.explorer().clone(), + ); + let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); + + let vote_plan_status = active_vote_plans + .iter() + .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) + .unwrap(); + + for proposal in vote_plan_status.proposals.iter() { + assert!( + proposal.tally.is_some(), + "Proposal is not tallied {:?}", + proposal + ); + } + + benchmark_consumption_monitor.stop(); + + jormungandr.assert_no_errors_in_log(); +} + +pub fn adversary_private_vote_load_scenario( + quick_config: PrivateVotingLoadTestConfig, + adversary_noise_config: Configuration, +) { + let temp_dir = TempDir::new().unwrap().into_persistent(); + let mut rng = OsRng; + let members = CommitteeMembersManager::new( + &mut rng, + quick_config.tally_threshold(), + quick_config.members_count(), + ); + + let committee_keys = members + .members() + .iter() + .map(|committee_member| committee_member.public_key()) + .collect::>(); + + let mut noise_wallet_from = Wallet::new_account(&mut rng); + + let voters: Vec = std::iter::from_fn(|| Some(Wallet::new_account(&mut rng))) + .take(quick_config.wallets_count()) + .collect(); + + let mut rng = OsRng; + let mut committee = Wallet::new_account(&mut rng); + + let vote_plan = VotePlanBuilder::new() + .proposals_count(quick_config.proposals_count()) + .action_type(VoteAction::Treasury { + action: TreasuryGovernanceAction::TransferToRewards { + value: Value(quick_config.rewards_increase()), + }, + }) + .with_vote_start(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[0].into(), + 0, + )) + .with_tally_start(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[1].into(), + 0, + )) + .with_tally_end(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[2].into(), + 0, + )) + .private() + .member_public_keys(committee_keys) + .build(); + + let vote_plan_cert = vote_plan_cert(&committee, &vote_plan).into(); + + let config = ConfigurationBuilder::new() + .with_funds(vec![ + noise_wallet_from.to_initial_fund(1_000_000_000), + committee.to_initial_fund(quick_config.initial_fund_per_wallet()), + ]) + .with_funds_split_if_needed( + voters + .iter() + .map(|x| x.to_initial_fund(quick_config.initial_fund_per_wallet())) + .collect(), + ) + .with_committees(&[&committee.clone()]) + .with_slots_per_epoch(quick_config.slots_in_epoch()) + .with_certs(vec![vote_plan_cert]) + .with_explorer() + .with_slot_duration(quick_config.slot_duration()) + .with_block_content_max_size(quick_config.block_content_max_size()) + .with_treasury(1_000.into()) + .build(&temp_dir); + + let jormungandr = Starter::new().config(config.clone()).start().unwrap(); + + let transaction_sender = FragmentSender::new( + jormungandr.genesis_block_hash(), + jormungandr.fees(), + FragmentSenderSetup::no_verify(), + ); + + let adversary_transaction_sender = AdversaryFragmentSender::new( + jormungandr.genesis_block_hash(), + jormungandr.fees(), + AdversaryFragmentSenderSetup::no_verify(), + ); + + let benchmark_consumption_monitor = benchmark_consumption(&quick_config.measurement_name()) + .target(quick_config.target_resources_usage()) + .for_process("Node", jormungandr.pid() as usize) + .start_async(std::time::Duration::from_secs(30)); + + let mut adversary_votes_generator = AdversaryFragmentGenerator::new( + jormungandr.to_remote(), + transaction_sender.clone(), + adversary_transaction_sender, + ); + + adversary_votes_generator.fill_from_faucet(&mut noise_wallet_from); + + let _noise = jortestkit::load::start_background_async( + adversary_votes_generator, + FragmentStatusProvider::new(jormungandr.to_remote()), + adversary_noise_config, + "noise fragments", + ); + + let votes_generator = VoteCastsGenerator::new( + voters, + vote_plan.clone(), + jormungandr.to_remote(), + transaction_sender.clone(), + ); + + let stats = jortestkit::load::start_async( + votes_generator, + FragmentStatusProvider::new(jormungandr.to_remote()), + quick_config.configuration(), + &quick_config.measurement_name(), + ); + + stats.print_summary(&quick_config.measurement_name()); + assert_eq!( + stats + .measure( + &quick_config.measurement_name(), + quick_config.tx_target_success_rate() + ) + .status(), + Status::Green + ); + + wait_for_epoch( + quick_config.voting_timing()[1].into(), + jormungandr.explorer().clone(), + ); + + transaction_sender + .send_encrypted_tally(&mut committee, &vote_plan, &jormungandr) + .unwrap(); + + wait_for_date( + BlockDateLib::new( + quick_config.voting_timing()[1].into(), + (quick_config.slots_in_epoch() / 2).into(), + ), + jormungandr.explorer().clone(), + ); + + let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); + let vote_plan_status = active_vote_plans + .iter() + .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) + .unwrap(); + + let shares = decrypt_tally(&vote_plan_status.clone().into(), &members); + + transaction_sender + .send_vote_tally( + &mut committee, + &vote_plan, + &jormungandr, + VoteTallyPayload::Private { inner: shares }, + ) + .unwrap(); + + wait_for_epoch( + quick_config.voting_timing()[2].into(), + jormungandr.explorer().clone(), + ); + let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); + + let vote_plan_status = active_vote_plans + .iter() + .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) + .unwrap(); + + for proposal in vote_plan_status.proposals.iter() { + assert!( + proposal.tally.is_some(), + "Proposal is not tallied {:?}", + proposal + ); + } + + benchmark_consumption_monitor.stop(); + + jormungandr.assert_no_errors_in_log(); +} diff --git a/testing/jormungandr-integration-tests/src/non_functional/voting/private/noise.rs b/testing/jormungandr-integration-tests/src/non_functional/voting/private/noise.rs index 2f92c035c4..0227161607 100644 --- a/testing/jormungandr-integration-tests/src/non_functional/voting/private/noise.rs +++ b/testing/jormungandr-integration-tests/src/non_functional/voting/private/noise.rs @@ -1,233 +1,10 @@ -use crate::common::jormungandr::{ConfigurationBuilder, Starter}; use crate::non_functional::voting::config::adversary_noise_config; -use crate::non_functional::voting::config::PrivateVotingLoadTestConfig; -use assert_fs::TempDir; -use chain_core::property::BlockDate; -use chain_impl_mockchain::testing::data::CommitteeMembersManager; -use chain_impl_mockchain::{ - certificate::{VoteAction, VoteTallyPayload}, - ledger::governance::TreasuryGovernanceAction, - testing::decrypt_tally, - value::Value, -}; -use jormungandr_lib::interfaces::BlockDate as BlockDateLib; -use jormungandr_testing_utils::testing::fragments::AdversaryFragmentGenerator; -use jormungandr_testing_utils::testing::AdversaryFragmentSender; -use jormungandr_testing_utils::testing::AdversaryFragmentSenderSetup; -use jormungandr_testing_utils::testing::VoteCastsGenerator; -use jormungandr_testing_utils::testing::{ - benchmark_consumption, FragmentStatusProvider, VotePlanBuilder, -}; -use jormungandr_testing_utils::{ - testing::{ - node::time::{wait_for_date, wait_for_epoch}, - vote_plan_cert, FragmentSender, FragmentSenderSetup, - }, - wallet::Wallet, -}; -use jortestkit::load::Configuration; -use jortestkit::{load, measurement::Status}; -use rand::rngs::OsRng; +use crate::non_functional::voting::private::adversary_private_vote_load_scenario; +use crate::non_functional::voting::private::PrivateVotingLoadTestConfig; #[test] -pub fn adversary_private_vote_load_quick_test() { +pub fn adversary_private_vote_quick_test() { let quick_config = PrivateVotingLoadTestConfig::quick(); let adversary_noise_config = adversary_noise_config(30, quick_config.test_duration()); adversary_private_vote_load_scenario(quick_config, adversary_noise_config) } - -#[test] -pub fn adversary_private_vote_load_long_test() { - let long_config = PrivateVotingLoadTestConfig::long(); - let adversary_noise_config = adversary_noise_config(30, long_config.test_duration()); - adversary_private_vote_load_scenario(long_config, adversary_noise_config) -} - -pub fn adversary_private_vote_load_scenario( - quick_config: PrivateVotingLoadTestConfig, - adversary_noise_config: Configuration, -) { - let temp_dir = TempDir::new().unwrap().into_persistent(); - let mut rng = OsRng; - let members = CommitteeMembersManager::new( - &mut rng, - quick_config.tally_threshold(), - quick_config.members_count(), - ); - - let committee_keys = members - .members() - .iter() - .map(|committee_member| committee_member.public_key()) - .collect::>(); - - let mut noise_wallet_from = Wallet::new_account(&mut rng); - - let voters: Vec = std::iter::from_fn(|| Some(Wallet::new_account(&mut rng))) - .take(quick_config.wallets_count()) - .collect(); - - let mut rng = OsRng; - let mut committee = Wallet::new_account(&mut rng); - - let vote_plan = VotePlanBuilder::new() - .proposals_count(quick_config.proposals_count()) - .action_type(VoteAction::Treasury { - action: TreasuryGovernanceAction::TransferToRewards { - value: Value(quick_config.rewards_increase()), - }, - }) - .with_vote_start(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[0].into(), - 0, - )) - .with_tally_start(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[1].into(), - 0, - )) - .with_tally_end(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[2].into(), - 0, - )) - .private() - .member_public_keys(committee_keys) - .build(); - - let vote_plan_cert = vote_plan_cert(&committee, &vote_plan).into(); - - let config = ConfigurationBuilder::new() - .with_funds(vec![ - noise_wallet_from.to_initial_fund(1_000_000_000), - committee.to_initial_fund(quick_config.initial_fund_per_wallet()), - ]) - .with_funds_split_if_needed( - voters - .iter() - .map(|x| x.to_initial_fund(quick_config.initial_fund_per_wallet())) - .collect(), - ) - .with_committees(&[&committee.clone()]) - .with_slots_per_epoch(quick_config.slots_in_epoch()) - .with_certs(vec![vote_plan_cert]) - .with_explorer() - .with_slot_duration(quick_config.slot_duration()) - .with_block_content_max_size(quick_config.block_content_max_size()) - .with_treasury(1_000.into()) - .build(&temp_dir); - - let jormungandr = Starter::new().config(config.clone()).start().unwrap(); - - let transaction_sender = FragmentSender::new( - jormungandr.genesis_block_hash(), - jormungandr.fees(), - FragmentSenderSetup::no_verify(), - ); - - let adversary_transaction_sender = AdversaryFragmentSender::new( - jormungandr.genesis_block_hash(), - jormungandr.fees(), - AdversaryFragmentSenderSetup::no_verify(), - ); - - let benchmark_consumption_monitor = benchmark_consumption(&quick_config.measurement_name()) - .target(quick_config.target_resources_usage()) - .for_process("Node", jormungandr.pid() as usize) - .start_async(std::time::Duration::from_secs(30)); - - let mut adversary_votes_generator = AdversaryFragmentGenerator::new( - jormungandr.to_remote(), - transaction_sender.clone(), - adversary_transaction_sender, - ); - - adversary_votes_generator.fill_from_faucet(&mut noise_wallet_from); - - let _noise = load::start_background_async( - adversary_votes_generator, - FragmentStatusProvider::new(jormungandr.to_remote()), - adversary_noise_config, - "noise fragments", - ); - - let votes_generator = VoteCastsGenerator::new( - voters, - vote_plan.clone(), - jormungandr.to_remote(), - transaction_sender.clone(), - ); - - let stats = load::start_async( - votes_generator, - FragmentStatusProvider::new(jormungandr.to_remote()), - quick_config.configuration(), - &quick_config.measurement_name(), - ); - - stats.print_summary(&quick_config.measurement_name()); - assert_eq!( - stats - .measure( - &quick_config.measurement_name(), - quick_config.tx_target_success_rate() - ) - .status(), - Status::Green - ); - - wait_for_epoch( - quick_config.voting_timing()[1].into(), - jormungandr.explorer().clone(), - ); - - transaction_sender - .send_encrypted_tally(&mut committee, &vote_plan, &jormungandr) - .unwrap(); - - wait_for_date( - BlockDateLib::new( - quick_config.voting_timing()[1].into(), - (quick_config.slots_in_epoch() / 2).into(), - ), - jormungandr.explorer().clone(), - ); - - let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); - let vote_plan_status = active_vote_plans - .iter() - .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) - .unwrap(); - - let shares = decrypt_tally(&vote_plan_status.clone().into(), &members); - - transaction_sender - .send_vote_tally( - &mut committee, - &vote_plan, - &jormungandr, - VoteTallyPayload::Private { inner: shares }, - ) - .unwrap(); - - wait_for_epoch( - quick_config.voting_timing()[2].into(), - jormungandr.explorer().clone(), - ); - let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); - - let vote_plan_status = active_vote_plans - .iter() - .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) - .unwrap(); - - for proposal in vote_plan_status.proposals.iter() { - assert!( - proposal.tally.is_some(), - "Proposal is not tallied {:?}", - proposal - ); - } - - benchmark_consumption_monitor.stop(); - - jormungandr.assert_no_errors_in_log(); -} diff --git a/testing/jormungandr-integration-tests/src/non_functional/voting/public/load.rs b/testing/jormungandr-integration-tests/src/non_functional/voting/public/load.rs index 7bb0a52613..3f5ea3c2f4 100644 --- a/testing/jormungandr-integration-tests/src/non_functional/voting/public/load.rs +++ b/testing/jormungandr-integration-tests/src/non_functional/voting/public/load.rs @@ -1,155 +1,8 @@ -use crate::common::jormungandr::{ConfigurationBuilder, Starter}; use crate::non_functional::voting::config::PublicVotingLoadTestConfig; -use assert_fs::TempDir; -use chain_core::property::BlockDate; -use chain_impl_mockchain::{ - certificate::{VoteAction, VoteTallyPayload}, - ledger::governance::TreasuryGovernanceAction, - value::Value, -}; -use jormungandr_testing_utils::testing::VoteCastsGenerator; -use jormungandr_testing_utils::testing::{ - benchmark_consumption, FragmentStatusProvider, VotePlanBuilder, -}; -use jormungandr_testing_utils::{ - testing::{node::time::wait_for_epoch, vote_plan_cert, FragmentSender, FragmentSenderSetup}, - wallet::Wallet, -}; -use jortestkit::{load, measurement::Status}; -use rand::rngs::OsRng; +use crate::non_functional::voting::public::public_vote_load_scenario; #[test] pub fn public_vote_load_quick_test() { let quick_config = PublicVotingLoadTestConfig::quick(); public_vote_load_scenario(quick_config) } - -#[test] -pub fn public_vote_load_long_test() { - let long_config = PublicVotingLoadTestConfig::long(); - public_vote_load_scenario(long_config) -} - -pub fn public_vote_load_scenario(quick_config: PublicVotingLoadTestConfig) { - let temp_dir = TempDir::new().unwrap(); - let mut rng = OsRng; - let mut committee = Wallet::new_account(&mut rng); - - let voters: Vec = std::iter::from_fn(|| Some(Wallet::new_account(&mut rng))) - .take(quick_config.wallets_count()) - .collect(); - - let vote_plan = VotePlanBuilder::new() - .proposals_count(quick_config.proposals_count()) - .action_type(VoteAction::Treasury { - action: TreasuryGovernanceAction::TransferToRewards { - value: Value(quick_config.rewards_increase()), - }, - }) - .with_vote_start(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[0], - 0, - )) - .with_tally_start(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[1], - 0, - )) - .with_tally_end(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[2], - 0, - )) - .public() - .build(); - - let vote_plan_cert = vote_plan_cert(&committee, &vote_plan).into(); - - let config = ConfigurationBuilder::new() - .with_fund(committee.to_initial_fund(quick_config.initial_fund_per_wallet())) - .with_funds_split_if_needed( - voters - .iter() - .map(|x| x.to_initial_fund(quick_config.initial_fund_per_wallet())) - .collect(), - ) - .with_committees(&[&committee.clone()]) - .with_slots_per_epoch(quick_config.slots_in_epoch()) - .with_certs(vec![vote_plan_cert]) - .with_explorer() - .with_slot_duration(quick_config.slot_duration()) - .with_treasury(1_000.into()) - .build(&temp_dir); - - let jormungandr = Starter::new().config(config.clone()).start().unwrap(); - - let transaction_sender = FragmentSender::new( - jormungandr.genesis_block_hash(), - jormungandr.fees(), - FragmentSenderSetup::no_verify(), - ); - - let benchmark_consumption_monitor = benchmark_consumption(quick_config.measurement_name()) - .target(quick_config.target_resources_usage()) - .for_process("Node", jormungandr.pid() as usize) - .start_async(std::time::Duration::from_secs(30)); - - let votes_generator = VoteCastsGenerator::new( - voters, - vote_plan.clone(), - jormungandr.to_remote(), - transaction_sender.clone(), - ); - - let stats = load::start_async( - votes_generator, - FragmentStatusProvider::new(jormungandr.to_remote()), - quick_config.configuration(), - &quick_config.measurement_name(), - ); - - stats.print_summary(&quick_config.measurement_name()); - assert_eq!( - stats - .measure( - &quick_config.measurement_name(), - quick_config.tx_target_success_rate() - ) - .status(), - Status::Green - ); - - wait_for_epoch( - quick_config.voting_timing()[1].into(), - jormungandr.explorer().clone(), - ); - - transaction_sender - .send_vote_tally( - &mut committee, - &vote_plan, - &jormungandr, - VoteTallyPayload::Public, - ) - .unwrap(); - - wait_for_epoch( - quick_config.voting_timing()[2].into(), - jormungandr.explorer().clone(), - ); - let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); - let vote_plan_status = active_vote_plans - .iter() - .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) - .unwrap(); - - for proposal in vote_plan_status.proposals.iter() { - assert!( - proposal.tally.is_some(), - "Proposal is not tallied {:?}", - proposal - ); - } - - benchmark_consumption_monitor.stop(); - - jormungandr.assert_no_errors_in_log(); -} diff --git a/testing/jormungandr-integration-tests/src/non_functional/voting/public/mod.rs b/testing/jormungandr-integration-tests/src/non_functional/voting/public/mod.rs index 29528a69ec..9795112955 100644 --- a/testing/jormungandr-integration-tests/src/non_functional/voting/public/mod.rs +++ b/testing/jormungandr-integration-tests/src/non_functional/voting/public/mod.rs @@ -1,2 +1,307 @@ +#[cfg(feature = "sanity-non-functional")] mod load; +#[cfg(feature = "sanity-non-functional")] mod noise; +#[cfg(feature = "soak-non-functional")] +mod soak; + +use crate::common::jormungandr::{ConfigurationBuilder, Starter}; +use crate::non_functional::voting::config::PublicVotingLoadTestConfig; +use assert_fs::TempDir; +use chain_core::property::BlockDate; +use chain_impl_mockchain::{ + certificate::{VoteAction, VoteTallyPayload}, + ledger::governance::TreasuryGovernanceAction, + value::Value, +}; +use jormungandr_testing_utils::testing::fragments::AdversaryFragmentGenerator; +use jormungandr_testing_utils::testing::AdversaryFragmentSender; +use jormungandr_testing_utils::testing::AdversaryFragmentSenderSetup; +use jormungandr_testing_utils::testing::VoteCastsGenerator; +use jormungandr_testing_utils::testing::{ + benchmark_consumption, FragmentStatusProvider, VotePlanBuilder, +}; +use jormungandr_testing_utils::{ + testing::{node::time::wait_for_epoch, vote_plan_cert, FragmentSender, FragmentSenderSetup}, + wallet::Wallet, +}; +use jortestkit::load::Configuration; +use jortestkit::measurement::Status; +use rand::rngs::OsRng; + +pub fn public_vote_load_scenario(quick_config: PublicVotingLoadTestConfig) { + let temp_dir = TempDir::new().unwrap(); + let mut rng = OsRng; + let mut committee = Wallet::new_account(&mut rng); + + let voters: Vec = std::iter::from_fn(|| Some(Wallet::new_account(&mut rng))) + .take(quick_config.wallets_count()) + .collect(); + + let vote_plan = VotePlanBuilder::new() + .proposals_count(quick_config.proposals_count()) + .action_type(VoteAction::Treasury { + action: TreasuryGovernanceAction::TransferToRewards { + value: Value(quick_config.rewards_increase()), + }, + }) + .with_vote_start(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[0], + 0, + )) + .with_tally_start(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[1], + 0, + )) + .with_tally_end(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[2], + 0, + )) + .public() + .build(); + + let vote_plan_cert = vote_plan_cert(&committee, &vote_plan).into(); + + let config = ConfigurationBuilder::new() + .with_fund(committee.to_initial_fund(quick_config.initial_fund_per_wallet())) + .with_funds_split_if_needed( + voters + .iter() + .map(|x| x.to_initial_fund(quick_config.initial_fund_per_wallet())) + .collect(), + ) + .with_committees(&[&committee.clone()]) + .with_slots_per_epoch(quick_config.slots_in_epoch()) + .with_certs(vec![vote_plan_cert]) + .with_explorer() + .with_slot_duration(quick_config.slot_duration()) + .with_treasury(1_000.into()) + .build(&temp_dir); + + let jormungandr = Starter::new().config(config.clone()).start().unwrap(); + + let transaction_sender = FragmentSender::new( + jormungandr.genesis_block_hash(), + jormungandr.fees(), + FragmentSenderSetup::no_verify(), + ); + + let benchmark_consumption_monitor = benchmark_consumption(quick_config.measurement_name()) + .target(quick_config.target_resources_usage()) + .for_process("Node", jormungandr.pid() as usize) + .start_async(std::time::Duration::from_secs(30)); + + let votes_generator = VoteCastsGenerator::new( + voters, + vote_plan.clone(), + jormungandr.to_remote(), + transaction_sender.clone(), + ); + + let stats = jortestkit::load::start_async( + votes_generator, + FragmentStatusProvider::new(jormungandr.to_remote()), + quick_config.configuration(), + &quick_config.measurement_name(), + ); + + stats.print_summary(&quick_config.measurement_name()); + assert_eq!( + stats + .measure( + &quick_config.measurement_name(), + quick_config.tx_target_success_rate() + ) + .status(), + Status::Green + ); + + wait_for_epoch( + quick_config.voting_timing()[1].into(), + jormungandr.explorer().clone(), + ); + + transaction_sender + .send_vote_tally( + &mut committee, + &vote_plan, + &jormungandr, + VoteTallyPayload::Public, + ) + .unwrap(); + + wait_for_epoch( + quick_config.voting_timing()[2].into(), + jormungandr.explorer().clone(), + ); + let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); + let vote_plan_status = active_vote_plans + .iter() + .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) + .unwrap(); + + for proposal in vote_plan_status.proposals.iter() { + assert!( + proposal.tally.is_some(), + "Proposal is not tallied {:?}", + proposal + ); + } + + benchmark_consumption_monitor.stop(); + + jormungandr.assert_no_errors_in_log(); +} + +pub fn adversary_public_vote_load_scenario( + quick_config: PublicVotingLoadTestConfig, + adversary_noise_config: Configuration, +) { + let temp_dir = TempDir::new().unwrap(); + let mut rng = OsRng; + let mut committee = Wallet::new_account(&mut rng); + + let mut noise_wallet_from = Wallet::new_account(&mut rng); + + let voters: Vec = std::iter::from_fn(|| Some(Wallet::new_account(&mut rng))) + .take(quick_config.wallets_count()) + .collect(); + + let vote_plan = VotePlanBuilder::new() + .proposals_count(quick_config.proposals_count()) + .action_type(VoteAction::Treasury { + action: TreasuryGovernanceAction::TransferToRewards { + value: Value(quick_config.rewards_increase()), + }, + }) + .with_vote_start(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[0].into(), + 0, + )) + .with_tally_start(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[1].into(), + 0, + )) + .with_tally_end(BlockDate::from_epoch_slot_id( + quick_config.voting_timing()[2].into(), + 0, + )) + .build(); + + let vote_plan_cert = vote_plan_cert(&committee, &vote_plan).into(); + + let config = ConfigurationBuilder::new() + .with_funds(vec![ + noise_wallet_from.to_initial_fund(1_000_000_000), + committee.to_initial_fund(quick_config.initial_fund_per_wallet()), + ]) + .with_funds_split_if_needed( + voters + .iter() + .map(|x| x.to_initial_fund(quick_config.initial_fund_per_wallet())) + .collect(), + ) + .with_committees(&[&committee.clone()]) + .with_slots_per_epoch(quick_config.slots_in_epoch()) + .with_certs(vec![vote_plan_cert]) + .with_explorer() + .with_slot_duration(quick_config.slot_duration()) + .with_block_content_max_size(quick_config.block_content_max_size()) + .with_treasury(1_000.into()) + .build(&temp_dir); + + let jormungandr = Starter::new().config(config.clone()).start().unwrap(); + + let transaction_sender = FragmentSender::new( + jormungandr.genesis_block_hash(), + jormungandr.fees(), + FragmentSenderSetup::no_verify(), + ); + + let adversary_transaction_sender = AdversaryFragmentSender::new( + jormungandr.genesis_block_hash(), + jormungandr.fees(), + AdversaryFragmentSenderSetup::no_verify(), + ); + + let benchmark_consumption_monitor = benchmark_consumption(&quick_config.measurement_name()) + .target(quick_config.target_resources_usage()) + .for_process("Node", jormungandr.pid() as usize) + .start_async(std::time::Duration::from_secs(30)); + + let mut adversary_votes_generator = AdversaryFragmentGenerator::new( + jormungandr.to_remote(), + transaction_sender.clone(), + adversary_transaction_sender, + ); + + adversary_votes_generator.fill_from_faucet(&mut noise_wallet_from); + + let _noise = jortestkit::load::start_background_async( + adversary_votes_generator, + FragmentStatusProvider::new(jormungandr.to_remote()), + adversary_noise_config, + "noise fragments", + ); + + let votes_generator = VoteCastsGenerator::new( + voters, + vote_plan.clone(), + jormungandr.to_remote(), + transaction_sender.clone(), + ); + + let stats = jortestkit::load::start_async( + votes_generator, + FragmentStatusProvider::new(jormungandr.to_remote()), + quick_config.configuration(), + &quick_config.measurement_name(), + ); + + stats.print_summary(&quick_config.measurement_name()); + assert_eq!( + stats + .measure( + &quick_config.measurement_name(), + quick_config.tx_target_success_rate() + ) + .status(), + Status::Green + ); + + wait_for_epoch( + quick_config.voting_timing()[1].into(), + jormungandr.explorer().clone(), + ); + + transaction_sender + .send_vote_tally( + &mut committee, + &vote_plan, + &jormungandr, + VoteTallyPayload::Public, + ) + .unwrap(); + + wait_for_epoch( + quick_config.voting_timing()[2].into(), + jormungandr.explorer().clone(), + ); + let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); + let vote_plan_status = active_vote_plans + .iter() + .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) + .unwrap(); + + for proposal in vote_plan_status.proposals.iter() { + assert!( + proposal.tally.is_some(), + "Proposal is not tallied {:?}", + proposal + ); + } + + benchmark_consumption_monitor.stop(); + + jormungandr.assert_no_errors_in_log(); +} diff --git a/testing/jormungandr-integration-tests/src/non_functional/voting/public/noise.rs b/testing/jormungandr-integration-tests/src/non_functional/voting/public/noise.rs index 97cc27fd38..1984d995c7 100644 --- a/testing/jormungandr-integration-tests/src/non_functional/voting/public/noise.rs +++ b/testing/jormungandr-integration-tests/src/non_functional/voting/public/noise.rs @@ -1,191 +1,10 @@ -use crate::common::jormungandr::{ConfigurationBuilder, Starter}; use crate::non_functional::voting::config::adversary_noise_config; -use crate::non_functional::voting::config::PublicVotingLoadTestConfig; -use assert_fs::TempDir; -use chain_core::property::BlockDate; -use chain_impl_mockchain::{ - certificate::{VoteAction, VoteTallyPayload}, - ledger::governance::TreasuryGovernanceAction, - value::Value, -}; -use jormungandr_testing_utils::testing::fragments::AdversaryFragmentGenerator; -use jormungandr_testing_utils::testing::AdversaryFragmentSender; -use jormungandr_testing_utils::testing::AdversaryFragmentSenderSetup; -use jormungandr_testing_utils::testing::VoteCastsGenerator; -use jormungandr_testing_utils::testing::{ - benchmark_consumption, FragmentStatusProvider, VotePlanBuilder, -}; -use jormungandr_testing_utils::{ - testing::{node::time::wait_for_epoch, vote_plan_cert, FragmentSender, FragmentSenderSetup}, - wallet::Wallet, -}; -use jortestkit::load::Configuration; -use jortestkit::{load, measurement::Status}; -use rand::rngs::OsRng; +use crate::non_functional::voting::public::adversary_public_vote_load_scenario; +use crate::non_functional::voting::public::PublicVotingLoadTestConfig; #[test] -pub fn adversary_public_vote_load_quick_test() { +pub fn adversary_public_vote_quick_test() { let quick_config = PublicVotingLoadTestConfig::quick(); let adversary_noise_config = adversary_noise_config(30, quick_config.test_duration()); adversary_public_vote_load_scenario(quick_config, adversary_noise_config) } - -#[test] -pub fn adversary_public_vote_load_long_test() { - let long_config = PublicVotingLoadTestConfig::long(); - let adversary_noise_config = adversary_noise_config(30, long_config.test_duration()); - adversary_public_vote_load_scenario(long_config, adversary_noise_config) -} - -pub fn adversary_public_vote_load_scenario( - quick_config: PublicVotingLoadTestConfig, - adversary_noise_config: Configuration, -) { - let temp_dir = TempDir::new().unwrap(); - let mut rng = OsRng; - let mut committee = Wallet::new_account(&mut rng); - - let mut noise_wallet_from = Wallet::new_account(&mut rng); - - let voters: Vec = std::iter::from_fn(|| Some(Wallet::new_account(&mut rng))) - .take(quick_config.wallets_count()) - .collect(); - - let vote_plan = VotePlanBuilder::new() - .proposals_count(quick_config.proposals_count()) - .action_type(VoteAction::Treasury { - action: TreasuryGovernanceAction::TransferToRewards { - value: Value(quick_config.rewards_increase()), - }, - }) - .with_vote_start(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[0].into(), - 0, - )) - .with_tally_start(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[1].into(), - 0, - )) - .with_tally_end(BlockDate::from_epoch_slot_id( - quick_config.voting_timing()[2].into(), - 0, - )) - .build(); - - let vote_plan_cert = vote_plan_cert(&committee, &vote_plan).into(); - - let config = ConfigurationBuilder::new() - .with_funds(vec![ - noise_wallet_from.to_initial_fund(1_000_000_000), - committee.to_initial_fund(quick_config.initial_fund_per_wallet()), - ]) - .with_funds_split_if_needed( - voters - .iter() - .map(|x| x.to_initial_fund(quick_config.initial_fund_per_wallet())) - .collect(), - ) - .with_committees(&[&committee.clone()]) - .with_slots_per_epoch(quick_config.slots_in_epoch()) - .with_certs(vec![vote_plan_cert]) - .with_explorer() - .with_slot_duration(quick_config.slot_duration()) - .with_block_content_max_size(quick_config.block_content_max_size()) - .with_treasury(1_000.into()) - .build(&temp_dir); - - let jormungandr = Starter::new().config(config.clone()).start().unwrap(); - - let transaction_sender = FragmentSender::new( - jormungandr.genesis_block_hash(), - jormungandr.fees(), - FragmentSenderSetup::no_verify(), - ); - - let adversary_transaction_sender = AdversaryFragmentSender::new( - jormungandr.genesis_block_hash(), - jormungandr.fees(), - AdversaryFragmentSenderSetup::no_verify(), - ); - - let benchmark_consumption_monitor = benchmark_consumption(&quick_config.measurement_name()) - .target(quick_config.target_resources_usage()) - .for_process("Node", jormungandr.pid() as usize) - .start_async(std::time::Duration::from_secs(30)); - - let mut adversary_votes_generator = AdversaryFragmentGenerator::new( - jormungandr.to_remote(), - transaction_sender.clone(), - adversary_transaction_sender, - ); - - adversary_votes_generator.fill_from_faucet(&mut noise_wallet_from); - - let _noise = load::start_background_async( - adversary_votes_generator, - FragmentStatusProvider::new(jormungandr.to_remote()), - adversary_noise_config, - "noise fragments", - ); - - let votes_generator = VoteCastsGenerator::new( - voters, - vote_plan.clone(), - jormungandr.to_remote(), - transaction_sender.clone(), - ); - - let stats = load::start_async( - votes_generator, - FragmentStatusProvider::new(jormungandr.to_remote()), - quick_config.configuration(), - &quick_config.measurement_name(), - ); - - stats.print_summary(&quick_config.measurement_name()); - assert_eq!( - stats - .measure( - &quick_config.measurement_name(), - quick_config.tx_target_success_rate() - ) - .status(), - Status::Green - ); - - wait_for_epoch( - quick_config.voting_timing()[1].into(), - jormungandr.explorer().clone(), - ); - - transaction_sender - .send_vote_tally( - &mut committee, - &vote_plan, - &jormungandr, - VoteTallyPayload::Public, - ) - .unwrap(); - - wait_for_epoch( - quick_config.voting_timing()[2].into(), - jormungandr.explorer().clone(), - ); - let active_vote_plans = jormungandr.rest().vote_plan_statuses().unwrap(); - let vote_plan_status = active_vote_plans - .iter() - .find(|c_vote_plan| c_vote_plan.id == vote_plan.to_id().into()) - .unwrap(); - - for proposal in vote_plan_status.proposals.iter() { - assert!( - proposal.tally.is_some(), - "Proposal is not tallied {:?}", - proposal - ); - } - - benchmark_consumption_monitor.stop(); - - jormungandr.assert_no_errors_in_log(); -}