Skip to content
Snippets Groups Projects
default_combine_data.rs 1.27 KiB
Newer Older
  • Learn to ignore specific revisions
  • use crate::{Config, MomentOf, TimestampedValueOf};
    
    use frame_support::traits::{Get, Time};
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    use orml_traits::CombineData;
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    use sp_std::{marker, prelude::*};
    
    Ermal Kaleci's avatar
    Ermal Kaleci committed
    
    /// Sort by value and returns median timestamped value.
    /// Returns prev_value if not enough valid values.
    
    pub struct DefaultCombineData<T, MinimumCount, ExpiresIn, I = ()>(marker::PhantomData<(T, I, MinimumCount, ExpiresIn)>);
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    impl<T, I, MinimumCount, ExpiresIn> CombineData<<T as Config<I>>::OracleKey, TimestampedValueOf<T, I>>
    
    	for DefaultCombineData<T, MinimumCount, ExpiresIn, I>
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    	T: Config<I>,
    
    	I: 'static,
    
    	MinimumCount: Get<u32>,
    
    	ExpiresIn: Get<MomentOf<T, I>>,
    
    Ermal Kaleci's avatar
    Ermal Kaleci committed
    	fn combine_data(
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		_key: &<T as Config<I>>::OracleKey,
    
    		mut values: Vec<TimestampedValueOf<T, I>>,
    		prev_value: Option<TimestampedValueOf<T, I>>,
    	) -> Option<TimestampedValueOf<T, I>> {
    
    		let expires_in = ExpiresIn::get();
    
    Ermal Kaleci's avatar
    Ermal Kaleci committed
    		let now = T::Time::now();
    
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    		values.retain(|x| x.timestamp + expires_in > now);
    
    		let count = values.len() as u32;
    
    		let minimum_count = MinimumCount::get();
    
    		if count < minimum_count || count == 0 {
    
    Ermal Kaleci's avatar
    Ermal Kaleci committed
    			return prev_value;
    		}
    
    
    		let mid_index = count / 2;
    		// Won't panic as `values` ensured not empty.
    		let (_, value, _) = values.select_nth_unstable_by(mid_index as usize, |a, b| a.value.cmp(&b.value));
    		Some(value.clone())
    
    Ermal Kaleci's avatar
    Ermal Kaleci committed
    	}
    }