From 59e061b17571ce8136001bc31b2794bdcf5eccdf Mon Sep 17 00:00:00 2001 From: Juan Ignacio Rios <54085674+JuaniRios@users.noreply.github.com> Date: Thu, 16 May 2024 13:19:48 +0200 Subject: [PATCH] =?UTF-8?q?=20=E2=9A=A1=EF=B8=8F=20Improve=20phase=20trans?= =?UTF-8?q?ition=20points=20and=20fix=20instant-mode=20=20(#298)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What? - Fix instant-mode benchmarks - Improve dry-run-benches just command - Improve phase transition points ## Why? - The calculation on the instantiator was inaccurate because the phase transition points were 1 block off - Just command can now run for a specific mode and runtime ## How? - Now the start block of a state is the same block where on_initialize is called. Before it was the next block, even though the current one was still possible to call the extrinsics for that state ## Testing? `just dry-run-benchmarks instant-mode` --- justfile | 34 ++++---- pallets/funding/src/benchmarking.rs | 17 +--- pallets/funding/src/functions.rs | 27 +++--- .../src/instantiator/async_features.rs | 18 ++-- .../src/instantiator/chain_interactions.rs | 49 +++++------ pallets/funding/src/mock.rs | 17 ++-- pallets/funding/src/tests/2_evaluation.rs | 4 +- pallets/funding/src/tests/3_auction.rs | 22 +++-- pallets/funding/src/tests/4_community.rs | 2 +- pallets/funding/src/tests/6_funding_end.rs | 1 + pallets/funding/src/tests/misc.rs | 83 ++----------------- pallets/funding/src/tests/mod.rs | 11 ++- 12 files changed, 113 insertions(+), 172 deletions(-) diff --git a/justfile b/justfile index 958b3af78..2bbcbde80 100644 --- a/justfile +++ b/justfile @@ -21,25 +21,31 @@ test-runtime-features runtime="polimec-runtime": test-integration: cargo test -p integration-tests -dry-run-benchmarks runtime="politest,polimec" pallet="*" extrinsic="*" : +dry-run-benchmarks mode="fast-mode" runtime="politest,polimec" pallet="*" extrinsic="*" : #!/bin/bash # Set the internal field separator for splitting the runtime variable IFS=',' # Read the runtime variable into an array read -ra runtimes <<< "{{runtime}}" - # Build the project - cargo build --features runtime-benchmarks --release - # Loop over each runtime and run the benchmark - for runtime in "${runtimes[@]}"; do \ - echo -e "\033[34mRunning benchmarks for runtime: \033[92m$runtime\033[34m\033[0m" - ./target/release/polimec-node benchmark pallet \ - --chain=${runtime}-local \ - --steps=2 \ - --repeat=1 \ - --pallet={{ pallet }} \ - --extrinsic={{ extrinsic }} \ - --wasm-execution=compiled \ - --heap-pages=4096 + read -ra modes <<< "{{mode}}" + + # Build the project with each mode + for mode in "${modes[@]}"; do \ + echo -e "\033[34mBuilding runtime with mode: \033[92m$mode\033[34m\033[0m" + cargo build --features runtime-benchmarks,$mode --release + # Loop over each runtime and run the benchmark + for runtime in "${runtimes[@]}"; do \ + echo -e "\033[34mRunning benchmarks for runtime: \033[92m$runtime\033[34m\033[0m" + + ./target/release/polimec-node benchmark pallet \ + --chain=${runtime}-local \ + --steps=2 \ + --repeat=1 \ + --pallet={{ pallet }} \ + --extrinsic={{ extrinsic }} \ + --wasm-execution=compiled \ + --heap-pages=4096 + done done # src: https://github.com/polkadot-fellows/runtimes/blob/48ccfae6141d2924f579d81e8b1877efd208693f/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/cumulus_pallet_xcmp_queue.rs diff --git a/pallets/funding/src/benchmarking.rs b/pallets/funding/src/benchmarking.rs index 07224b9fb..969c17d86 100644 --- a/pallets/funding/src/benchmarking.rs +++ b/pallets/funding/src/benchmarking.rs @@ -639,7 +639,7 @@ mod benchmarks { let current_block = inst.current_block(); // `do_auction_opening` fn will try to add an automatic transition 1 block after the last opening round block - let insertion_block_number: BlockNumberFor = current_block + T::AuctionOpeningDuration::get() + One::one(); + let insertion_block_number: BlockNumberFor = current_block + T::AuctionOpeningDuration::get(); fill_projects_to_update::(x, insertion_block_number); @@ -2108,19 +2108,8 @@ mod benchmarks { inst.bid_for_users(project_id, accepted_bids).unwrap(); - let now = inst.current_block(); - frame_system::Pallet::::set_block_number(now + ::AuctionOpeningDuration::get()); - // automatic transition to opening auction - inst.advance_time(1u32.into()).unwrap(); - - let project_details = inst.get_project_details(project_id); - let auction_closing_block_end = project_details.phase_transition_points.auction_closing.end().unwrap(); - // probably the last block will always be after random end - let random_ending: BlockNumberFor = auction_closing_block_end; - frame_system::Pallet::::set_block_number(random_ending); - - inst.bid_for_users(project_id, rejected_bids).unwrap(); - + let transition_block = inst.get_update_block(project_id, &UpdateType::AuctionClosingStart).unwrap(); + inst.jump_to_block(transition_block); let auction_closing_end_block = inst.get_project_details(project_id).phase_transition_points.auction_closing.end().unwrap(); // we don't use advance time to avoid triggering on_initialize. This benchmark should only measure the fn diff --git a/pallets/funding/src/functions.rs b/pallets/funding/src/functions.rs index ea9d635a0..6eb0178df 100644 --- a/pallets/funding/src/functions.rs +++ b/pallets/funding/src/functions.rs @@ -85,9 +85,9 @@ impl Pallet { ensure!(project_metadata.policy_ipfs_cid.is_some(), Error::::CidNotProvided); // * Calculate new variables * - let evaluation_end_block = now + T::EvaluationDuration::get(); + let evaluation_end_block = now.saturating_add(T::EvaluationDuration::get()).saturating_sub(One::one()); project_details.phase_transition_points.application.update(None, Some(now)); - project_details.phase_transition_points.evaluation.update(Some(now + 1u32.into()), Some(evaluation_end_block)); + project_details.phase_transition_points.evaluation.update(Some(now), Some(evaluation_end_block)); project_details.is_frozen = true; project_details.status = ProjectStatus::EvaluationRound; @@ -162,9 +162,10 @@ impl Pallet { let usd_total_amount_bonded = project_details.evaluation_round_info.total_bonded_usd; let evaluation_target_usd = ::EvaluationSuccessThreshold::get() * fundraising_target_usd; - let auction_initialize_period_start_block = now + 1u32.into(); - let auction_initialize_period_end_block = - auction_initialize_period_start_block + T::AuctionInitializePeriodDuration::get(); + let auction_initialize_period_start_block = now; + let auction_initialize_period_end_block = auction_initialize_period_start_block + .saturating_add(T::AuctionInitializePeriodDuration::get()) + .saturating_sub(One::one()); // Check which logic path to follow let is_funded = usd_total_amount_bonded >= evaluation_target_usd; @@ -267,8 +268,8 @@ impl Pallet { ensure!(project_details.status == ProjectStatus::AuctionInitializePeriod, Error::::IncorrectRound); // * Calculate new variables * - let opening_start_block = now + 1u32.into(); - let opening_end_block = now + T::AuctionOpeningDuration::get(); + let opening_start_block = now; + let opening_end_block = now.saturating_add(T::AuctionOpeningDuration::get()).saturating_sub(One::one()); // * Update Storage * project_details @@ -340,8 +341,8 @@ impl Pallet { ensure!(project_details.status == ProjectStatus::AuctionOpening, Error::::IncorrectRound); // * Calculate new variables * - let closing_start_block = now + 1u32.into(); - let closing_end_block = now + T::AuctionClosingDuration::get(); + let closing_start_block = now; + let closing_end_block = now.saturating_add(T::AuctionClosingDuration::get()).saturating_sub(One::one()); // * Update Storage * project_details @@ -407,8 +408,8 @@ impl Pallet { // * Calculate new variables * let end_block = Self::select_random_block(auction_closing_start_block, auction_closing_end_block); - let community_start_block = now + 1u32.into(); - let community_end_block = now + T::CommunityFundingDuration::get(); + let community_start_block = now; + let community_end_block = now.saturating_add(T::CommunityFundingDuration::get()).saturating_sub(One::one()); // * Update Storage * let calculation_result = Self::calculate_weighted_average_price( project_id, @@ -495,8 +496,8 @@ impl Pallet { ); // * Calculate new variables * - let remainder_start_block = now + 1u32.into(); - let remainder_end_block = now + T::RemainderFundingDuration::get(); + let remainder_start_block = now; + let remainder_end_block = now.saturating_add(T::RemainderFundingDuration::get()).saturating_sub(One::one()); // * Update Storage * project_details diff --git a/pallets/funding/src/instantiator/async_features.rs b/pallets/funding/src/instantiator/async_features.rs index 687e7e7c2..d15235e1a 100644 --- a/pallets/funding/src/instantiator/async_features.rs +++ b/pallets/funding/src/instantiator/async_features.rs @@ -171,6 +171,7 @@ pub async fn async_create_evaluating_project< let mut inst = instantiator.lock().await; inst.start_evaluation(project_id, issuer).unwrap(); + let now = inst.current_block(); project_id } @@ -191,7 +192,7 @@ pub async fn async_start_auction< if project_details.status == ProjectStatus::EvaluationRound { let update_block = inst.get_update_block(project_id, &UpdateType::EvaluationEnd).unwrap(); let notify = Arc::new(Notify::new()); - block_orchestrator.add_awaiting_project(update_block + 1u32.into(), notify.clone()).await; + block_orchestrator.add_awaiting_project(update_block, notify.clone()).await; // Wait for the notification that our desired block was reached to continue drop(inst); @@ -282,7 +283,7 @@ pub async fn async_start_community_funding< let mut inst = instantiator.lock().await; let update_block = inst.get_update_block(project_id, &UpdateType::AuctionClosingStart).unwrap(); - let closing_start = update_block + 1u32.into(); + let closing_start = update_block; let notify = Arc::new(Notify::new()); @@ -296,7 +297,7 @@ pub async fn async_start_community_funding< inst = instantiator.lock().await; let update_block = inst.get_update_block(project_id, &UpdateType::CommunityFundingStart).unwrap(); - let community_start = update_block + 1u32.into(); + let community_start = update_block; let notify = Arc::new(Notify::new()); @@ -433,7 +434,7 @@ pub async fn async_start_remainder_or_end_funding< assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::CommunityRound); let update_block = inst.get_update_block(project_id, &UpdateType::RemainderFundingStart).unwrap(); - let remainder_start = update_block + 1u32.into(); + let remainder_start = update_block; let notify = Arc::new(Notify::new()); @@ -550,7 +551,9 @@ pub async fn async_finish_funding< let update_block = inst.get_update_block(project_id, &UpdateType::FundingEnd).unwrap(); let notify = Arc::new(Notify::new()); - block_orchestrator.add_awaiting_project(update_block + 1u32.into(), notify.clone()).await; + block_orchestrator.add_awaiting_project(update_block, notify.clone()).await; + drop(inst); + notify.notified().await; Ok(()) } @@ -768,7 +771,9 @@ pub async fn async_create_project_at< let time_to_community: BlockNumberFor = time_to_auction + ::AuctionOpeningDuration::get() + ::AuctionClosingDuration::get(); let time_to_remainder: BlockNumberFor = time_to_community + ::CommunityFundingDuration::get(); - let time_to_finish: BlockNumberFor = time_to_remainder + ::RemainderFundingDuration::get(); + let time_to_finish: BlockNumberFor = time_to_remainder + + ::RemainderFundingDuration::get() + + ::SuccessToSettlementTime::get(); let mut inst = mutex_inst.lock().await; let now = inst.current_block(); drop(inst); @@ -786,6 +791,7 @@ pub async fn async_create_project_at< block_orchestrator.add_awaiting_project(now + time_to_finish - time_to_evaluation, notify.clone()).await; // Wait for the notification that our desired block was reached to continue notify.notified().await; + let now = mutex_inst.lock().await.current_block(); async_create_evaluating_project( mutex_inst.clone(), test_project_params.metadata, diff --git a/pallets/funding/src/instantiator/chain_interactions.rs b/pallets/funding/src/instantiator/chain_interactions.rs index 9a38e5d9f..d0a70f8ec 100644 --- a/pallets/funding/src/instantiator/chain_interactions.rs +++ b/pallets/funding/src/instantiator/chain_interactions.rs @@ -165,6 +165,16 @@ impl< }) } + pub fn jump_to_block(&mut self, block: BlockNumberFor) { + let current_block = self.current_block(); + if block > current_block { + self.execute(|| frame_system::Pallet::::set_block_number(block - One::one())); + self.advance_time(One::one()).unwrap(); + } else { + panic!("Cannot jump to a block in the present or past") + } + } + pub fn do_free_plmc_assertions(&mut self, correct_funds: Vec>) { for UserToPLMCBalance { account, plmc_amount } in correct_funds { self.execute(|| { @@ -230,6 +240,10 @@ impl< pub fn test_ct_created_for(&mut self, project_id: ProjectId) { self.execute(|| { let metadata = ProjectsMetadata::::get(project_id).unwrap(); + assert!( + ::ContributionTokenCurrency::asset_exists(project_id), + "Asset should exist, since funding was successful" + ); assert_eq!( ::ContributionTokenCurrency::name(project_id), metadata.token_information.name.to_vec() @@ -430,10 +444,9 @@ impl< let project_details = self.get_project_details(project_id); if project_details.status == ProjectStatus::EvaluationRound { - let evaluation_end = project_details.phase_transition_points.evaluation.end().unwrap(); - let auction_start = evaluation_end.saturating_add(2u32.into()); - let blocks_to_start = auction_start.saturating_sub(self.current_block()); - self.advance_time(blocks_to_start + 1u32.into()).unwrap(); + let now = self.current_block(); + let evaluation_end_execution = self.get_update_block(project_id, &UpdateType::EvaluationEnd).unwrap(); + self.advance_time(evaluation_end_execution - now).unwrap(); }; assert_eq!(self.get_project_details(project_id).status, ProjectStatus::AuctionInitializePeriod); @@ -501,26 +514,14 @@ impl< } pub fn start_community_funding(&mut self, project_id: ProjectId) -> Result<(), DispatchError> { - let opening_end = self - .get_project_details(project_id) - .phase_transition_points - .auction_opening - .end() - .expect("Auction Opening end point should exist"); - - self.execute(|| frame_system::Pallet::::set_block_number(opening_end)); - // run on_initialize - self.advance_time(2u32.into()).unwrap(); - - let closing_end = self - .get_project_details(project_id) - .phase_transition_points - .auction_closing - .end() - .expect("closing end point should exist"); - - self.execute(|| frame_system::Pallet::::set_block_number(closing_end)); - // run on_initialize + if let Some(update_block) = self.get_update_block(project_id, &UpdateType::AuctionClosingStart) { + self.execute(|| frame_system::Pallet::::set_block_number(update_block - One::one())); + self.advance_time(1u32.into()).unwrap(); + } + let Some(update_block) = self.get_update_block(project_id, &UpdateType::CommunityFundingStart) else { + unreachable!() + }; + self.execute(|| frame_system::Pallet::::set_block_number(update_block - One::one())); self.advance_time(1u32.into()).unwrap(); ensure!( diff --git a/pallets/funding/src/mock.rs b/pallets/funding/src/mock.rs index 0bbc3b625..778dda116 100644 --- a/pallets/funding/src/mock.rs +++ b/pallets/funding/src/mock.rs @@ -290,14 +290,15 @@ pub const HOURS: BlockNumber = 300u64; // REMARK: In the production configuration we use DAYS instead of HOURS. parameter_types! { - pub const EvaluationDuration: BlockNumber = (28 * HOURS) as BlockNumber; - pub const AuctionInitializePeriodDuration: BlockNumber = (7 * HOURS) as BlockNumber; - pub const AuctionOpeningDuration: BlockNumber = (2 * HOURS) as BlockNumber; - pub const AuctionClosingDuration: BlockNumber = (3 * HOURS) as BlockNumber; - pub const CommunityRoundDuration: BlockNumber = (5 * HOURS) as BlockNumber; - pub const RemainderFundingDuration: BlockNumber = (1 * HOURS) as BlockNumber; - pub const ManualAcceptanceDuration: BlockNumber = (3 * HOURS) as BlockNumber; - pub const SuccessToSettlementTime: BlockNumber =(4 * HOURS) as BlockNumber; + pub const EvaluationDuration: BlockNumber = 3u64; + pub const AuctionInitializePeriodDuration: BlockNumber = 3u64; + pub const AuctionOpeningDuration: BlockNumber = 3u64; + pub const AuctionClosingDuration: BlockNumber = 3u64; + pub const CommunityRoundDuration: BlockNumber = 3u64; + pub const RemainderFundingDuration: BlockNumber = 3u64; + pub const ManualAcceptanceDuration: BlockNumber = 3u64; + pub const SuccessToSettlementTime: BlockNumber = 3u64; + pub const FundingPalletId: PalletId = PalletId(*b"py/cfund"); pub FeeBrackets: Vec<(Percent, Balance)> = vec![ (Percent::from_percent(10), 1_000_000 * USD_UNIT), diff --git a/pallets/funding/src/tests/2_evaluation.rs b/pallets/funding/src/tests/2_evaluation.rs index 60deb4d25..725e3fd79 100644 --- a/pallets/funding/src/tests/2_evaluation.rs +++ b/pallets/funding/src/tests/2_evaluation.rs @@ -305,8 +305,8 @@ mod start_evaluation_extrinsic { phase_transition_points: PhaseTransitionPoints { application: BlockNumberPair { start: Some(1u64), end: Some(1u64) }, evaluation: BlockNumberPair { - start: Some(2u64), - end: Some(1u64 + ::EvaluationDuration::get()), + start: Some(1u64), + end: Some(::EvaluationDuration::get()), }, auction_initialize_period: BlockNumberPair { start: None, end: None }, auction_opening: BlockNumberPair { start: None, end: None }, diff --git a/pallets/funding/src/tests/3_auction.rs b/pallets/funding/src/tests/3_auction.rs index cad40ae2e..6319bcf32 100644 --- a/pallets/funding/src/tests/3_auction.rs +++ b/pallets/funding/src/tests/3_auction.rs @@ -722,10 +722,14 @@ mod start_auction_extrinsic { inst.mint_plmc_to(required_plmc); inst.mint_plmc_to(ed_plmc); inst.evaluate_for_users(project_id, evaluations).unwrap(); - inst.advance_time(::EvaluationDuration::get() + 1).unwrap(); - assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::AuctionInitializePeriod); - inst.advance_time(::AuctionInitializePeriodDuration::get() + 2).unwrap(); - assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::AuctionOpening); + + let update_block = inst.get_update_block(project_id, &UpdateType::EvaluationEnd).unwrap(); + inst.execute(|| System::set_block_number(update_block - 1)); + inst.advance_time(1).unwrap(); + + let update_block = inst.get_update_block(project_id, &UpdateType::AuctionOpeningStart).unwrap(); + inst.execute(|| System::set_block_number(update_block - 1)); + inst.advance_time(1).unwrap(); } #[test] @@ -809,15 +813,15 @@ mod start_auction_extrinsic { inst.mint_plmc_to(required_plmc); inst.mint_plmc_to(ed_plmc); inst.evaluate_for_users(project_id, evaluations).unwrap(); - inst.advance_time(::EvaluationDuration::get() + 1).unwrap(); - inst.advance_time(::AuctionInitializePeriodDuration::get() + 2).unwrap(); - assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::AuctionOpening); + inst.start_auction(project_id, ISSUER_1).unwrap(); // Main test with failed evaluation let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); let project_id = inst.create_evaluating_project(default_project_metadata(ISSUER_1), ISSUER_1); - inst.advance_time(::EvaluationDuration::get() + 1).unwrap(); - inst.advance_time(::AuctionInitializePeriodDuration::get() + 2).unwrap(); + + let evaluation_end_execution = inst.get_update_block(project_id, &UpdateType::EvaluationEnd).unwrap(); + inst.execute(|| System::set_block_number(evaluation_end_execution - 1)); + inst.advance_time(1).unwrap(); assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::FundingFailed); } } diff --git a/pallets/funding/src/tests/4_community.rs b/pallets/funding/src/tests/4_community.rs index 7a5d9cbc7..5111d6f5b 100644 --- a/pallets/funding/src/tests/4_community.rs +++ b/pallets/funding/src/tests/4_community.rs @@ -760,7 +760,7 @@ mod community_contribute_extrinsic { inst.bid_for_users(project_id, successful_bids).unwrap(); inst.advance_time( ::AuctionOpeningDuration::get() + - ::AuctionClosingDuration::get() + + ::AuctionClosingDuration::get() - 1, ) .unwrap(); diff --git a/pallets/funding/src/tests/6_funding_end.rs b/pallets/funding/src/tests/6_funding_end.rs index d7a294d89..430218b79 100644 --- a/pallets/funding/src/tests/6_funding_end.rs +++ b/pallets/funding/src/tests/6_funding_end.rs @@ -56,6 +56,7 @@ fn automatic_acceptance_on_manual_decision_after_time_delta() { let project_id = project_id; inst.advance_time(1u64 + ::ManualAcceptanceDuration::get()).unwrap(); assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::FundingSuccessful); + dbg!(inst.get_project_details(project_id)); inst.advance_time(::SuccessToSettlementTime::get()).unwrap(); inst.test_ct_created_for(project_id); diff --git a/pallets/funding/src/tests/misc.rs b/pallets/funding/src/tests/misc.rs index e0d1fe702..f8263b7cf 100644 --- a/pallets/funding/src/tests/misc.rs +++ b/pallets/funding/src/tests/misc.rs @@ -412,6 +412,7 @@ mod async_tests { ]; let (project_ids, mut inst) = create_multiple_projects_at(inst, project_params); + let now = inst.current_block(); dbg!(inst.get_project_details(project_ids[0]).status); dbg!(inst.get_project_details(project_ids[1]).status); @@ -555,12 +556,12 @@ mod async_tests { dbg!(inst.get_project_details(4).status); dbg!(inst.get_project_details(5).status); - assert_eq!(inst.get_project_details(5).status, ProjectStatus::Application); - assert_eq!(inst.get_project_details(4).status, ProjectStatus::EvaluationRound); - assert_eq!(inst.get_project_details(3).status, ProjectStatus::AuctionOpening); - assert_eq!(inst.get_project_details(2).status, ProjectStatus::CommunityRound); - assert_eq!(inst.get_project_details(1).status, ProjectStatus::RemainderRound); assert_eq!(inst.get_project_details(0).status, ProjectStatus::FundingSuccessful); + assert_eq!(inst.get_project_details(1).status, ProjectStatus::RemainderRound); + assert_eq!(inst.get_project_details(2).status, ProjectStatus::CommunityRound); + assert_eq!(inst.get_project_details(3).status, ProjectStatus::AuctionOpening); + assert_eq!(inst.get_project_details(4).status, ProjectStatus::EvaluationRound); + assert_eq!(inst.get_project_details(5).status, ProjectStatus::Application); } #[test] @@ -634,75 +635,3 @@ mod async_tests { assert_eq!(total_bids_count, max_bids_per_project as usize); } } - -// Bug hunting -mod bug_hunting { - use super::*; - - #[test] - // Check that a failed do_function in on_initialize doesn't change the storage - fn transactional_on_initialize() { - let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); - let max_projects_per_update_block: u32 = ::MaxProjectsToUpdatePerBlock::get(); - // This bug will more likely happen with a limit of 1 - assert_eq!(max_projects_per_update_block, 1u32); - let max_insertion_attempts: u32 = ::MaxProjectsToUpdateInsertionAttempts::get(); - - let project_id = inst.create_evaluating_project(default_project_metadata(ISSUER_1), ISSUER_1); - let plmc_balances = inst.calculate_evaluation_plmc_spent(default_evaluations()); - let ed = plmc_balances.accounts().existential_deposits(); - inst.mint_plmc_to(plmc_balances); - inst.mint_plmc_to(ed); - inst.evaluate_for_users(project_id, default_evaluations()).unwrap(); - let update_block = inst.get_update_block(project_id, &UpdateType::EvaluationEnd).unwrap(); - inst.execute(|| frame_system::Pallet::::set_block_number(update_block - 1)); - let now = inst.current_block(); - - let auction_initialize_period_start_block = now + 2u64; - let auction_initialize_period_end_block = - auction_initialize_period_start_block + ::AuctionInitializePeriodDuration::get(); - let automatic_auction_start = auction_initialize_period_end_block + 1u64; - for i in 0..max_insertion_attempts { - let key: BlockNumberFor = automatic_auction_start + i as u64; - let val: (ProjectId, UpdateType) = (69u32, UpdateType::EvaluationEnd); - inst.execute(|| crate::ProjectsToUpdate::::insert(key, val)); - } - - let old_project_details = inst.get_project_details(project_id); - inst.advance_time(1).unwrap(); - - let new_project_details = inst.get_project_details(project_id); - assert_eq!(old_project_details, new_project_details); - } - - // This shows us that "plausible" combination of ct decimals and ct price can lead to unrepresentable usd cents - #[test] - fn price_too_low_for_usd_conversion_1() { - let ct_decimals = 4u8; - let original_price = FixedU128::from_float(1000f64); - let decimal_aware_price = ::PriceProvider::calculate_decimals_aware_price( - original_price, - USD_DECIMALS, - ct_decimals, - ) - .unwrap(); - - let usd_cent = USD_UNIT / 100; - let cent_in_ct = decimal_aware_price.reciprocal().unwrap().checked_mul_int(usd_cent).unwrap(); - assert_eq!(cent_in_ct, 0u128); - } - - // This shows us that even using the lowest possible price with FixedU128, we can still represent 1bn USD - #[test] - fn billion_saturating() { - let decimal_aware_price = FixedU128::from_inner(1u128); - dbg!(decimal_aware_price); - - let usd_billion = USD_UNIT * 1_000_000_000; - let billion_in_ct = decimal_aware_price.reciprocal().unwrap().checked_mul_int(usd_billion).unwrap(); - dbg!(billion_in_ct); - dbg!(billion_in_ct.checked_ilog10()); - dbg!(u128::MAX); - dbg!(u128::MAX.checked_ilog10()); - } -} diff --git a/pallets/funding/src/tests/mod.rs b/pallets/funding/src/tests/mod.rs index 5ded52d14..6caf0318f 100644 --- a/pallets/funding/src/tests/mod.rs +++ b/pallets/funding/src/tests/mod.rs @@ -398,6 +398,10 @@ pub fn create_project_with_funding_percentage( assert!(maybe_decision.is_some()); inst.execute(|| PolimecFunding::do_decide_project_outcome(ISSUER_1, project_id, maybe_decision.unwrap())) .unwrap(); + + let decision_execution = + inst.get_update_block(project_id, &UpdateType::ProjectDecision(maybe_decision.unwrap())).unwrap(); + inst.jump_to_block(decision_execution); }, ProjectStatus::FundingSuccessful => { assert!(percentage >= 90); @@ -408,7 +412,9 @@ pub fn create_project_with_funding_percentage( _ => panic!("unexpected project status"), }; - inst.advance_time(::SuccessToSettlementTime::get() + 1u64).unwrap(); + let settlement_execution = inst.get_update_block(project_id, &UpdateType::StartSettlement).unwrap(); + inst.jump_to_block(settlement_execution); + let funding_sucessful = match percentage { 0..=33 => false, 34..=89 if matches!(maybe_decision, Some(FundingOutcomeDecision::RejectFunding)) => false, @@ -426,6 +432,3 @@ pub fn create_project_with_funding_percentage( } (inst, project_id) } - -// 0xa1151597e1a929babe1dcfc6bc3b90e7f931af4d91f609b105333247ba08ab32 -// 0xa1151597e1a929babe1dcfc6bc3b90e718001f24b6aa0f335e9ef0f5d75a9695