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

difftreelog

feat implement sponsoring primitive for nft

Yaroslav Bolyukin2021-06-24parent: #a9bfe04.patch.diff
in: master

3 files changed

modifiedpallets/nft/Cargo.tomldiffbeforeafterboth
--- a/pallets/nft/Cargo.toml
+++ b/pallets/nft/Cargo.toml
@@ -30,6 +30,7 @@
     'pallet-transaction-payment/std',
     'fp-evm/std',
     'nft-data-structs/std',
+    'up-sponsorship/std',
     'sp-std/std',
     'sp-api/std',
     'sp-runtime/std',
@@ -135,9 +136,14 @@
 
 [dependencies.nft-data-structs]
 default-features = false
-path = '../../primitives'
+path = '../../primitives/nft'
 version = '0.9.0'
 
+[dependencies.up-sponsorship]
+default-features = false
+path = '../../primitives/sponsorship'
+version = '0.1.0'
+
 
 [dependencies]
 ethereum-tx-sign = { version = "3.0.4", optional = true }
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -50,6 +50,8 @@
 
 mod default_weights;
 mod eth;
+mod sponsorship;
+pub use sponsorship::NftSponsorshipHandler;
 
 pub use eth::NftErcSupport;
 pub use eth::account::*;
@@ -2232,12 +2234,6 @@
     ) -> DispatchResult {
         Self::remove_token_index(collection_id, item_index, old_owner)?;
         Self::add_token_index(collection_id, item_index, new_owner)?;
-
-        Ok(())
-    }
-    
-    fn ensure_contract_owned(account: T::AccountId, contract: &T::AccountId) -> DispatchResult {
-        ensure!(<ContractOwner<T>>::get(contract) == Some(account), Error::<T>::NoPermission);
 
         Ok(())
     }
addedpallets/nft/src/sponsorship.rsdiffbeforeafterboth
after · pallets/nft/src/sponsorship.rs
1use crate::{Config, Call, CollectionById, CreateItemBasket, VariableMetaDataBasket, ReFungibleTransferBasket, FungibleTransferBasket, NftTransferBasket, ChainLimit, CreateItemData, CollectionMode};2use core::marker::PhantomData;3use up_sponsorship::SponsorshipHandler;4use frame_support::{5	traits::IsSubType,6	storage::{StorageMap, StorageDoubleMap, StorageValue},7};8use nft_data_structs::{TokenId, CollectionId};9use alloc::vec::Vec;1011pub struct NftSponsorshipHandler<T>(PhantomData<T>);12impl<T: Config> NftSponsorshipHandler<T> {13	pub fn withdraw_create_item(14		who: &T::AccountId,15		collection_id: &CollectionId,16		_properties: &CreateItemData,17	) -> Option<T::AccountId> {18	19		let collection = CollectionById::<T>::get(collection_id)?;2021		// sponsor timeout22		let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;2324		let limit = collection.limits.sponsor_transfer_timeout;25		if CreateItemBasket::<T>::contains_key((collection_id, &who)) {26			let last_tx_block = CreateItemBasket::<T>::get((collection_id, &who));27			let limit_time = last_tx_block + limit.into();28			if block_number <= limit_time {29				return None;30			}31		}32		CreateItemBasket::<T>::insert((collection_id, who.clone()), block_number);3334		// check free create limit35		if collection.limits.sponsored_data_size >= (_properties.len() as u32) {36			collection.sponsorship.sponsor()37				.cloned()38		} else {39			None40		}41	}4243	pub fn withdraw_transfer(44		who: &T::AccountId,45		collection_id: &CollectionId,46		item_id: &TokenId,47	) -> Option<T::AccountId> {4849		let collection = CollectionById::<T>::get(collection_id)?;50		let limits = ChainLimit::get();5152		let mut sponsor_transfer = false;53		if collection.sponsorship.confirmed() {5455			let collection_limits = collection.limits.clone();56			let collection_mode = collection.mode.clone();5758			// sponsor timeout59			let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;60			sponsor_transfer = match collection_mode {61				CollectionMode::NFT => {6263					// get correct limit64					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {65						collection_limits.sponsor_transfer_timeout66					} else {67						limits.nft_sponsor_transfer_timeout68					};6970					let mut sponsored = true;71					if NftTransferBasket::<T>::contains_key(collection_id, item_id) {72						let last_tx_block = NftTransferBasket::<T>::get(collection_id, item_id);73						let limit_time = last_tx_block + limit.into();74						if block_number <= limit_time {75							sponsored = false;76						}77					}78					if sponsored {79						NftTransferBasket::<T>::insert(collection_id, item_id, block_number);80					}8182					sponsored83				}84				CollectionMode::Fungible(_) => {8586					// get correct limit87					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {88						collection_limits.sponsor_transfer_timeout89					} else {90						limits.fungible_sponsor_transfer_timeout91					};9293					let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;94					let mut sponsored = true;95					if FungibleTransferBasket::<T>::contains_key(collection_id, who) {96						let last_tx_block = FungibleTransferBasket::<T>::get(collection_id, who);97						let limit_time = last_tx_block + limit.into();98						if block_number <= limit_time {99							sponsored = false;100						}101					}102					if sponsored {103						FungibleTransferBasket::<T>::insert(collection_id, who, block_number);104					}105106					sponsored107				}108				CollectionMode::ReFungible => {109110					// get correct limit111					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {112						collection_limits.sponsor_transfer_timeout113					} else {114						limits.refungible_sponsor_transfer_timeout115					};116117					let mut sponsored = true;118					if ReFungibleTransferBasket::<T>::contains_key(collection_id, item_id) {119						let last_tx_block = ReFungibleTransferBasket::<T>::get(collection_id, item_id);120						let limit_time = last_tx_block + limit.into();121						if block_number <= limit_time {122							sponsored = false;123						}124					}125					if sponsored {126						ReFungibleTransferBasket::<T>::insert(collection_id, item_id, block_number);127					}128129					sponsored130				}131				_ => {132					false133				},134			};135		}136137		if !sponsor_transfer {138			None139		} else {140			collection.sponsorship.sponsor()141				.cloned()142		}143	}144	145	pub fn withdraw_set_variable_meta_data(146		collection_id: &CollectionId,147		item_id: &TokenId,148		data: &Vec<u8>,149	) -> Option<T::AccountId> {150151		let mut sponsor_metadata_changes = false;152153		let collection = CollectionById::<T>::get(collection_id)?;154155		if156			collection.sponsorship.confirmed() &&157			// Can't sponsor fungible collection, this tx will be rejected158			// as invalid159			!matches!(collection.mode, CollectionMode::Fungible(_)) &&160			data.len() <= collection.limits.sponsored_data_size as usize161		{162			if let Some(rate_limit) = collection.limits.sponsored_data_rate_limit {163				let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;164165				if VariableMetaDataBasket::<T>::get(collection_id, item_id)166					.map(|last_block| block_number - last_block > rate_limit)167					.unwrap_or(true) 168				{169					sponsor_metadata_changes = true;170					VariableMetaDataBasket::<T>::insert(collection_id, item_id, block_number);171				}172			}173		}174175		if !sponsor_metadata_changes {176			None177		} else {178			collection.sponsorship.sponsor().cloned()179		}180181	}182}183184impl<T, C> SponsorshipHandler<T::AccountId, C> for NftSponsorshipHandler<T>185where 186    T: Config,187    C: IsSubType<Call<T>>188{189    fn get_sponsor(who: &T::AccountId, call: &C) -> Option<T::AccountId> {190        match IsSubType::<Call<T>>::is_sub_type(call)? {191            Call::create_item(collection_id, _owner, _properties) => {192                Self::withdraw_create_item(who, collection_id, &_properties)193            },194            Call::transfer(_new_owner, collection_id, item_id, _value) => {195                Self::withdraw_transfer(who, collection_id, item_id)196            },197            Call::set_variable_meta_data(collection_id, item_id, data) => {198                Self::withdraw_set_variable_meta_data(collection_id, item_id, &data)199			},200			_ => None,201        }202    }203}