diff --git a/pallets/distance/src/lib.rs b/pallets/distance/src/lib.rs index 4860ff4b4f9e9b9a25a1bc0016500021200559dd..c39aa02ff0b6b0253c21b290fb631dfddc5f3942 100644 --- a/pallets/distance/src/lib.rs +++ b/pallets/distance/src/lib.rs @@ -35,9 +35,11 @@ pub use types::*; pub use weights::WeightInfo; use frame_support::traits::StorageVersion; -use pallet_authority_members::SessionIndex; use sp_distance::{InherentError, INHERENT_IDENTIFIER}; use sp_inherents::{InherentData, InherentIdentifier}; +use sp_runtime::traits::One; +use sp_runtime::traits::Zero; +use sp_runtime::Saturating; use sp_std::convert::TryInto; use sp_std::prelude::*; @@ -67,7 +69,6 @@ pub mod pallet { frame_system::Config + pallet_authorship::Config + pallet_identity::Config<IdtyIndex = IdtyIndex> - + pallet_session::Config { /// Currency type used in this pallet (used for reserve/slash) type Currency: ReservableCurrency<Self::AccountId>; @@ -76,6 +77,11 @@ pub mod pallet { type EvaluationPrice: Get< <Self::Currency as frame_support::traits::Currency<Self::AccountId>>::Balance, >; + /// Evaluation period in block numbers. + /// As the evaluation is done using 3 pools, + /// the evaluation will take 3 * EvaluationPeriod. + #[pallet::constant] + type EvaluationPeriod: Get<u32>; /// Maximum distance used to define referee's accessibility /// Unused by runtime but needed by client distance oracle #[pallet::constant] @@ -152,6 +158,10 @@ pub mod pallet { #[pallet::storage] pub(super) type DidUpdate<T: Config> = StorageValue<_, bool, ValueQuery>; + /// Current evaluation pool. + #[pallet::storage] + pub(super) type CurrentPoolIndex<T: Config> = StorageValue<_, u32, ValueQuery>; + // session_index % 3: // storage_id + 0 => pending // storage_id + 1 => receives results @@ -207,16 +217,20 @@ pub mod pallet { #[pallet::hooks] impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> { - /// dummy `on_initialize` to return the weight used in `on_finalize`. - fn on_initialize(_n: BlockNumberFor<T>) -> Weight { - // weight of `on_finalize` + fn on_initialize(block: BlockNumberFor<T>) -> Weight + where + BlockNumberFor<T>: From<u32>, + { + if block % BlockNumberFor::<T>::one().saturating_mul(T::EvaluationPeriod::get().into()) + == BlockNumberFor::<T>::zero() + { + let index = (CurrentPoolIndex::<T>::get() + 1) % 3; + CurrentPoolIndex::<T>::put(index); + Self::do_evaluation(index); + } <T as pallet::Config>::WeightInfo::on_finalize() } - /// # <weight> - /// - `O(1)` - /// - 1 storage deletion (codec `O(1)`). - /// # </weight> fn on_finalize(_n: BlockNumberFor<T>) { DidUpdate::<T>::take(); } @@ -322,10 +336,10 @@ pub mod pallet { >, ) -> R, >( - index: SessionIndex, + index: u32, f: F, ) -> R { - match index % 3 { + match index { 0 => EvaluationPool2::<T>::mutate(f), 1 => EvaluationPool0::<T>::mutate(f), 2 => EvaluationPool1::<T>::mutate(f), @@ -343,10 +357,10 @@ pub mod pallet { >, ) -> R, >( - index: SessionIndex, + index: u32, f: F, ) -> R { - match index % 3 { + match index { 0 => EvaluationPool0::<T>::mutate(f), 1 => EvaluationPool1::<T>::mutate(f), 2 => EvaluationPool2::<T>::mutate(f), @@ -359,12 +373,12 @@ pub mod pallet { /// * when this session ends: the evaluation requests #[allow(clippy::type_complexity)] fn take_current_pool( - index: SessionIndex, + index: u32, ) -> EvaluationPool< <T as frame_system::Config>::AccountId, <T as pallet_identity::Config>::IdtyIndex, > { - match index % 3 { + match index { 0 => EvaluationPool2::<T>::take(), 1 => EvaluationPool0::<T>::take(), 2 => EvaluationPool1::<T>::take(), @@ -439,31 +453,28 @@ pub mod pallet { who: &T::AccountId, idty_index: <T as pallet_identity::Config>::IdtyIndex, ) -> Result<(), DispatchError> { - Pallet::<T>::mutate_current_pool( - pallet_session::CurrentIndex::<T>::get(), - |current_pool| { - // extrinsics are transactional by default, this check might not be needed - ensure!( - current_pool.evaluations.len() < (MAX_EVALUATIONS_PER_SESSION as usize), - Error::<T>::QueueFull - ); - - T::Currency::reserve(who, <T as Config>::EvaluationPrice::get())?; - - current_pool - .evaluations - .try_push((idty_index, median::MedianAcc::new())) - .map_err(|_| Error::<T>::QueueFull)?; - - PendingEvaluationRequest::<T>::insert(idty_index, who); - - Self::deposit_event(Event::EvaluationRequested { - idty_index, - who: who.clone(), - }); - Ok(()) - }, - ) + Pallet::<T>::mutate_current_pool(CurrentPoolIndex::<T>::get(), |current_pool| { + // extrinsics are transactional by default, this check might not be needed + ensure!( + current_pool.evaluations.len() < (MAX_EVALUATIONS_PER_SESSION as usize), + Error::<T>::QueueFull + ); + + T::Currency::reserve(who, <T as Config>::EvaluationPrice::get())?; + + current_pool + .evaluations + .try_push((idty_index, median::MedianAcc::new())) + .map_err(|_| Error::<T>::QueueFull)?; + + PendingEvaluationRequest::<T>::insert(idty_index, who); + + Self::deposit_event(Event::EvaluationRequested { + idty_index, + who: who.clone(), + }); + Ok(()) + }) } /// update distance evaluation in next pool @@ -471,7 +482,7 @@ pub mod pallet { evaluator: <T as frame_system::Config>::AccountId, computation_result: ComputationResult, ) -> DispatchResult { - Pallet::<T>::mutate_next_pool(pallet_session::CurrentIndex::<T>::get(), |result_pool| { + Pallet::<T>::mutate_next_pool(CurrentPoolIndex::<T>::get(), |result_pool| { // evaluation must be provided for all identities (no more, no less) ensure!( computation_result.distances.len() == result_pool.evaluations.len(), @@ -507,10 +518,8 @@ pub mod pallet { // deposit event Self::deposit_event(Event::EvaluatedValid { idty_index: idty }); } - } - impl<T: Config> pallet_authority_members::OnNewSession for Pallet<T> { - fn on_new_session(index: SessionIndex) { + fn do_evaluation(index: u32) { // set evaluation block EvaluationBlock::<T>::set(frame_system::Pallet::<T>::parent_hash()); diff --git a/pallets/distance/src/mock.rs b/pallets/distance/src/mock.rs index 5c668052944ea5b087838dd2a3ac89ca0f0225e8..b880b29cf7b72b1ff528722614d909bbae8e9904 100644 --- a/pallets/distance/src/mock.rs +++ b/pallets/distance/src/mock.rs @@ -250,6 +250,7 @@ parameter_types! { impl pallet_distance::Config for Test { type CheckRequestDistanceEvaluation = (); type Currency = Balances; + type EvaluationPeriod = frame_support::traits::ConstU32<300>; type EvaluationPrice = frame_support::traits::ConstU64<1000>; type MaxRefereeDistance = frame_support::traits::ConstU32<5>; type MinAccessibleReferees = MinAccessibleReferees; diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs index f72a59a3c07ab8d00afa533227061c66ad4972ca..35d8b8712d44c0897f47ff36e58dbb02178436f2 100644 --- a/runtime/common/src/handlers.rs +++ b/runtime/common/src/handlers.rs @@ -24,12 +24,10 @@ use pallet_smith_members::SmithRemovalReason; pub struct OnNewSessionHandler<Runtime>(core::marker::PhantomData<Runtime>); impl<Runtime> pallet_authority_members::traits::OnNewSession for OnNewSessionHandler<Runtime> where - Runtime: - pallet_provide_randomness::Config + pallet_distance::Config + pallet_smith_members::Config, + Runtime: pallet_provide_randomness::Config + pallet_smith_members::Config, { fn on_new_session(index: sp_staking::SessionIndex) { pallet_provide_randomness::Pallet::<Runtime>::on_new_epoch(); - pallet_distance::Pallet::<Runtime>::on_new_session(index); pallet_smith_members::Pallet::<Runtime>::on_new_session(index); } } diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs index 154025005a22b4cc253da54c9251c3bd472fa3fb..8498f797f8b306b35b55670ff80512d2b3333c7d 100644 --- a/runtime/common/src/pallets_config.rs +++ b/runtime/common/src/pallets_config.rs @@ -524,6 +524,7 @@ type RuntimeFreezeReason = (); } impl pallet_distance::Config for Runtime { type Currency = Balances; + type EvaluationPeriod = frame_support::traits::ConstU32<25>; type EvaluationPrice = frame_support::traits::ConstU64<1000>; type MaxRefereeDistance = frame_support::traits::ConstU32<5>; type MinAccessibleReferees = MinAccessibleReferees; diff --git a/runtime/gdev/tests/integration_tests.rs b/runtime/gdev/tests/integration_tests.rs index 3864d3a012d39f363b9c8c0b42c2b5279672804b..0cfb9ee2886a5ae843ddaf5ddaa8fe66c2b65b8e 100644 --- a/runtime/gdev/tests/integration_tests.rs +++ b/runtime/gdev/tests/integration_tests.rs @@ -614,7 +614,7 @@ fn test_membership_renewal() { frame_system::RawOrigin::Signed(AccountKeyring::Alice.to_account_id()).into(), )); - run_to_block(51); // Pass 2 sessions + run_to_block(51); // Pass 5 sessions assert_ok!(Distance::force_update_evaluation( frame_system::RawOrigin::Root.into(), AccountKeyring::Alice.to_account_id(),