diff --git a/custom-pallets/positive-externality/src/lib.rs b/custom-pallets/positive-externality/src/lib.rs index d172e90..1281738 100644 --- a/custom-pallets/positive-externality/src/lib.rs +++ b/custom-pallets/positive-externality/src/lib.rs @@ -267,10 +267,10 @@ pub mod pallet { let three_month_block = Self::u64_to_block_saturated(three_month_number); let modulus = now % three_month_block; let storage_main_block = now - modulus; - // println!("{:?}", now); - // println!("{:?}", three_month_number); - // println!("{:?}", storage_main_block); - // println!("{:?}", pe_block_number); + // println!("now: {:?}", now); + // println!("three month number{:?}", three_month_number); + // println!("storage main block {:?}", storage_main_block); + // println!("pe block number {:?}", pe_block_number); let key = SumTreeName::PositiveExternality { user_address: user_to_calculate.clone(), @@ -423,8 +423,27 @@ pub mod pallet { T::SchellingGameSharedSource::reveal_vote_score_helper_link(key, who, choice, salt)?; Ok(()) } + #[pallet::call_index(9)] #[pallet::weight(0)] + pub fn set_new_mean_value( + origin: OriginFor, + user_to_calculate: T::AccountId, + ) -> DispatchResult { + let _= ensure_signed(origin)?; + let pe_block_number = >::get(user_to_calculate.clone()); + + let key = SumTreeName::PositiveExternality { + user_address: user_to_calculate, + block_number: pe_block_number.clone(), + }; + + T::SchellingGameSharedSource::set_new_mean_value(key)?; + Ok(()) + } + + #[pallet::call_index(10)] + #[pallet::weight(0)] pub fn release_positive_externality_fund( origin: OriginFor, user_to_calculate: T::AccountId, @@ -466,7 +485,7 @@ pub mod pallet { Ok(()) } - #[pallet::call_index(10)] + #[pallet::call_index(11)] #[pallet::weight(0)] pub fn add_incentive_count( origin: OriginFor, @@ -535,7 +554,7 @@ pub mod pallet { // Provide incentives - #[pallet::call_index(11)] + #[pallet::call_index(12)] #[pallet::weight(0)] pub fn get_incentives(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; diff --git a/custom-pallets/positive-externality/src/tests.rs b/custom-pallets/positive-externality/src/tests.rs index 7d402a3..375a4e1 100644 --- a/custom-pallets/positive-externality/src/tests.rs +++ b/custom-pallets/positive-externality/src/tests.rs @@ -1,6 +1,10 @@ +use crate::types::Incentives; use crate::types::Post; use crate::{mock::*, Error, Event}; use frame_support::{assert_noop, assert_ok}; +use pallet_schelling_game_shared::types::Period; +use pallet_sortition_sum_game::types::SumTreeName; +use pallet_support::WhenDetails; use pallet_support::{Content, WhoAndWhen}; #[test] @@ -341,3 +345,583 @@ fn test_commit_and_incentives_vote() { // assert_ok!(TemplateModule::get_incentives(RuntimeOrigin::signed(4), 1)); }) } + +// Play two schelling game to check incentives are updated + +fn full_schelling_game_func(user_to_calculate: u64, start_block_number: u64) { + assert_ok!(TemplateModule::set_validate_positive_externality( + RuntimeOrigin::signed(1), + true + )); + System::set_block_number(start_block_number); + assert_ok!(TemplateModule::apply_staking_period( + RuntimeOrigin::signed(2), + user_to_calculate + )); + + let phase_data = TemplateModule::get_phase_data(); + + for j in 4..30 { + assert_ok!(TemplateModule::apply_jurors( + RuntimeOrigin::signed(j), + user_to_calculate, + j * 100 + )); + } + + assert_noop!( + TemplateModule::draw_jurors(RuntimeOrigin::signed(5), user_to_calculate, 5), + >::PeriodDontMatch + ); + + assert_noop!( + TemplateModule::pass_period(RuntimeOrigin::signed(5), user_to_calculate), + >::StakingPeriodNotOver + ); + + System::set_block_number(start_block_number + phase_data.staking_length); + + assert_ok!(TemplateModule::pass_period( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + assert_ok!(TemplateModule::draw_jurors( + RuntimeOrigin::signed(5), + user_to_calculate, + 5 + )); + + let block_number = TemplateModule::validation_block(user_to_calculate); + + let key = SumTreeName::PositiveExternality { + user_address: user_to_calculate, + block_number: block_number, + }; + + let draws_in_round = SchellingGameShared::draws_in_round(key.clone()); + assert_eq!(5, draws_in_round); + + let drawn_jurors = SchellingGameShared::drawn_jurors(key.clone()); + assert_eq!( + vec![(4, 400), (7, 700), (13, 1300), (14, 1400), (15, 1500)], + drawn_jurors + ); + + assert_ok!(TemplateModule::pass_period( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + let period = SchellingGameShared::get_period(key.clone()); + + assert_eq!(Some(Period::Commit), period); + + assert_ok!(TemplateModule::unstaking( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + let hash = sp_io::hashing::keccak_256("1salt".as_bytes()); + assert_noop!( + TemplateModule::commit_vote(RuntimeOrigin::signed(6), user_to_calculate, hash), + >::JurorDoesNotExists + ); + let hash = sp_io::hashing::keccak_256("1salt".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(4), + user_to_calculate, + hash + )); + + // You can replace vote within the commit period. + let hash = sp_io::hashing::keccak_256("1salt2".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(4), + user_to_calculate, + hash + )); + + let hash = sp_io::hashing::keccak_256("1salt3".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(7), + user_to_calculate, + hash + )); + + let hash = sp_io::hashing::keccak_256("1salt4".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(13), + user_to_calculate, + hash + )); + + let hash = sp_io::hashing::keccak_256("1salt5".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(14), + user_to_calculate, + hash + )); + + let hash = sp_io::hashing::keccak_256("3salt6".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(15), + user_to_calculate, + hash + )); + + assert_noop!( + TemplateModule::pass_period(RuntimeOrigin::signed(5), user_to_calculate), + >::CommitPeriodNotOver + ); + System::set_block_number( + phase_data.evidence_length + + start_block_number + + phase_data.staking_length + + phase_data.commit_length, + ); + assert_ok!(TemplateModule::pass_period( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + assert_noop!( + TemplateModule::reveal_vote( + RuntimeOrigin::signed(4), + user_to_calculate, + 2, + "salt2".as_bytes().to_vec() + ), + >::CommitDoesNotMatch + ); + + assert_ok!(TemplateModule::reveal_vote( + RuntimeOrigin::signed(4), + user_to_calculate, + 1, + "salt2".as_bytes().to_vec() + )); + + assert_ok!(TemplateModule::reveal_vote( + RuntimeOrigin::signed(7), + user_to_calculate, + 1, + "salt3".as_bytes().to_vec() + )); + + assert_ok!(TemplateModule::reveal_vote( + RuntimeOrigin::signed(14), + user_to_calculate, + 1, + "salt5".as_bytes().to_vec() + )); + + assert_ok!(TemplateModule::reveal_vote( + RuntimeOrigin::signed(15), + user_to_calculate, + 3, + "salt6".as_bytes().to_vec() + )); + + assert_noop!( + TemplateModule::pass_period(RuntimeOrigin::signed(5), user_to_calculate), + >::VotePeriodNotOver + ); + System::set_block_number( + phase_data.evidence_length + + start_block_number + + phase_data.staking_length + + phase_data.commit_length + + phase_data.vote_length, + ); + assert_ok!(TemplateModule::pass_period( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + assert_ok!(TemplateModule::set_new_mean_value( + RuntimeOrigin::signed(13), + user_to_calculate + )); + + assert_noop!( + TemplateModule::add_incentive_count(RuntimeOrigin::signed(13), user_to_calculate), + >::VoteNotRevealed + ); + assert_ok!(TemplateModule::add_incentive_count( + RuntimeOrigin::signed(14), + user_to_calculate + )); + assert_ok!(TemplateModule::add_incentive_count( + RuntimeOrigin::signed(15), + user_to_calculate + )); +} + +fn full_schelling_game_func2(user_to_calculate: u64, start_block_number: u64) { + + assert_ok!(TemplateModule::set_validate_positive_externality( + RuntimeOrigin::signed(1), + true + )); + System::set_block_number(start_block_number); + assert_ok!(TemplateModule::apply_staking_period( + RuntimeOrigin::signed(2), + user_to_calculate + )); + + let phase_data = TemplateModule::get_phase_data(); + + for j in 4..30 { + assert_ok!(TemplateModule::apply_jurors( + RuntimeOrigin::signed(j), + user_to_calculate, + j * 100 + )); + } + + assert_noop!( + TemplateModule::draw_jurors(RuntimeOrigin::signed(5), user_to_calculate, 5), + >::PeriodDontMatch + ); + + assert_noop!( + TemplateModule::pass_period(RuntimeOrigin::signed(5), user_to_calculate), + >::StakingPeriodNotOver + ); + + System::set_block_number(start_block_number + phase_data.staking_length); + + assert_ok!(TemplateModule::pass_period( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + assert_ok!(TemplateModule::draw_jurors( + RuntimeOrigin::signed(5), + user_to_calculate, + 5 + )); + let block_number = TemplateModule::validation_block(user_to_calculate); + + let key = SumTreeName::PositiveExternality { + user_address: user_to_calculate, + block_number: block_number, + }; + + let draws_in_round = SchellingGameShared::draws_in_round(key.clone()); + // println!("Draws in round{draws_in_round}"); + assert_eq!(5, draws_in_round); + + let drawn_jurors = SchellingGameShared::drawn_jurors(key.clone()); + assert_eq!( + vec![(4, 400), (7, 700), (13, 1300), (14, 1400), (15, 1500)], + drawn_jurors + ); + + assert_ok!(TemplateModule::pass_period( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + let period = SchellingGameShared::get_period(key.clone()); + + assert_eq!(Some(Period::Commit), period); + + assert_ok!(TemplateModule::unstaking( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + let hash = sp_io::hashing::keccak_256("1salt".as_bytes()); + assert_noop!( + TemplateModule::commit_vote(RuntimeOrigin::signed(6), user_to_calculate, hash), + >::JurorDoesNotExists + ); + let hash = sp_io::hashing::keccak_256("1salt".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(4), + user_to_calculate, + hash + )); + + // You can replace vote within the commit period. + let hash = sp_io::hashing::keccak_256("1salt2".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(4), + user_to_calculate, + hash + )); + + let hash = sp_io::hashing::keccak_256("1salt3".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(7), + user_to_calculate, + hash + )); + + let hash = sp_io::hashing::keccak_256("1salt4".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(13), + user_to_calculate, + hash + )); + + let hash = sp_io::hashing::keccak_256("3salt5".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(14), + user_to_calculate, + hash + )); + + let hash = sp_io::hashing::keccak_256("1salt6".as_bytes()); + assert_ok!(TemplateModule::commit_vote( + RuntimeOrigin::signed(15), + user_to_calculate, + hash + )); + + assert_noop!( + TemplateModule::pass_period(RuntimeOrigin::signed(5), user_to_calculate), + >::CommitPeriodNotOver + ); + System::set_block_number( + phase_data.evidence_length + + start_block_number + + phase_data.staking_length + + phase_data.commit_length, + ); + assert_ok!(TemplateModule::pass_period( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + assert_noop!( + TemplateModule::reveal_vote( + RuntimeOrigin::signed(4), + user_to_calculate, + 2, + "salt2".as_bytes().to_vec() + ), + >::CommitDoesNotMatch + ); + + assert_ok!(TemplateModule::reveal_vote( + RuntimeOrigin::signed(4), + user_to_calculate, + 1, + "salt2".as_bytes().to_vec() + )); + + assert_ok!(TemplateModule::reveal_vote( + RuntimeOrigin::signed(7), + user_to_calculate, + 1, + "salt3".as_bytes().to_vec() + )); + + assert_ok!(TemplateModule::reveal_vote( + RuntimeOrigin::signed(14), + user_to_calculate, + 3, + "salt5".as_bytes().to_vec() + )); + + assert_ok!(TemplateModule::reveal_vote( + RuntimeOrigin::signed(15), + user_to_calculate, + 1, + "salt6".as_bytes().to_vec() + )); + + assert_noop!( + TemplateModule::pass_period(RuntimeOrigin::signed(5), user_to_calculate), + >::VotePeriodNotOver + ); + System::set_block_number( + phase_data.evidence_length + + start_block_number + + phase_data.staking_length + + phase_data.commit_length + + phase_data.vote_length, + ); + assert_ok!(TemplateModule::pass_period( + RuntimeOrigin::signed(5), + user_to_calculate + )); + + assert_ok!(TemplateModule::set_new_mean_value( + RuntimeOrigin::signed(13), + user_to_calculate + )); + + assert_noop!( + TemplateModule::add_incentive_count(RuntimeOrigin::signed(13), user_to_calculate), + >::VoteNotRevealed + ); + assert_ok!(TemplateModule::add_incentive_count( + RuntimeOrigin::signed(14), + user_to_calculate + )); + assert_ok!(TemplateModule::add_incentive_count( + RuntimeOrigin::signed(15), + user_to_calculate + )); +} + +#[test] +fn schelling_game_incentives_get_test() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + + let startblock1 = 1 * (3 * 30 * 24 * 60 * 60) / 6; + + let startblock2 = 2 * (3 * 30 * 24 * 60 * 60) / 6; + + let startblock3 = 3 * (3 * 30 * 24 * 60 * 60) / 6; + + let startblock4 = 4 * (3 * 30 * 24 * 60 * 60) / 6; + + + + full_schelling_game_func(2, 1); + full_schelling_game_func(3, startblock1); + + let incentive_count = TemplateModule::incentives_count(14).unwrap(); + + let incentive_count_eq: Incentives = Incentives { + number_of_games: 2, + winner: 2, + loser: 0, + total_stake: 14 * 100 + 14 * 100, + start: WhenDetails { + block: 201, + time: 0, + }, + }; + + assert_eq!(incentive_count, incentive_count_eq); + // println!("{:?}", incentive_count); + + let incentive_count = TemplateModule::incentives_count(15).unwrap(); + + // println!("{:?}", incentive_count); + + let incentive_count_eq: Incentives = Incentives { + number_of_games: 2, + winner: 0, + loser: 2, + total_stake: 15 * 100 + 15 * 100, + start: WhenDetails { + block: 201, + time: 0, + }, + }; + + assert_eq!(incentive_count, incentive_count_eq); + + // draw twenty schelling game + // use 14 and 15, increase both loser and winner count. + + assert_noop!( + TemplateModule::get_incentives(RuntimeOrigin::signed(15)), + Error::::NotReachedMinimumDecision + ); + + + full_schelling_game_func2(4, startblock2); + + + full_schelling_game_func2(5, startblock3); + + let incentive_count = TemplateModule::incentives_count(14).unwrap(); + + // println!("incentive count:{:?}", incentive_count); + + let incentive_count_eq: Incentives = Incentives { + number_of_games: 4, + winner: 2, + loser: 2, + total_stake: 14 * 100 + 14 * 100 + 14 * 100 + 14 * 100, + start: WhenDetails { + block: 201, + time: 0, + }, + }; + + assert_eq!(incentive_count, incentive_count_eq); + + let incentive_count = TemplateModule::incentives_count(15).unwrap(); + + // println!("{:?}", incentive_count); + + let incentive_count_eq: Incentives = Incentives { + number_of_games: 4, + winner: 2, + loser: 2, + total_stake: 15 * 100 + 15 * 100 + 15 * 100 + 15 * 100, + start: WhenDetails { + block: 201, + time: 0, + }, + }; + + assert_eq!(incentive_count, incentive_count_eq); + for x in 4..20 { + System::set_block_number(x * startblock4); + full_schelling_game_func(x, x * startblock4); + } + + let incentive_count = TemplateModule::incentives_count(14).unwrap(); + + let incentive_count_eq: Incentives = Incentives { + number_of_games: 20, + winner: 18, + loser: 2, + total_stake: 14 * 100 * 20, + start: WhenDetails { + block: 201, + time: 0, + }, + }; + + assert_eq!(incentive_count, incentive_count_eq); + // println!("incentive count:{:?}", incentive_count); + + let balance = Balances::free_balance(14); + + // println!("balance account before(14):{:?}", balance); + + assert_ok!(TemplateModule::get_incentives(RuntimeOrigin::signed(14))); + + let balance = Balances::free_balance(14); + + // println!("balance account after(14):{:?}", balance); + + let incentive_count = TemplateModule::incentives_count(15).unwrap(); + + let incentive_count_eq: Incentives = Incentives { + number_of_games: 20, + winner: 2, + loser: 18, + total_stake: 15 * 100 * 20, + start: WhenDetails { + block: 201, + time: 0, + }, + }; + + assert_eq!(incentive_count, incentive_count_eq); + // println!("incentive count:{:?}", incentive_count); + + let balance = Balances::free_balance(15); + + // println!("balance account before(15):{:?}", balance); + + assert_ok!(TemplateModule::get_incentives(RuntimeOrigin::signed(15))); + + let balance = Balances::free_balance(15); + + // println!("balance account after(15):{:?}", balance); + }) +} diff --git a/custom-pallets/schelling-game-shared/src/score_game.rs b/custom-pallets/schelling-game-shared/src/score_game.rs index a33c45c..2db0a77 100644 --- a/custom-pallets/schelling-game-shared/src/score_game.rs +++ b/custom-pallets/schelling-game-shared/src/score_game.rs @@ -214,6 +214,12 @@ impl Pallet { } pub(super) fn set_new_mean_value(key: SumTreeNameType) -> DispatchResult { + match >::get(&key) { + Some(period) => { + ensure!(period == Period::Execution, Error::::PeriodDontMatch); + } + None => Err(Error::::PeriodDoesNotExists)?, + } let reveal_values = >::get(&key); let sd_and_mean = Self::std_deviation_interger(&reveal_values); let new_mean = Self::calculate_new_mean(&reveal_values, sd_and_mean).unwrap();