From e9c5c5eb82707ad288b5d983b8e6a43be47989a4 Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Thu, 25 Feb 2021 14:58:09 +0000 Subject: [PATCH] feat: implement setVariableMetadata sponsoring --- --- 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)) --- 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 = 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 @@ >::remove_prefix(collection_id); >::remove_prefix(collection_id); + >::remove_prefix(collection_id); + >::remove(collection_id); + if CollectionCount::get() > 0 { // bound couter @@ -1424,6 +1432,19 @@ Ok(()) } + #[weight = ::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())?; + + >::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 = >::get(collection_id); + + ensure!( + collection.sponsor_confirmed && + collection.sponsor == subject, + Error::::NoPermission, + ); + Ok(()) + } + fn is_item_owner(subject: T::AccountId, collection_id: CollectionId, item_id: TokenId) -> bool { let target_collection = >::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 = >::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 = >::get(collection_id); + if rate_limit > 0.into() { + // sponsor timeout + let block_number = >::block_number() as T::BlockNumber; + + if >::get(collection_id, item_id) + .map(|last_block| block_number - last_block >= rate_limit) + .unwrap_or(true) + { + sponsor_metadata_changes = true; + >::insert(collection_id, item_id, block_number); + } + } + } + + if !sponsor_metadata_changes { + T::AccountId::default() + } else { + >::get(collection_id).sponsor + } + } + _ => T::AccountId::default(), }; --- a/runtime/src/nft_weights.rs +++ b/runtime/src/nft_weights.rs @@ -133,6 +133,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(1 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } fn toggle_contract_white_list() -> Weight { (3_000_000 as Weight) .saturating_add(DbWeight::get().reads(0 as Weight)) -- gitstuff