Browse Source

Fix nonce mechanism design issue

iorveth 4 years ago
parent
commit
3de80c0199

+ 10 - 10
runtime-modules/content-directory/src/example.rs

@@ -421,10 +421,10 @@ fn create_podcast_class_schema() {
         // 15
         p.next_text_value(b"crypto,blockchain,governance,staking,bitcoin,ethereum".to_vec());
         // 16
-        p.next_value(PropertyValue::TextVec(vec![
-            b"Technology".to_vec(),
-            b"Software How-To".to_vec(),
-        ]));
+        p.next_value(PropertyValue::TextVec(
+            vec![b"Technology".to_vec(), b"Software How-To".to_vec()],
+            <Runtime as Trait>::Nonce::default(),
+        ));
         // 17
         p.next_text_value(
             b"https://ssl-static.libsyn.com/p/assets/2/d/2/5/2d25eb5fa72739f7/iTunes_Cover.png"
@@ -518,20 +518,20 @@ fn create_podcast_class_schema() {
     })
 }
 
-struct PropHelper {
+struct PropHelper<T: Trait> {
     prop_idx: u16,
-    property_values: BTreeMap<u16, PropertyValue>,
+    property_values: BTreeMap<u16, PropertyValue<T>>,
 }
 
-impl PropHelper {
-    fn new() -> PropHelper {
+impl<T: Trait> PropHelper<T> {
+    fn new() -> PropHelper<T> {
         PropHelper {
             prop_idx: 0,
             property_values: BTreeMap::new(),
         }
     }
 
-    fn next_value(&mut self, value: PropertyValue) {
+    fn next_value(&mut self, value: PropertyValue<T>) {
         self.property_values.insert(self.prop_idx, value);
         self.prop_idx += 1;
     }
@@ -540,7 +540,7 @@ impl PropHelper {
         self.next_value(PropertyValue::Text(text))
     }
 
-    fn get_property_values(self) -> BTreeMap<u16, PropertyValue> {
+    fn get_property_values(self) -> BTreeMap<u16, PropertyValue<T>> {
         self.property_values
     }
 }

+ 191 - 164
runtime-modules/content-directory/src/lib.rs

@@ -24,12 +24,13 @@ mod permissions;
 mod tests;
 
 pub use constraint::*;
+use core::fmt::Debug;
 pub use credentials::*;
 pub use errors::*;
 pub use operations::*;
 pub use permissions::*;
 
-pub trait Trait: system::Trait {
+pub trait Trait: system::Trait + Debug {
     /// Type that represents an actor or group of actors in the system.
     type Credential: Parameter
         + Member
@@ -55,7 +56,8 @@ pub trait Trait: system::Trait {
         + MaybeSerializeDeserialize
         + Eq
         + PartialEq
-        + Ord;
+        + Ord
+        + From<u32>;
 
     /// Security/configuration constraints
 
@@ -237,12 +239,8 @@ pub struct Entity<T: Trait> {
 
     /// Values for properties on class that are used by some schema used by this entity!
     /// Length is no more than Class.properties.
-    pub values: BTreeMap<u16, PropertyValue>,
-
-    /// Map, representing relation between entity vec_values index and nonce, where vec_value was updated
-    /// Used to avoid race update conditions
-    pub vec_value_nonces: BTreeMap<u16, T::Nonce>,
-    // pub deleted: bool,
+    pub values: BTreeMap<u16, PropertyValue<T>>, // Map, representing relation between entity vec_values index and nonce, where vec_value was updated
+                                                 // pub deleted: bool
 }
 
 impl<T: Trait> Default for Entity<T> {
@@ -251,7 +249,6 @@ impl<T: Trait> Default for Entity<T> {
             class_id: ClassId::default(),
             supported_schemas: BTreeSet::new(),
             values: BTreeMap::new(),
-            vec_value_nonces: BTreeMap::new(),
         }
     }
 }
@@ -260,13 +257,12 @@ impl<T: Trait> Entity<T> {
     fn new(
         class_id: ClassId,
         supported_schemas: BTreeSet<u16>,
-        values: BTreeMap<u16, PropertyValue>,
+        values: BTreeMap<u16, PropertyValue<T>>,
     ) -> Self {
         Self {
             class_id,
             supported_schemas,
             values,
-            ..Entity::default()
         }
     }
 }
@@ -353,7 +349,7 @@ impl Default for PropertyType {
 
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
-pub enum PropertyValue {
+pub enum PropertyValue<T: Trait> {
     // Single value:
     Bool(bool),
     Uint16(u16),
@@ -365,49 +361,109 @@ pub enum PropertyValue {
     Text(Vec<u8>),
     Reference(EntityId),
 
-    // Vector of values:
-    BoolVec(Vec<bool>),
-    Uint16Vec(Vec<u16>),
-    Uint32Vec(Vec<u32>),
-    Uint64Vec(Vec<u64>),
-    Int16Vec(Vec<i16>),
-    Int32Vec(Vec<i32>),
-    Int64Vec(Vec<i64>),
-    TextVec(Vec<Vec<u8>>),
-    ReferenceVec(Vec<EntityId>),
+    // Vector of values, nonce used to avoid race update conditions:
+    BoolVec(Vec<bool>, T::Nonce),
+    Uint16Vec(Vec<u16>, T::Nonce),
+    Uint32Vec(Vec<u32>, T::Nonce),
+    Uint64Vec(Vec<u64>, T::Nonce),
+    Int16Vec(Vec<i16>, T::Nonce),
+    Int32Vec(Vec<i32>, T::Nonce),
+    Int64Vec(Vec<i64>, T::Nonce),
+    TextVec(Vec<Vec<u8>>, T::Nonce),
+    ReferenceVec(Vec<EntityId>, T::Nonce),
     // External(ExternalPropertyType),
     // ExternalVec(Vec<ExternalPropertyType>),
 }
 
-impl PropertyValue {
+impl<T: Trait> PropertyValue<T> {
+    fn update(&mut self, new_value: PropertyValue<T>) {
+        if let Some(new_nonce) = self.try_increment_nonce() {
+            *self = new_value;
+            self.try_set_nonce(new_nonce)
+        } else {
+            *self = new_value;
+        }
+    }
+
+    fn try_increment_nonce(&mut self) -> Option<T::Nonce> {
+        // Increment nonce if property value is vec
+        match self {
+            PropertyValue::BoolVec(_, nonce)
+            | PropertyValue::Uint16Vec(_, nonce)
+            | PropertyValue::Uint32Vec(_, nonce)
+            | PropertyValue::Uint64Vec(_, nonce)
+            | PropertyValue::Int16Vec(_, nonce)
+            | PropertyValue::Int32Vec(_, nonce)
+            | PropertyValue::Int64Vec(_, nonce)
+            | PropertyValue::TextVec(_, nonce)
+            | PropertyValue::ReferenceVec(_, nonce) => {
+                *nonce += T::Nonce::one();
+                Some(*nonce)
+            }
+            _ => None,
+        }
+    }
+
+    fn try_set_nonce(&mut self, new_nonce: T::Nonce) {
+        // Set new nonce if property value is vec
+        match self {
+            PropertyValue::BoolVec(_, nonce)
+            | PropertyValue::Uint16Vec(_, nonce)
+            | PropertyValue::Uint32Vec(_, nonce)
+            | PropertyValue::Uint64Vec(_, nonce)
+            | PropertyValue::Int16Vec(_, nonce)
+            | PropertyValue::Int32Vec(_, nonce)
+            | PropertyValue::Int64Vec(_, nonce)
+            | PropertyValue::TextVec(_, nonce)
+            | PropertyValue::ReferenceVec(_, nonce) => *nonce = new_nonce,
+            _ => (),
+        }
+    }
+
+    fn get_nonce(&self) -> Option<T::Nonce> {
+        match self {
+            PropertyValue::BoolVec(_, nonce)
+            | PropertyValue::Uint16Vec(_, nonce)
+            | PropertyValue::Uint32Vec(_, nonce)
+            | PropertyValue::Uint64Vec(_, nonce)
+            | PropertyValue::Int16Vec(_, nonce)
+            | PropertyValue::Int32Vec(_, nonce)
+            | PropertyValue::Int64Vec(_, nonce)
+            | PropertyValue::TextVec(_, nonce)
+            | PropertyValue::ReferenceVec(_, nonce) => Some(*nonce),
+            _ => None,
+        }
+    }
+
     fn is_vec(&self) -> bool {
         match self {
-            PropertyValue::BoolVec(_)
-            | PropertyValue::Uint16Vec(_)
-            | PropertyValue::Uint32Vec(_)
-            | PropertyValue::Uint64Vec(_)
-            | PropertyValue::Int16Vec(_)
-            | PropertyValue::Int32Vec(_)
-            | PropertyValue::Int64Vec(_)
-            | PropertyValue::TextVec(_)
-            | PropertyValue::ReferenceVec(_) => true,
+            PropertyValue::BoolVec(_, _)
+            | PropertyValue::Uint16Vec(_, _)
+            | PropertyValue::Uint32Vec(_, _)
+            | PropertyValue::Uint64Vec(_, _)
+            | PropertyValue::Int16Vec(_, _)
+            | PropertyValue::Int32Vec(_, _)
+            | PropertyValue::Int64Vec(_, _)
+            | PropertyValue::TextVec(_, _)
+            | PropertyValue::ReferenceVec(_, _) => true,
             _ => false,
         }
     }
 
     fn vec_clear(&mut self) {
         match self {
-            PropertyValue::BoolVec(vec) => *vec = vec![],
-            PropertyValue::Uint16Vec(vec) => *vec = vec![],
-            PropertyValue::Uint32Vec(vec) => *vec = vec![],
-            PropertyValue::Uint64Vec(vec) => *vec = vec![],
-            PropertyValue::Int16Vec(vec) => *vec = vec![],
-            PropertyValue::Int32Vec(vec) => *vec = vec![],
-            PropertyValue::Int64Vec(vec) => *vec = vec![],
-            PropertyValue::TextVec(vec) => *vec = vec![],
-            PropertyValue::ReferenceVec(vec) => *vec = vec![],
+            PropertyValue::BoolVec(vec, _) => *vec = vec![],
+            PropertyValue::Uint16Vec(vec, _) => *vec = vec![],
+            PropertyValue::Uint32Vec(vec, _) => *vec = vec![],
+            PropertyValue::Uint64Vec(vec, _) => *vec = vec![],
+            PropertyValue::Int16Vec(vec, _) => *vec = vec![],
+            PropertyValue::Int32Vec(vec, _) => *vec = vec![],
+            PropertyValue::Int64Vec(vec, _) => *vec = vec![],
+            PropertyValue::TextVec(vec, _) => *vec = vec![],
+            PropertyValue::ReferenceVec(vec, _) => *vec = vec![],
             _ => (),
         }
+        self.try_increment_nonce();
     }
 
     fn vec_remove_at(&mut self, index_in_property_vec: u32) {
@@ -418,17 +474,18 @@ impl PropertyValue {
         }
 
         match self {
-            PropertyValue::BoolVec(vec) => remove_at_checked(vec, index_in_property_vec),
-            PropertyValue::Uint16Vec(vec) => remove_at_checked(vec, index_in_property_vec),
-            PropertyValue::Uint32Vec(vec) => remove_at_checked(vec, index_in_property_vec),
-            PropertyValue::Uint64Vec(vec) => remove_at_checked(vec, index_in_property_vec),
-            PropertyValue::Int16Vec(vec) => remove_at_checked(vec, index_in_property_vec),
-            PropertyValue::Int32Vec(vec) => remove_at_checked(vec, index_in_property_vec),
-            PropertyValue::Int64Vec(vec) => remove_at_checked(vec, index_in_property_vec),
-            PropertyValue::TextVec(vec) => remove_at_checked(vec, index_in_property_vec),
-            PropertyValue::ReferenceVec(vec) => remove_at_checked(vec, index_in_property_vec),
+            PropertyValue::BoolVec(vec, _) => remove_at_checked(vec, index_in_property_vec),
+            PropertyValue::Uint16Vec(vec, _) => remove_at_checked(vec, index_in_property_vec),
+            PropertyValue::Uint32Vec(vec, _) => remove_at_checked(vec, index_in_property_vec),
+            PropertyValue::Uint64Vec(vec, _) => remove_at_checked(vec, index_in_property_vec),
+            PropertyValue::Int16Vec(vec, _) => remove_at_checked(vec, index_in_property_vec),
+            PropertyValue::Int32Vec(vec, _) => remove_at_checked(vec, index_in_property_vec),
+            PropertyValue::Int64Vec(vec, _) => remove_at_checked(vec, index_in_property_vec),
+            PropertyValue::TextVec(vec, _) => remove_at_checked(vec, index_in_property_vec),
+            PropertyValue::ReferenceVec(vec, _) => remove_at_checked(vec, index_in_property_vec),
             _ => (),
         }
+        self.try_increment_nonce();
     }
 
     fn vec_insert_at(&mut self, index_in_property_vec: u32, property_value: Self) {
@@ -438,32 +495,34 @@ impl PropertyValue {
             }
         }
 
+        self.try_increment_nonce();
+
         match (self, property_value) {
-            (PropertyValue::BoolVec(vec), PropertyValue::Bool(value)) => {
+            (PropertyValue::BoolVec(vec, _), PropertyValue::Bool(value)) => {
                 insert_at(vec, index_in_property_vec, value)
             }
-            (PropertyValue::Uint16Vec(vec), PropertyValue::Uint16(value)) => {
+            (PropertyValue::Uint16Vec(vec, _), PropertyValue::Uint16(value)) => {
                 insert_at(vec, index_in_property_vec, value)
             }
-            (PropertyValue::Uint32Vec(vec), PropertyValue::Uint32(value)) => {
+            (PropertyValue::Uint32Vec(vec, _), PropertyValue::Uint32(value)) => {
                 insert_at(vec, index_in_property_vec, value)
             }
-            (PropertyValue::Uint64Vec(vec), PropertyValue::Uint64(value)) => {
+            (PropertyValue::Uint64Vec(vec, _), PropertyValue::Uint64(value)) => {
                 insert_at(vec, index_in_property_vec, value)
             }
-            (PropertyValue::Int16Vec(vec), PropertyValue::Int16(value)) => {
+            (PropertyValue::Int16Vec(vec, _), PropertyValue::Int16(value)) => {
                 insert_at(vec, index_in_property_vec, value)
             }
-            (PropertyValue::Int32Vec(vec), PropertyValue::Int32(value)) => {
+            (PropertyValue::Int32Vec(vec, _), PropertyValue::Int32(value)) => {
                 insert_at(vec, index_in_property_vec, value)
             }
-            (PropertyValue::Int64Vec(vec), PropertyValue::Int64(value)) => {
+            (PropertyValue::Int64Vec(vec, _), PropertyValue::Int64(value)) => {
                 insert_at(vec, index_in_property_vec, value)
             }
-            (PropertyValue::TextVec(vec), PropertyValue::Text(ref value)) => {
+            (PropertyValue::TextVec(vec, _), PropertyValue::Text(ref value)) => {
                 insert_at(vec, index_in_property_vec, value.to_owned())
             }
-            (PropertyValue::ReferenceVec(vec), PropertyValue::Reference(value)) => {
+            (PropertyValue::ReferenceVec(vec, _), PropertyValue::Reference(value)) => {
                 insert_at(vec, index_in_property_vec, value)
             }
             _ => (),
@@ -471,7 +530,7 @@ impl PropertyValue {
     }
 }
 
-impl Default for PropertyValue {
+impl<T: Trait> Default for PropertyValue<T> {
     fn default() -> Self {
         PropertyValue::Bool(false)
     }
@@ -768,7 +827,7 @@ decl_module! {
             as_entity_maintainer: bool,
             entity_id: EntityId,
             schema_id: u16, // Do not type alias u16!! - u16,
-            property_values: BTreeMap<u16, PropertyValue>
+            property_values: BTreeMap<u16, PropertyValue<T>>
         ) -> dispatch::Result {
             let raw_origin = Self::ensure_root_or_signed(origin)?;
             Self::do_add_schema_support_to_entity(&raw_origin, with_credential, as_entity_maintainer, entity_id, schema_id, property_values)
@@ -779,7 +838,7 @@ decl_module! {
             with_credential: Option<T::Credential>,
             as_entity_maintainer: bool,
             entity_id: EntityId,
-            property_values: BTreeMap<u16, PropertyValue>
+            property_values: BTreeMap<u16, PropertyValue<T>>
         ) -> dispatch::Result {
             let raw_origin = Self::ensure_root_or_signed(origin)?;
             Self::do_update_entity_property_values(&raw_origin, with_credential, as_entity_maintainer, entity_id, property_values)
@@ -816,7 +875,7 @@ decl_module! {
             entity_id: EntityId,
             in_class_schema_property_id: u16,
             index_in_property_vec: u32,
-            property_value: PropertyValue,
+            property_value: PropertyValue<T>,
             nonce: T::Nonce
         ) -> dispatch::Result {
             let raw_origin = Self::ensure_root_or_signed(origin)?;
@@ -832,7 +891,7 @@ decl_module! {
             )
         }
 
-        pub fn transaction(origin, operations: Vec<Operation<T::Credential>>) -> dispatch::Result {
+        pub fn transaction(origin, operations: Vec<Operation<T::Credential, T>>) -> dispatch::Result {
             // This map holds the EntityId of the entity created as a result of executing a CreateEntity Operation
             // keyed by the indexed of the operation, in the operations vector.
             let mut entity_created_in_operation: BTreeMap<usize, EntityId> = BTreeMap::new();
@@ -937,7 +996,7 @@ impl<T: Trait> Module<T> {
         with_credential: Option<T::Credential>,
         as_entity_maintainer: bool,
         entity_id: EntityId,
-        property_values: BTreeMap<u16, PropertyValue>,
+        property_values: BTreeMap<u16, PropertyValue<T>>,
     ) -> dispatch::Result {
         let class_id = Self::get_class_id_by_entity_id(entity_id)?;
 
@@ -1032,7 +1091,7 @@ impl<T: Trait> Module<T> {
         entity_id: EntityId,
         in_class_schema_property_id: u16,
         index_in_property_vec: u32,
-        property_value: PropertyValue,
+        property_value: PropertyValue<T>,
         nonce: T::Nonce,
     ) -> dispatch::Result {
         let class_id = Self::get_class_id_by_entity_id(entity_id)?;
@@ -1076,7 +1135,7 @@ impl<T: Trait> Module<T> {
 
     pub fn complete_entity_property_values_update(
         entity_id: EntityId,
-        new_property_values: BTreeMap<u16, PropertyValue>,
+        new_property_values: BTreeMap<u16, PropertyValue<T>>,
     ) -> dispatch::Result {
         Self::ensure_known_entity_id(entity_id)?;
 
@@ -1085,7 +1144,6 @@ impl<T: Trait> Module<T> {
         // Get current property values of an entity as a mutable vector,
         // so we can update them if new values provided present in new_property_values.
         let mut updated_values = entity.values;
-        let mut vec_value_nonces = entity.vec_value_nonces;
         let mut updated = false;
         // Iterate over a vector of new values and update corresponding properties
         // of this entity if new values are valid.
@@ -1101,11 +1159,7 @@ impl<T: Trait> Module<T> {
                     Self::ensure_property_value_to_update_is_valid(&new_value, class_prop)?;
 
                     // Update a current prop value in a mutable vector, if a new value is valid.
-                    *current_prop_value = new_value;
-                    if current_prop_value.is_vec() {
-                        // Update last block of vec prop value if update performed
-                        Self::refresh_vec_value_nonces(id, &mut vec_value_nonces);
-                    }
+                    current_prop_value.update(new_value);
                     updated = true;
                 }
             } else {
@@ -1119,23 +1173,12 @@ impl<T: Trait> Module<T> {
         if updated {
             <EntityById<T>>::mutate(entity_id, |entity| {
                 entity.values = updated_values;
-                entity.vec_value_nonces = vec_value_nonces;
             });
         }
 
         Ok(())
     }
 
-    fn refresh_vec_value_nonces(id: u16, vec_value_nonces: &mut BTreeMap<u16, T::Nonce>) {
-        if let Some(nonce) = vec_value_nonces.get_mut(&id) {
-            *nonce += T::Nonce::one();
-        } else {
-            // If there no nonce entry under a given key, we need to initialize it manually with one nonce, as given entity value exist
-            // and first vec value specific operation was already performed
-            vec_value_nonces.insert(id, T::Nonce::one());
-        }
-    }
-
     fn complete_entity_property_vector_cleaning(
         entity_id: EntityId,
         in_class_schema_property_id: u16,
@@ -1161,10 +1204,6 @@ impl<T: Trait> Module<T> {
             {
                 current_property_value_vec.vec_clear();
             }
-            Self::refresh_vec_value_nonces(
-                in_class_schema_property_id,
-                &mut entity.vec_value_nonces,
-            );
         });
 
         Ok(())
@@ -1179,11 +1218,10 @@ impl<T: Trait> Module<T> {
         Self::ensure_known_entity_id(entity_id)?;
         let entity = Self::entity_by_id(entity_id);
 
-        // Ensure property value vector nonces equality to avoid possible data races,
-        // when performing vector specific operations
-        Self::ensure_nonce_equality(in_class_schema_property_id, &entity.vec_value_nonces, nonce)?;
-
         if let Some(current_prop_value) = entity.values.get(&in_class_schema_property_id) {
+            // Ensure property value vector nonces equality to avoid possible data races,
+            // when performing vector specific operations
+            Self::ensure_nonce_equality(current_prop_value, nonce)?;
             Self::ensure_index_in_property_vector_is_valid(
                 current_prop_value,
                 index_in_property_vec,
@@ -1199,10 +1237,6 @@ impl<T: Trait> Module<T> {
             if let Some(current_prop_value) = entity.values.get_mut(&in_class_schema_property_id) {
                 current_prop_value.vec_remove_at(index_in_property_vec)
             }
-            Self::refresh_vec_value_nonces(
-                in_class_schema_property_id,
-                &mut entity.vec_value_nonces,
-            );
         });
 
         Ok(())
@@ -1212,21 +1246,21 @@ impl<T: Trait> Module<T> {
         entity_id: EntityId,
         in_class_schema_property_id: u16,
         index_in_property_vec: u32,
-        property_value: PropertyValue,
+        property_value: PropertyValue<T>,
         nonce: T::Nonce,
     ) -> dispatch::Result {
         Self::ensure_known_entity_id(entity_id)?;
 
         let (entity, class) = Self::get_entity_and_class(entity_id);
 
-        // Ensure property value vector nonces equality to avoid possible data races,
-        // when performing vector specific operations
-        Self::ensure_nonce_equality(in_class_schema_property_id, &entity.vec_value_nonces, nonce)?;
         // Get class-level information about this property
         if let Some(class_prop) = class.properties.get(in_class_schema_property_id as usize) {
             // Try to find a current property value in the entity
             // by matching its id to the id of a property with an updated value.
             if let Some(entity_prop_value) = entity.values.get(&in_class_schema_property_id) {
+                // Ensure property value vector nonces equality to avoid possible data races,
+                // when performing vector specific operations
+                Self::ensure_nonce_equality(entity_prop_value, nonce)?;
                 // Validate a new property value against the type of this property
                 // and check any additional constraints like the length of a vector
                 // if it's a vector property or the length of a text if it's a text property.
@@ -1250,10 +1284,6 @@ impl<T: Trait> Module<T> {
             if let Some(current_prop_value) = entity.values.get_mut(&in_class_schema_property_id) {
                 current_prop_value.vec_insert_at(index_in_property_vec, property_value)
             }
-            Self::refresh_vec_value_nonces(
-                in_class_schema_property_id,
-                &mut entity.vec_value_nonces,
-            );
         });
 
         Ok(())
@@ -1265,7 +1295,7 @@ impl<T: Trait> Module<T> {
         as_entity_maintainer: bool,
         entity_id: EntityId,
         schema_id: u16,
-        property_values: BTreeMap<u16, PropertyValue>,
+        property_values: BTreeMap<u16, PropertyValue<T>>,
     ) -> dispatch::Result {
         // class id of the entity being updated
         let class_id = Self::get_class_id_by_entity_id(entity_id)?;
@@ -1418,7 +1448,7 @@ impl<T: Trait> Module<T> {
     // the target entity and class exists and constraint allows it.
     fn ensure_internal_property_values_permitted(
         source_class_id: ClassId,
-        property_values: &BTreeMap<u16, PropertyValue>,
+        property_values: &BTreeMap<u16, PropertyValue<T>>,
     ) -> dispatch::Result {
         for (in_class_index, property_value) in property_values.iter() {
             if let PropertyValue::Reference(ref target_entity_id) = property_value {
@@ -1452,18 +1482,12 @@ impl<T: Trait> Module<T> {
     }
 
     fn ensure_nonce_equality(
-        in_class_schema_property_id: u16,
-        vec_value_nonces: &BTreeMap<u16, T::Nonce>,
-        nonce: T::Nonce,
+        vec_value: &PropertyValue<T>,
+        new_nonce: T::Nonce,
     ) -> dispatch::Result {
-        if let Some(vec_value_nonce) = vec_value_nonces.get(&in_class_schema_property_id) {
-            ensure!(
-                *vec_value_nonce == nonce,
-                ERROR_PROP_VALUE_VEC_NONCES_DOES_NOT_MATCH
-            );
-        } else {
+        if let Some(nonce) = vec_value.get_nonce() {
             ensure!(
-                nonce == T::Nonce::zero(),
+                nonce == new_nonce,
                 ERROR_PROP_VALUE_VEC_NONCES_DOES_NOT_MATCH
             );
         }
@@ -1547,7 +1571,7 @@ impl<T: Trait> Module<T> {
     pub fn add_entity_schema_support(
         entity_id: EntityId,
         schema_id: u16,
-        property_values: BTreeMap<u16, PropertyValue>,
+        property_values: BTreeMap<u16, PropertyValue<T>>,
     ) -> dispatch::Result {
         Self::ensure_known_entity_id(entity_id)?;
 
@@ -1657,7 +1681,10 @@ impl<T: Trait> Module<T> {
         Ok(())
     }
 
-    pub fn ensure_valid_internal_prop(value: &PropertyValue, prop: &Property) -> dispatch::Result {
+    pub fn ensure_valid_internal_prop(
+        value: &PropertyValue<T>,
+        prop: &Property,
+    ) -> dispatch::Result {
         match (value, prop.prop_type) {
             (PV::Reference(entity_id), PT::Reference(class_id)) => {
                 Self::ensure_known_class_id(class_id)?;
@@ -1674,7 +1701,7 @@ impl<T: Trait> Module<T> {
     }
 
     pub fn ensure_index_in_property_vector_is_valid(
-        value: &PropertyValue,
+        value: &PropertyValue<T>,
         index_in_property_vec: u32,
     ) -> dispatch::Result {
         fn is_valid_index<T>(vec: &[T], index_in_property_vec: u32) -> bool {
@@ -1682,15 +1709,15 @@ impl<T: Trait> Module<T> {
         }
 
         let is_valid_index = match value {
-            PropertyValue::BoolVec(vec) => is_valid_index(vec, index_in_property_vec),
-            PropertyValue::Uint16Vec(vec) => is_valid_index(vec, index_in_property_vec),
-            PropertyValue::Uint32Vec(vec) => is_valid_index(vec, index_in_property_vec),
-            PropertyValue::Uint64Vec(vec) => is_valid_index(vec, index_in_property_vec),
-            PropertyValue::Int16Vec(vec) => is_valid_index(vec, index_in_property_vec),
-            PropertyValue::Int32Vec(vec) => is_valid_index(vec, index_in_property_vec),
-            PropertyValue::Int64Vec(vec) => is_valid_index(vec, index_in_property_vec),
-            PropertyValue::TextVec(vec) => is_valid_index(vec, index_in_property_vec),
-            PropertyValue::ReferenceVec(vec) => is_valid_index(vec, index_in_property_vec),
+            PropertyValue::BoolVec(vec, _) => is_valid_index(vec, index_in_property_vec),
+            PropertyValue::Uint16Vec(vec, _) => is_valid_index(vec, index_in_property_vec),
+            PropertyValue::Uint32Vec(vec, _) => is_valid_index(vec, index_in_property_vec),
+            PropertyValue::Uint64Vec(vec, _) => is_valid_index(vec, index_in_property_vec),
+            PropertyValue::Int16Vec(vec, _) => is_valid_index(vec, index_in_property_vec),
+            PropertyValue::Int32Vec(vec, _) => is_valid_index(vec, index_in_property_vec),
+            PropertyValue::Int64Vec(vec, _) => is_valid_index(vec, index_in_property_vec),
+            PropertyValue::TextVec(vec, _) => is_valid_index(vec, index_in_property_vec),
+            PropertyValue::ReferenceVec(vec, _) => is_valid_index(vec, index_in_property_vec),
             _ => return Err(ERROR_PROP_VALUE_UNDER_GIVEN_INDEX_IS_NOT_A_VECTOR),
         };
 
@@ -1701,7 +1728,7 @@ impl<T: Trait> Module<T> {
         Ok(())
     }
 
-    pub fn is_unknown_internal_entity_id(id: PropertyValue) -> bool {
+    pub fn is_unknown_internal_entity_id(id: PropertyValue<T>) -> bool {
         if let PropertyValue::Reference(entity_id) = id {
             !<EntityById<T>>::exists(entity_id)
         } else {
@@ -1716,7 +1743,7 @@ impl<T: Trait> Module<T> {
     }
 
     pub fn ensure_property_value_to_update_is_valid(
-        value: &PropertyValue,
+        value: &PropertyValue<T>,
         prop: &Property,
     ) -> dispatch::Result {
         Self::ensure_prop_value_matches_its_type(value, prop)?;
@@ -1727,8 +1754,8 @@ impl<T: Trait> Module<T> {
     }
 
     pub fn ensure_prop_value_can_be_inserted_at_prop_vec(
-        value: &PropertyValue,
-        entity_prop_value: &PropertyValue,
+        value: &PropertyValue<T>,
+        entity_prop_value: &PropertyValue<T>,
         index_in_property_vec: u32,
         prop: &Property,
     ) -> dispatch::Result {
@@ -1740,28 +1767,28 @@ impl<T: Trait> Module<T> {
 
         let is_valid_len = match (value, entity_prop_value, prop.prop_type) {
             // Single values
-            (PV::Bool(_), PV::BoolVec(vec), PT::BoolVec(max_len)) => {
+            (PV::Bool(_), PV::BoolVec(vec, _), PT::BoolVec(max_len)) => {
                 validate_prop_vec_len_after_value_insert(vec, max_len)
             }
-            (PV::Uint16(_), PV::Uint16Vec(vec), PT::Uint16Vec(max_len)) => {
+            (PV::Uint16(_), PV::Uint16Vec(vec, _), PT::Uint16Vec(max_len)) => {
                 validate_prop_vec_len_after_value_insert(vec, max_len)
             }
-            (PV::Uint32(_), PV::Uint32Vec(vec), PT::Uint32Vec(max_len)) => {
+            (PV::Uint32(_), PV::Uint32Vec(vec, _), PT::Uint32Vec(max_len)) => {
                 validate_prop_vec_len_after_value_insert(vec, max_len)
             }
-            (PV::Uint64(_), PV::Uint64Vec(vec), PT::Uint64Vec(max_len)) => {
+            (PV::Uint64(_), PV::Uint64Vec(vec, _), PT::Uint64Vec(max_len)) => {
                 validate_prop_vec_len_after_value_insert(vec, max_len)
             }
-            (PV::Int16(_), PV::Int16Vec(vec), PT::Int16Vec(max_len)) => {
+            (PV::Int16(_), PV::Int16Vec(vec, _), PT::Int16Vec(max_len)) => {
                 validate_prop_vec_len_after_value_insert(vec, max_len)
             }
-            (PV::Int32(_), PV::Int32Vec(vec), PT::Int32Vec(max_len)) => {
+            (PV::Int32(_), PV::Int32Vec(vec, _), PT::Int32Vec(max_len)) => {
                 validate_prop_vec_len_after_value_insert(vec, max_len)
             }
-            (PV::Int64(_), PV::Int64Vec(vec), PT::Int64Vec(max_len)) => {
+            (PV::Int64(_), PV::Int64Vec(vec, _), PT::Int64Vec(max_len)) => {
                 validate_prop_vec_len_after_value_insert(vec, max_len)
             }
-            (PV::Text(text_item), PV::TextVec(vec), PT::TextVec(vec_max_len, text_max_len)) => {
+            (PV::Text(text_item), PV::TextVec(vec, _), PT::TextVec(vec_max_len, text_max_len)) => {
                 if validate_prop_vec_len_after_value_insert(vec, vec_max_len) {
                     Self::validate_max_len_of_text(text_item, text_max_len)?;
                     true
@@ -1771,7 +1798,7 @@ impl<T: Trait> Module<T> {
             }
             (
                 PV::Reference(entity_id),
-                PV::ReferenceVec(vec),
+                PV::ReferenceVec(vec, _),
                 PT::ReferenceVec(vec_max_len, class_id),
             ) => {
                 Self::ensure_known_class_id(class_id)?;
@@ -1795,7 +1822,7 @@ impl<T: Trait> Module<T> {
     }
 
     pub fn validate_max_len_if_text_prop(
-        value: &PropertyValue,
+        value: &PropertyValue<T>,
         prop: &Property,
     ) -> dispatch::Result {
         match (value, &prop.prop_type) {
@@ -1813,7 +1840,7 @@ impl<T: Trait> Module<T> {
     }
 
     pub fn validate_max_len_if_vec_prop(
-        value: &PropertyValue,
+        value: &PropertyValue<T>,
         prop: &Property,
     ) -> dispatch::Result {
         fn validate_vec_len<T>(vec: &[T], max_len: u16) -> bool {
@@ -1821,15 +1848,15 @@ impl<T: Trait> Module<T> {
         }
 
         let is_valid_len = match (value, prop.prop_type) {
-            (PV::BoolVec(vec), PT::BoolVec(max_len)) => validate_vec_len(vec, max_len),
-            (PV::Uint16Vec(vec), PT::Uint16Vec(max_len)) => validate_vec_len(vec, max_len),
-            (PV::Uint32Vec(vec), PT::Uint32Vec(max_len)) => validate_vec_len(vec, max_len),
-            (PV::Uint64Vec(vec), PT::Uint64Vec(max_len)) => validate_vec_len(vec, max_len),
-            (PV::Int16Vec(vec), PT::Int16Vec(max_len)) => validate_vec_len(vec, max_len),
-            (PV::Int32Vec(vec), PT::Int32Vec(max_len)) => validate_vec_len(vec, max_len),
-            (PV::Int64Vec(vec), PT::Int64Vec(max_len)) => validate_vec_len(vec, max_len),
-
-            (PV::TextVec(vec), PT::TextVec(vec_max_len, text_max_len)) => {
+            (PV::BoolVec(vec, _), PT::BoolVec(max_len)) => validate_vec_len(vec, max_len),
+            (PV::Uint16Vec(vec, _), PT::Uint16Vec(max_len)) => validate_vec_len(vec, max_len),
+            (PV::Uint32Vec(vec, _), PT::Uint32Vec(max_len)) => validate_vec_len(vec, max_len),
+            (PV::Uint64Vec(vec, _), PT::Uint64Vec(max_len)) => validate_vec_len(vec, max_len),
+            (PV::Int16Vec(vec, _), PT::Int16Vec(max_len)) => validate_vec_len(vec, max_len),
+            (PV::Int32Vec(vec, _), PT::Int32Vec(max_len)) => validate_vec_len(vec, max_len),
+            (PV::Int64Vec(vec, _), PT::Int64Vec(max_len)) => validate_vec_len(vec, max_len),
+
+            (PV::TextVec(vec, _), PT::TextVec(vec_max_len, text_max_len)) => {
                 if validate_vec_len(vec, vec_max_len) {
                     for text_item in vec.iter() {
                         Self::validate_max_len_of_text(text_item, text_max_len)?;
@@ -1840,7 +1867,7 @@ impl<T: Trait> Module<T> {
                 }
             }
 
-            (PV::ReferenceVec(vec), PT::ReferenceVec(vec_max_len, class_id)) => {
+            (PV::ReferenceVec(vec, _), PT::ReferenceVec(vec_max_len, class_id)) => {
                 Self::ensure_known_class_id(class_id)?;
                 if validate_vec_len(vec, vec_max_len) {
                     for entity_id in vec.iter() {
@@ -1868,7 +1895,7 @@ impl<T: Trait> Module<T> {
     }
 
     pub fn ensure_prop_value_matches_its_type(
-        value: &PropertyValue,
+        value: &PropertyValue<T>,
         prop: &Property,
     ) -> dispatch::Result {
         ensure!(
@@ -1878,7 +1905,7 @@ impl<T: Trait> Module<T> {
         Ok(())
     }
 
-    pub fn does_prop_value_match_type(value: &PropertyValue, prop: &Property) -> bool {
+    pub fn does_prop_value_match_type(value: &PropertyValue<T>, prop: &Property) -> bool {
         // A non required property can be updated to None:
         if !prop.required && *value == PV::Bool(false) {
             return true;
@@ -1895,15 +1922,15 @@ impl<T: Trait> Module<T> {
                 (PV::Text(_),     PT::Text(_)) |
                 (PV::Reference(_), PT::Reference(_)) |
                 // Vectors:
-                (PV::BoolVec(_),     PT::BoolVec(_)) |
-                (PV::Uint16Vec(_),   PT::Uint16Vec(_)) |
-                (PV::Uint32Vec(_),   PT::Uint32Vec(_)) |
-                (PV::Uint64Vec(_),   PT::Uint64Vec(_)) |
-                (PV::Int16Vec(_),    PT::Int16Vec(_)) |
-                (PV::Int32Vec(_),    PT::Int32Vec(_)) |
-                (PV::Int64Vec(_),    PT::Int64Vec(_)) |
-                (PV::TextVec(_),     PT::TextVec(_, _)) |
-                (PV::ReferenceVec(_), PT::ReferenceVec(_, _)) => true,
+                (PV::BoolVec(_, _),     PT::BoolVec(_)) |
+                (PV::Uint16Vec(_, _),   PT::Uint16Vec(_)) |
+                (PV::Uint32Vec(_, _),   PT::Uint32Vec(_)) |
+                (PV::Uint64Vec(_, _),   PT::Uint64Vec(_)) |
+                (PV::Int16Vec(_, _),    PT::Int16Vec(_)) |
+                (PV::Int32Vec(_, _),    PT::Int32Vec(_)) |
+                (PV::Int64Vec(_, _),    PT::Int64Vec(_)) |
+                (PV::TextVec(_, _),     PT::TextVec(_, _)) |
+                (PV::ReferenceVec(_, _), PT::ReferenceVec(_, _)) => true,
                 // (PV::External(_), PT::External(_)) => true,
                 // (PV::ExternalVec(_), PT::ExternalVec(_, _)) => true,
                 _ => false,

+ 7 - 4
runtime-modules/content-directory/src/mock.rs

@@ -294,7 +294,7 @@ pub fn simple_test_schema() -> Vec<Property> {
     }]
 }
 
-pub fn simple_test_entity_property_values() -> BTreeMap<u16, PropertyValue> {
+pub fn simple_test_entity_property_values<T: Trait>() -> BTreeMap<u16, PropertyValue<T>> {
     let mut property_values = BTreeMap::new();
     property_values.insert(0, PropertyValue::Int64(1337));
     property_values
@@ -351,7 +351,7 @@ pub fn create_entity_with_schema_support() -> EntityId {
     property_values.insert(PROP_ID_BOOL, PropertyValue::Bool(true));
     property_values.insert(
         PROP_ID_U32_VEC,
-        PropertyValue::Uint32Vec(vec![123, 234, 44]),
+        PropertyValue::Uint32Vec(vec![123, 234, 44], <Runtime as Trait>::Nonce::default()),
     );
     assert_ok!(TestModule::add_entity_schema_support(
         entity_id,
@@ -453,13 +453,16 @@ pub fn good_prop_ids() -> Vec<u16> {
     vec![0, 1]
 }
 
-pub fn bool_prop_value() -> BTreeMap<u16, PropertyValue> {
+pub fn bool_prop_value<T: Trait>() -> BTreeMap<u16, PropertyValue<T>> {
     let mut property_values = BTreeMap::new();
     property_values.insert(0, PropertyValue::Bool(true));
     property_values
 }
 
-pub fn prop_value(index: u16, value: PropertyValue) -> BTreeMap<u16, PropertyValue> {
+pub fn prop_value<T: Trait>(
+    index: u16,
+    value: PropertyValue<T>,
+) -> BTreeMap<u16, PropertyValue<T>> {
     let mut property_values = BTreeMap::new();
     property_values.insert(index, value);
     property_values

+ 18 - 18
runtime-modules/content-directory/src/operations.rs

@@ -1,12 +1,12 @@
-use crate::{ClassId, EntityId, PropertyValue};
+use crate::{ClassId, EntityId, PropertyValue, Trait};
 use codec::{Decode, Encode};
 use rstd::collections::btree_map::BTreeMap;
 use rstd::prelude::*;
 
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
-pub enum ParametrizedPropertyValue {
+pub enum ParametrizedPropertyValue<T: Trait> {
     /// Same fields as normal PropertyValue
-    PropertyValue(PropertyValue),
+    PropertyValue(PropertyValue<T>),
 
     /// This is the index of an operation creating an entity in the transaction/batch operations
     InternalEntityJustAdded(u32), // should really be usize but it doesn't have Encode/Decode support
@@ -22,12 +22,12 @@ pub enum ParameterizedEntity {
 }
 
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
-pub struct ParametrizedClassPropertyValue {
+pub struct ParametrizedClassPropertyValue<T: Trait> {
     /// Index is into properties vector of class.
     pub in_class_index: u16,
 
     /// Value of property with index `in_class_index` in a given class.
-    pub value: ParametrizedPropertyValue,
+    pub value: ParametrizedPropertyValue<T>,
 }
 
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
@@ -36,30 +36,30 @@ pub struct CreateEntityOperation {
 }
 
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
-pub struct UpdatePropertyValuesOperation {
+pub struct UpdatePropertyValuesOperation<T: Trait> {
     pub entity_id: ParameterizedEntity,
-    pub new_parametrized_property_values: Vec<ParametrizedClassPropertyValue>,
+    pub new_parametrized_property_values: Vec<ParametrizedClassPropertyValue<T>>,
 }
 
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
-pub struct AddSchemaSupportToEntityOperation {
+pub struct AddSchemaSupportToEntityOperation<T: Trait> {
     pub entity_id: ParameterizedEntity,
     pub schema_id: u16,
-    pub parametrized_property_values: Vec<ParametrizedClassPropertyValue>,
+    pub parametrized_property_values: Vec<ParametrizedClassPropertyValue<T>>,
 }
 
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
-pub enum OperationType {
+pub enum OperationType<T: Trait> {
     CreateEntity(CreateEntityOperation),
-    UpdatePropertyValues(UpdatePropertyValuesOperation),
-    AddSchemaSupportToEntity(AddSchemaSupportToEntityOperation),
+    UpdatePropertyValues(UpdatePropertyValuesOperation<T>),
+    AddSchemaSupportToEntity(AddSchemaSupportToEntityOperation<T>),
 }
 
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
-pub struct Operation<Credential> {
+pub struct Operation<Credential, T: Trait> {
     pub with_credential: Option<Credential>,
     pub as_entity_maintainer: bool,
-    pub operation_type: OperationType,
+    pub operation_type: OperationType<T>,
 }
 
 pub fn parametrized_entity_to_entity_id(
@@ -80,10 +80,10 @@ pub fn parametrized_entity_to_entity_id(
     }
 }
 
-pub fn parametrized_property_values_to_property_values(
+pub fn parametrized_property_values_to_property_values<T: Trait>(
     created_entities: &BTreeMap<usize, EntityId>,
-    parametrized_property_values: Vec<ParametrizedClassPropertyValue>,
-) -> Result<BTreeMap<u16, PropertyValue>, &'static str> {
+    parametrized_property_values: Vec<ParametrizedClassPropertyValue<T>>,
+) -> Result<BTreeMap<u16, PropertyValue<T>>, &'static str> {
     let mut class_property_values = BTreeMap::new();
 
     for parametrized_class_property_value in parametrized_property_values.into_iter() {
@@ -121,7 +121,7 @@ pub fn parametrized_property_values_to_property_values(
                     }
                 }
 
-                PropertyValue::ReferenceVec(entities)
+                PropertyValue::ReferenceVec(entities, T::Nonce::default())
             }
         };
 

+ 23 - 11
runtime-modules/content-directory/src/tests.rs

@@ -669,7 +669,10 @@ fn batch_transaction_vector_of_entities() {
                 BTreeSet::from_iter(vec![SCHEMA_ID_0].into_iter()),
                 prop_value(
                     0,
-                    PropertyValue::ReferenceVec(vec![entity_id + 1, entity_id + 2,])
+                    PropertyValue::ReferenceVec(
+                        vec![entity_id + 1, entity_id + 2,],
+                        <Runtime as Trait>::Nonce::default()
+                    )
                 )
             )
         );
@@ -1124,7 +1127,7 @@ fn update_entity_props_successfully() {
         prop_values.insert(PROP_ID_REFERENCE, PropertyValue::Bool(false));
         prop_values.insert(
             PROP_ID_U32_VEC,
-            PropertyValue::Uint32Vec(vec![123, 234, 44]),
+            PropertyValue::Uint32Vec(vec![123, 234, 44], <Runtime as Trait>::Nonce::default()),
         );
         assert_eq!(TestModule::entity_by_id(entity_id).values, prop_values);
         prop_values = prop_value(PROP_ID_BOOL, PropertyValue::Bool(false));
@@ -1132,7 +1135,7 @@ fn update_entity_props_successfully() {
         prop_values.insert(PROP_ID_REFERENCE, PropertyValue::Reference(entity_id));
         prop_values.insert(
             PROP_ID_U32_VEC,
-            PropertyValue::Uint32Vec(vec![123, 234, 44, 88, 43]),
+            PropertyValue::Uint32Vec(vec![123, 234, 44, 88, 43], <Runtime as Trait>::Nonce::one()),
         );
         assert_ok!(TestModule::complete_entity_property_values_update(
             entity_id,
@@ -1208,7 +1211,7 @@ fn complete_entity_property_vector_cleaning_successfully() {
         prop_values.insert(PROP_ID_U32, PropertyValue::Bool(false));
         prop_values.insert(
             PROP_ID_U32_VEC,
-            PropertyValue::Uint32Vec(vec![123, 234, 44]),
+            PropertyValue::Uint32Vec(vec![123, 234, 44], <Runtime as Trait>::Nonce::default()),
         );
         prop_values.insert(PROP_ID_REFERENCE, PropertyValue::Bool(false));
 
@@ -1222,7 +1225,10 @@ fn complete_entity_property_vector_cleaning_successfully() {
         ));
 
         // Update entity property values to compare with runtime storage entity value under given schema id
-        prop_values.insert(PROP_ID_U32_VEC, PropertyValue::Uint32Vec(vec![]));
+        prop_values.insert(
+            PROP_ID_U32_VEC,
+            PropertyValue::Uint32Vec(vec![], <Runtime as Trait>::Nonce::one()),
+        );
 
         // Check property values runtime storage related to a entity right after
         // cleaning entity property vector under given schema id
@@ -1271,7 +1277,7 @@ fn complete_remove_at_entity_property_vector() -> EntityId {
     prop_values.insert(PROP_ID_U32, PropertyValue::Bool(false));
     prop_values.insert(
         PROP_ID_U32_VEC,
-        PropertyValue::Uint32Vec(vec![123, 234, 44]),
+        PropertyValue::Uint32Vec(vec![123, 234, 44], <Runtime as Trait>::Nonce::default()),
     );
     prop_values.insert(PROP_ID_REFERENCE, PropertyValue::Bool(false));
 
@@ -1287,7 +1293,10 @@ fn complete_remove_at_entity_property_vector() -> EntityId {
     ));
 
     // Update entity property values to compare with runtime storage entity value under given schema id
-    prop_values.insert(PROP_ID_U32_VEC, PropertyValue::Uint32Vec(vec![234, 44]));
+    prop_values.insert(
+        PROP_ID_U32_VEC,
+        PropertyValue::Uint32Vec(vec![234, 44], <Runtime as Trait>::Nonce::one()),
+    );
 
     // Check property values runtime storage related to a entity right after
     // removing at given index of entity property vector value
@@ -1393,7 +1402,7 @@ fn complete_insert_at_entity_property_vector_successfully() {
         prop_values.insert(PROP_ID_U32, PropertyValue::Bool(false));
         prop_values.insert(
             PROP_ID_U32_VEC,
-            PropertyValue::Uint32Vec(vec![123, 234, 44]),
+            PropertyValue::Uint32Vec(vec![123, 234, 44], <Runtime as Trait>::Nonce::default()),
         );
         prop_values.insert(PROP_ID_REFERENCE, PropertyValue::Bool(false));
 
@@ -1421,7 +1430,7 @@ fn complete_insert_at_entity_property_vector_successfully() {
         // Update entity property values to compare with runtime storage entity value under given schema id
         prop_values.insert(
             PROP_ID_U32_VEC,
-            PropertyValue::Uint32Vec(vec![55, 33, 123, 234, 44]),
+            PropertyValue::Uint32Vec(vec![55, 33, 123, 234, 44], 2_u32.into()),
         );
 
         // Check property values runtime storage related to a entity right after
@@ -1520,7 +1529,10 @@ fn cannot_complete_insert_at_entity_property_vector_when_entity_prop_value_vecto
         property_values.insert(PROP_ID_BOOL, PropertyValue::Bool(true));
         property_values.insert(
             PROP_ID_U32_VEC,
-            PropertyValue::Uint32Vec(vec![5; PROP_ID_U32_VEC_MAX_LEN as usize]),
+            PropertyValue::Uint32Vec(
+                vec![5; PROP_ID_U32_VEC_MAX_LEN as usize],
+                <Runtime as Trait>::Nonce::default(),
+            ),
         );
         assert_ok!(TestModule::add_entity_schema_support(
             entity_id,
@@ -1576,7 +1588,7 @@ fn cannot_complete_insert_at_entity_property_vector_when_unknown_internal_entity
         property_values.insert(PROP_ID_BOOL, PropertyValue::Bool(true));
         property_values.insert(
             PROP_ID_REFERENCE_VEC,
-            PropertyValue::ReferenceVec(vec![entity_id_2]),
+            PropertyValue::ReferenceVec(vec![entity_id_2], <Runtime as Trait>::Nonce::default()),
         );
         assert_ok!(TestModule::add_entity_schema_support(
             entity_id,