From d488824556c12e0649dca81f7218504a79431fb8 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Mon, 18 Jan 2021 16:36:51 +0000 Subject: [PATCH] Merge pull request #65 from usetech-llc/feature/NFTPAR-288 Feature/nftpar 288 --- --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -209,7 +209,10 @@ custom_data_limit: 2048, nft_sponsor_transfer_timeout: 15, fungible_sponsor_transfer_timeout: 15, - refungible_sponsor_transfer_timeout: 15, + refungible_sponsor_transfer_timeout: 15, + offchain_schema_limit: 1024, + variable_on_chain_schema_limit: 1024, + const_on_chain_schema_limit: 1024, }, }), pallet_contracts: Some(ContractsConfig { --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -74,6 +74,12 @@ ReFungible(DecimalPoints), } +impl Default for CollectionMode { + fn default() -> Self { + Self::Invalid + } +} + impl Into for CollectionMode { fn into(self) -> u8 { match self { @@ -97,12 +103,6 @@ } } -impl Default for CollectionMode { - fn default() -> Self { - Self::Invalid - } -} - #[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum SchemaVersion { @@ -208,6 +208,11 @@ pub nft_sponsor_transfer_timeout: u32, pub fungible_sponsor_transfer_timeout: u32, pub refungible_sponsor_transfer_timeout: u32, + + // Schema limits + pub offchain_schema_limit: u32, + pub variable_on_chain_schema_limit: u32, + pub const_on_chain_schema_limit: u32, } pub trait WeightInfo { @@ -367,7 +372,9 @@ /// Account token limit exceeded per collection AccountTokenLimitExceeded, /// Collection limit bounds per collection exceeded - CollectionLimitBoundsExceeded + CollectionLimitBoundsExceeded, + /// Schema data size limit bound exceeded + SchemaDataLimitExceeded } } @@ -1281,6 +1288,9 @@ let sender = ensure_signed(origin)?; Self::check_owner_or_admin_permissions(collection_id, sender.clone())?; + // check schema limit + ensure!(schema.len() as u32 > ChainLimit::get().offchain_schema_limit, ""); + let mut target_collection = >::get(collection_id); target_collection.offchain_schema = schema; >::insert(collection_id, target_collection); @@ -1309,6 +1319,9 @@ let sender = ensure_signed(origin)?; Self::check_owner_or_admin_permissions(collection_id, sender.clone())?; + // check schema limit + ensure!(schema.len() as u32 > ChainLimit::get().const_on_chain_schema_limit, ""); + let mut target_collection = >::get(collection_id); target_collection.const_on_chain_schema = schema; >::insert(collection_id, target_collection); @@ -1337,6 +1350,9 @@ let sender = ensure_signed(origin)?; Self::check_owner_or_admin_permissions(collection_id, sender.clone())?; + // check schema limit + ensure!(schema.len() as u32 > ChainLimit::get().variable_on_chain_schema_limit, ""); + let mut target_collection = >::get(collection_id); target_collection.variable_on_chain_schema = schema; >::insert(collection_id, target_collection); --- /dev/null +++ b/pallets/nft/src/types.rs @@ -0,0 +1,234 @@ +#[cfg(feature = "std")] +pub use std::*; + +#[cfg(feature = "std")] +pub use serde::*; + +use codec::{Decode, Encode}; + +pub type CollectionId = u32; +pub type TokenId = u32; +pub type DecimalPoints = u8; + +#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum CollectionMode { + Invalid, + NFT, + // decimal points + Fungible(DecimalPoints), + // decimal points + ReFungible(DecimalPoints), +} + +impl Into for CollectionMode { + fn into(self) -> u8 { + match self { + CollectionMode::Invalid => 0, + CollectionMode::NFT => 1, + CollectionMode::Fungible(_) => 2, + CollectionMode::ReFungible(_) => 3, + } + } +} + +#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum AccessMode { + Normal, + WhiteList, +} +impl Default for AccessMode { + fn default() -> Self { + Self::Normal + } +} + +impl Default for CollectionMode { + fn default() -> Self { + Self::Invalid + } +} + +#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum SchemaVersion { + ImageURL, + Unique, +} +impl Default for SchemaVersion { + fn default() -> Self { + Self::ImageURL + } +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct Ownership { + pub owner: AccountId, + pub fraction: u128, +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct CollectionType { + pub owner: AccountId, + pub mode: CollectionMode, + pub access: AccessMode, + pub decimal_points: DecimalPoints, + pub name: Vec, // 64 include null escape char + pub description: Vec, // 256 include null escape char + pub token_prefix: Vec, // 16 include null escape char + pub mint_mode: bool, + pub offchain_schema: Vec, + pub schema_version: SchemaVersion, + pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender + pub unconfirmed_sponsor: AccountId, // Sponsor address that has not yet confirmed sponsorship + pub limits: CollectionLimits, // Collection private restrictions + pub variable_on_chain_schema: Vec, // + pub const_on_chain_schema: Vec, // +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct NftItemType { + pub collection: CollectionId, + pub owner: AccountId, + pub const_data: Vec, + pub variable_data: Vec, +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct FungibleItemType { + pub collection: CollectionId, + pub owner: AccountId, + pub value: u128, +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct ReFungibleItemType { + pub collection: CollectionId, + pub owner: Vec>, + pub const_data: Vec, + pub variable_data: Vec, +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct ApprovePermissions { + pub approved: AccountId, + pub amount: u128, +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct VestingItem { + pub sender: AccountId, + pub recipient: AccountId, + pub collection_id: CollectionId, + pub item_id: TokenId, + pub amount: u64, + pub vesting_date: Moment, +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct BasketItem { + pub address: AccountId, + pub start_block: BlockNumber, +} + +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct CollectionLimits { + pub account_token_ownership_limit: u32, + pub sponsored_data_size: u32, + pub token_limit: u32, + + // Timeouts for item types in passed blocks + pub sponsor_transfer_timeout: u32, +} + +impl Default for CollectionLimits { + fn default() -> CollectionLimits { + CollectionLimits { + account_token_ownership_limit: 10_000_000, + token_limit: u32::max_value(), + sponsored_data_size: u32::max_value(), + sponsor_transfer_timeout: 14400 } + } +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct ChainLimits { + pub collection_numbers_limit: u32, + pub account_token_ownership_limit: u32, + pub collections_admins_limit: u64, + pub custom_data_limit: u32, + + // Timeouts for item types in passed blocks + pub nft_sponsor_transfer_timeout: u32, + pub fungible_sponsor_transfer_timeout: u32, + pub refungible_sponsor_transfer_timeout: u32, +} + + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct CreateNftData { + pub const_data: Vec, + pub variable_data: Vec, +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct CreateFungibleData { +} + +#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct CreateReFungibleData { + pub const_data: Vec, + pub variable_data: Vec, +} + +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum CreateItemData { + NFT(CreateNftData), + Fungible(CreateFungibleData), + ReFungible(CreateReFungibleData), +} + +impl CreateItemData { + pub fn len(&self) -> usize { + let len = match self { + CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(), + CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(), + _ => 0 + }; + + return len; + } +} + +impl From for CreateItemData { + fn from(item: CreateNftData) -> Self { + CreateItemData::NFT(item) + } +} + +impl From for CreateItemData { + fn from(item: CreateReFungibleData) -> Self { + CreateItemData::ReFungible(item) + } +} + +impl From for CreateItemData { + fn from(item: CreateFungibleData) -> Self { + CreateItemData::Fungible(item) + } +} -- gitstuff