git.delta.rocks / unique-network / refs/commits / e9c5c5eb8270

difftreelog

feat implement setVariableMetadata sponsoring

Yaroslav Bolyukin2021-02-25parent: #65e4349.patch.diff
in: master

3 files changed

modifiedpallets/nft/src/default_weights.rsdiffbeforeafterboth
--- a/pallets/nft/src/default_weights.rs
+++ b/pallets/nft/src/default_weights.rs
@@ -127,6 +127,11 @@
             .saturating_add(DbWeight::get().reads(0 as Weight))
             .saturating_add(DbWeight::get().writes(2 as Weight))
     }    
+    fn set_variable_meta_data_sponsoring_rate_limit() -> Weight {
+        (3_500_000 as Weight)
+            .saturating_add(DbWeight::get().reads(2 as Weight))
+            .saturating_add(DbWeight::get().writes(1 as Weight))
+    }
     fn toggle_contract_white_list() -> Weight {
         (3_000_000 as Weight)
             .saturating_add(DbWeight::get().reads(0 as Weight))
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -247,6 +247,7 @@
     fn set_schema_version() -> Weight;
     fn set_chain_limits() -> Weight;
     fn set_contract_sponsoring_rate_limit() -> Weight;
+    fn set_variable_meta_data_sponsoring_rate_limit() -> Weight;
     fn toggle_contract_white_list() -> Weight;
     fn add_to_contract_white_list() -> Weight;
     fn remove_from_contract_white_list() -> Weight;
@@ -442,6 +443,10 @@
         pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;
         pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;
 
+        /// Variable metadata sponsoring
+        pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => Option<T::BlockNumber> = None;
+        pub VariableMetaDataSponsoringRateLimit get(fn variable_meta_data_sponsoring_rate_limit): map hasher(identity) CollectionId => T::BlockNumber = 0.into();
+
         // Contract Sponsorship and Ownership
         pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => T::AccountId;
         pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;
@@ -640,6 +645,9 @@
             <FungibleTransferBasket<T>>::remove_prefix(collection_id);
             <ReFungibleTransferBasket<T>>::remove_prefix(collection_id);
 
+            <VariableMetaDataBasket<T>>::remove_prefix(collection_id);
+            <VariableMetaDataSponsoringRateLimit<T>>::remove(collection_id);
+
             if CollectionCount::get() > 0
             {
                 // bound couter
@@ -1424,6 +1432,19 @@
             Ok(())
         }
 
+        #[weight = <T as Config>::WeightInfo::set_variable_meta_data_sponsoring_rate_limit()]
+        pub fn set_variable_meta_data_sponsoring_rate_limit(
+            origin,
+            collection_id: CollectionId,
+            rate_limit: T::BlockNumber
+        ) -> DispatchResult {
+            let sender = ensure_signed(origin)?;
+            Self::check_collection_sponsor(collection_id.clone(), sender.clone())?;
+
+            <VariableMetaDataSponsoringRateLimit<T>>::insert(collection_id, rate_limit);
+            Ok(())
+        }
+
         /// Enable the white list for a contract. Only addresses added to the white list with addToContractWhiteList will be able to call this smart contract.
         /// 
         /// # Permissions
@@ -1866,6 +1887,21 @@
         Ok(())
     }
 
+    fn check_collection_sponsor(
+        collection_id: CollectionId,
+        subject: T::AccountId,
+    ) -> DispatchResult {
+        Self::collection_exists(collection_id)?;
+        let collection = <Collection<T>>::get(collection_id);
+        
+        ensure!(
+            collection.sponsor_confirmed &&
+            collection.sponsor == subject,
+            Error::<T>::NoPermission,
+        );
+        Ok(())
+    }
+
     fn is_item_owner(subject: T::AccountId, collection_id: CollectionId, item_id: TokenId) -> bool {
         let target_collection = <Collection<T>>::get(collection_id);
 
@@ -2467,6 +2503,39 @@
                 }
             }
 
+            Some(Call::set_variable_meta_data(collection_id, item_id, data)) => {
+                let mut sponsor_metadata_changes = false;
+
+                let collection = <Collection<T>>::get(collection_id);
+                if
+                    collection.sponsor_confirmed &&
+                    // Can't sponsor fungible collection, this tx will be rejected
+                    // as invalid
+                    !matches!(collection.mode, CollectionMode::Fungible(_)) &&
+                    data.len() <= collection.limits.sponsored_data_size as usize
+                {
+                    let rate_limit = <VariableMetaDataSponsoringRateLimit<T>>::get(collection_id);
+                    if rate_limit > 0.into() {
+                        // sponsor timeout
+                        let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
+
+                        if <VariableMetaDataBasket<T>>::get(collection_id, item_id)
+                            .map(|last_block| block_number - last_block >= rate_limit)
+                            .unwrap_or(true) 
+                        {
+                            sponsor_metadata_changes = true;
+                            <VariableMetaDataBasket<T>>::insert(collection_id, item_id, block_number);
+                        }
+                    }
+                }
+
+                if !sponsor_metadata_changes {
+                    T::AccountId::default()
+                } else {
+                    <Collection<T>>::get(collection_id).sponsor
+                }
+            }
+
             _ => T::AccountId::default(),
         };
 
modifiedruntime/src/nft_weights.rsdiffbeforeafterboth
133 .saturating_add(DbWeight::get().reads(0 as Weight))133 .saturating_add(DbWeight::get().reads(0 as Weight))
134 .saturating_add(DbWeight::get().writes(2 as Weight))134 .saturating_add(DbWeight::get().writes(2 as Weight))
135 } 135 }
136 fn set_variable_meta_data_sponsoring_rate_limit() -> Weight {
137 (3_500_000 as Weight)
138 .saturating_add(DbWeight::get().reads(1 as Weight))
139 .saturating_add(DbWeight::get().writes(2 as Weight))
140 }
136 fn toggle_contract_white_list() -> Weight {141 fn toggle_contract_white_list() -> Weight {
137 (3_000_000 as Weight)142 (3_000_000 as Weight)
138 .saturating_add(DbWeight::get().reads(0 as Weight))143 .saturating_add(DbWeight::get().reads(0 as Weight))