diff --git a/Cargo.lock b/Cargo.lock index f484d2c5..e344aea7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,9 +72,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e1f47f7dc0422027a4e370dd4548d4d66b26782e513e98dca1e689e058a80e" +checksum = "ecc78c299ae753905840c5d3ba036c51f61ce5a98a83f98d9c9d29dffd427f71" [[package]] name = "arrayref" @@ -2121,6 +2121,7 @@ dependencies = [ "cfg-if 1.0.0", "chain-addr", "chain-core", + "chain-crypto", "chain-impl-mockchain", "chain-ser", "chrono", @@ -2187,7 +2188,7 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "jcli" version = "0.13.0" -source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#eabf9ecf3df2be77d4b4a16c20854fb099228d33" +source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#73fe8614eaa0f3438b182bd296aa250370b0821b" dependencies = [ "base64 0.13.0", "bech32 0.8.1", @@ -2221,7 +2222,7 @@ dependencies = [ [[package]] name = "jormungandr-integration-tests" version = "0.13.0" -source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#eabf9ecf3df2be77d4b4a16c20854fb099228d33" +source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#73fe8614eaa0f3438b182bd296aa250370b0821b" dependencies = [ "assert_cmd", "assert_fs", @@ -2268,7 +2269,7 @@ dependencies = [ [[package]] name = "jormungandr-lib" version = "0.13.0" -source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#eabf9ecf3df2be77d4b4a16c20854fb099228d33" +source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#73fe8614eaa0f3438b182bd296aa250370b0821b" dependencies = [ "base64 0.13.0", "bech32 0.8.1", @@ -2297,7 +2298,7 @@ dependencies = [ [[package]] name = "jormungandr-scenario-tests" version = "0.13.0" -source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#eabf9ecf3df2be77d4b4a16c20854fb099228d33" +source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#73fe8614eaa0f3438b182bd296aa250370b0821b" dependencies = [ "assert_fs", "chain-addr", @@ -2338,7 +2339,7 @@ dependencies = [ [[package]] name = "jormungandr-testing-utils" version = "0.13.0" -source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#eabf9ecf3df2be77d4b4a16c20854fb099228d33" +source = "git+https://github.com/input-output-hk/jormungandr.git?branch=catalyst-fund7#73fe8614eaa0f3438b182bd296aa250370b0821b" dependencies = [ "assert_cmd", "assert_fs", @@ -3958,9 +3959,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" [[package]] name = "safemem" diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 15840c93..46bd11dd 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -18,6 +18,7 @@ jortestkit = { git = "https://github.com/input-output-hk/jortestkit.git", branch chain-addr = { git = "https://github.com/input-output-hk/chain-libs.git", branch = "catalyst-fund7" } chain-core = { git = "https://github.com/input-output-hk/chain-libs.git", branch = "catalyst-fund7" } chain-ser = { git = "https://github.com/input-output-hk/chain-libs.git", branch = "catalyst-fund7" } +chain-crypto = { git = "https://github.com/input-output-hk/chain-libs.git", branch = "catalyst-fund7" } vitup = { path = "../vitup"} iapyx = { path = "../iapyx"} valgrind = { path = "../valgrind"} diff --git a/integration-tests/src/backend/features/mod.rs b/integration-tests/src/backend/features/mod.rs index 883b090d..361300cb 100644 --- a/integration-tests/src/backend/features/mod.rs +++ b/integration-tests/src/backend/features/mod.rs @@ -1,3 +1,4 @@ mod batch; mod persistent_log; +mod update_proposal; mod votes_history; diff --git a/integration-tests/src/backend/features/update_proposal.rs b/integration-tests/src/backend/features/update_proposal.rs new file mode 100644 index 00000000..517eb0d3 --- /dev/null +++ b/integration-tests/src/backend/features/update_proposal.rs @@ -0,0 +1,192 @@ +use crate::common::{iapyx_from_secret_key, vitup_setup}; +use assert_fs::TempDir; +use chain_crypto::Ed25519; +use chain_impl_mockchain::block::BlockDate; +use chain_impl_mockchain::certificate::UpdateProposal; +use chain_impl_mockchain::certificate::UpdateVote; +use chain_impl_mockchain::vote::Choice; +use jormungandr_lib::crypto::hash::Hash; +use jormungandr_lib::crypto::key::SigningKey; +use jormungandr_lib::interfaces::BlockContentMaxSize; +use jormungandr_lib::interfaces::ConfigParam; +use jormungandr_lib::interfaces::ConfigParams; +use jormungandr_lib::interfaces::FragmentStatus; +use jormungandr_scenario_tests::test::utils::wait; +use jormungandr_testing_utils::testing::node::time; +use jormungandr_testing_utils::testing::BlockDateGenerator; +use jormungandr_testing_utils::testing::FragmentSender; +use jormungandr_testing_utils::wallet::Wallet; +use std::str::FromStr; +use valgrind::{Proposal, Protocol}; +use vit_servicing_station_tests::common::data::ArbitraryValidVotingTemplateGenerator; +use vitup::builders::VitBackendSettingsBuilder; +use vitup::config::VoteBlockchainTime; +use vitup::config::{InitialEntry, Initials}; +use vitup::scenario::network::setup_network; +const PIN: &str = "1234"; +const ALICE: &str = "ALICE"; +const COMMITTEE: &str = "COMMITTEE"; +#[test] +pub fn increase_max_block_content_size_during_voting() { + let old_block_context_max_size = 10_000; + let new_block_context_max_size = 100_000; + + let testing_directory = TempDir::new().unwrap().into_persistent(); + let endpoint = "127.0.0.1:8080"; + let version = "2.0"; + let batch_size = 1; + let vote_timing = VoteBlockchainTime { + vote_start: 0, + tally_start: 5, + tally_end: 10, + slots_per_epoch: 30, + }; + + let mut quick_setup = VitBackendSettingsBuilder::new(); + quick_setup + .initials(Initials(vec![ + InitialEntry::Wallet { + name: ALICE.to_string(), + funds: 10_000, + pin: PIN.to_string(), + }, + InitialEntry::Wallet { + name: COMMITTEE.to_string(), + funds: 10_000, + pin: PIN.to_string(), + }, + ])) + .vote_timing(vote_timing.into()) + .slot_duration_in_seconds(2) + .proposals_count(300) + .block_content_max_size(old_block_context_max_size) + .voting_power(31_000) + .private(true); + + let mut template_generator = ArbitraryValidVotingTemplateGenerator::new(); + let (mut vit_controller, mut controller, vit_parameters, _fund_name) = + vitup_setup(quick_setup, testing_directory.path().to_path_buf()); + + let (nodes, vit_station, wallet_proxy) = setup_network( + &mut controller, + &mut vit_controller, + vit_parameters, + &mut template_generator, + endpoint.to_string(), + &Protocol::Http, + version.to_owned(), + ) + .unwrap(); + + let mut alice = iapyx_from_secret_key( + testing_directory + .path() + .join(format!("vit_backend/wallet_{}", ALICE)), + &wallet_proxy, + ) + .unwrap(); + let mut committee = Wallet::import_account( + testing_directory + .path() + .join(format!("vit_backend/wallet_{}", COMMITTEE)), + Some(0u32), + ); + let bft_leader_secrets: Vec<&SigningKey> = controller + .settings() + .nodes + .iter() + .filter(|(_id, settings)| settings.secret.bft.is_some()) + .take(3) + .map(|(_id, settings)| &settings.secret.bft.as_ref().unwrap().signing_key) + .collect(); + + let change_params = ConfigParams::new(vec![ConfigParam::BlockContentMaxSize( + BlockContentMaxSize::from(new_block_context_max_size), + )]); + let update_proposal = UpdateProposal::new( + change_params.into(), + bft_leader_secrets[0].identifier().into_public_key().into(), + ); + + let old_settings = nodes[1].rest().settings().unwrap(); + assert_eq!( + old_settings.block_content_max_size, + old_block_context_max_size + ); + + let wallet_settings = wallet_proxy.client().settings().unwrap(); + let fragment_sender = FragmentSender::new( + Hash::from_str(&wallet_settings.block0_hash).unwrap(), + wallet_settings.fees, + BlockDateGenerator::rolling( + &wallet_settings, + BlockDate { + epoch: 1, + slot_id: 0, + }, + false, + ), + Default::default(), + ); + + let check = fragment_sender + .send_update_proposal( + &mut committee, + &bft_leader_secrets[0].clone().into_secret_key(), + update_proposal, + &nodes[1], + ) + .unwrap(); + + for bft_leader_secret in bft_leader_secrets { + let update_vote = UpdateVote::new( + *check.fragment_id(), + bft_leader_secret.identifier().into_public_key().into(), + ); + fragment_sender + .send_update_vote( + &mut committee, + &bft_leader_secret.clone().into_secret_key(), + update_vote, + &nodes[1], + ) + .unwrap(); + } + + time::wait_for_epoch(4, nodes[1].rest()); + + let new_settings = nodes[1].rest().settings().unwrap(); + assert_eq!( + new_settings.block_content_max_size, + new_block_context_max_size + ); + + //send batch of votes just to be sure everything is ok + let proposals = alice.proposals().unwrap(); + let votes_data: Vec<(&Proposal, Choice)> = proposals + .iter() + .take(batch_size) + .map(|proposal| (proposal, Choice::new(0))) + .collect(); + + let fragment_ids = alice + .votes_batch(votes_data.clone()) + .unwrap() + .iter() + .map(|item| item.to_string()) + .collect(); + + wait(30); + + let fragment_statuses = nodes[1].rest().fragments_statuses(fragment_ids).unwrap(); + assert!(fragment_statuses + .iter() + .all(|(_, status)| matches!(status, FragmentStatus::InABlock { .. }))); + + vit_station.shutdown(); + wallet_proxy.shutdown(); + for mut node in nodes { + node.shutdown().unwrap(); + } + controller.finalize(); +} diff --git a/vitup/src/builders/mod.rs b/vitup/src/builders/mod.rs index 992ebbdb..dfb776f0 100644 --- a/vitup/src/builders/mod.rs +++ b/vitup/src/builders/mod.rs @@ -106,6 +106,11 @@ impl VitBackendSettingsBuilder { self } + pub fn block_content_max_size(&mut self, block_content_max_size: u32) -> &mut Self { + self.config.params.block_content_max_size = block_content_max_size; + self + } + pub fn initials_count(&mut self, initials_count: usize, pin: &str) -> &mut Self { self.initials(Initials::new_above_threshold( initials_count, @@ -287,34 +292,37 @@ impl VitBackendSettingsBuilder { let vote_blockchain_time = convert_to_blockchain_date(&self.config.params, self.block0_date); - let mut blockchain = Blockchain::default(); - blockchain.set_consensus(ConsensusVersion::Bft); - blockchain.set_slots_per_epoch( - NumberOfSlotsPerEpoch::new(vote_blockchain_time.slots_per_epoch).unwrap(), - ); - blockchain.set_slot_duration(SlotDuration::new(self.config.params.slot_duration).unwrap()); + let mut blockchain = Blockchain::default() + .with_consensus(ConsensusVersion::Bft) + .with_slots_per_epoch( + NumberOfSlotsPerEpoch::new(vote_blockchain_time.slots_per_epoch).unwrap(), + ) + .with_slot_duration(SlotDuration::new(self.config.params.slot_duration).unwrap()); println!("building topology.."); builder = builder.topology(self.build_topology()); - blockchain.add_leader(LEADER_1); - blockchain.add_leader(LEADER_2); - blockchain.add_leader(LEADER_3); + blockchain = blockchain + .with_leader(LEADER_1) + .with_leader(LEADER_2) + .with_leader(LEADER_3); println!("building blockchain parameters.."); - blockchain.set_linear_fee(self.config.linear_fees); - blockchain.set_tx_max_expiry_epochs(self.config.params.tx_max_expiry_epochs); - blockchain.set_discrimination(chain_addr::Discrimination::Production); - blockchain.set_block_content_max_size(self.config.params.block_content_max_size.into()); - blockchain.set_block0_date(self.block0_date); + blockchain = blockchain + .with_linear_fee(self.config.linear_fees) + .with_tx_max_expiry_epochs(self.config.params.tx_max_expiry_epochs) + .with_discrimination(chain_addr::Discrimination::Production) + .with_block_content_max_size(self.config.params.block_content_max_size.into()) + .with_block0_date(self.block0_date); if !self.config.consensus_leader_ids.is_empty() { - blockchain.set_external_consensus_leader_ids(self.config.consensus_leader_ids.clone()); + blockchain = blockchain + .with_external_consensus_leader_ids(self.config.consensus_leader_ids.clone()); } if !self.config.committees.is_empty() { - blockchain.set_external_committees(self.config.committees.clone()); + blockchain = blockchain.with_external_committees(self.config.committees.clone()); } let committee_wallet = WalletTemplate::new_account( @@ -322,8 +330,9 @@ impl VitBackendSettingsBuilder { Value(1_000_000_000), blockchain.discrimination(), ); - blockchain.add_wallet(committee_wallet); - blockchain.add_committee(self.committee_wallet.clone()); + blockchain = blockchain + .with_wallet(committee_wallet) + .with_committee(self.committee_wallet.clone()); let child = context.child_directory(self.title()); @@ -331,19 +340,20 @@ impl VitBackendSettingsBuilder { let mut templates = HashMap::new(); if self.config.params.initials.any() { - blockchain.set_external_wallets(self.config.params.initials.external_templates()); + blockchain = + blockchain.with_external_wallets(self.config.params.initials.external_templates()); templates = self .config .params .initials .templates(self.config.params.voting_power, blockchain.discrimination()); for (wallet, _) in templates.iter().filter(|(x, _)| *x.value() > Value::zero()) { - blockchain.add_wallet(wallet.clone()); + blockchain = blockchain.with_wallet(wallet.clone()); } } println!("building voteplan.."); - VitVotePlanDefBuilder::new(vote_blockchain_time) + for vote_plan_def in VitVotePlanDefBuilder::new(vote_blockchain_time) .options(2) .split_by(255) .fund_name(self.fund_name()) @@ -351,13 +361,13 @@ impl VitBackendSettingsBuilder { .with_parameters(self.config.params.clone()) .build() .into_iter() - .for_each(|vote_plan_def| { - blockchain.add_vote_plan( - vote_plan_def.alias(), - vote_plan_def.owner(), - chain_impl_mockchain::certificate::VotePlan::from(vote_plan_def).into(), - ) - }); + { + blockchain = blockchain.with_vote_plan( + vote_plan_def.alias(), + vote_plan_def.owner(), + chain_impl_mockchain::certificate::VotePlan::from(vote_plan_def).into(), + ) + } builder = builder.blockchain(blockchain);