Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pallet-collection-data-feed implementation #1324

Merged
merged 16 commits into from
May 2, 2023
37 changes: 37 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ members = [
"pallets/permissions",
"pallets/pool-system",
"pallets/pool-registry",
"pallets/collection-data-feed",
"pallets/restricted-tokens",
"pallets/transfer-allowlist",
"pallets/rewards",
Expand Down
100 changes: 100 additions & 0 deletions libs/mocks/src/data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#[frame_support::pallet]
pub mod pallet {
use cfg_traits::data::{DataCollection, DataRegistry};
use frame_support::pallet_prelude::*;
use mock_builder::{execute_call, register_call};

#[pallet::config]
pub trait Config: frame_system::Config {
type DataId;
type CollectionId;
type Collection: DataCollection<Self::DataId>;
type Data;
}

#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);

#[pallet::storage]
pub(super) type CallIds<T: Config> = StorageMap<
_,
Blake2_128Concat,
<Blake2_128 as frame_support::StorageHasher>::Output,
mock_builder::CallId,
>;

impl<T: Config> Pallet<T> {
pub fn mock_get(f: impl Fn(&T::DataId) -> T::Data + 'static) {
register_call!(f);
}

pub fn mock_cache(f: impl Fn(&T::CollectionId) -> T::Collection + 'static) {
register_call!(f);
}

pub fn mock_register_id(
f: impl Fn(&T::DataId, &T::CollectionId) -> DispatchResult + 'static,
) {
register_call!(move |(a, b)| f(a, b));
}

pub fn mock_unregister_id(
f: impl Fn(&T::DataId, &T::CollectionId) -> DispatchResult + 'static,
) {
register_call!(move |(a, b)| f(a, b));
}
}

impl<T: Config> DataRegistry<T::DataId, T::CollectionId> for Pallet<T> {
type Collection = T::Collection;
type Data = T::Data;

fn get(a: &T::DataId) -> T::Data {
let a = unsafe { std::mem::transmute::<_, &'static T::DataId>(a) };
execute_call!(a)
}

fn collection(a: &T::CollectionId) -> T::Collection {
let a = unsafe { std::mem::transmute::<_, &'static T::CollectionId>(a) };
execute_call!(a)
}

fn register_id(a: &T::DataId, b: &T::CollectionId) -> DispatchResult {
let a = unsafe { std::mem::transmute::<_, &'static T::DataId>(a) };
let b = unsafe { std::mem::transmute::<_, &'static T::CollectionId>(b) };
execute_call!((a, b))
}

fn unregister_id(a: &T::DataId, b: &T::CollectionId) -> DispatchResult {
let a = unsafe { std::mem::transmute::<_, &'static T::DataId>(a) };
let b = unsafe { std::mem::transmute::<_, &'static T::CollectionId>(b) };
execute_call!((a, b))
}
}

#[cfg(feature = "std")]
pub mod util {
use std::collections::HashMap;

use super::*;

pub struct MockDataCollection<T: Config>(pub HashMap<T::DataId, T::Data>);

impl<T: Config> DataCollection<T::DataId> for MockDataCollection<T>
where
T::DataId: std::hash::Hash + Eq,
T::Data: Clone,
{
type Data = Result<T::Data, DispatchError>;

fn get(&self, data_id: &T::DataId) -> Self::Data {
Ok(self
.0
.get(data_id)
.ok_or(DispatchError::CannotLookup)?
.clone())
}
}
}
}
2 changes: 2 additions & 0 deletions libs/mocks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
mod data;
mod fees;
mod permissions;
mod pools;
mod rewards;

pub use data::pallet as pallet_mock_data;
pub use fees::pallet as pallet_mock_fees;
pub use permissions::pallet as pallet_mock_permissions;
pub use pools::pallet as pallet_mock_pools;
Expand Down
32 changes: 32 additions & 0 deletions libs/traits/src/data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use sp_runtime::DispatchResult;

/// Abstraction that represents a storage where
/// you can subscribe to data updates and collect them
pub trait DataRegistry<DataId, CollectionId> {
/// A collection of data
type Collection: DataCollection<DataId>;

/// Represents a data
type Data;

/// Return the last data value for a data id
fn get(data_id: &DataId) -> Self::Data;

/// Retrives a collection of data with all data associated to a collection id
fn collection(collection_id: &CollectionId) -> Self::Collection;

/// Start listening data changes for a data id in a collection id
fn register_id(data_id: &DataId, collection_id: &CollectionId) -> DispatchResult;

/// Start listening data changes for a data id in a collection id
fn unregister_id(data_id: &DataId, collection_id: &CollectionId) -> DispatchResult;
}

/// Abstration to represent a collection of data in memory
pub trait DataCollection<DataId> {
/// Represents a data
type Data;

/// Return the last data value for a data id
fn get(&self, data_id: &DataId) -> Self::Data;
}
2 changes: 2 additions & 0 deletions libs/traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ pub mod ops;
/// Traits related to rewards.
pub mod rewards;

pub mod data;

/// A trait used for loosely coupling the claim pallet with a reward mechanism.
///
/// ## Overview
Expand Down
57 changes: 57 additions & 0 deletions pallets/collection-data-feed/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
[package]
authors = ["Centrifuge <[email protected]>"]
description = "Pallet to collect data from a feeder entity"
edition = "2021"
license = "LGPL-3.0"
name = "pallet-collection-data-feed"
repository = "https://github.com/centrifuge/centrifuge-chain"
version = "1.0.0"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", default-features = false, version = "3.0.0", features = ["derive"] }
scale-info = { version = "2.3.0", default-features = false, features = ["derive"] }

frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.37" }
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.37" }
sp-arithmetic = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.37" }
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.37" }
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.37" }

orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", default-features = true, branch = "polkadot-v0.9.37" }

cfg-traits = { path = "../../libs/traits", default-features = false }

[dev-dependencies]
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" }

orml-oracle = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.37" }
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" }

[features]
default = ["std"]
std = [
"codec/std",
"scale-info/std",
"frame-support/std",
"frame-system/std",
"sp-arithmetic/std",
"sp-runtime/std",
"sp-std/std",
"cfg-traits/std",
"orml-traits/std",
]
runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"cfg-traits/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"cfg-traits/try-runtime",
]
Loading