lib.rs 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645
  1. // Ensure we're `no_std` when compiling for Wasm.
  2. #![cfg_attr(not(feature = "std"), no_std)]
  3. #![recursion_limit = "256"]
  4. use codec::{Codec, Decode, Encode};
  5. use rstd::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
  6. use rstd::prelude::*;
  7. use runtime_primitives::traits::{MaybeSerializeDeserialize, Member, One, SimpleArithmetic, Zero};
  8. use srml_support::{
  9. decl_module, decl_storage, dispatch, ensure, traits::Get, Parameter, StorageDoubleMap,
  10. };
  11. use system::ensure_signed;
  12. #[cfg(feature = "std")]
  13. pub use serde::{Deserialize, Serialize};
  14. mod errors;
  15. mod mock;
  16. mod operations;
  17. mod permissions;
  18. mod schema;
  19. mod tests;
  20. use core::fmt::Debug;
  21. pub use errors::*;
  22. pub use operations::*;
  23. pub use permissions::*;
  24. pub use schema::*;
  25. type MaxNumber = u32;
  26. /// Type, representing vector of vectors of all referenced entitity id`s
  27. type EntitiesRcVec<T> = Vec<Vec<<T as Trait>::EntityId>>;
  28. pub trait Trait: system::Trait + ActorAuthenticator + Debug + Clone {
  29. /// Nonce type is used to avoid data race update conditions, when performing property value vector operations
  30. type Nonce: Parameter
  31. + Member
  32. + SimpleArithmetic
  33. + Codec
  34. + Default
  35. + Copy
  36. + Clone
  37. + One
  38. + Zero
  39. + MaybeSerializeDeserialize
  40. + Eq
  41. + PartialEq
  42. + Ord
  43. + From<u32>;
  44. /// Type of identifier for classes
  45. type ClassId: Parameter
  46. + Member
  47. + SimpleArithmetic
  48. + Codec
  49. + Default
  50. + Copy
  51. + Clone
  52. + One
  53. + Zero
  54. + MaybeSerializeDeserialize
  55. + Eq
  56. + PartialEq
  57. + Ord;
  58. /// Type of identifier for entities
  59. type EntityId: Parameter
  60. + Member
  61. + SimpleArithmetic
  62. + Codec
  63. + Default
  64. + Copy
  65. + Clone
  66. + One
  67. + Zero
  68. + MaybeSerializeDeserialize
  69. + Eq
  70. + PartialEq
  71. + Ord;
  72. /// Security/configuration constraints
  73. /// The maximum length of property name
  74. type PropertyNameConstraint: Get<InputValidationLengthConstraint>;
  75. /// The maximum length of property description
  76. type PropertyDescriptionConstraint: Get<InputValidationLengthConstraint>;
  77. /// Type, representing min & max class name length constraints
  78. type ClassNameConstraint: Get<InputValidationLengthConstraint>;
  79. /// Type, representing min & max class description length constraints
  80. type ClassDescriptionConstraint: Get<InputValidationLengthConstraint>;
  81. /// The maximum number of classes
  82. type NumberOfClassesConstraint: Get<MaxNumber>;
  83. /// The maximum number of maintainers per class constraint
  84. type NumberOfMaintainersConstraint: Get<MaxNumber>;
  85. /// The maximum number of curators per group constraint
  86. type NumberOfCuratorsConstraint: Get<MaxNumber>;
  87. /// The maximum number of schemas per class constraint
  88. type NumberOfSchemasConstraint: Get<MaxNumber>;
  89. /// The maximum number of properties per class constraint
  90. type NumberOfPropertiesConstraint: Get<MaxNumber>;
  91. /// The maximum length of vector property value constarint
  92. type VecMaxLengthConstraint: Get<VecMaxLength>;
  93. /// The maximum length of text property value constarint
  94. type TextMaxLengthConstraint: Get<TextMaxLength>;
  95. /// Entities creation constraint per class
  96. type EntitiesCreationConstraint: Get<CreationLimit>;
  97. /// Entities creation constraint per individual
  98. type IndividualEntitiesCreationConstraint: Get<CreationLimit>;
  99. }
  100. /// Length constraint for input validation
  101. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  102. #[derive(Encode, Decode, Default, Clone, Copy, PartialEq, Eq, Debug)]
  103. pub struct InputValidationLengthConstraint {
  104. /// Minimum length
  105. pub min: u16,
  106. /// Difference between minimum length and max length.
  107. /// While having max would have been more direct, this
  108. /// way makes max < min unrepresentable semantically,
  109. /// which is safer.
  110. pub max_min_diff: u16,
  111. }
  112. impl InputValidationLengthConstraint {
  113. pub fn new(min: u16, max_min_diff: u16) -> Self {
  114. Self { min, max_min_diff }
  115. }
  116. /// Helper for computing max
  117. pub fn max(self) -> u16 {
  118. self.min + self.max_min_diff
  119. }
  120. pub fn ensure_valid(
  121. self,
  122. len: usize,
  123. too_short_msg: &'static str,
  124. too_long_msg: &'static str,
  125. ) -> Result<(), &'static str> {
  126. let length = len as u16;
  127. if length < self.min {
  128. Err(too_short_msg)
  129. } else if length > self.max() {
  130. Err(too_long_msg)
  131. } else {
  132. Ok(())
  133. }
  134. }
  135. }
  136. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  137. #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
  138. pub struct Class<T: Trait> {
  139. /// Permissions for an instance of a Class.
  140. class_permissions: ClassPermissions<T>,
  141. /// All properties that have been used on this class across different class schemas.
  142. /// Unlikely to be more than roughly 20 properties per class, often less.
  143. /// For Person, think "height", "weight", etc.
  144. pub properties: Vec<Property<T>>,
  145. /// All schemas that are available for this class, think v0.0 Person, v.1.0 Person, etc.
  146. pub schemas: Vec<Schema>,
  147. pub name: Vec<u8>,
  148. pub description: Vec<u8>,
  149. /// The maximum number of entities which can be created.
  150. maximum_entities_count: CreationLimit,
  151. /// The current number of entities which exist.
  152. current_number_of_entities: CreationLimit,
  153. /// How many entities a given controller may create at most.
  154. per_controller_entity_creation_limit: CreationLimit,
  155. }
  156. impl<T: Trait> Default for Class<T> {
  157. fn default() -> Self {
  158. Self {
  159. class_permissions: ClassPermissions::<T>::default(),
  160. properties: vec![],
  161. schemas: vec![],
  162. name: vec![],
  163. description: vec![],
  164. maximum_entities_count: CreationLimit::default(),
  165. current_number_of_entities: CreationLimit::default(),
  166. per_controller_entity_creation_limit: CreationLimit::default(),
  167. }
  168. }
  169. }
  170. impl<T: Trait> Class<T> {
  171. fn new(
  172. class_permissions: ClassPermissions<T>,
  173. name: Vec<u8>,
  174. description: Vec<u8>,
  175. maximum_entities_count: CreationLimit,
  176. per_controller_entity_creation_limit: CreationLimit,
  177. ) -> Self {
  178. Self {
  179. class_permissions,
  180. properties: vec![],
  181. schemas: vec![],
  182. name,
  183. description,
  184. maximum_entities_count,
  185. current_number_of_entities: 0,
  186. per_controller_entity_creation_limit,
  187. }
  188. }
  189. fn update_schema_status(&mut self, schema_index: SchemaId, schema_status: bool) {
  190. // Such indexing is safe, when length bounds were previously checked
  191. self.schemas[schema_index as usize].set_status(schema_status);
  192. }
  193. fn set_property_lock_status_at_index(
  194. &mut self,
  195. in_class_schema_property_id: PropertyId,
  196. is_locked: PropertyLockingPolicy,
  197. ) {
  198. // Such indexing is safe, when length bounds were previously checked
  199. self.properties[in_class_schema_property_id as usize].set_locked_for(is_locked)
  200. }
  201. fn set_reference_property_same_controller_status(
  202. &mut self,
  203. in_class_schema_property_id: PropertyId,
  204. same_controller: SameController,
  205. ) {
  206. // Such indexing is safe, when length bounds were previously checked
  207. self.properties[in_class_schema_property_id as usize]
  208. .prop_type
  209. .set_same_controller_status(same_controller)
  210. }
  211. fn increment_entities_count(&mut self) {
  212. self.current_number_of_entities += 1;
  213. }
  214. fn decrement_entities_count(&mut self) {
  215. self.current_number_of_entities -= 1;
  216. }
  217. fn get_permissions_mut(&mut self) -> &mut ClassPermissions<T> {
  218. &mut self.class_permissions
  219. }
  220. fn get_permissions(&self) -> &ClassPermissions<T> {
  221. &self.class_permissions
  222. }
  223. pub fn get_controller_entity_creation_limit(&self) -> CreationLimit {
  224. self.per_controller_entity_creation_limit
  225. }
  226. pub fn get_maximum_entities_count(&self) -> CreationLimit {
  227. self.maximum_entities_count
  228. }
  229. fn is_active_schema(&self, schema_index: SchemaId) -> bool {
  230. // Such indexing is safe, when length bounds were previously checked
  231. self.schemas[schema_index as usize].is_active()
  232. }
  233. pub fn ensure_schema_id_exists(&self, schema_id: SchemaId) -> dispatch::Result {
  234. ensure!(
  235. schema_id < self.schemas.len() as SchemaId,
  236. ERROR_UNKNOWN_CLASS_SCHEMA_ID
  237. );
  238. Ok(())
  239. }
  240. pub fn ensure_property_id_exists(
  241. &self,
  242. in_class_schema_property_id: PropertyId,
  243. ) -> dispatch::Result {
  244. ensure!(
  245. in_class_schema_property_id < self.properties.len() as PropertyId,
  246. ERROR_CLASS_PROP_NOT_FOUND
  247. );
  248. Ok(())
  249. }
  250. pub fn ensure_schema_is_active(&self, schema_id: SchemaId) -> dispatch::Result {
  251. ensure!(
  252. self.is_active_schema(schema_id),
  253. ERROR_CLASS_SCHEMA_NOT_ACTIVE
  254. );
  255. Ok(())
  256. }
  257. pub fn ensure_schemas_limit_not_reached(&self) -> dispatch::Result {
  258. ensure!(
  259. T::NumberOfSchemasConstraint::get() < self.schemas.len() as MaxNumber,
  260. ERROR_CLASS_SCHEMAS_LIMIT_REACHED
  261. );
  262. Ok(())
  263. }
  264. pub fn ensure_properties_limit_not_reached(
  265. &self,
  266. new_properties: &[Property<T>],
  267. ) -> dispatch::Result {
  268. ensure!(
  269. T::NumberOfPropertiesConstraint::get()
  270. <= (self.properties.len() + new_properties.len()) as MaxNumber,
  271. ERROR_CLASS_PROPERTIES_LIMIT_REACHED
  272. );
  273. Ok(())
  274. }
  275. pub fn ensure_maximum_entities_count_limit_not_reached(&self) -> dispatch::Result {
  276. ensure!(
  277. self.current_number_of_entities < self.maximum_entities_count,
  278. ERROR_MAX_NUMBER_OF_ENTITIES_PER_CLASS_LIMIT_REACHED
  279. );
  280. Ok(())
  281. }
  282. }
  283. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  284. #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
  285. pub struct Entity<T: Trait> {
  286. /// Permissions for an instance of an Entity.
  287. pub entity_permission: EntityPermissions<T>,
  288. /// The class id of this entity.
  289. pub class_id: T::ClassId,
  290. /// What schemas under which this entity of a class is available, think
  291. /// v.2.0 Person schema for John, v3.0 Person schema for John
  292. /// Unlikely to be more than roughly 20ish, assuming schemas for a given class eventually stableize, or that very old schema are eventually removed.
  293. pub supported_schemas: BTreeSet<SchemaId>, // indices of schema in corresponding class
  294. /// Values for properties on class that are used by some schema used by this entity!
  295. /// Length is no more than Class.properties.
  296. pub values: BTreeMap<PropertyId, PropertyValue<T>>,
  297. /// Number of property values referencing current entity
  298. pub reference_count: u32,
  299. }
  300. impl<T: Trait> Default for Entity<T> {
  301. fn default() -> Self {
  302. Self {
  303. entity_permission: EntityPermissions::<T>::default(),
  304. class_id: T::ClassId::default(),
  305. supported_schemas: BTreeSet::new(),
  306. values: BTreeMap::new(),
  307. reference_count: 0,
  308. }
  309. }
  310. }
  311. impl<T: Trait> Entity<T> {
  312. fn new(
  313. controller: EntityController<T>,
  314. class_id: T::ClassId,
  315. supported_schemas: BTreeSet<SchemaId>,
  316. values: BTreeMap<PropertyId, PropertyValue<T>>,
  317. ) -> Self {
  318. Self {
  319. entity_permission: EntityPermissions::<T>::default_with_controller(controller),
  320. class_id,
  321. supported_schemas,
  322. values,
  323. reference_count: 0,
  324. }
  325. }
  326. fn get_permissions_mut(&mut self) -> &mut EntityPermissions<T> {
  327. &mut self.entity_permission
  328. }
  329. fn get_permissions(&self) -> &EntityPermissions<T> {
  330. &self.entity_permission
  331. }
  332. pub fn ensure_schema_id_is_not_added(&self, schema_id: SchemaId) -> dispatch::Result {
  333. let schema_not_added = !self.supported_schemas.contains(&schema_id);
  334. ensure!(schema_not_added, ERROR_SCHEMA_ALREADY_ADDED_TO_ENTITY);
  335. Ok(())
  336. }
  337. }
  338. decl_storage! {
  339. trait Store for Module<T: Trait> as ContentDirectory {
  340. /// Map, representing ClassId -> Class relation
  341. pub ClassById get(class_by_id) config(): linked_map T::ClassId => Class<T>;
  342. /// Map, representing EntityId -> Entity relation
  343. pub EntityById get(entity_by_id) config(): map T::EntityId => Entity<T>;
  344. /// Curator groups
  345. pub CuratorGroupById get(curator_group_by_id): map T::CuratorGroupId => CuratorGroup<T>;
  346. pub NextClassId get(next_class_id) config(): T::ClassId;
  347. pub NextEntityId get(next_entity_id) config(): T::EntityId;
  348. // The voucher associated with entity creation for a given class and controller.
  349. // Is updated whenever an entity is created in a given class by a given controller.
  350. // Constraint is updated by Root, an initial value comes from `ClassPermissions::per_controller_entity_creation_limit`.
  351. pub EntityCreationVouchers get(entity_creation_vouchers): double_map hasher(blake2_128) T::ClassId, blake2_128(EntityController<T>) => EntityCreationVoucher;
  352. /// Upper limit for how many operations can be included in a single invocation of `atomic_batched_operations`.
  353. pub MaximumNumberOfOperationsDuringAtomicBatching: u64;
  354. }
  355. }
  356. decl_module! {
  357. pub struct Module<T: Trait> for enum Call where origin: T::Origin {
  358. // ======
  359. // Next set of extrinsics can only be invoked by lead.
  360. // ======
  361. pub fn add_curator_group(
  362. origin,
  363. curator_group_id: T::CuratorGroupId,
  364. curator_group: CuratorGroup<T>
  365. ) -> dispatch::Result {
  366. perform_lead_auth::<T>(origin)?;
  367. Self::ensure_curator_group_does_not_exist(curator_group_id)?;
  368. //
  369. // == MUTATION SAFE ==
  370. //
  371. <CuratorGroupById<T>>::insert(curator_group_id, curator_group);
  372. Ok(())
  373. }
  374. pub fn remove_curator_group(
  375. origin,
  376. curator_group_id: T::CuratorGroupId,
  377. ) -> dispatch::Result {
  378. perform_lead_auth::<T>(origin)?;
  379. Self::ensure_curator_group_exists(&curator_group_id)?;
  380. //
  381. // == MUTATION SAFE ==
  382. //
  383. <CuratorGroupById<T>>::remove(curator_group_id);
  384. let class_ids: Vec<T::ClassId> = <ClassById<T>>::enumerate().map(|(class_id, _)| class_id).collect();
  385. for class_id in class_ids {
  386. <ClassById<T>>::mutate(class_id, |class| {
  387. let class_permissions = class.get_permissions_mut();
  388. class_permissions.get_maintainers_mut().remove(&curator_group_id);
  389. })
  390. };
  391. Ok(())
  392. }
  393. pub fn set_curator_group_status(
  394. origin,
  395. curator_group_id: T::CuratorGroupId,
  396. is_active: bool,
  397. ) -> dispatch::Result {
  398. perform_lead_auth::<T>(origin)?;
  399. Self::ensure_curator_group_exists(&curator_group_id)?;
  400. //
  401. // == MUTATION SAFE ==
  402. //
  403. <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
  404. curator_group.set_status(is_active)
  405. });
  406. Ok(())
  407. }
  408. /// Add curator to a given curator group
  409. pub fn add_curator(
  410. origin,
  411. curator_group_id: T::CuratorGroupId,
  412. curator_id: T::CuratorId,
  413. ) -> dispatch::Result {
  414. perform_lead_auth::<T>(origin)?;
  415. Self::ensure_curator_group_exists(&curator_group_id)?;
  416. Self::ensure_max_number_of_curators_limit_not_reached(curator_group_id)?;
  417. //
  418. // == MUTATION SAFE ==
  419. //
  420. <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
  421. curator_group.get_curators_mut().insert(curator_id);
  422. });
  423. Ok(())
  424. }
  425. /// Remove curator from a given curator group
  426. pub fn remove_curator(
  427. origin,
  428. curator_group_id: T::CuratorGroupId,
  429. curator_id: T::CuratorId,
  430. ) -> dispatch::Result {
  431. perform_lead_auth::<T>(origin)?;
  432. Self::ensure_curator_group_exists(&curator_group_id)?;
  433. //
  434. // == MUTATION SAFE ==
  435. //
  436. <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
  437. curator_group.get_curators_mut().remove(&curator_id);
  438. });
  439. Ok(())
  440. }
  441. /// Add curator group as specific class maintainer
  442. pub fn add_maintainer(
  443. origin,
  444. class_id: T::ClassId,
  445. curator_group_id: T::CuratorGroupId,
  446. ) -> dispatch::Result {
  447. perform_lead_auth::<T>(origin)?;
  448. Self::ensure_known_class_id(class_id)?;
  449. Self::ensure_curator_group_exists(&curator_group_id)?;
  450. let class = Self::class_by_id(class_id);
  451. let class_permissions = class.get_permissions();
  452. class_permissions.ensure_maintainers_limit_not_reached()?;
  453. class_permissions.ensure_maintainer_does_not_exist(&curator_group_id)?;
  454. //
  455. // == MUTATION SAFE ==
  456. //
  457. <ClassById<T>>::mutate(class_id, |class|
  458. class.get_permissions_mut().get_maintainers_mut().insert(curator_group_id)
  459. );
  460. Ok(())
  461. }
  462. /// Remove curator group from class maintainers set
  463. pub fn remove_maintainer(
  464. origin,
  465. class_id: T::ClassId,
  466. curator_group_id: T::CuratorGroupId,
  467. ) -> dispatch::Result {
  468. perform_lead_auth::<T>(origin)?;
  469. Self::ensure_known_class_id(class_id)?;
  470. Self::class_by_id(class_id).get_permissions().ensure_maintainer_exists(&curator_group_id)?;
  471. //
  472. // == MUTATION SAFE ==
  473. //
  474. <ClassById<T>>::mutate(class_id, |class|
  475. class.get_permissions_mut().get_maintainers_mut().remove(&curator_group_id)
  476. );
  477. Ok(())
  478. }
  479. /// Updates or creates new entity creation voucher for given controller with individual limit
  480. pub fn update_entity_creation_voucher(
  481. origin,
  482. class_id: T::ClassId,
  483. controller: EntityController<T>,
  484. maximum_entities_count: CreationLimit
  485. ) -> dispatch::Result {
  486. perform_lead_auth::<T>(origin)?;
  487. Self::ensure_known_class_id(class_id)?;
  488. let per_controller_entity_creation_limit = Self::class_by_id(class_id).per_controller_entity_creation_limit;
  489. let voucher_exists = <EntityCreationVouchers<T>>::exists(class_id, &controller);
  490. if voucher_exists {
  491. // Ensure new voucher`s max entities count is less than number of already created entities in given voucher
  492. // and runtime entities creation constraint per actor satisfied
  493. Self::entity_creation_vouchers(class_id, &controller)
  494. .ensure_new_max_entities_count_is_valid::<T>(maximum_entities_count)?;
  495. }
  496. Self::ensure_valid_number_of_class_entities_per_actor(per_controller_entity_creation_limit, maximum_entities_count)?;
  497. //
  498. // == MUTATION SAFE ==
  499. //
  500. if voucher_exists {
  501. <EntityCreationVouchers<T>>::mutate(class_id, &controller, |entity_creation_voucher|
  502. entity_creation_voucher.set_maximum_entities_count(maximum_entities_count)
  503. );
  504. } else {
  505. <EntityCreationVouchers<T>>::insert(class_id, controller, EntityCreationVoucher::new(maximum_entities_count));
  506. }
  507. Ok(())
  508. }
  509. pub fn create_class(
  510. origin,
  511. name: Vec<u8>,
  512. description: Vec<u8>,
  513. class_permissions: ClassPermissions<T>,
  514. maximum_entities_count: CreationLimit,
  515. per_controller_entity_creation_limit: CreationLimit
  516. ) -> dispatch::Result {
  517. perform_lead_auth::<T>(origin)?;
  518. Self::ensure_entities_limits_are_valid(maximum_entities_count, per_controller_entity_creation_limit)?;
  519. Self::ensure_class_limit_not_reached()?;
  520. Self::ensure_class_name_is_valid(&name)?;
  521. Self::ensure_class_description_is_valid(&description)?;
  522. Self::ensure_class_permissions_are_valid(&class_permissions)?;
  523. let class_id = Self::next_class_id();
  524. let class = Class::new(class_permissions, name, description, maximum_entities_count, per_controller_entity_creation_limit);
  525. //
  526. // == MUTATION SAFE ==
  527. //
  528. <ClassById<T>>::insert(&class_id, class);
  529. // Increment the next class id:
  530. <NextClassId<T>>::mutate(|n| *n += T::ClassId::one());
  531. Ok(())
  532. }
  533. pub fn create_class_with_default_permissions(
  534. origin,
  535. name: Vec<u8>,
  536. description: Vec<u8>,
  537. maximum_entities_count: CreationLimit,
  538. per_controller_entity_creation_limit: CreationLimit
  539. ) -> dispatch::Result {
  540. Self::create_class(origin, name, description, ClassPermissions::default(), maximum_entities_count, per_controller_entity_creation_limit)
  541. }
  542. pub fn update_class_permissions(
  543. origin,
  544. class_id: T::ClassId,
  545. any_member: Option<bool>,
  546. entity_creation_blocked: Option<bool>,
  547. all_entity_property_values_locked: Option<bool>,
  548. maintainers: Option<BTreeSet<T::CuratorGroupId>>,
  549. ) -> dispatch::Result {
  550. perform_lead_auth::<T>(origin)?;
  551. Self::ensure_known_class_id(class_id)?;
  552. if let Some(ref maintainers) = maintainers {
  553. Self::ensure_curator_groups_exist(maintainers)?;
  554. ensure!(maintainers.len() <= T::NumberOfMaintainersConstraint::get() as usize, ERROR_NUMBER_OF_MAINTAINERS_PER_CLASS_LIMIT_REACHED);
  555. }
  556. //
  557. // == MUTATION SAFE ==
  558. //
  559. if let Some(any_member) = any_member {
  560. <ClassById<T>>::mutate(class_id, |class|
  561. class.get_permissions_mut().set_any_member_status(any_member)
  562. );
  563. }
  564. if let Some(entity_creation_blocked) = entity_creation_blocked {
  565. <ClassById<T>>::mutate(class_id, |class| class.get_permissions_mut().set_entity_creation_blocked(entity_creation_blocked));
  566. }
  567. if let Some(all_entity_property_values_locked) = all_entity_property_values_locked {
  568. <ClassById<T>>::mutate(class_id, |class|
  569. class.get_permissions_mut().set_all_entity_property_values_locked(all_entity_property_values_locked)
  570. );
  571. }
  572. if let Some(maintainers) = maintainers {
  573. <ClassById<T>>::mutate(class_id, |class|
  574. class.get_permissions_mut().set_maintainers(maintainers)
  575. );
  576. }
  577. Ok(())
  578. }
  579. pub fn add_class_schema(
  580. origin,
  581. class_id: T::ClassId,
  582. existing_properties: Vec<PropertyId>,
  583. new_properties: Vec<Property<T>>
  584. ) -> dispatch::Result {
  585. perform_lead_auth::<T>(origin)?;
  586. Self::ensure_known_class_id(class_id)?;
  587. Self::ensure_non_empty_schema(&existing_properties, &new_properties)?;
  588. let class = <ClassById<T>>::get(class_id);
  589. class.ensure_schemas_limit_not_reached()?;
  590. class.ensure_properties_limit_not_reached(&new_properties)?;
  591. let mut schema = Schema::new(existing_properties);
  592. let mut unique_prop_names = BTreeSet::new();
  593. for prop in class.properties.iter() {
  594. unique_prop_names.insert(prop.name.clone());
  595. }
  596. for prop in new_properties.iter() {
  597. prop.ensure_name_is_valid()?;
  598. prop.ensure_description_is_valid()?;
  599. prop.ensure_prop_type_size_is_valid()?;
  600. // Check that the name of a new property is unique within its class.
  601. ensure!(
  602. !unique_prop_names.contains(&prop.name),
  603. ERROR_PROP_NAME_NOT_UNIQUE_IN_A_CLASS
  604. );
  605. unique_prop_names.insert(prop.name.clone());
  606. }
  607. // Check that existing props are valid indices of class properties vector:
  608. let has_unknown_props = schema.get_properties()
  609. .iter()
  610. .any(|&prop_id| prop_id >= class.properties.len() as PropertyId);
  611. ensure!(
  612. !has_unknown_props,
  613. ERROR_CLASS_SCHEMA_REFERS_UNKNOWN_PROP_INDEX
  614. );
  615. // Check validity of Reference Types for new_properties.
  616. let has_unknown_reference = new_properties.iter().any(|prop| if let Type::Reference(other_class_id, _) = prop.prop_type.get_inner_type() {
  617. !<ClassById<T>>::exists(other_class_id)
  618. } else {
  619. false
  620. });
  621. ensure!(
  622. !has_unknown_reference,
  623. ERROR_CLASS_SCHEMA_REFERS_UNKNOWN_CLASS
  624. );
  625. let mut updated_class_props = class.properties;
  626. new_properties.into_iter().for_each(|prop| {
  627. let prop_id = updated_class_props.len() as PropertyId;
  628. updated_class_props.push(prop);
  629. schema.get_properties_mut().push(prop_id);
  630. });
  631. //
  632. // == MUTATION SAFE ==
  633. //
  634. <ClassById<T>>::mutate(class_id, |class| {
  635. class.properties = updated_class_props;
  636. class.schemas.push(schema);
  637. });
  638. Ok(())
  639. }
  640. pub fn update_class_schema_status(
  641. origin,
  642. class_id: T::ClassId,
  643. schema_id: SchemaId,
  644. schema_status: bool
  645. ) -> dispatch::Result {
  646. perform_lead_auth::<T>(origin)?;
  647. Self::ensure_known_class_id(class_id)?;
  648. //
  649. // == MUTATION SAFE ==
  650. //
  651. // Check that schema_id is a valid index of class schemas vector:
  652. Self::class_by_id(class_id).ensure_schema_id_exists(schema_id)?;
  653. <ClassById<T>>::mutate(class_id, |class| {
  654. class.update_schema_status(schema_id, schema_status)
  655. });
  656. Ok(())
  657. }
  658. pub fn set_class_property_lock_status_at_index(
  659. origin,
  660. class_id: T::ClassId,
  661. in_class_schema_property_id: PropertyId,
  662. is_locked: PropertyLockingPolicy
  663. ) -> dispatch::Result {
  664. perform_lead_auth::<T>(origin)?;
  665. Self::ensure_known_class_id(class_id)?;
  666. // Ensure property_id is a valid index of class properties vector:
  667. Self::class_by_id(class_id).ensure_property_id_exists(in_class_schema_property_id)?;
  668. //
  669. // == MUTATION SAFE ==
  670. //
  671. <ClassById<T>>::mutate(class_id, |class| {
  672. class.set_property_lock_status_at_index(in_class_schema_property_id, is_locked)
  673. });
  674. Ok(())
  675. }
  676. pub fn set_reference_property_same_controller_status(
  677. origin,
  678. class_id: T::ClassId,
  679. in_class_schema_property_id: PropertyId,
  680. same_controller: SameController
  681. ) -> dispatch::Result {
  682. perform_lead_auth::<T>(origin)?;
  683. Self::ensure_known_class_id(class_id)?;
  684. // Ensure property_id is a valid index of class properties vector:
  685. Self::class_by_id(class_id).ensure_property_id_exists(in_class_schema_property_id)?;
  686. //
  687. // == MUTATION SAFE ==
  688. //
  689. <ClassById<T>>::mutate(class_id, |class| {
  690. class.set_reference_property_same_controller_status(in_class_schema_property_id, same_controller)
  691. });
  692. Ok(())
  693. }
  694. /// Update entity permissions.
  695. ///
  696. pub fn update_entity_permissions(
  697. origin,
  698. entity_id: T::EntityId,
  699. controller: Option<EntityController<T>>,
  700. frozen_for_controller: Option<bool>,
  701. referenceable: Option<bool>
  702. ) -> dispatch::Result {
  703. perform_lead_auth::<T>(origin)?;
  704. Self::ensure_known_entity_id(entity_id)?;
  705. //
  706. // == MUTATION SAFE ==
  707. //
  708. if let Some(controller) = controller {
  709. // Ensure if class permissions satisfied and controller curator group exist
  710. <EntityById<T>>::mutate(entity_id, |inner_entity|
  711. inner_entity.get_permissions_mut().set_conroller(controller)
  712. );
  713. }
  714. if let Some(frozen_for_controller) = frozen_for_controller {
  715. <EntityById<T>>::mutate(entity_id, |inner_entity|
  716. inner_entity.get_permissions_mut().set_frozen(frozen_for_controller)
  717. );
  718. }
  719. if let Some(referenceable) = referenceable {
  720. <EntityById<T>>::mutate(entity_id, |inner_entity|
  721. inner_entity.get_permissions_mut().set_referencable(referenceable)
  722. );
  723. }
  724. Ok(())
  725. }
  726. // ======
  727. // The next set of extrinsics can be invoked by anyone who can properly sign for provided value of `Actor<T>`.
  728. // ======
  729. /// Create an entity.
  730. /// If someone is making an entity of this class for first time, then a voucher is also added with the class limit as the default limit value.
  731. /// class limit default value.
  732. pub fn create_entity(
  733. origin,
  734. class_id: T::ClassId,
  735. actor: Actor<T>,
  736. ) -> dispatch::Result {
  737. let account_id = ensure_signed(origin)?;
  738. let class = Self::ensure_class_exists(class_id)?;
  739. class.ensure_maximum_entities_count_limit_not_reached()?;
  740. let class_permissions = class.get_permissions();
  741. class_permissions.ensure_entity_creation_not_blocked()?;
  742. class_permissions.ensure_can_create_entities(&account_id, &actor)?;
  743. let entity_controller = EntityController::from_actor(&actor);
  744. // Check if entity creation voucher exists
  745. let voucher_exists = if <EntityCreationVouchers<T>>::exists(class_id, &entity_controller) {
  746. let entity_creation_voucher = Self::entity_creation_vouchers(class_id, &entity_controller);
  747. // Ensure voucher limit not reached
  748. Self::ensure_voucher_limit_not_reached(entity_creation_voucher)?;
  749. true
  750. } else {
  751. false
  752. };
  753. //
  754. // == MUTATION SAFE ==
  755. //
  756. if voucher_exists {
  757. // Increment number of created entities count, if voucher already exist
  758. <EntityCreationVouchers<T>>::mutate(class_id, &entity_controller, |entity_creation_voucher| {
  759. entity_creation_voucher.increment_created_entities_count()
  760. });
  761. } else {
  762. // Create new voucher for given entity creator with default limit and increment created entities count
  763. let mut entity_creation_voucher = EntityCreationVoucher::new(class.get_controller_entity_creation_limit());
  764. entity_creation_voucher.increment_created_entities_count();
  765. <EntityCreationVouchers<T>>::insert(class_id, entity_controller.clone(), entity_creation_voucher);
  766. }
  767. Self::complete_entity_creation(class_id, entity_controller);
  768. Ok(())
  769. }
  770. pub fn remove_entity(
  771. origin,
  772. actor: Actor<T>,
  773. entity_id: T::EntityId,
  774. ) -> dispatch::Result {
  775. let account_id = ensure_signed(origin)?;
  776. Self::ensure_known_entity_id(entity_id)?;
  777. let (_, access_level) = Self::get_entity_and_access_level(account_id, entity_id, actor)?;
  778. EntityPermissions::<T>::ensure_group_can_remove_entity(access_level)?;
  779. // Ensure there is no property values pointing to the given entity
  780. Self::ensure_rc_is_zero(entity_id)?;
  781. //
  782. // == MUTATION SAFE ==
  783. //
  784. Self::complete_entity_removal(entity_id);
  785. Ok(())
  786. }
  787. pub fn add_schema_support_to_entity(
  788. origin,
  789. actor: Actor<T>,
  790. entity_id: T::EntityId,
  791. schema_id: SchemaId,
  792. property_values: BTreeMap<PropertyId, PropertyValue<T>>
  793. ) -> dispatch::Result {
  794. let account_id = ensure_signed(origin)?;
  795. Self::ensure_known_entity_id(entity_id)?;
  796. let (entity, _) = Self::get_entity_and_access_level(account_id, entity_id, actor)?;
  797. let class = Self::class_by_id(entity.class_id);
  798. // Check that schema_id is a valid index of class schemas vector:
  799. class.ensure_schema_id_exists(schema_id)?;
  800. // Ensure class schema is active
  801. class.ensure_schema_is_active(schema_id)?;
  802. // Check that schema id is not yet added to this entity
  803. entity.ensure_schema_id_is_not_added(schema_id)?;
  804. let class_schema_opt = class.schemas.get(schema_id as usize);
  805. let schema_prop_ids = class_schema_opt.unwrap().get_properties();
  806. let current_entity_values = entity.values.clone();
  807. let mut appended_entity_values = entity.values.clone();
  808. let mut entities_rc_to_increment_vec = vec![];
  809. for prop_id in schema_prop_ids.iter() {
  810. if current_entity_values.contains_key(prop_id) {
  811. // A property is already added to the entity and cannot be updated
  812. // while adding a schema support to this entity.
  813. continue;
  814. }
  815. Self::add_new_property_value(&class, &entity, *prop_id, &property_values, &mut entities_rc_to_increment_vec, &mut appended_entity_values)?;
  816. }
  817. //
  818. // == MUTATION SAFE ==
  819. //
  820. <EntityById<T>>::mutate(entity_id, |entity| {
  821. // Add a new schema to the list of schemas supported by this entity.
  822. entity.supported_schemas.insert(schema_id);
  823. // Update entity values only if new properties have been added.
  824. if appended_entity_values.len() > entity.values.len() {
  825. entity.values = appended_entity_values;
  826. }
  827. });
  828. entities_rc_to_increment_vec
  829. .iter()
  830. .for_each(|entities_rc_to_increment| {
  831. Self::increment_entities_rc(entities_rc_to_increment);
  832. });
  833. Ok(())
  834. }
  835. pub fn update_entity_property_values(
  836. origin,
  837. actor: Actor<T>,
  838. entity_id: T::EntityId,
  839. new_property_values: BTreeMap<PropertyId, PropertyValue<T>>
  840. ) -> dispatch::Result {
  841. let account_id = ensure_signed(origin)?;
  842. Self::ensure_known_entity_id(entity_id)?;
  843. let (entity, access_level) = Self::get_entity_and_access_level(account_id, entity_id, actor)?;
  844. let class = Self::class_by_id(entity.class_id);
  845. // Ensure property values were not locked on class level
  846. ensure!(
  847. !class.get_permissions().all_entity_property_values_locked(),
  848. ERROR_ALL_PROP_WERE_LOCKED_ON_CLASS_LEVEL
  849. );
  850. // Get current property values of an entity as a mutable vector,
  851. // so we can update them if new values provided present in new_property_values.
  852. let mut updated_values = entity.values.clone();
  853. let mut updated = false;
  854. let mut entities_rc_to_increment_vec = vec![];
  855. let mut entities_rc_to_decrement_vec = vec![];
  856. // Iterate over a vector of new values and update corresponding properties
  857. // of this entity if new values are valid.
  858. for (id, new_value) in new_property_values.into_iter() {
  859. // Try to find a current property value in the entity
  860. // by matching its id to the id of a property with an updated value.
  861. let current_prop_value = updated_values
  862. .get_mut(&id)
  863. // Throw an error if a property was not found on entity
  864. // by an in-class index of a property update.
  865. .ok_or(ERROR_UNKNOWN_ENTITY_PROP_ID)?;
  866. // Skip update if new value is equal to the current one or class property type
  867. // is locked for update from current actor
  868. if new_value == *current_prop_value {
  869. continue;
  870. } else {
  871. let (mut temp_entities_rc_to_increment_vec, mut temp_entities_rc_to_decrement_vec) = Self::perform_entity_property_value_update(&class, &entity, id, access_level, new_value, current_prop_value)?;
  872. entities_rc_to_increment_vec.append(&mut temp_entities_rc_to_increment_vec);
  873. entities_rc_to_decrement_vec.append(&mut temp_entities_rc_to_decrement_vec);
  874. updated = true;
  875. }
  876. }
  877. // If property values should be updated:
  878. if updated {
  879. //
  880. // == MUTATION SAFE ==
  881. //
  882. <EntityById<T>>::mutate(entity_id, |entity| {
  883. entity.values = updated_values;
  884. });
  885. entities_rc_to_increment_vec
  886. .iter()
  887. .for_each(|entities_rc_to_increment| {
  888. Self::increment_entities_rc(entities_rc_to_increment);
  889. });
  890. entities_rc_to_decrement_vec
  891. .iter()
  892. .for_each(|entities_rc_to_decrement| {
  893. Self::decrement_entities_rc(entities_rc_to_decrement);
  894. });
  895. }
  896. Ok(())
  897. }
  898. pub fn clear_entity_property_vector(
  899. origin,
  900. actor: Actor<T>,
  901. entity_id: T::EntityId,
  902. in_class_schema_property_id: PropertyId
  903. ) -> dispatch::Result {
  904. let account_id = ensure_signed(origin)?;
  905. Self::ensure_known_entity_id(entity_id)?;
  906. let (entity, access_level) = Self::get_entity_and_access_level(account_id, entity_id, actor)?;
  907. let current_property_value_vec =
  908. Self::get_property_value_vec(&entity, in_class_schema_property_id)?;
  909. Self::ensure_class_property_type_unlocked_for(
  910. entity.class_id,
  911. in_class_schema_property_id,
  912. access_level,
  913. )?;
  914. let entities_rc_to_decrement = current_property_value_vec
  915. .get_vec_value()
  916. .get_involved_entities();
  917. //
  918. // == MUTATION SAFE ==
  919. //
  920. // Clear property value vector:
  921. <EntityById<T>>::mutate(entity_id, |entity| {
  922. if let Some(PropertyValue::Vector(current_property_value_vec)) =
  923. entity.values.get_mut(&in_class_schema_property_id)
  924. {
  925. current_property_value_vec.vec_clear();
  926. }
  927. if let Some(entities_rc_to_decrement) = entities_rc_to_decrement {
  928. Self::decrement_entities_rc(&entities_rc_to_decrement);
  929. }
  930. });
  931. Ok(())
  932. }
  933. pub fn remove_at_entity_property_vector(
  934. origin,
  935. actor: Actor<T>,
  936. entity_id: T::EntityId,
  937. in_class_schema_property_id: PropertyId,
  938. index_in_property_vec: VecMaxLength,
  939. nonce: T::Nonce
  940. ) -> dispatch::Result {
  941. let account_id = ensure_signed(origin)?;
  942. Self::ensure_known_entity_id(entity_id)?;
  943. let (entity, access_level) = Self::get_entity_and_access_level(account_id, entity_id, actor)?;
  944. let current_property_value_vec =
  945. Self::get_property_value_vec(&entity, in_class_schema_property_id)?;
  946. Self::ensure_class_property_type_unlocked_for(
  947. entity.class_id,
  948. in_class_schema_property_id,
  949. access_level,
  950. )?;
  951. // Ensure property value vector nonces equality to avoid possible data races,
  952. // when performing vector specific operations
  953. current_property_value_vec.ensure_nonce_equality(nonce)?;
  954. current_property_value_vec
  955. .ensure_index_in_property_vector_is_valid(index_in_property_vec)?;
  956. let involved_entity_id = current_property_value_vec
  957. .get_vec_value()
  958. .get_involved_entities()
  959. .map(|involved_entities| involved_entities[index_in_property_vec as usize]);
  960. //
  961. // == MUTATION SAFE ==
  962. //
  963. // Remove property value vector
  964. <EntityById<T>>::mutate(entity_id, |entity| {
  965. if let Some(PropertyValue::Vector(current_prop_value)) =
  966. entity.values.get_mut(&in_class_schema_property_id)
  967. {
  968. current_prop_value.vec_remove_at(index_in_property_vec)
  969. }
  970. });
  971. if let Some(involved_entity_id) = involved_entity_id {
  972. <EntityById<T>>::mutate(involved_entity_id, |entity| entity.reference_count -= 1)
  973. }
  974. Ok(())
  975. }
  976. pub fn insert_at_entity_property_vector(
  977. origin,
  978. actor: Actor<T>,
  979. entity_id: T::EntityId,
  980. in_class_schema_property_id: PropertyId,
  981. index_in_property_vec: VecMaxLength,
  982. property_value: SinglePropertyValue<T>,
  983. nonce: T::Nonce
  984. ) -> dispatch::Result {
  985. let account_id = ensure_signed(origin)?;
  986. Self::ensure_known_entity_id(entity_id)?;
  987. let (entity, access_level) = Self::get_entity_and_access_level(account_id, entity_id, actor)?;
  988. // Try to find a current property value in the entity
  989. // by matching its id to the id of a property with an updated value.
  990. if let Some(PropertyValue::Vector(entity_prop_value)) =
  991. entity.values.get(&in_class_schema_property_id)
  992. {
  993. let class_prop = Self::ensure_class_property_type_unlocked_for(
  994. entity.class_id,
  995. in_class_schema_property_id,
  996. access_level,
  997. )?;
  998. // Ensure property value vector nonces equality to avoid possible data races,
  999. // when performing vector specific operations
  1000. entity_prop_value.ensure_nonce_equality(nonce)?;
  1001. // Validate a new property value against the type of this property
  1002. // and check any additional constraints like the length of a vector
  1003. // if it's a vector property or the length of a text if it's a text property.
  1004. class_prop.ensure_prop_value_can_be_inserted_at_prop_vec(
  1005. &property_value,
  1006. entity_prop_value,
  1007. index_in_property_vec,
  1008. entity.get_permissions().get_controller(),
  1009. )?;
  1010. };
  1011. //
  1012. // == MUTATION SAFE ==
  1013. //
  1014. // Insert property value into property value vector
  1015. <EntityById<T>>::mutate(entity_id, |entity| {
  1016. let value = property_value.get_value();
  1017. if let Some(entities_rc_to_increment) = value.get_involved_entity() {
  1018. Self::increment_entities_rc(&[entities_rc_to_increment]);
  1019. }
  1020. if let Some(PropertyValue::Vector(current_prop_value)) =
  1021. entity.values.get_mut(&in_class_schema_property_id)
  1022. {
  1023. current_prop_value.vec_insert_at(index_in_property_vec, value)
  1024. }
  1025. });
  1026. Ok(())
  1027. }
  1028. pub fn transaction(origin, actor: Actor<T>, operations: Vec<OperationType<T>>) -> dispatch::Result {
  1029. // This map holds the T::EntityId of the entity created as a result of executing a CreateEntity Operation
  1030. // keyed by the indexed of the operation, in the operations vector.
  1031. let mut entity_created_in_operation: BTreeMap<usize, T::EntityId> = BTreeMap::new();
  1032. let raw_origin = origin.into().map_err(|_| ERROR_ORIGIN_CANNOT_BE_MADE_INTO_RAW_ORIGIN)?;
  1033. for (op_index, operation_type) in operations.into_iter().enumerate() {
  1034. let origin = T::Origin::from(raw_origin.clone());
  1035. let actor = actor.clone();
  1036. match operation_type {
  1037. OperationType::CreateEntity(create_entity_operation) => {
  1038. Self::create_entity(origin, create_entity_operation.class_id, actor)?;
  1039. // entity id of newly created entity
  1040. let entity_id = Self::next_entity_id() - T::EntityId::one();
  1041. entity_created_in_operation.insert(op_index, entity_id);
  1042. },
  1043. OperationType::UpdatePropertyValues(update_property_values_operation) => {
  1044. let entity_id = operations::parametrized_entity_to_entity_id(&entity_created_in_operation, update_property_values_operation.entity_id)?;
  1045. let property_values = operations::parametrized_property_values_to_property_values(&entity_created_in_operation, update_property_values_operation.new_parametrized_property_values)?;
  1046. Self::update_entity_property_values(origin, actor, entity_id, property_values)?;
  1047. },
  1048. OperationType::AddSchemaSupportToEntity(add_schema_support_to_entity_operation) => {
  1049. let entity_id = operations::parametrized_entity_to_entity_id(&entity_created_in_operation, add_schema_support_to_entity_operation.entity_id)?;
  1050. let schema_id = add_schema_support_to_entity_operation.schema_id;
  1051. let property_values = operations::parametrized_property_values_to_property_values(&entity_created_in_operation, add_schema_support_to_entity_operation.parametrized_property_values)?;
  1052. Self::add_schema_support_to_entity(origin, actor, entity_id, schema_id, property_values)?;
  1053. }
  1054. }
  1055. }
  1056. Ok(())
  1057. }
  1058. }
  1059. }
  1060. impl<T: Trait> Module<T> {
  1061. fn complete_entity_creation(class_id: T::ClassId, entity_controller: EntityController<T>) {
  1062. let entity_id = Self::next_entity_id();
  1063. let new_entity = Entity::<T>::new(
  1064. entity_controller,
  1065. class_id,
  1066. BTreeSet::new(),
  1067. BTreeMap::new(),
  1068. );
  1069. // Save newly created entity:
  1070. EntityById::insert(entity_id, new_entity);
  1071. // Increment the next entity id:
  1072. <NextEntityId<T>>::mutate(|n| *n += T::EntityId::one());
  1073. <ClassById<T>>::mutate(class_id, |class| {
  1074. class.increment_entities_count();
  1075. });
  1076. }
  1077. fn complete_entity_removal(entity_id: T::EntityId) {
  1078. let class_id = Self::get_class_id_by_entity_id(entity_id);
  1079. <EntityById<T>>::remove(entity_id);
  1080. <ClassById<T>>::mutate(class_id, |class| class.decrement_entities_count());
  1081. }
  1082. fn increment_entities_rc(entity_ids: &[T::EntityId]) {
  1083. entity_ids.iter().for_each(|entity_id| {
  1084. <EntityById<T>>::mutate(entity_id, |entity| entity.reference_count += 1)
  1085. });
  1086. }
  1087. fn decrement_entities_rc(entity_ids: &[T::EntityId]) {
  1088. entity_ids.iter().for_each(|entity_id| {
  1089. <EntityById<T>>::mutate(entity_id, |entity| entity.reference_count -= 1)
  1090. });
  1091. }
  1092. /// Returns the stored class if exist, error otherwise.
  1093. fn ensure_class_exists(class_id: T::ClassId) -> Result<Class<T>, &'static str> {
  1094. ensure!(<ClassById<T>>::exists(class_id), ERROR_CLASS_NOT_FOUND);
  1095. Ok(Self::class_by_id(class_id))
  1096. }
  1097. /// Add property value, if was not already povided for the property of this schema
  1098. fn add_new_property_value(
  1099. class: &Class<T>,
  1100. entity: &Entity<T>,
  1101. prop_id: PropertyId,
  1102. property_values: &BTreeMap<PropertyId, PropertyValue<T>>,
  1103. entities_rc_to_increment_vec: &mut Vec<Vec<T::EntityId>>,
  1104. appended_entity_values: &mut BTreeMap<PropertyId, PropertyValue<T>>,
  1105. ) -> Result<(), &'static str> {
  1106. let class_prop = &class.properties[prop_id as usize];
  1107. if let Some(new_value) = property_values.get(&prop_id) {
  1108. class_prop.ensure_property_value_to_update_is_valid(
  1109. new_value,
  1110. entity.get_permissions().get_controller(),
  1111. )?;
  1112. if let Some(entities_rc_to_increment) = new_value.get_involved_entities() {
  1113. entities_rc_to_increment_vec.push(entities_rc_to_increment);
  1114. }
  1115. appended_entity_values.insert(prop_id, new_value.to_owned());
  1116. } else {
  1117. // All required prop values should be provided
  1118. ensure!(!class_prop.required, ERROR_MISSING_REQUIRED_PROP);
  1119. // Add all missing non required schema prop values as PropertyValue::default()
  1120. appended_entity_values.insert(prop_id, PropertyValue::default());
  1121. }
  1122. Ok(())
  1123. }
  1124. pub fn perform_entity_property_value_update(
  1125. class: &Class<T>,
  1126. entity: &Entity<T>,
  1127. id: PropertyId,
  1128. access_level: EntityAccessLevel,
  1129. new_value: PropertyValue<T>,
  1130. current_prop_value: &mut PropertyValue<T>,
  1131. ) -> Result<(EntitiesRcVec<T>, EntitiesRcVec<T>), &'static str> {
  1132. let mut entities_rc_to_increment_vec = vec![];
  1133. let mut entities_rc_to_decrement_vec = vec![];
  1134. // Get class-level information about this property
  1135. if let Some(class_prop) = class.properties.get(id as usize) {
  1136. // Ensure class property is unlocked for given actor
  1137. ensure!(
  1138. !class_prop.is_locked_from(access_level),
  1139. ERROR_CLASS_PROPERTY_TYPE_IS_LOCKED_FOR_GIVEN_ACTOR
  1140. );
  1141. // Validate a new property value against the type of this property
  1142. // and check any additional constraints like the length of a vector
  1143. // if it's a vector property or the length of a text if it's a text property.
  1144. class_prop.ensure_property_value_to_update_is_valid(
  1145. &new_value,
  1146. entity.get_permissions().get_controller(),
  1147. )?;
  1148. // Get unique entity ids to update rc
  1149. if let (Some(entities_rc_to_increment), Some(entities_rc_to_decrement)) = (
  1150. new_value.get_involved_entities(),
  1151. current_prop_value.get_involved_entities(),
  1152. ) {
  1153. let (entities_rc_to_decrement, entities_rc_to_increment): (
  1154. Vec<T::EntityId>,
  1155. Vec<T::EntityId>,
  1156. ) = entities_rc_to_decrement
  1157. .into_iter()
  1158. .zip(entities_rc_to_increment.into_iter())
  1159. .filter(|(entity_rc_to_decrement, entity_rc_to_increment)| {
  1160. entity_rc_to_decrement != entity_rc_to_increment
  1161. })
  1162. .unzip();
  1163. entities_rc_to_increment_vec.push(entities_rc_to_increment);
  1164. entities_rc_to_decrement_vec.push(entities_rc_to_decrement);
  1165. }
  1166. // Update a current prop value in a mutable vector, if a new value is valid.
  1167. current_prop_value.update(new_value);
  1168. }
  1169. Ok((entities_rc_to_increment_vec, entities_rc_to_decrement_vec))
  1170. }
  1171. fn get_property_value_vec(
  1172. entity: &Entity<T>,
  1173. in_class_schema_property_id: PropertyId,
  1174. ) -> Result<&VecPropertyValue<T>, &'static str> {
  1175. entity
  1176. .values
  1177. .get(&in_class_schema_property_id)
  1178. // Throw an error if a property was not found on entity
  1179. // by an in-class index of a property.
  1180. .ok_or(ERROR_UNKNOWN_ENTITY_PROP_ID)?
  1181. .as_vec_property_value()
  1182. // Ensure prop value under given class schema property id is vector
  1183. .ok_or(ERROR_PROP_VALUE_UNDER_GIVEN_INDEX_IS_NOT_A_VECTOR)
  1184. }
  1185. fn get_entity_and_access_level(
  1186. account_id: T::AccountId,
  1187. entity_id: T::EntityId,
  1188. actor: Actor<T>,
  1189. ) -> Result<(Entity<T>, EntityAccessLevel), &'static str> {
  1190. let (entity, class) = Self::get_entity_and_class(entity_id);
  1191. let access_level = EntityAccessLevel::derive(
  1192. &account_id,
  1193. entity.get_permissions(),
  1194. class.get_permissions(),
  1195. actor,
  1196. )?;
  1197. Ok((entity, access_level))
  1198. }
  1199. pub fn get_entity_and_class(entity_id: T::EntityId) -> (Entity<T>, Class<T>) {
  1200. let entity = <EntityById<T>>::get(entity_id);
  1201. let class = ClassById::get(entity.class_id);
  1202. (entity, class)
  1203. }
  1204. pub fn get_class_id_by_entity_id(entity_id: T::EntityId) -> T::ClassId {
  1205. <EntityById<T>>::get(entity_id).class_id
  1206. }
  1207. pub fn ensure_class_property_type_unlocked_for(
  1208. class_id: T::ClassId,
  1209. in_class_schema_property_id: PropertyId,
  1210. entity_access_level: EntityAccessLevel,
  1211. ) -> Result<Property<T>, &'static str> {
  1212. let class = Self::class_by_id(class_id);
  1213. // Ensure property values were not locked on class level
  1214. ensure!(
  1215. !class.get_permissions().all_entity_property_values_locked(),
  1216. ERROR_ALL_PROP_WERE_LOCKED_ON_CLASS_LEVEL
  1217. );
  1218. // Get class-level information about this property
  1219. let class_prop = class
  1220. .properties
  1221. .get(in_class_schema_property_id as usize)
  1222. // Throw an error if a property was not found on class
  1223. // by an in-class index of a property.
  1224. .ok_or(ERROR_CLASS_PROP_NOT_FOUND)?;
  1225. ensure!(
  1226. !class_prop.is_locked_from(entity_access_level),
  1227. ERROR_CLASS_PROPERTY_TYPE_IS_LOCKED_FOR_GIVEN_ACTOR
  1228. );
  1229. Ok(class_prop.to_owned())
  1230. }
  1231. pub fn ensure_known_class_id(class_id: T::ClassId) -> dispatch::Result {
  1232. ensure!(<ClassById<T>>::exists(class_id), ERROR_CLASS_NOT_FOUND);
  1233. Ok(())
  1234. }
  1235. pub fn ensure_known_entity_id(entity_id: T::EntityId) -> dispatch::Result {
  1236. ensure!(<EntityById<T>>::exists(entity_id), ERROR_ENTITY_NOT_FOUND);
  1237. Ok(())
  1238. }
  1239. pub fn ensure_rc_is_zero(entity_id: T::EntityId) -> dispatch::Result {
  1240. let entity = Self::entity_by_id(entity_id);
  1241. ensure!(
  1242. entity.reference_count == 0,
  1243. ERROR_ENTITY_REFERENCE_COUNTER_DOES_NOT_EQUAL_TO_ZERO
  1244. );
  1245. Ok(())
  1246. }
  1247. pub fn ensure_curator_group_exists(group_id: &T::CuratorGroupId) -> dispatch::Result {
  1248. ensure!(
  1249. <CuratorGroupById<T>>::exists(group_id),
  1250. ERROR_CURATOR_GROUP_DOES_NOT_EXIST
  1251. );
  1252. Ok(())
  1253. }
  1254. pub fn ensure_voucher_limit_not_reached(voucher: EntityCreationVoucher) -> dispatch::Result {
  1255. ensure!(voucher.limit_not_reached(), ERROR_VOUCHER_LIMIT_REACHED);
  1256. Ok(())
  1257. }
  1258. pub fn ensure_curator_group_does_not_exist(group_id: T::CuratorGroupId) -> dispatch::Result {
  1259. ensure!(
  1260. !<CuratorGroupById<T>>::exists(group_id),
  1261. ERROR_CURATOR_GROUP_ALREADY_EXISTS
  1262. );
  1263. Ok(())
  1264. }
  1265. pub fn ensure_curator_groups_exist(
  1266. curator_groups: &BTreeSet<T::CuratorGroupId>,
  1267. ) -> dispatch::Result {
  1268. for curator_group in curator_groups {
  1269. Self::ensure_curator_group_exists(curator_group)?;
  1270. }
  1271. Ok(())
  1272. }
  1273. pub fn ensure_max_number_of_curators_limit_not_reached(
  1274. group_id: T::CuratorGroupId,
  1275. ) -> dispatch::Result {
  1276. let curator_group = Self::curator_group_by_id(group_id);
  1277. ensure!(
  1278. curator_group.get_curators().len() < T::NumberOfCuratorsConstraint::get() as usize,
  1279. ERROR_NUMBER_OF_CURATORS_PER_GROUP_LIMIT_REACHED
  1280. );
  1281. Ok(())
  1282. }
  1283. pub fn ensure_class_permissions_are_valid(
  1284. class_permissions: &ClassPermissions<T>,
  1285. ) -> dispatch::Result {
  1286. class_permissions.ensure_maintainers_limit_not_reached()?;
  1287. Self::ensure_curator_groups_exist(class_permissions.get_maintainers())?;
  1288. Ok(())
  1289. }
  1290. pub fn ensure_non_empty_schema(
  1291. existing_properties: &[PropertyId],
  1292. new_properties: &[Property<T>],
  1293. ) -> dispatch::Result {
  1294. let non_empty_schema = !existing_properties.is_empty() || !new_properties.is_empty();
  1295. ensure!(non_empty_schema, ERROR_NO_PROPS_IN_CLASS_SCHEMA);
  1296. Ok(())
  1297. }
  1298. pub fn ensure_class_name_is_valid(text: &[u8]) -> dispatch::Result {
  1299. T::ClassNameConstraint::get().ensure_valid(
  1300. text.len(),
  1301. ERROR_CLASS_NAME_TOO_SHORT,
  1302. ERROR_CLASS_NAME_TOO_LONG,
  1303. )
  1304. }
  1305. pub fn ensure_class_description_is_valid(text: &[u8]) -> dispatch::Result {
  1306. T::ClassDescriptionConstraint::get().ensure_valid(
  1307. text.len(),
  1308. ERROR_CLASS_DESCRIPTION_TOO_SHORT,
  1309. ERROR_CLASS_DESCRIPTION_TOO_LONG,
  1310. )
  1311. }
  1312. pub fn ensure_class_limit_not_reached() -> dispatch::Result {
  1313. ensure!(
  1314. T::NumberOfClassesConstraint::get() < <ClassById<T>>::enumerate().count() as MaxNumber,
  1315. ERROR_CLASS_LIMIT_REACHED
  1316. );
  1317. Ok(())
  1318. }
  1319. pub fn ensure_valid_number_of_entities_per_class(
  1320. maximum_entities_count: CreationLimit,
  1321. ) -> dispatch::Result {
  1322. ensure!(
  1323. maximum_entities_count < T::EntitiesCreationConstraint::get(),
  1324. ERROR_ENTITIES_NUMBER_PER_CLASS_CONSTRAINT_VIOLATED
  1325. );
  1326. Ok(())
  1327. }
  1328. pub fn ensure_valid_number_of_class_entities_per_actor_constraint(
  1329. per_controller_entity_creation_limit: CreationLimit,
  1330. ) -> dispatch::Result {
  1331. ensure!(
  1332. per_controller_entity_creation_limit < T::IndividualEntitiesCreationConstraint::get(),
  1333. ERROR_NUMBER_OF_CLASS_ENTITIES_PER_ACTOR_CONSTRAINT_VIOLATED
  1334. );
  1335. Ok(())
  1336. }
  1337. pub fn ensure_valid_number_of_class_entities_per_actor(
  1338. // per class individual controller entity creation limit
  1339. per_controller_entity_creation_limit: CreationLimit,
  1340. maximum_entities_count: CreationLimit,
  1341. ) -> dispatch::Result {
  1342. ensure!(
  1343. per_controller_entity_creation_limit >= maximum_entities_count,
  1344. ERROR_INDIVIDUAL_NUMBER_OF_CLASS_ENTITIES_PER_ACTOR_IS_TOO_BIG
  1345. );
  1346. Ok(())
  1347. }
  1348. pub fn ensure_entities_limits_are_valid(
  1349. maximum_entities_count: CreationLimit,
  1350. per_controller_entities_creation_limit: CreationLimit,
  1351. ) -> dispatch::Result {
  1352. ensure!(
  1353. per_controller_entities_creation_limit < maximum_entities_count,
  1354. ERROR_PER_CONTROLLER_ENTITIES_CREATION_LIMIT_EXCEEDS_OVERALL_LIMIT
  1355. );
  1356. Self::ensure_valid_number_of_entities_per_class(maximum_entities_count)?;
  1357. Self::ensure_valid_number_of_class_entities_per_actor_constraint(
  1358. per_controller_entities_creation_limit,
  1359. )
  1360. }
  1361. }