orml_oracle/
default_combine_data.rs1use crate::{Config, MomentOf, TimestampedValueOf};
2use frame_support::traits::{Get, Time};
3use orml_traits::CombineData;
4use sp_runtime::traits::Saturating;
5use sp_std::{marker, prelude::*};
6
7pub struct DefaultCombineData<T, MinimumCount, ExpiresIn, I = ()>(marker::PhantomData<(T, I, MinimumCount, ExpiresIn)>);
10
11impl<T, I, MinimumCount, ExpiresIn> CombineData<<T as Config<I>>::OracleKey, TimestampedValueOf<T, I>>
12 for DefaultCombineData<T, MinimumCount, ExpiresIn, I>
13where
14 T: Config<I>,
15 I: 'static,
16 MinimumCount: Get<u32>,
17 ExpiresIn: Get<MomentOf<T, I>>,
18{
19 fn combine_data(
20 _key: &<T as Config<I>>::OracleKey,
21 mut values: Vec<TimestampedValueOf<T, I>>,
22 prev_value: Option<TimestampedValueOf<T, I>>,
23 ) -> Option<TimestampedValueOf<T, I>> {
24 let expires_in = ExpiresIn::get();
25 let now = T::Time::now();
26
27 values.retain(|x| x.timestamp.saturating_add(expires_in) > now);
28
29 let count = values.len() as u32;
30 let minimum_count = MinimumCount::get();
31 if count < minimum_count || count == 0 {
32 return prev_value;
33 }
34
35 let mid_index = count / 2;
36 let (_, value, _) = values.select_nth_unstable_by(mid_index as usize, |a, b| a.value.cmp(&b.value));
38 Some(value.clone())
39 }
40}