Skip to content
Snippets Groups Projects

Change distance evaluation period from Sessions to Blocks

Merged Benjamin Gallois requested to merge 202-distance-oracle-reevaluation into master
5 files
+ 57
48
Compare changes
  • Side-by-side
  • Inline
Files
5
+ 53
44
@@ -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());
Loading