difftreelog
refactor make collection limits fields optional
in: master
8 files changed
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -105,10 +105,10 @@
Ok(())
}
pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {
- Ok(self.limits.owner_can_transfer && self.is_owner_or_admin(user)?)
+ Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?)
}
pub fn ignores_owned_amount(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {
- Ok(self.limits.owner_can_transfer && self.is_owner_or_admin(user)?)
+ Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?)
}
pub fn check_allowlist(&self, user: &T::CrossAccountId) -> DispatchResult {
self.consume_sload()?;
@@ -405,9 +405,10 @@
collection: CollectionHandle<T>,
sender: &T::CrossAccountId,
) -> DispatchResult {
- if !collection.limits.owner_can_destroy {
- fail!(Error::<T>::NoPermission);
- }
+ ensure!(
+ collection.limits.owner_can_destroy(),
+ <Error<T>>::NoPermission,
+ );
collection.check_is_owner(&sender)?;
let destroyed_collections = <DestroyedCollectionCount<T>>::get()
pallets/fungible/src/lib.rsdiffbeforeafterboth--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -157,8 +157,8 @@
amount: u128,
) -> DispatchResult {
ensure!(
- collection.transfers_enabled,
- <CommonError<T>>::TransferNotAllowed
+ collection.limits.transfers_enabled(),
+ <CommonError<T>>::TransferNotAllowed,
);
if collection.access == AccessMode::WhiteList {
pallets/nft/src/eth/sponsoring.rsdiffbeforeafterboth--- a/pallets/nft/src/eth/sponsoring.rs
+++ b/pallets/nft/src/eth/sponsoring.rs
@@ -43,11 +43,8 @@
let token_id: u32 = token_id.try_into().map_err(|_| AnyError)?;
let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
let collection_limits = &collection.limits;
- let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
- collection_limits.sponsor_transfer_timeout
- } else {
- NFT_SPONSOR_TRANSFER_TIMEOUT
- };
+ let limit =
+ collection_limits.sponsor_transfer_timeout(NFT_SPONSOR_TRANSFER_TIMEOUT);
let mut sponsor = true;
if <NftTransferBasket<T>>::contains_key(collection_id, token_id) {
@@ -74,11 +71,8 @@
UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
let who = T::CrossAccountId::from_eth(*caller);
let collection_limits = &collection.limits;
- let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
- collection_limits.sponsor_transfer_timeout
- } else {
- FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
- };
+ let limit = collection_limits
+ .sponsor_transfer_timeout(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
let mut sponsored = true;
pallets/nft/src/lib.rsdiffbeforeafterboth37use nft_data_structs::{37use nft_data_structs::{38 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,38 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,39 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, COLLECTION_ADMINS_LIMIT,39 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, COLLECTION_ADMINS_LIMIT,40 OFFCHAIN_SCHEMA_LIMIT, AccessMode, Collection, CreateItemData, CollectionLimits, CollectionId,40 OFFCHAIN_SCHEMA_LIMIT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,41 NFT_SPONSOR_TRANSFER_TIMEOUT, AccessMode, Collection, CreateItemData, CollectionLimits,41 CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,42 CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,42};43};43use pallet_common::{44use pallet_common::{189 // Anyone can create a collection190 // Anyone can create a collection190 let who = ensure_signed(origin)?;191 let who = ensure_signed(origin)?;191192 let limits = CollectionLimits::<T::BlockNumber> {193 sponsored_data_size: CUSTOM_DATA_LIMIT,194 ..Default::default()195 };196192197 // Create new collection193 // Create new collection198 let new_collection = Collection::<T> {194 let new_collection = Collection::<T> {208 sponsorship: SponsorshipState::Disabled,204 sponsorship: SponsorshipState::Disabled,209 variable_on_chain_schema: Vec::new(),205 variable_on_chain_schema: Vec::new(),210 const_on_chain_schema: Vec::new(),206 const_on_chain_schema: Vec::new(),211 limits,207 limits: Default::default(),212 transfers_enabled: true,213 meta_update_permission: Default::default(),208 meta_update_permission: Default::default(),214 };209 };215210582577583 // =========578 // =========584579585 target_collection.transfers_enabled = value;580 target_collection.limits.transfers_enabled = Some(value);586 target_collection.save()581 target_collection.save()587 }582 }588583888 pub fn set_collection_limits(883 pub fn set_collection_limits(889 origin,884 origin,890 collection_id: CollectionId,885 collection_id: CollectionId,891 new_limits: CollectionLimits<T::BlockNumber>,886 new_limit: CollectionLimits,892 ) -> DispatchResult {887 ) -> DispatchResult {888 let mut new_limit = new_limit;893 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);889 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);894 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;890 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;895 target_collection.check_is_owner(&sender)?;891 target_collection.check_is_owner(&sender)?;896 let old_limits = &target_collection.limits;892 let old_limit = &target_collection.limits;897893898 // collection bounds899 ensure!(new_limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&894 macro_rules! limit_default {895 ($old:ident, $new:ident, $($field:ident $(($arg:expr))? => $check:expr),* $(,)?) => {{896 $(897 if let Some($new) = $new.$field {900 new_limits.account_token_ownership_limit.unwrap_or(0) <= MAX_TOKEN_OWNERSHIP &&898 let $old = $old.$field($($arg)?);899 let _ = $new;900 let _ = $old;901 $check902 } else {903 $new.$field = $old.$field904 }905 )*906 }};907 }908909 limit_default!(old_limit, new_limit,910 account_token_ownership_limit => ensure!(911 new_limit <= MAX_TOKEN_OWNERSHIP,912 <Error<T>>::CollectionLimitBoundsExceeded,913 ),901 new_limits.sponsored_data_size <= CUSTOM_DATA_LIMIT,914 sponsor_transfer_timeout(match target_collection.mode {915 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,916 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,917 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,918 }) => ensure!(919 new_limit <= MAX_SPONSOR_TIMEOUT,902 Error::<T>::CollectionLimitBoundsExceeded);920 <Error<T>>::CollectionLimitBoundsExceeded,903921 ),904 // token_limit check prev905 ensure!(old_limits.token_limit >= new_limits.token_limit, <CommonError<T>>::CollectionTokenLimitExceeded);922 sponsored_data_size => ensure!(923 new_limit <= CUSTOM_DATA_LIMIT,924 <Error<T>>::CollectionLimitBoundsExceeded,925 ),906 ensure!(new_limits.token_limit > 0, <CommonError<T>>::CollectionTokenLimitExceeded);926 token_limit => ensure!(907927 old_limit >= new_limit && new_limit > 0,928 <CommonError<T>>::CollectionTokenLimitExceeded929 ),908 ensure!(930 owner_can_transfer => ensure!(909 (old_limits.owner_can_transfer || !new_limits.owner_can_transfer) &&931 old_limit || !new_limit,932 <Error<T>>::OwnerPermissionsCantBeReverted,933 ),910 (old_limits.owner_can_destroy || !new_limits.owner_can_destroy),934 owner_can_destroy => ensure!(935 old_limit || !new_limit,911 Error::<T>::OwnerPermissionsCantBeReverted,936 <Error<T>>::OwnerPermissionsCantBeReverted,937 ),938 sponsored_data_rate_limit => {},939 transfers_enabled => {},912 );940 );913941914 target_collection.limits = new_limits;942 target_collection.limits = new_limit;915943916 target_collection.save()944 target_collection.save()917 }945 }pallets/nft/src/sponsorship.rsdiffbeforeafterboth--- a/pallets/nft/src/sponsorship.rs
+++ b/pallets/nft/src/sponsorship.rs
@@ -26,7 +26,13 @@
// sponsor timeout
let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let limit = collection.limits.sponsor_transfer_timeout;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match _properties {
+ CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
if CreateItemBasket::<T>::contains_key((collection_id, &who)) {
let last_tx_block = CreateItemBasket::<T>::get((collection_id, &who));
let limit_time = last_tx_block + limit.into();
@@ -37,7 +43,7 @@
CreateItemBasket::<T>::insert((collection_id, who.clone()), block_number);
// check free create limit
- if collection.limits.sponsored_data_size >= (_properties.data_size() as u32) {
+ if collection.limits.sponsored_data_size() >= (_properties.data_size() as u32) {
collection.sponsorship.sponsor().cloned()
} else {
None
@@ -61,11 +67,8 @@
sponsor_transfer = match collection_mode {
CollectionMode::NFT => {
// get correct limit
- let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
- collection_limits.sponsor_transfer_timeout
- } else {
- NFT_SPONSOR_TRANSFER_TIMEOUT
- };
+ let limit =
+ collection_limits.sponsor_transfer_timeout(NFT_SPONSOR_TRANSFER_TIMEOUT);
let mut sponsored = true;
if NftTransferBasket::<T>::contains_key(collection_id, item_id) {
@@ -83,11 +86,8 @@
}
CollectionMode::Fungible(_) => {
// get correct limit
- let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
- collection_limits.sponsor_transfer_timeout
- } else {
- FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
- };
+ let limit = collection_limits
+ .sponsor_transfer_timeout(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
let mut sponsored = true;
@@ -106,11 +106,8 @@
}
CollectionMode::ReFungible => {
// get correct limit
- let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
- collection_limits.sponsor_transfer_timeout
- } else {
- REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
- };
+ let limit = collection_limits
+ .sponsor_transfer_timeout(REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
let mut sponsored = true;
if ReFungibleTransferBasket::<T>::contains_key(collection_id, item_id) {
@@ -150,13 +147,13 @@
// 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
+ data.len() <= collection.limits.sponsored_data_size() as usize
{
- if let Some(rate_limit) = collection.limits.sponsored_data_rate_limit {
+ if let Some(rate_limit) = collection.limits.sponsored_data_rate_limit() {
let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
if VariableMetaDataBasket::<T>::get(collection_id, item_id)
- .map(|last_block| block_number - last_block > rate_limit)
+ .map(|last_block| block_number - last_block > rate_limit.into())
.unwrap_or(true)
{
sponsor_metadata_changes = true;
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -164,7 +164,7 @@
.ok_or_else(|| <CommonError<T>>::TokenNotFound)?;
ensure!(
&token_data.owner == sender
- || (collection.limits.owner_can_transfer
+ || (collection.limits.owner_can_transfer()
&& collection.is_owner_or_admin(sender)?),
<CommonError<T>>::NoPermission
);
@@ -215,7 +215,7 @@
token: TokenId,
) -> DispatchResult {
ensure!(
- collection.transfers_enabled,
+ collection.limits.transfers_enabled(),
<CommonError<T>>::TransferNotAllowed
);
@@ -223,7 +223,8 @@
.ok_or_else(|| <CommonError<T>>::TokenNotFound)?;
ensure!(
&token_data.owner == from
- || (collection.limits.owner_can_transfer && collection.is_owner_or_admin(from)?),
+ || (collection.limits.owner_can_transfer()
+ && collection.is_owner_or_admin(from)?),
<CommonError<T>>::NoPermission
);
@@ -327,7 +328,7 @@
.checked_add(data.len() as u32)
.ok_or(ArithmeticError::Overflow)?;
ensure!(
- tokens_minted < collection.limits.token_limit,
+ tokens_minted < collection.limits.token_limit(),
<CommonError<T>>::CollectionTokenLimitExceeded
);
collection.consume_sstore()?;
pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -268,7 +268,7 @@
amount: u128,
) -> DispatchResult {
ensure!(
- collection.transfers_enabled,
+ collection.limits.transfers_enabled(),
<CommonError<T>>::TransferNotAllowed
);
@@ -404,7 +404,7 @@
.checked_add(data.len() as u32)
.ok_or(ArithmeticError::Overflow)?;
ensure!(
- tokens_minted < collection.limits.token_limit,
+ tokens_minted < collection.limits.token_limit(),
<CommonError<T>>::CollectionTokenLimitExceeded
);
primitives/nft/src/lib.rsdiffbeforeafterboth--- a/primitives/nft/src/lib.rs
+++ b/primitives/nft/src/lib.rs
@@ -42,6 +42,7 @@
10
};
pub const COLLECTION_ADMINS_LIMIT: u64 = 5;
+pub const COLLECTION_TOKEN_LIMIT: u32 = u32::MAX;
pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
1000000
} else {
@@ -217,11 +218,10 @@
pub offchain_schema: Vec<u8>,
pub schema_version: SchemaVersion,
pub sponsorship: SponsorshipState<T::AccountId>,
- pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions
- pub variable_on_chain_schema: Vec<u8>, //
- pub const_on_chain_schema: Vec<u8>, //
+ pub limits: CollectionLimits, // Collection private restrictions
+ pub variable_on_chain_schema: Vec<u8>, //
+ pub const_on_chain_schema: Vec<u8>, //
pub meta_update_permission: MetaUpdatePermission,
- pub transfers_enabled: bool,
}
#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]
@@ -246,42 +246,57 @@
pub variable_data: Vec<u8>,
}
-#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]
+#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
-pub struct CollectionLimits<BlockNumber: Encode + Decode> {
+pub struct CollectionLimits {
pub account_token_ownership_limit: Option<u32>,
- pub sponsored_data_size: u32,
+ pub sponsored_data_size: Option<u32>,
/// None - setVariableMetadata is not sponsored
/// Some(v) - setVariableMetadata is sponsored
/// if there is v block between txs
- pub sponsored_data_rate_limit: Option<BlockNumber>,
- pub token_limit: u32,
+ pub sponsored_data_rate_limit: Option<u32>,
+ pub token_limit: Option<u32>,
// Timeouts for item types in passed blocks
- pub sponsor_transfer_timeout: u32,
- pub owner_can_transfer: bool,
- pub owner_can_destroy: bool,
+ pub sponsor_transfer_timeout: Option<u32>,
+ pub owner_can_transfer: Option<bool>,
+ pub owner_can_destroy: Option<bool>,
+ pub transfers_enabled: Option<bool>,
}
-impl<BlockNumber: Encode + Decode> CollectionLimits<BlockNumber> {
+impl CollectionLimits {
pub fn account_token_ownership_limit(&self) -> u32 {
self.account_token_ownership_limit
.unwrap_or(ACCOUNT_TOKEN_OWNERSHIP_LIMIT)
- .min(ACCOUNT_TOKEN_OWNERSHIP_LIMIT)
+ .min(MAX_TOKEN_OWNERSHIP)
}
-}
-
-impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {
- fn default() -> Self {
- Self {
- account_token_ownership_limit: Some(10_000_000),
- token_limit: u32::max_value(),
- sponsored_data_size: u32::MAX,
- sponsored_data_rate_limit: None,
- sponsor_transfer_timeout: 14400,
- owner_can_transfer: true,
- owner_can_destroy: true,
- }
+ pub fn sponsored_data_size(&self) -> u32 {
+ self.sponsored_data_size
+ .unwrap_or(CUSTOM_DATA_LIMIT)
+ .min(CUSTOM_DATA_LIMIT)
+ }
+ pub fn token_limit(&self) -> u32 {
+ self.token_limit
+ .unwrap_or(COLLECTION_TOKEN_LIMIT)
+ .min(COLLECTION_TOKEN_LIMIT)
+ }
+ pub fn sponsor_transfer_timeout(&self, default: u32) -> u32 {
+ self.sponsor_transfer_timeout
+ .unwrap_or(default)
+ .min(MAX_SPONSOR_TIMEOUT)
+ }
+ pub fn owner_can_transfer(&self) -> bool {
+ self.owner_can_transfer.unwrap_or(true)
+ }
+ pub fn owner_can_destroy(&self) -> bool {
+ self.owner_can_destroy.unwrap_or(true)
+ }
+ pub fn transfers_enabled(&self) -> bool {
+ self.transfers_enabled.unwrap_or(true)
+ }
+ pub fn sponsored_data_rate_limit(&self) -> Option<u32> {
+ self.sponsored_data_rate_limit
+ .map(|v| v.min(MAX_SPONSOR_TIMEOUT))
}
}