Skip to content

Commit

Permalink
add AggregationProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
lemunozm committed Dec 1, 2023
1 parent a3abd60 commit 13fd2c9
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 12 deletions.
56 changes: 47 additions & 9 deletions pallets/oracle-data-collection/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub mod pallet {
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use crate::{
traits::AggregationProvider,
types::{CachedCollection, Change, KeyInfo},
util,
};
Expand All @@ -67,17 +68,21 @@ pub mod pallet {
/// Represent an oracle value
type OracleValue: Parameter + Member + Copy + MaxEncodedLen + Ord;

/// Represent the a time moment
type Moment: Parameter + Member + Copy + MaxEncodedLen + Ord;
/// Represent the time moment when the value was fed
type Timestamp: Parameter + Member + Copy + MaxEncodedLen + Ord;

/// A way to obtain oracle values from feeders
type OracleProvider: ValueProvider<
(Self::AccountId, Self::CollectionId),
Self::OracleKey,
Value = Self::OracleValue,
Timestamp = Self::Moment,
Timestamp = Self::Timestamp,
>;

/// A way to perform aggregations from a list of feeders feeding the
/// same keys
type AggregationProvider: AggregationProvider<Self::OracleValue, Self::Timestamp>;

/// Used to verify collection admin permissions
type IsAdmin: PreConditions<(Self::AccountId, Self::CollectionId), Result = bool>;

Expand All @@ -104,7 +109,7 @@ pub mod pallet {
_,
Blake2_128Concat,
T::CollectionId,
BoundedBTreeMap<T::OracleKey, (T::OracleValue, T::Moment), T::MaxCollectionSize>,
BoundedBTreeMap<T::OracleKey, (T::OracleValue, T::Timestamp), T::MaxCollectionSize>,
ValueQuery,
>;

Expand Down Expand Up @@ -253,7 +258,7 @@ pub mod pallet {

impl<T: Config> DataRegistry<T::OracleKey, T::CollectionId> for Pallet<T> {
type Collection = CachedCollection<T>;
type Data = (T::OracleValue, T::Moment);
type Data = (T::OracleValue, T::Timestamp);
#[cfg(feature = "runtime-benchmarks")]
type MaxCollectionSize = T::MaxCollectionSize;

Expand Down Expand Up @@ -378,16 +383,16 @@ pub mod types {

/// A collection cached in memory
pub struct CachedCollection<T: Config>(
pub BoundedBTreeMap<T::OracleKey, (T::OracleValue, T::Moment), T::MaxCollectionSize>,
pub BoundedBTreeMap<T::OracleKey, (T::OracleValue, T::Timestamp), T::MaxCollectionSize>,
);

impl<T: Config> DataCollection<T::OracleKey> for CachedCollection<T> {
type Data = (T::OracleValue, T::Moment);
type Data = (T::OracleValue, T::Timestamp);

fn get(
&self,
data_id: &T::OracleKey,
) -> Result<(T::OracleValue, T::Moment), DispatchError> {
) -> Result<(T::OracleValue, T::Timestamp), DispatchError> {
self.0
.get(data_id)
.cloned()
Expand All @@ -403,9 +408,42 @@ pub mod types {
}
}

mod util {
/// Traits specifically used by this pallet
pub mod traits {
/// Defined an aggregation behavior
pub trait AggregationProvider<Value, Timestamp> {
fn aggregate(pairs: impl Iterator<Item = (Value, Timestamp)>)
-> Option<(Value, Timestamp)>;
}
}

/// Provide types to use in runtime to configure this pallet
pub mod util {
use sp_std::vec::Vec;

use super::traits::AggregationProvider;

/// Type that performs an aggregation using the median for values and
/// timestamps
pub struct MedianAggregation;

impl<Value, Timestamp> AggregationProvider<Value, Timestamp> for MedianAggregation
where
Value: Ord + Clone,
Timestamp: Ord + Clone,
{
fn aggregate(
pairs: impl Iterator<Item = (Value, Timestamp)>,
) -> Option<(Value, Timestamp)> {
let (mut values, mut timestamps): (Vec<_>, Vec<_>) = pairs.unzip();

let value = median(&mut values)?.clone();
let timestamp = median(&mut timestamps)?.clone();

Some((value, timestamp))
}
}

/// Computes fastly the median of a list of values
/// Extracted from orml
pub fn median<'a, T: Ord>(items: &'a mut Vec<T>) -> Option<&'a T> {
Expand Down
9 changes: 6 additions & 3 deletions runtime/development/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1324,6 +1324,8 @@ impl pallet_membership::Config for Runtime {
}

parameter_types! {
#[derive(Clone, PartialEq, Eq, Debug, TypeInfo, Encode, Decode, MaxEncodedLen)]
pub const MaxFeedersPerKey: u32 = 10;
pub const FirstValueFee: Fee = Fee::Balance(10 * CFG);
}

Expand All @@ -1336,17 +1338,18 @@ impl pallet_oracle_feed::Config for Runtime {
}

impl pallet_oracle_data_collection::Config for Runtime {
type AggregationProvider = pallet_oracle_data_collection::util::MedianAggregation;
type ChangeGuard = PoolSystem;
type CollectionId = PoolId;
type IsAdmin = PoolAdminCheck<Permissions>;
type MaxCollectionSize = MaxActiveLoansPerPool;
type MaxFeedersPerKey = ConstU32<10>;
type Moment = Millis;
type MaxFeedersPerKey = MaxFeedersPerKey;
type OracleKey = OracleKey;
type OracleProvider = OracleConverterBridge<OraclePriceFeed, OrmlAssetRegistry, PoolSystem>;
type OracleValue = Balance;
type RuntimeChange = runtime_common::changes::fast::RuntimeChange<Runtime>;
type RuntimeChange = runtime_common::changes::RuntimeChange<Runtime, FastDelay>;
type RuntimeEvent = RuntimeEvent;
type Timestamp = Millis;
}

parameter_types! {
Expand Down

0 comments on commit 13fd2c9

Please sign in to comment.