git.delta.rocks / unique-network / refs/commits / 8a18c9958995

difftreelog

source

primitives/data-structs/src/lib.rs59.7 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! # Primitives crate.18//!19//! This crate contains types, traits and constants.2021#![cfg_attr(not(feature = "std"), no_std)]2223use core::{24	convert::{TryFrom, TryInto},25	fmt,26	ops::Deref,27};28use frame_support::storage::{bounded_btree_map::BoundedBTreeMap, bounded_btree_set::BoundedBTreeSet};2930#[cfg(feature = "serde")]31use serde::{Serialize, Deserialize};3233use sp_core::U256;34use sp_runtime::{ArithmeticError, sp_std::prelude::Vec};35use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};36use bondrewd::Bitfields;37use frame_support::{BoundedVec, traits::ConstU32};38use derivative::Derivative;39use scale_info::TypeInfo;4041mod bondrewd_codec;42mod bounded;43pub mod budget;44pub mod mapping;45mod migration;4647/// Maximum of decimal points.48pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;4950/// Maximum pieces for refungible token.51pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;52pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;5354/// Maximum tokens for user.55pub const MAX_TOKEN_OWNERSHIP: u32 = if cfg!(not(feature = "limit-testing")) {56	100_00057} else {58	1059};6061/// Maximum for collections can be created.62pub const COLLECTION_NUMBER_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {63	100_00064} else {65	1066};6768/// Maximum for various custom data of token.69pub const CUSTOM_DATA_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {70	204871} else {72	1073};7475/// Maximum admins per collection.76pub const COLLECTION_ADMINS_LIMIT: u32 = 5;7778/// Maximum tokens per collection.79pub const COLLECTION_TOKEN_LIMIT: u32 = u32::MAX;8081/// Maximum tokens per account.82pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {83	1_000_00084} else {85	1086};8788/// Default timeout for transfer sponsoring NFT item.89pub const NFT_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;90/// Default timeout for transfer sponsoring fungible item.91pub const FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;92/// Default timeout for transfer sponsoring refungible item.93pub const REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;9495/// Default timeout for sponsored approving.96pub const SPONSOR_APPROVE_TIMEOUT: u32 = 5;9798// Schema limits99pub const OFFCHAIN_SCHEMA_LIMIT: u32 = 8192;100pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 8192;101pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 32768;102103// TODO: not used. Delete?104pub const COLLECTION_FIELD_LIMIT: u32 = CONST_ON_CHAIN_SCHEMA_LIMIT;105106/// Maximal length of a collection name.107pub const MAX_COLLECTION_NAME_LENGTH: u32 = 64;108109/// Maximal length of a collection description.110pub const MAX_COLLECTION_DESCRIPTION_LENGTH: u32 = 256;111112/// Maximal length of a token prefix.113pub const MAX_TOKEN_PREFIX_LENGTH: u32 = 16;114115/// Maximal length of a property key.116pub const MAX_PROPERTY_KEY_LENGTH: u32 = 256;117118/// Maximal length of a property value.119pub const MAX_PROPERTY_VALUE_LENGTH: u32 = 32768;120121/// A maximum number of token properties.122pub const MAX_PROPERTIES_PER_ITEM: u32 = 64;123124/// Maximal lenght of extended property value.125pub const MAX_AUX_PROPERTY_VALUE_LENGTH: u32 = 2048;126127/// Maximum size for all collection properties.128pub const MAX_COLLECTION_PROPERTIES_SIZE: u32 = 40960;129130/// Maximum size of all token properties.131pub const MAX_TOKEN_PROPERTIES_SIZE: u32 = 32768;132133/// How much items can be created per single134/// create_many call.135pub const MAX_ITEMS_PER_BATCH: u32 = 200;136137/// Used for limit bounded types of token custom data.138pub type CustomDataLimit = ConstU32<CUSTOM_DATA_LIMIT>;139140/// Collection id.141#[derive(142	Encode,143	Decode,144	PartialEq,145	Eq,146	PartialOrd,147	Ord,148	Clone,149	Copy,150	Debug,151	Default,152	TypeInfo,153	MaxEncodedLen,154)]155#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]156pub struct CollectionId(pub u32);157impl EncodeLike<u32> for CollectionId {}158impl EncodeLike<CollectionId> for u32 {}159160impl From<u32> for CollectionId {161	fn from(value: u32) -> Self {162		Self(value)163	}164}165166/// Token id.167#[derive(168	Encode,169	Decode,170	PartialEq,171	Eq,172	PartialOrd,173	Ord,174	Clone,175	Copy,176	Debug,177	Default,178	TypeInfo,179	MaxEncodedLen,180)]181#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]182pub struct TokenId(pub u32);183impl EncodeLike<u32> for TokenId {}184impl EncodeLike<TokenId> for u32 {}185186impl TokenId {187	/// Try to get next token id.188	///189	/// If next id cause overflow, then [`ArithmeticError::Overflow`] returned.190	pub fn try_next(self) -> Result<TokenId, ArithmeticError> {191		self.0192			.checked_add(1)193			.ok_or(ArithmeticError::Overflow)194			.map(Self)195	}196}197198impl From<TokenId> for U256 {199	fn from(t: TokenId) -> Self {200		t.0.into()201	}202}203204impl TryFrom<U256> for TokenId {205	type Error = &'static str;206207	fn try_from(value: U256) -> Result<Self, Self::Error> {208		Ok(TokenId(value.try_into().map_err(|_| "too large token id")?))209	}210}211212/// Token data.213#[struct_versioning::versioned(version = 2, upper)]214#[derive(Encode, Decode, Clone, PartialEq, TypeInfo)]215#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]216pub struct TokenData<CrossAccountId> {217	/// Properties of token.218	pub properties: Vec<Property>,219220	/// Token owner.221	pub owner: Option<CrossAccountId>,222223	/// Token pieces.224	#[version(2.., upper(0))]225	pub pieces: u128,226}227228// TODO: unused type229pub struct OverflowError;230impl From<OverflowError> for &'static str {231	fn from(_: OverflowError) -> Self {232		"overflow occured"233	}234}235236/// Alias for decimal points type.237pub type DecimalPoints = u8;238239/// Collection mode.240///241/// Collection can represent various types of tokens.242/// Each collection can contain only one type of tokens at a time.243/// This type helps to understand which tokens the collection contains.244#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]245#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]246pub enum CollectionMode {247	/// Non fungible tokens.248	NFT,249	/// Fungible tokens.250	Fungible(DecimalPoints),251	/// Refungible tokens.252	ReFungible,253}254255impl CollectionMode {256	/// Get collection mod as number.257	pub fn id(&self) -> u8 {258		match self {259			CollectionMode::NFT => 1,260			CollectionMode::Fungible(_) => 2,261			CollectionMode::ReFungible => 3,262		}263	}264}265266// TODO: unused trait267pub trait SponsoringResolve<AccountId, Call> {268	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;269}270271/// Access mode for some token operations.272#[derive(Encode, Decode, Eq, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]273#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]274pub enum AccessMode {275	/// Access grant for owner and admins. Used as default.276	Normal,277	/// Like a [`Normal`](AccessMode::Normal) but also users in allow list.278	AllowList,279}280impl Default for AccessMode {281	fn default() -> Self {282		Self::Normal283	}284}285286// TODO: remove in future.287#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]288#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]289pub enum SchemaVersion {290	ImageURL,291	Unique,292}293impl Default for SchemaVersion {294	fn default() -> Self {295		Self::ImageURL296	}297}298299// TODO: unused type300#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, TypeInfo)]301#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]302pub struct Ownership<AccountId> {303	pub owner: AccountId,304	pub fraction: u128,305}306307/// The state of collection sponsorship.308#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]309#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]310pub enum SponsorshipState<AccountId> {311	/// The fees are applied to the transaction sender.312	Disabled,313	/// The sponsor is under consideration. Until the sponsor gives his consent,314	/// the fee will still be charged to sender.315	Unconfirmed(AccountId),316	/// Transactions are sponsored by specified account.317	Confirmed(AccountId),318}319320impl<AccountId> SponsorshipState<AccountId> {321	/// Get a sponsor of the collection who has confirmed his status.322	pub fn sponsor(&self) -> Option<&AccountId> {323		match self {324			Self::Confirmed(sponsor) => Some(sponsor),325			_ => None,326		}327	}328329	/// Get a sponsor of the collection who has pending or confirmed status.330	pub fn pending_sponsor(&self) -> Option<&AccountId> {331		match self {332			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),333			_ => None,334		}335	}336337	/// Whether the sponsorship is confirmed.338	pub fn confirmed(&self) -> bool {339		matches!(self, Self::Confirmed(_))340	}341}342343impl<T> Default for SponsorshipState<T> {344	fn default() -> Self {345		Self::Disabled346	}347}348349pub type CollectionName = BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>;350pub type CollectionDescription = BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>;351pub type CollectionTokenPrefix = BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>;352353#[derive(Bitfields, Clone, Copy, PartialEq, Eq, Debug, Default)]354#[bondrewd(enforce_bytes = 1)]355pub struct CollectionFlags {356	/// Tokens in foreign collections can be transferred, but not burnt357	#[bondrewd(bits = "0..1")]358	pub foreign: bool,359	/// Supports ERC721Metadata360	#[bondrewd(bits = "1..2")]361	pub erc721metadata: bool,362	/// External collections can't be managed using `unique` api363	#[bondrewd(bits = "7..8")]364	pub external: bool,365366	#[bondrewd(reserve, bits = "2..7")]367	pub reserved: u8,368}369bondrewd_codec!(CollectionFlags);370371/// Base structure for represent collection.372///373/// Used to provide basic functionality for all types of collections.374///375/// #### Note376/// Collection parameters, used in storage (see [`RpcCollection`] for the RPC version).377#[struct_versioning::versioned(version = 2, upper)]378#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen)]379pub struct Collection<AccountId> {380	/// Collection owner account.381	pub owner: AccountId,382383	/// Collection mode.384	pub mode: CollectionMode,385386	/// Access mode.387	#[version(..2)]388	pub access: AccessMode,389390	/// Collection name.391	pub name: CollectionName,392393	/// Collection description.394	pub description: CollectionDescription,395396	/// Token prefix.397	pub token_prefix: CollectionTokenPrefix,398399	#[version(..2)]400	pub mint_mode: bool,401402	#[version(..2)]403	pub offchain_schema: BoundedVec<u8, ConstU32<OFFCHAIN_SCHEMA_LIMIT>>,404405	#[version(..2)]406	pub schema_version: SchemaVersion,407408	/// The state of sponsorship of the collection.409	pub sponsorship: SponsorshipState<AccountId>,410411	/// Collection limits.412	pub limits: CollectionLimits,413414	/// Collection permissions.415	#[version(2.., upper(Default::default()))]416	pub permissions: CollectionPermissions,417418	#[version(2.., upper(Default::default()))]419	pub flags: CollectionFlags,420421	#[version(..2)]422	pub variable_on_chain_schema: BoundedVec<u8, ConstU32<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>>,423424	#[version(..2)]425	pub const_on_chain_schema: BoundedVec<u8, ConstU32<CONST_ON_CHAIN_SCHEMA_LIMIT>>,426427	#[version(..2)]428	pub meta_update_permission: MetaUpdatePermission,429}430431#[derive(Debug, Encode, Decode, Clone, PartialEq, TypeInfo)]432#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]433pub struct RpcCollectionFlags {434	/// Is collection is foreign.435	pub foreign: bool,436	/// Collection supports ERC721Metadata.437	pub erc721metadata: bool,438}439440/// Collection parameters, used in RPC calls (see [`Collection`] for the storage version).441#[struct_versioning::versioned(version = 2, upper)]442#[derive(Debug, Encode, Decode, Clone, PartialEq, TypeInfo)]443#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]444pub struct RpcCollection<AccountId> {445	/// Collection owner account.446	pub owner: AccountId,447448	/// Collection mode.449	pub mode: CollectionMode,450451	/// Collection name.452	pub name: Vec<u16>,453454	/// Collection description.455	pub description: Vec<u16>,456457	/// Token prefix.458	pub token_prefix: Vec<u8>,459460	/// The state of sponsorship of the collection.461	pub sponsorship: SponsorshipState<AccountId>,462463	/// Collection limits.464	pub limits: CollectionLimits,465466	/// Collection permissions.467	pub permissions: CollectionPermissions,468469	/// Token property permissions.470	pub token_property_permissions: Vec<PropertyKeyPermission>,471472	/// Collection properties.473	pub properties: Vec<Property>,474475	/// Is collection read only.476	pub read_only: bool,477478	/// Extra collection flags479	#[version(2.., upper(RpcCollectionFlags {foreign: false, erc721metadata: false}))]480	pub flags: RpcCollectionFlags,481}482483impl<AccountId> From<CollectionVersion1<AccountId>> for RpcCollection<AccountId> {484	fn from(value: CollectionVersion1<AccountId>) -> Self {485		let CollectionVersion1 {486			name,487			description,488			owner,489			mode,490			access,491			token_prefix,492			mint_mode,493			sponsorship,494			limits,495			..496		} = value;497498		RpcCollection {499			name: name.into_inner(),500			description: description.into_inner(),501			owner,502			mode,503			token_prefix: token_prefix.into_inner(),504			sponsorship,505			limits,506			permissions: CollectionPermissions {507				access: Some(access),508				mint_mode: Some(mint_mode),509				nesting: None,510			},511			token_property_permissions: Vec::default(),512			properties: Vec::default(),513			read_only: true,514515			flags: RpcCollectionFlags {516				foreign: false,517				erc721metadata: false,518			},519		}520	}521}522523pub struct RawEncoded(Vec<u8>);524525impl codec::Decode for RawEncoded {526	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {527		let mut out = Vec::new();528		while let Ok(v) = input.read_byte() {529			out.push(v);530		}531		Ok(Self(out))532	}533}534535impl Deref for RawEncoded {536	type Target = Vec<u8>;537538	fn deref(&self) -> &Self::Target {539		return &self.0;540	}541}542543/// Data used for create collection.544///545/// All fields are wrapped in [`Option`], where `None` means chain default.546#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, Derivative, MaxEncodedLen)]547#[derivative(Debug, Default(bound = ""))]548pub struct CreateCollectionData<AccountId> {549	/// Collection mode.550	#[derivative(Default(value = "CollectionMode::NFT"))]551	pub mode: CollectionMode,552553	/// Access mode.554	pub access: Option<AccessMode>,555556	/// Collection name.557	pub name: CollectionName,558559	/// Collection description.560	pub description: CollectionDescription,561562	/// Token prefix.563	pub token_prefix: CollectionTokenPrefix,564565	/// Pending collection sponsor.566	pub pending_sponsor: Option<AccountId>,567568	/// Collection limits.569	pub limits: Option<CollectionLimits>,570571	/// Collection permissions.572	pub permissions: Option<CollectionPermissions>,573574	/// Token property permissions.575	pub token_property_permissions: CollectionPropertiesPermissionsVec,576577	/// Collection properties.578	pub properties: CollectionPropertiesVec,579}580581/// Bounded vector of properties permissions. Max length is [`MAX_PROPERTIES_PER_ITEM`].582// TODO: maybe rename to PropertiesPermissionsVec583pub type CollectionPropertiesPermissionsVec =584	BoundedVec<PropertyKeyPermission, ConstU32<MAX_PROPERTIES_PER_ITEM>>;585586/// Bounded vector of properties. Max length is [`MAX_PROPERTIES_PER_ITEM`].587pub type CollectionPropertiesVec = BoundedVec<Property, ConstU32<MAX_PROPERTIES_PER_ITEM>>;588589/// Limits and restrictions of a collection.590///591/// All fields are wrapped in [`Option`], where `None` means chain default.592///593/// Update with `pallet_common::Pallet::clamp_limits`.594// IMPORTANT: When adding/removing fields from this struct - don't forget to also595#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]596#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]597// When adding/removing fields from this struct - don't forget to also update with `pallet_common::Pallet::clamp_limits`.598// TODO: move `pallet_common::Pallet::clamp_limits` into `impl CollectionLimits`.599// TODO: may be remove [`Option`] and **pub** from fields and create struct with default values.600pub struct CollectionLimits {601	/// How many tokens can a user have on one account.602	/// * Default - [`ACCOUNT_TOKEN_OWNERSHIP_LIMIT`].603	/// * Limit - [`MAX_TOKEN_OWNERSHIP`].604	pub account_token_ownership_limit: Option<u32>,605606	/// How many bytes of data are available for sponsorship.607	/// * Default - [`CUSTOM_DATA_LIMIT`].608	/// * Limit - [`CUSTOM_DATA_LIMIT`].609	pub sponsored_data_size: Option<u32>,610611	// FIXME should we delete this or repurpose it?612	/// Times in how many blocks we sponsor data.613	///614	/// If is `Some(v)` then **setVariableMetadata** is sponsored if there is `v` block between transactions.615	///616	/// * Default - [`SponsoringDisabled`](SponsoringRateLimit::SponsoringDisabled).617	/// * Limit - [`MAX_SPONSOR_TIMEOUT`].618	///619	/// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]620	pub sponsored_data_rate_limit: Option<SponsoringRateLimit>,621	/// Maximum amount of tokens inside the collection. Chain default: [`COLLECTION_TOKEN_LIMIT`]622623	/// How many tokens can be mined into this collection.624	///625	/// * Default - [`COLLECTION_TOKEN_LIMIT`].626	/// * Limit - [`COLLECTION_TOKEN_LIMIT`].627	pub token_limit: Option<u32>,628629	/// Timeouts for transfer sponsoring.630	///631	/// * Default632	///   - **Fungible** - [`FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`]633	///   - **NFT** - [`NFT_SPONSOR_TRANSFER_TIMEOUT`]634	///   - **Refungible** - [`REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`]635	/// * Limit - [`MAX_SPONSOR_TIMEOUT`].636	pub sponsor_transfer_timeout: Option<u32>,637638	/// Timeout for sponsoring an approval in passed blocks.639	///640	/// * Default - [`SPONSOR_APPROVE_TIMEOUT`].641	/// * Limit - [`MAX_SPONSOR_TIMEOUT`].642	pub sponsor_approve_timeout: Option<u32>,643644	/// Whether the collection owner of the collection can send tokens (which belong to other users).645	///646	/// * Default - **false**.647	pub owner_can_transfer: Option<bool>,648649	/// Can the collection owner burn other people's tokens.650	///651	/// * Default - **true**.652	pub owner_can_destroy: Option<bool>,653654	/// Is it possible to send tokens from this collection between users.655	///656	/// * Default - **true**.657	pub transfers_enabled: Option<bool>,658}659660impl CollectionLimits {661	pub fn with_default_limits(collection_type: CollectionMode) -> Self {662		CollectionLimits {663			account_token_ownership_limit: Some(ACCOUNT_TOKEN_OWNERSHIP_LIMIT),664			sponsored_data_size: Some(CUSTOM_DATA_LIMIT),665			sponsored_data_rate_limit: Some(SponsoringRateLimit::SponsoringDisabled),666			token_limit: Some(COLLECTION_TOKEN_LIMIT),667			sponsor_transfer_timeout: match collection_type {668				CollectionMode::NFT => Some(NFT_SPONSOR_TRANSFER_TIMEOUT),669				CollectionMode::ReFungible => Some(REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT),670				CollectionMode::Fungible(_) => Some(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT),671			},672			sponsor_approve_timeout: Some(SPONSOR_APPROVE_TIMEOUT),673			owner_can_transfer: Some(false),674			owner_can_destroy: Some(true),675			transfers_enabled: Some(true),676		}677	}678679	/// Get effective value for [`account_token_ownership_limit`](self.account_token_ownership_limit).680	pub fn account_token_ownership_limit(&self) -> u32 {681		self.account_token_ownership_limit682			.unwrap_or(ACCOUNT_TOKEN_OWNERSHIP_LIMIT)683			.min(MAX_TOKEN_OWNERSHIP)684	}685686	/// Get effective value for [`sponsored_data_size`](self.sponsored_data_size).687	pub fn sponsored_data_size(&self) -> u32 {688		self.sponsored_data_size689			.unwrap_or(CUSTOM_DATA_LIMIT)690			.min(CUSTOM_DATA_LIMIT)691	}692693	/// Get effective value for [`token_limit`](self.token_limit).694	pub fn token_limit(&self) -> u32 {695		self.token_limit696			.unwrap_or(COLLECTION_TOKEN_LIMIT)697			.min(COLLECTION_TOKEN_LIMIT)698	}699700	// TODO: may be replace u32 to mode?701	/// Get effective value for [`sponsor_transfer_timeout`](self.sponsor_transfer_timeout).702	pub fn sponsor_transfer_timeout(&self, default: u32) -> u32 {703		self.sponsor_transfer_timeout704			.unwrap_or(default)705			.min(MAX_SPONSOR_TIMEOUT)706	}707708	/// Get effective value for [`sponsor_approve_timeout`](self.sponsor_approve_timeout).709	pub fn sponsor_approve_timeout(&self) -> u32 {710		self.sponsor_approve_timeout711			.unwrap_or(SPONSOR_APPROVE_TIMEOUT)712			.min(MAX_SPONSOR_TIMEOUT)713	}714715	/// Get effective value for [`owner_can_transfer`](self.owner_can_transfer).716	pub fn owner_can_transfer(&self) -> bool {717		self.owner_can_transfer.unwrap_or(false)718	}719720	/// Get effective value for [`owner_can_transfer_instaled`](self.owner_can_transfer_instaled).721	pub fn owner_can_transfer_instaled(&self) -> bool {722		self.owner_can_transfer.is_some()723	}724725	/// Get effective value for [`owner_can_destroy`](self.owner_can_destroy).726	pub fn owner_can_destroy(&self) -> bool {727		self.owner_can_destroy.unwrap_or(true)728	}729730	/// Get effective value for [`transfers_enabled`](self.transfers_enabled).731	pub fn transfers_enabled(&self) -> bool {732		self.transfers_enabled.unwrap_or(true)733	}734735	/// Get effective value for [`sponsored_data_rate_limit`](self.sponsored_data_rate_limit).736	pub fn sponsored_data_rate_limit(&self) -> Option<u32> {737		match self738			.sponsored_data_rate_limit739			.unwrap_or(SponsoringRateLimit::SponsoringDisabled)740		{741			SponsoringRateLimit::SponsoringDisabled => None,742			SponsoringRateLimit::Blocks(v) => Some(v.min(MAX_SPONSOR_TIMEOUT)),743		}744	}745}746747/// Permissions on certain operations within a collection.748///749/// Some fields are wrapped in [`Option`], where `None` means chain default.750///751/// Update with `pallet_common::Pallet::clamp_permissions`.752#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]753#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]754// When adding/removing fields from this struct - don't forget to also update `pallet_common::Pallet::clamp_permissions`.755// TODO: move `pallet_common::Pallet::clamp_permissions` into `impl CollectionPermissions`.756pub struct CollectionPermissions {757	/// Access mode.758	///759	/// * Default - [`AccessMode::Normal`].760	pub access: Option<AccessMode>,761762	/// Minting allowance.763	///764	/// * Default - **false**.765	pub mint_mode: Option<bool>,766767	/// Permissions for nesting.768	///769	/// * Default770	///   - `token_owner` - **false**771	///   - `collection_admin` - **false**772	///   - `restricted` - **None**773	pub nesting: Option<NestingPermissions>,774}775776impl CollectionPermissions {777	/// Get effective value for [`access`](self.access).778	pub fn access(&self) -> AccessMode {779		self.access.unwrap_or(AccessMode::Normal)780	}781782	/// Get effective value for [`mint_mode`](self.mint_mode).783	pub fn mint_mode(&self) -> bool {784		self.mint_mode.unwrap_or(false)785	}786787	/// Get effective value for [`nesting`](self.nesting).788	pub fn nesting(&self) -> &NestingPermissions {789		static DEFAULT: NestingPermissions = NestingPermissions {790			token_owner: false,791			collection_admin: false,792			restricted: None,793			#[cfg(feature = "runtime-benchmarks")]794			permissive: false,795		};796		self.nesting.as_ref().unwrap_or(&DEFAULT)797	}798}799800/// Inner set for collections allowed to nest.801type OwnerRestrictedSetInner = BoundedBTreeSet<CollectionId, ConstU32<16>>;802803/// Wraper for collections set allowing nest.804#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen, Derivative)]805#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]806#[derivative(Debug)]807pub struct OwnerRestrictedSet(808	#[cfg_attr(feature = "serde1", serde(with = "bounded::set_serde"))]809	#[derivative(Debug(format_with = "bounded::set_debug"))]810	pub OwnerRestrictedSetInner,811);812813impl OwnerRestrictedSet {814	/// Create new set.815	pub fn new() -> Self {816		Self(Default::default())817	}818}819impl core::ops::Deref for OwnerRestrictedSet {820	type Target = OwnerRestrictedSetInner;821	fn deref(&self) -> &Self::Target {822		&self.0823	}824}825impl core::ops::DerefMut for OwnerRestrictedSet {826	fn deref_mut(&mut self) -> &mut Self::Target {827		&mut self.0828	}829}830831/// Part of collection permissions, if set, defines who is able to nest tokens into other tokens.832#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen, Derivative)]833#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]834#[derivative(Debug)]835pub struct NestingPermissions {836	/// Owner of token can nest tokens under it.837	pub token_owner: bool,838	/// Admin of token collection can nest tokens under token.839	pub collection_admin: bool,840	/// If set - only tokens from specified collections can be nested.841	pub restricted: Option<OwnerRestrictedSet>,842843	#[cfg(feature = "runtime-benchmarks")]844	/// Anyone can nest tokens, mutually exclusive with `token_owner`, `admin`.845	pub permissive: bool,846}847848/// Enum denominating how often can sponsoring occur if it is enabled.849///850/// Used for [`collection limits`](CollectionLimits).851#[derive(Encode, Decode, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]852#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]853pub enum SponsoringRateLimit {854	/// Sponsoring is disabled, and the collection sponsor will not pay for transactions855	SponsoringDisabled,856	/// Once per how many blocks can sponsorship of a transaction type occur857	Blocks(u32),858}859860/// Data used to describe an NFT at creation.861#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]862#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]863#[derivative(Debug)]864pub struct CreateNftData {865	/// Key-value pairs used to describe the token as metadata866	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]867	#[derivative(Debug(format_with = "bounded::vec_debug"))]868	/// Properties that wil be assignet to created item.869	pub properties: CollectionPropertiesVec,870}871872/// Data used to describe a Fungible token at creation.873#[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq, TypeInfo)]874#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]875pub struct CreateFungibleData {876	/// Number of fungible coins minted877	pub value: u128,878}879880/// Data used to describe a Refungible token at creation.881#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]882#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]883#[derivative(Debug)]884pub struct CreateReFungibleData {885	/// Number of pieces the RFT is split into886	pub pieces: u128,887888	/// Key-value pairs used to describe the token as metadata889	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]890	#[derivative(Debug(format_with = "bounded::vec_debug"))]891	pub properties: CollectionPropertiesVec,892}893894// TODO: remove this.895#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]896#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]897pub enum MetaUpdatePermission {898	ItemOwner,899	Admin,900	None,901}902903/// Enum holding data used for creation of all three item types.904/// Unified data for create item.905#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]906#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]907pub enum CreateItemData {908	/// Data for create NFT.909	NFT(CreateNftData),910	/// Data for create Fungible item.911	Fungible(CreateFungibleData),912	/// Data for create ReFungible item.913	ReFungible(CreateReFungibleData),914}915916/// Extended data for create NFT.917#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]918#[derivative(Debug)]919pub struct CreateNftExData<CrossAccountId> {920	/// Properties that wil be assignet to created item.921	#[derivative(Debug(format_with = "bounded::vec_debug"))]922	pub properties: CollectionPropertiesVec,923924	/// Owner of creating item.925	pub owner: CrossAccountId,926}927928/// Extended data for create ReFungible item.929#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]930#[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]931pub struct CreateRefungibleExMultipleOwners<CrossAccountId> {932	#[derivative(Debug(format_with = "bounded::map_debug"))]933	pub users: BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,934	#[derivative(Debug(format_with = "bounded::vec_debug"))]935	pub properties: CollectionPropertiesVec,936}937938/// Extended data for create ReFungible item.939#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]940#[derivative(Debug(bound = "CrossAccountId: fmt::Debug"))]941pub struct CreateRefungibleExSingleOwner<CrossAccountId> {942	pub user: CrossAccountId,943	pub pieces: u128,944	#[derivative(Debug(format_with = "bounded::vec_debug"))]945	pub properties: CollectionPropertiesVec,946}947948/// Unified extended data for creating item.949#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]950#[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]951pub enum CreateItemExData<CrossAccountId> {952	/// Extended data for create NFT.953	NFT(954		#[derivative(Debug(format_with = "bounded::vec_debug"))]955		BoundedVec<CreateNftExData<CrossAccountId>, ConstU32<MAX_ITEMS_PER_BATCH>>,956	),957958	/// Extended data for create Fungible item.959	Fungible(960		#[derivative(Debug(format_with = "bounded::map_debug"))]961		BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,962	),963964	/// Extended data for create ReFungible item in case of965	/// many tokens, each may have only one owner966	RefungibleMultipleItems(967		#[derivative(Debug(format_with = "bounded::vec_debug"))]968		BoundedVec<CreateRefungibleExSingleOwner<CrossAccountId>, ConstU32<MAX_ITEMS_PER_BATCH>>,969	),970971	/// Extended data for create ReFungible item in case of972	/// single token, which may have many owners973	RefungibleMultipleOwners(CreateRefungibleExMultipleOwners<CrossAccountId>),974}975976impl From<CreateNftData> for CreateItemData {977	fn from(item: CreateNftData) -> Self {978		CreateItemData::NFT(item)979	}980}981982impl From<CreateReFungibleData> for CreateItemData {983	fn from(item: CreateReFungibleData) -> Self {984		CreateItemData::ReFungible(item)985	}986}987988impl From<CreateFungibleData> for CreateItemData {989	fn from(item: CreateFungibleData) -> Self {990		CreateItemData::Fungible(item)991	}992}993994/// Token's address, dictated by its collection and token IDs.995#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]996#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]997// todo possibly rename to be used generally as an address pair998pub struct TokenChild {999	/// Token id.1000	pub token: TokenId,10011002	/// Collection id.1003	pub collection: CollectionId,1004}10051006/// Collection statistics.1007#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]1008#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]1009pub struct CollectionStats {1010	/// Number of created items.1011	pub created: u32,10121013	/// Number of burned items.1014	pub destroyed: u32,10151016	/// Number of current items.1017	pub alive: u32,1018}10191020/// This type works like [`PhantomData`] but supports generating _scale-info_ descriptions to generate node metadata.1021#[derive(Encode, Decode, Clone, Debug)]1022#[cfg_attr(feature = "std", derive(PartialEq))]1023pub struct PhantomType<T>(core::marker::PhantomData<T>);10241025impl<T: TypeInfo + 'static> TypeInfo for PhantomType<T> {1026	type Identity = PhantomType<T>;10271028	fn type_info() -> scale_info::Type {1029		use scale_info::{1030			Type, Path,1031			build::{FieldsBuilder, UnnamedFields},1032			form::MetaForm,1033			type_params,1034		};1035		Type::builder()1036			.path(Path::new("up_data_structs", "PhantomType"))1037			.type_params(type_params!(T))1038			.composite(1039				<FieldsBuilder<MetaForm, UnnamedFields>>::default().field(|b| b.ty::<[T; 0]>()),1040			)1041	}1042}1043impl<T> MaxEncodedLen for PhantomType<T> {1044	fn max_encoded_len() -> usize {1045		01046	}1047}10481049/// Bounded vector of bytes.1050pub type BoundedBytes<S> = BoundedVec<u8, S>;10511052/// Extra properties for external collections.1053pub type AuxPropertyValue = BoundedBytes<ConstU32<MAX_AUX_PROPERTY_VALUE_LENGTH>>;10541055/// Property key.1056pub type PropertyKey = BoundedBytes<ConstU32<MAX_PROPERTY_KEY_LENGTH>>;10571058/// Property value.1059pub type PropertyValue = BoundedBytes<ConstU32<MAX_PROPERTY_VALUE_LENGTH>>;10601061/// Property permission.1062#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone, Default)]1063#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]1064pub struct PropertyPermission {1065	/// Permission to change the property and property permission.1066	///1067	/// If it **false** then you can not change corresponding property even if [`collection_admin`] and [`token_owner`] are **true**.1068	pub mutable: bool,10691070	/// Change permission for the collection administrator.1071	pub collection_admin: bool,10721073	/// Permission to change the property for the owner of the token.1074	pub token_owner: bool,1075}10761077impl PropertyPermission {1078	/// Creates mutable property permission but changes restricted for collection admin and token owner.1079	pub fn none() -> Self {1080		Self {1081			mutable: true,1082			collection_admin: false,1083			token_owner: false,1084		}1085	}1086}10871088/// Property is simpl key-value record.1089#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, MaxEncodedLen)]1090#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]1091pub struct Property {1092	/// Property key.1093	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]1094	pub key: PropertyKey,10951096	/// Property value.1097	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]1098	pub value: PropertyValue,1099}11001101impl Into<(PropertyKey, PropertyValue)> for Property {1102	fn into(self) -> (PropertyKey, PropertyValue) {1103		(self.key, self.value)1104	}1105}11061107/// Record for proprty key permission.1108#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]1109#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]1110pub struct PropertyKeyPermission {1111	/// Key.1112	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]1113	pub key: PropertyKey,11141115	/// Permission.1116	pub permission: PropertyPermission,1117}11181119impl Into<(PropertyKey, PropertyPermission)> for PropertyKeyPermission {1120	fn into(self) -> (PropertyKey, PropertyPermission) {1121		(self.key, self.permission)1122	}1123}11241125/// Errors for properties actions.1126#[derive(Debug)]1127pub enum PropertiesError {1128	/// The space allocated for properties has run out.1129	///1130	/// * Limit for colection - [`MAX_COLLECTION_PROPERTIES_SIZE`].1131	/// * Limit for token - [`MAX_TOKEN_PROPERTIES_SIZE`].1132	NoSpaceForProperty,11331134	/// The property limit has been reached.1135	///1136	/// * Limit - [`MAX_PROPERTIES_PER_ITEM`].1137	PropertyLimitReached,11381139	/// Property key contains not allowed character.1140	InvalidCharacterInPropertyKey,11411142	/// Property key length is too long.1143	///1144	/// * Limit - [`MAX_PROPERTY_KEY_LENGTH`].1145	PropertyKeyIsTooLong,11461147	/// Property key is empty.1148	EmptyPropertyKey,1149}11501151/// Token owner error: it could be either `NotFound` ot `MultipleOwners`.1152#[derive(Debug)]1153pub enum TokenOwnerError {1154	NotFound,1155	MultipleOwners,1156}11571158/// Marker for scope of property.1159///1160/// Scoped property can't be changed by user. Used for external collections.1161#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Clone, Copy)]1162pub enum PropertyScope {1163	None,1164	Rmrk,1165}11661167impl PropertyScope {1168	pub fn prefix(&self) -> &'static [u8] {1169		match self {1170			Self::None => b"",1171			Self::Rmrk => b"rmrk:",1172		}1173	}1174	/// Apply scope to property key.1175	pub fn apply(self, key: PropertyKey) -> Result<PropertyKey, PropertiesError> {1176		let prefix = self.prefix();1177		if prefix == b"" {1178			return Ok(key);1179		}1180		[prefix, key.as_slice()]1181			.concat()1182			.try_into()1183			.map_err(|_| PropertiesError::PropertyKeyIsTooLong)1184	}1185}11861187/// Trait for operate with properties.1188pub trait TrySetProperty: Sized {1189	type Value;11901191	/// Try to set property with scope.1192	fn try_scoped_set(1193		&mut self,1194		scope: PropertyScope,1195		key: PropertyKey,1196		value: Self::Value,1197	) -> Result<Option<Self::Value>, PropertiesError>;11981199	/// Try to set property with scope from iterator.1200	fn try_scoped_set_from_iter<I, KV>(1201		&mut self,1202		scope: PropertyScope,1203		iter: I,1204	) -> Result<(), PropertiesError>1205	where1206		I: Iterator<Item = KV>,1207		KV: Into<(PropertyKey, Self::Value)>,1208	{1209		for kv in iter {1210			let (key, value) = kv.into();1211			self.try_scoped_set(scope, key, value)?;1212		}12131214		Ok(())1215	}12161217	/// Try to set property.1218	fn try_set(1219		&mut self,1220		key: PropertyKey,1221		value: Self::Value,1222	) -> Result<Option<Self::Value>, PropertiesError> {1223		self.try_scoped_set(PropertyScope::None, key, value)1224	}12251226	/// Try to set property from iterator.1227	fn try_set_from_iter<I, KV>(&mut self, iter: I) -> Result<(), PropertiesError>1228	where1229		I: Iterator<Item = KV>,1230		KV: Into<(PropertyKey, Self::Value)>,1231	{1232		self.try_scoped_set_from_iter(PropertyScope::None, iter)1233	}1234}12351236/// Wrapped map for storing properties.1237#[derive(Encode, Decode, TypeInfo, Derivative, Clone, PartialEq, MaxEncodedLen)]1238#[derivative(Default(bound = ""))]1239pub struct PropertiesMap<Value>(1240	BoundedBTreeMap<PropertyKey, Value, ConstU32<MAX_PROPERTIES_PER_ITEM>>,1241);12421243impl<Value> PropertiesMap<Value> {1244	/// Create new property map.1245	pub fn new() -> Self {1246		Self(BoundedBTreeMap::new())1247	}12481249	/// Remove property from map.1250	pub fn remove(&mut self, key: &PropertyKey) -> Result<Option<Value>, PropertiesError> {1251		Self::check_property_key(key)?;12521253		Ok(self.0.remove(key))1254	}12551256	/// Get property with appropriate key from map.1257	pub fn get(&self, key: &PropertyKey) -> Option<&Value> {1258		self.0.get(key)1259	}12601261	/// Check if map contains key.1262	pub fn contains_key(&self, key: &PropertyKey) -> bool {1263		self.0.contains_key(key)1264	}12651266	/// Check if map contains key with key validation.1267	fn check_property_key(key: &PropertyKey) -> Result<(), PropertiesError> {1268		if key.is_empty() {1269			return Err(PropertiesError::EmptyPropertyKey);1270		}12711272		for byte in key.as_slice().iter() {1273			let byte = *byte;12741275			if !byte.is_ascii_alphanumeric() && byte != b'_' && byte != b'-' && byte != b'.' {1276				return Err(PropertiesError::InvalidCharacterInPropertyKey);1277			}1278		}12791280		Ok(())1281	}12821283	pub fn values(&self) -> impl Iterator<Item = &Value> {1284		self.0.values()1285	}12861287	pub fn iter(&self) -> impl Iterator<Item = (&PropertyKey, &Value)> {1288		self.0.iter()1289	}1290}12911292impl<Value> IntoIterator for PropertiesMap<Value> {1293	type Item = (PropertyKey, Value);1294	type IntoIter = <1295		BoundedBTreeMap<1296			PropertyKey,1297			Value,1298			ConstU32<MAX_PROPERTIES_PER_ITEM>1299		> as IntoIterator1300	>::IntoIter;13011302	fn into_iter(self) -> Self::IntoIter {1303		self.0.into_iter()1304	}1305}13061307impl<Value> TrySetProperty for PropertiesMap<Value> {1308	type Value = Value;13091310	fn try_scoped_set(1311		&mut self,1312		scope: PropertyScope,1313		key: PropertyKey,1314		value: Self::Value,1315	) -> Result<Option<Self::Value>, PropertiesError> {1316		Self::check_property_key(&key)?;13171318		let key = scope.apply(key)?;1319		self.01320			.try_insert(key, value)1321			.map_err(|_| PropertiesError::PropertyLimitReached)1322	}1323}13241325/// Alias for property permissions map.1326pub type PropertiesPermissionMap = PropertiesMap<PropertyPermission>;13271328fn slice_size(data: &[u8]) -> u32 {1329	scoped_slice_size(PropertyScope::None, data)1330}1331fn scoped_slice_size(scope: PropertyScope, data: &[u8]) -> u32 {1332	use codec::Compact;1333	let prefix = scope.prefix();1334	<Compact<u32>>::encoded_size(&Compact(data.len() as u32 + prefix.len() as u32)) as u321335		+ data.len() as u321336		+ prefix.len() as u321337}13381339/// Wrapper for properties map with consumed space control.1340#[derive(Encode, Decode, TypeInfo, Clone, PartialEq)]1341pub struct Properties<const S: u32> {1342	map: PropertiesMap<PropertyValue>,1343	consumed_space: u32,1344	// May be not zero, previously served as a current S generic1345	_reserved: u32,1346}13471348impl<const S: u32> MaxEncodedLen for Properties<S> {1349	fn max_encoded_len() -> usize {1350		// len of map + len of consumed_space + len of space_limit1351		u32::max_encoded_len() * 3 + S as usize1352	}1353}13541355impl<const S: u32> Default for Properties<S> {1356	fn default() -> Self {1357		Self::new()1358	}1359}13601361impl<const S: u32> Properties<S> {1362	/// Create new properies container.1363	pub fn new() -> Self {1364		Self {1365			map: PropertiesMap::new(),1366			consumed_space: 0,1367			_reserved: 0,1368		}1369	}13701371	/// Remove propery with appropiate key.1372	pub fn remove(&mut self, key: &PropertyKey) -> Result<Option<PropertyValue>, PropertiesError> {1373		let value = self.map.remove(key)?;13741375		if let Some(ref value) = value {1376			let kv_len = slice_size(key) + slice_size(value);1377			self.consumed_space = self.consumed_space.saturating_sub(kv_len);1378		}13791380		Ok(value)1381	}13821383	/// Get property with appropriate key.1384	pub fn get(&self, key: &PropertyKey) -> Option<&PropertyValue> {1385		self.map.get(key)1386	}13871388	/// Recomputes the consumed space for the current properties state.1389	/// Needed to repair a token due to a bug fixed in the [PR #733](https://github.com/UniqueNetwork/unique-chain/pull/773).1390	pub fn recompute_consumed_space(&mut self) {1391		self.consumed_space = self1392			.map1393			.iter()1394			.map(|(key, value)| slice_size(key) + slice_size(value))1395			.sum();1396	}1397}13981399impl<const S: u32> IntoIterator for Properties<S> {1400	type Item = (PropertyKey, PropertyValue);1401	type IntoIter = <PropertiesMap<PropertyValue> as IntoIterator>::IntoIter;14021403	fn into_iter(self) -> Self::IntoIter {1404		self.map.into_iter()1405	}1406}14071408impl<const S: u32> TrySetProperty for Properties<S> {1409	type Value = PropertyValue;14101411	fn try_scoped_set(1412		&mut self,1413		scope: PropertyScope,1414		key: PropertyKey,1415		value: Self::Value,1416	) -> Result<Option<Self::Value>, PropertiesError> {1417		let key_size = scoped_slice_size(scope, &key);1418		let value_size = slice_size(&value) as u32;14191420		if self.consumed_space + value_size + key_size > S && !cfg!(feature = "runtime-benchmarks")1421		{1422			return Err(PropertiesError::NoSpaceForProperty);1423		}14241425		let old_value = self.map.try_scoped_set(scope, key, value)?;14261427		if let Some(old_value) = old_value.as_ref() {1428			let old_value_size = slice_size(&old_value);1429			self.consumed_space = self.consumed_space.saturating_sub(old_value_size) + value_size;1430		} else {1431			self.consumed_space += key_size + value_size;1432		}14331434		Ok(old_value)1435	}1436}14371438pub type CollectionProperties = Properties<MAX_COLLECTION_PROPERTIES_SIZE>;1439pub type TokenProperties = Properties<MAX_TOKEN_PROPERTIES_SIZE>;14401441#[cfg(test)]1442mod tests {1443	use super::*;1444	use codec::IoReader;14451446	#[test]1447	fn rpc_collection_supports_decoding_old_versions() {1448		let encoded_rpc_collection: [u8; 1013] = [1449			0, 1, 250, 241, 137, 120, 188, 29, 94, 210, 193, 237, 186, 22, 203, 241, 52, 248, 167,1450			235, 241, 211, 236, 28, 138, 156, 59, 160, 156, 105, 39, 247, 207, 101, 0, 0, 48, 65,1451			0, 73, 0, 32, 0, 67, 0, 114, 0, 101, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 115, 0,1452			252, 65, 0, 32, 0, 112, 0, 105, 0, 101, 0, 99, 0, 101, 0, 32, 0, 111, 0, 102, 0, 32, 0,1453			97, 0, 32, 0, 109, 0, 97, 0, 99, 0, 104, 0, 105, 0, 110, 0, 101, 0, 32, 0, 109, 0, 105,1454			0, 110, 0, 100, 0, 46, 0, 32, 0, 69, 0, 118, 0, 101, 0, 114, 0, 121, 0, 32, 0, 78, 0,1455			70, 0, 84, 0, 32, 0, 105, 0, 115, 0, 32, 0, 109, 0, 97, 0, 100, 0, 101, 0, 32, 0, 101,1456			0, 120, 0, 99, 0, 108, 0, 117, 0, 115, 0, 105, 0, 118, 0, 101, 0, 108, 0, 121, 0, 32,1457			0, 98, 0, 121, 0, 32, 0, 65, 0, 73, 0, 46, 0, 12, 65, 73, 67, 0, 0, 1, 0, 0, 0, 0, 0,1458			0, 0, 0, 0, 0, 17, 1, 123, 34, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 67, 111,1459			118, 101, 114, 34, 58, 34, 81, 109, 98, 52, 104, 122, 76, 101, 51, 49, 102, 98, 71, 74,1460			77, 89, 68, 82, 88, 84, 115, 107, 56, 49, 76, 103, 76, 97, 88, 76, 69, 112, 121, 97,1461			122, 102, 66, 85, 103, 111, 110, 118, 49, 118, 84, 85, 34, 125, 125, 11, 123, 34, 110,1462			101, 115, 116, 101, 100, 34, 58, 123, 34, 111, 110, 67, 104, 97, 105, 110, 77, 101,1463			116, 97, 68, 97, 116, 97, 34, 58, 123, 34, 110, 101, 115, 116, 101, 100, 34, 58, 123,1464			34, 78, 70, 84, 77, 101, 116, 97, 34, 58, 123, 34, 102, 105, 101, 108, 100, 115, 34,1465			58, 123, 34, 105, 112, 102, 115, 74, 115, 111, 110, 34, 58, 123, 34, 105, 100, 34, 58,1466			49, 44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34,1467			44, 34, 116, 121, 112, 101, 34, 58, 34, 115, 116, 114, 105, 110, 103, 34, 125, 44, 34,1468			67, 111, 108, 111, 114, 34, 58, 123, 34, 105, 100, 34, 58, 50, 44, 34, 114, 117, 108,1469			101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44, 34, 116, 121, 112,1470			101, 34, 58, 34, 67, 111, 108, 111, 114, 34, 125, 44, 34, 73, 110, 116, 101, 110, 115,1471			105, 111, 110, 115, 34, 58, 123, 34, 105, 100, 34, 58, 51, 44, 34, 114, 117, 108, 101,1472			34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44, 34, 116, 121, 112, 101, 34,1473			58, 34, 73, 110, 116, 101, 110, 115, 105, 111, 110, 115, 34, 125, 44, 34, 77, 111, 111,1474			100, 34, 58, 123, 34, 105, 100, 34, 58, 52, 44, 34, 114, 117, 108, 101, 34, 58, 34,1475			114, 101, 113, 117, 105, 114, 101, 100, 34, 44, 34, 116, 121, 112, 101, 34, 58, 34, 77,1476			111, 111, 100, 34, 125, 125, 125, 44, 34, 67, 111, 108, 111, 114, 34, 58, 123, 34, 111,1477			112, 116, 105, 111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34,1478			123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 67, 111, 108, 111, 114, 101, 100, 92, 34,1479			125, 34, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92,1480			34, 58, 92, 34, 66, 108, 97, 99, 107, 38, 87, 104, 105, 116, 101, 92, 34, 125, 34, 125,1481			44, 34, 118, 97, 108, 117, 101, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34,1482			58, 48, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 49, 125, 125, 44, 34, 73, 110,1483			116, 101, 110, 115, 105, 111, 110, 115, 34, 58, 123, 34, 111, 112, 116, 105, 111, 110,1484			115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92, 34, 101, 110,1485			92, 34, 58, 92, 34, 101, 118, 105, 108, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108,1486			100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 103, 111, 111, 100, 92,1487			34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 34, 123, 92, 34, 101, 110,1488			92, 34, 58, 92, 34, 110, 101, 117, 116, 114, 97, 108, 92, 34, 125, 34, 125, 44, 34,1489			118, 97, 108, 117, 101, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 48,1490			44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 49, 44, 34, 102, 105, 101, 108, 100, 51,1491			34, 58, 50, 125, 125, 44, 34, 77, 111, 111, 100, 34, 58, 123, 34, 111, 112, 116, 105,1492			111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92, 34,1493			101, 110, 92, 34, 58, 92, 34, 65, 98, 115, 116, 114, 97, 99, 116, 92, 34, 125, 34, 44,1494			34, 102, 105, 101, 108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34,1495			85, 110, 99, 97, 110, 110, 101, 121, 32, 118, 97, 108, 108, 101, 121, 92, 34, 125, 34,1496			44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92,1497			34, 83, 117, 114, 114, 101, 97, 108, 105, 115, 116, 92, 34, 125, 34, 125, 44, 34, 118,1498			97, 108, 117, 101, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 48, 44,1499			34, 102, 105, 101, 108, 100, 50, 34, 58, 49, 44, 34, 102, 105, 101, 108, 100, 51, 34,1500			58, 50, 125, 125, 125, 125, 125, 125, 0,1501		];1502		let mut bytes = IoReader(encoded_rpc_collection.as_slice());1503		CollectionVersion1::<[u8; 34]>::decode(&mut bytes).unwrap();1504	}15051506	#[test]1507	fn rpc_collection_supports_decoding_new_versions() {1508		let encoded_rpc_collection: [u8; 1576] = [1509			0, 1, 238, 236, 179, 149, 150, 47, 71, 194, 69, 174, 250, 116, 251, 148, 90, 15, 56,1510			220, 91, 79, 49, 79, 45, 197, 171, 98, 14, 171, 80, 23, 58, 92, 0, 96, 77, 0, 105, 0,1511			110, 0, 116, 0, 70, 0, 101, 0, 115, 0, 116, 0, 32, 0, 83, 0, 121, 0, 109, 0, 109, 0,1512			101, 0, 116, 0, 114, 0, 121, 0, 32, 0, 66, 0, 114, 0, 101, 0, 97, 0, 99, 0, 104, 0,1513			113, 3, 83, 0, 121, 0, 109, 0, 109, 0, 101, 0, 116, 0, 114, 0, 121, 0, 32, 0, 104, 0,1514			97, 0, 115, 0, 32, 0, 115, 0, 111, 0, 109, 0, 101, 0, 116, 0, 104, 0, 105, 0, 110, 0,1515			103, 0, 32, 0, 105, 0, 110, 0, 116, 0, 111, 0, 120, 0, 105, 0, 99, 0, 97, 0, 116, 0,1516			105, 0, 110, 0, 103, 0, 32, 0, 116, 0, 104, 0, 97, 0, 116, 0, 32, 0, 100, 0, 114, 0,1517			97, 0, 119, 0, 115, 0, 32, 0, 121, 0, 111, 0, 117, 0, 32, 0, 105, 0, 110, 0, 46, 0, 10,1518			0, 73, 0, 110, 0, 115, 0, 112, 0, 105, 0, 114, 0, 101, 0, 100, 0, 32, 0, 98, 0, 121, 0,1519			32, 0, 116, 0, 104, 0, 101, 0, 32, 0, 112, 0, 101, 0, 114, 0, 102, 0, 101, 0, 99, 0,1520			116, 0, 105, 0, 111, 0, 110, 0, 32, 0, 111, 0, 102, 0, 32, 0, 116, 0, 104, 0, 101, 0,1521			32, 0, 115, 0, 121, 0, 109, 0, 109, 0, 101, 0, 116, 0, 114, 0, 121, 0, 44, 0, 32, 0,1522			73, 0, 32, 0, 104, 0, 97, 0, 118, 0, 101, 0, 32, 0, 99, 0, 114, 0, 101, 0, 97, 0, 116,1523			0, 101, 0, 100, 0, 32, 0, 115, 0, 121, 0, 109, 0, 109, 0, 101, 0, 116, 0, 114, 0, 105,1524			0, 99, 0, 97, 0, 108, 0, 32, 0, 105, 0, 109, 0, 97, 0, 103, 0, 101, 0, 115, 0, 32, 0,1525			111, 0, 102, 0, 32, 0, 115, 0, 101, 0, 118, 0, 101, 0, 114, 0, 97, 0, 108, 0, 32, 0,1526			118, 0, 101, 0, 114, 0, 116, 0, 105, 0, 99, 0, 101, 0, 115, 0, 44, 0, 32, 0, 98, 0,1527			117, 0, 116, 0, 32, 0, 115, 0, 111, 0, 109, 0, 101, 0, 32, 0, 115, 0, 121, 0, 109, 0,1528			109, 0, 101, 0, 116, 0, 114, 0, 121, 0, 32, 0, 98, 0, 114, 0, 101, 0, 97, 0, 99, 0,1529			104, 0, 101, 0, 115, 0, 32, 0, 97, 0, 110, 0, 100, 0, 32, 0, 99, 0, 111, 0, 108, 0,1530			111, 0, 114, 0, 115, 0, 32, 0, 116, 0, 104, 0, 97, 0, 116, 0, 32, 0, 109, 0, 97, 0,1531			107, 0, 101, 0, 32, 0, 101, 0, 97, 0, 99, 0, 104, 0, 32, 0, 105, 0, 109, 0, 97, 0, 103,1532			0, 101, 0, 32, 0, 85, 0, 78, 0, 73, 0, 81, 0, 85, 0, 69, 0, 46, 0, 12, 83, 121, 66, 0,1533			0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 4, 56, 95, 111, 108, 100, 95, 99,1534			111, 110, 115, 116, 68, 97, 116, 97, 0, 1, 0, 12, 92, 95, 111, 108, 100, 95, 99, 111,1535			110, 115, 116, 79, 110, 67, 104, 97, 105, 110, 83, 99, 104, 101, 109, 97, 97, 13, 123,1536			34, 110, 101, 115, 116, 101, 100, 34, 58, 123, 34, 111, 110, 67, 104, 97, 105, 110, 77,1537			101, 116, 97, 68, 97, 116, 97, 34, 58, 123, 34, 110, 101, 115, 116, 101, 100, 34, 58,1538			123, 34, 78, 70, 84, 77, 101, 116, 97, 34, 58, 123, 34, 102, 105, 101, 108, 100, 115,1539			34, 58, 123, 34, 105, 112, 102, 115, 74, 115, 111, 110, 34, 58, 123, 34, 105, 100, 34,1540			58, 49, 44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100,1541			34, 44, 34, 116, 121, 112, 101, 34, 58, 34, 115, 116, 114, 105, 110, 103, 34, 125, 44,1542			34, 67, 111, 108, 111, 114, 34, 58, 123, 34, 105, 100, 34, 58, 50, 44, 34, 114, 117,1543			108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44, 34, 116, 121,1544			112, 101, 34, 58, 34, 67, 111, 108, 111, 114, 34, 125, 44, 34, 83, 121, 109, 109, 101,1545			116, 114, 121, 32, 66, 114, 101, 97, 99, 104, 34, 58, 123, 34, 105, 100, 34, 58, 51,1546			44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44,1547			34, 116, 121, 112, 101, 34, 58, 34, 83, 121, 109, 109, 101, 116, 114, 121, 32, 66, 114,1548			101, 97, 99, 104, 34, 125, 44, 34, 86, 101, 114, 116, 105, 99, 101, 34, 58, 123, 34,1549			105, 100, 34, 58, 52, 44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105,1550			114, 101, 100, 34, 44, 34, 116, 121, 112, 101, 34, 58, 34, 86, 101, 114, 116, 105, 99,1551			101, 34, 125, 125, 125, 44, 34, 67, 111, 108, 111, 114, 34, 58, 123, 34, 111, 112, 116,1552			105, 111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92,1553			34, 101, 110, 92, 34, 58, 92, 34, 49, 32, 32, 32, 92, 34, 125, 34, 44, 34, 102, 105,1554			101, 108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 50, 32, 92,1555			34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 34, 123, 92, 34, 101, 110,1556			92, 34, 58, 92, 34, 51, 92, 34, 125, 34, 125, 44, 34, 118, 97, 108, 117, 101, 115, 34,1557			58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 48, 44, 34, 102, 105, 101, 108, 100,1558			50, 34, 58, 49, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 50, 125, 125, 44, 34, 83,1559			121, 109, 109, 101, 116, 114, 121, 32, 66, 114, 101, 97, 99, 104, 34, 58, 123, 34, 111,1560			112, 116, 105, 111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34,1561			123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 49, 92, 34, 125, 34, 44, 34, 102, 105, 101,1562			108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 50, 92, 34, 125,1563			34, 125, 44, 34, 118, 97, 108, 117, 101, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100,1564			49, 34, 58, 48, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 49, 125, 125, 44, 34, 86,1565			101, 114, 116, 105, 99, 101, 34, 58, 123, 34, 111, 112, 116, 105, 111, 110, 115, 34,1566			58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34,1567			58, 92, 34, 54, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 34, 123,1568			92, 34, 101, 110, 92, 34, 58, 92, 34, 55, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108,1569			100, 51, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 56, 92, 34, 125, 34,1570			44, 34, 102, 105, 101, 108, 100, 52, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92,1571			34, 57, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 53, 34, 58, 34, 123, 92, 34,1572			101, 110, 92, 34, 58, 92, 34, 49, 48, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108, 100,1573			54, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 49, 49, 92, 34, 125, 34, 44,1574			34, 102, 105, 101, 108, 100, 55, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34,1575			49, 50, 92, 34, 125, 34, 125, 44, 34, 118, 97, 108, 117, 101, 115, 34, 58, 123, 34,1576			102, 105, 101, 108, 100, 49, 34, 58, 48, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58,1577			49, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 50, 44, 34, 102, 105, 101, 108, 100,1578			52, 34, 58, 51, 44, 34, 102, 105, 101, 108, 100, 53, 34, 58, 52, 44, 34, 102, 105, 101,1579			108, 100, 54, 34, 58, 53, 44, 34, 102, 105, 101, 108, 100, 55, 34, 58, 54, 125, 125,1580			125, 125, 125, 125, 72, 95, 111, 108, 100, 95, 115, 99, 104, 101, 109, 97, 86, 101,1581			114, 115, 105, 111, 110, 24, 85, 110, 105, 113, 117, 101, 104, 95, 111, 108, 100, 95,1582			118, 97, 114, 105, 97, 98, 108, 101, 79, 110, 67, 104, 97, 105, 110, 83, 99, 104, 101,1583			109, 97, 17, 1, 123, 34, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 67, 111, 118,1584			101, 114, 34, 58, 34, 81, 109, 82, 67, 77, 84, 109, 57, 118, 81, 107, 76, 89, 86, 65,1585			54, 54, 87, 80, 49, 75, 72, 57, 55, 106, 84, 76, 76, 115, 56, 74, 78, 86, 65, 114, 80,1586			66, 52, 56, 98, 106, 87, 84, 75, 74, 110, 34, 125, 0, 0, 0,1587		];1588		let mut bytes = IoReader(encoded_rpc_collection.as_slice());1589		RpcCollection::<[u8; 34]>::decode(&mut bytes).unwrap();1590	}15911592	#[test]1593	fn rpc_collection_supports_decoding_through_vec() {1594		let encoded_rpc_collection: [u8; 1576] = [1595			0, 1, 238, 236, 179, 149, 150, 47, 71, 194, 69, 174, 250, 116, 251, 148, 90, 15, 56,1596			220, 91, 79, 49, 79, 45, 197, 171, 98, 14, 171, 80, 23, 58, 92, 0, 96, 77, 0, 105, 0,1597			110, 0, 116, 0, 70, 0, 101, 0, 115, 0, 116, 0, 32, 0, 83, 0, 121, 0, 109, 0, 109, 0,1598			101, 0, 116, 0, 114, 0, 121, 0, 32, 0, 66, 0, 114, 0, 101, 0, 97, 0, 99, 0, 104, 0,1599			113, 3, 83, 0, 121, 0, 109, 0, 109, 0, 101, 0, 116, 0, 114, 0, 121, 0, 32, 0, 104, 0,1600			97, 0, 115, 0, 32, 0, 115, 0, 111, 0, 109, 0, 101, 0, 116, 0, 104, 0, 105, 0, 110, 0,1601			103, 0, 32, 0, 105, 0, 110, 0, 116, 0, 111, 0, 120, 0, 105, 0, 99, 0, 97, 0, 116, 0,1602			105, 0, 110, 0, 103, 0, 32, 0, 116, 0, 104, 0, 97, 0, 116, 0, 32, 0, 100, 0, 114, 0,1603			97, 0, 119, 0, 115, 0, 32, 0, 121, 0, 111, 0, 117, 0, 32, 0, 105, 0, 110, 0, 46, 0, 10,1604			0, 73, 0, 110, 0, 115, 0, 112, 0, 105, 0, 114, 0, 101, 0, 100, 0, 32, 0, 98, 0, 121, 0,1605			32, 0, 116, 0, 104, 0, 101, 0, 32, 0, 112, 0, 101, 0, 114, 0, 102, 0, 101, 0, 99, 0,1606			116, 0, 105, 0, 111, 0, 110, 0, 32, 0, 111, 0, 102, 0, 32, 0, 116, 0, 104, 0, 101, 0,1607			32, 0, 115, 0, 121, 0, 109, 0, 109, 0, 101, 0, 116, 0, 114, 0, 121, 0, 44, 0, 32, 0,1608			73, 0, 32, 0, 104, 0, 97, 0, 118, 0, 101, 0, 32, 0, 99, 0, 114, 0, 101, 0, 97, 0, 116,1609			0, 101, 0, 100, 0, 32, 0, 115, 0, 121, 0, 109, 0, 109, 0, 101, 0, 116, 0, 114, 0, 105,1610			0, 99, 0, 97, 0, 108, 0, 32, 0, 105, 0, 109, 0, 97, 0, 103, 0, 101, 0, 115, 0, 32, 0,1611			111, 0, 102, 0, 32, 0, 115, 0, 101, 0, 118, 0, 101, 0, 114, 0, 97, 0, 108, 0, 32, 0,1612			118, 0, 101, 0, 114, 0, 116, 0, 105, 0, 99, 0, 101, 0, 115, 0, 44, 0, 32, 0, 98, 0,1613			117, 0, 116, 0, 32, 0, 115, 0, 111, 0, 109, 0, 101, 0, 32, 0, 115, 0, 121, 0, 109, 0,1614			109, 0, 101, 0, 116, 0, 114, 0, 121, 0, 32, 0, 98, 0, 114, 0, 101, 0, 97, 0, 99, 0,1615			104, 0, 101, 0, 115, 0, 32, 0, 97, 0, 110, 0, 100, 0, 32, 0, 99, 0, 111, 0, 108, 0,1616			111, 0, 114, 0, 115, 0, 32, 0, 116, 0, 104, 0, 97, 0, 116, 0, 32, 0, 109, 0, 97, 0,1617			107, 0, 101, 0, 32, 0, 101, 0, 97, 0, 99, 0, 104, 0, 32, 0, 105, 0, 109, 0, 97, 0, 103,1618			0, 101, 0, 32, 0, 85, 0, 78, 0, 73, 0, 81, 0, 85, 0, 69, 0, 46, 0, 12, 83, 121, 66, 0,1619			0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 4, 56, 95, 111, 108, 100, 95, 99,1620			111, 110, 115, 116, 68, 97, 116, 97, 0, 1, 0, 12, 92, 95, 111, 108, 100, 95, 99, 111,1621			110, 115, 116, 79, 110, 67, 104, 97, 105, 110, 83, 99, 104, 101, 109, 97, 97, 13, 123,1622			34, 110, 101, 115, 116, 101, 100, 34, 58, 123, 34, 111, 110, 67, 104, 97, 105, 110, 77,1623			101, 116, 97, 68, 97, 116, 97, 34, 58, 123, 34, 110, 101, 115, 116, 101, 100, 34, 58,1624			123, 34, 78, 70, 84, 77, 101, 116, 97, 34, 58, 123, 34, 102, 105, 101, 108, 100, 115,1625			34, 58, 123, 34, 105, 112, 102, 115, 74, 115, 111, 110, 34, 58, 123, 34, 105, 100, 34,1626			58, 49, 44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100,1627			34, 44, 34, 116, 121, 112, 101, 34, 58, 34, 115, 116, 114, 105, 110, 103, 34, 125, 44,1628			34, 67, 111, 108, 111, 114, 34, 58, 123, 34, 105, 100, 34, 58, 50, 44, 34, 114, 117,1629			108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44, 34, 116, 121,1630			112, 101, 34, 58, 34, 67, 111, 108, 111, 114, 34, 125, 44, 34, 83, 121, 109, 109, 101,1631			116, 114, 121, 32, 66, 114, 101, 97, 99, 104, 34, 58, 123, 34, 105, 100, 34, 58, 51,1632			44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105, 114, 101, 100, 34, 44,1633			34, 116, 121, 112, 101, 34, 58, 34, 83, 121, 109, 109, 101, 116, 114, 121, 32, 66, 114,1634			101, 97, 99, 104, 34, 125, 44, 34, 86, 101, 114, 116, 105, 99, 101, 34, 58, 123, 34,1635			105, 100, 34, 58, 52, 44, 34, 114, 117, 108, 101, 34, 58, 34, 114, 101, 113, 117, 105,1636			114, 101, 100, 34, 44, 34, 116, 121, 112, 101, 34, 58, 34, 86, 101, 114, 116, 105, 99,1637			101, 34, 125, 125, 125, 44, 34, 67, 111, 108, 111, 114, 34, 58, 123, 34, 111, 112, 116,1638			105, 111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92,1639			34, 101, 110, 92, 34, 58, 92, 34, 49, 32, 32, 32, 92, 34, 125, 34, 44, 34, 102, 105,1640			101, 108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 50, 32, 92,1641			34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 34, 123, 92, 34, 101, 110,1642			92, 34, 58, 92, 34, 51, 92, 34, 125, 34, 125, 44, 34, 118, 97, 108, 117, 101, 115, 34,1643			58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 48, 44, 34, 102, 105, 101, 108, 100,1644			50, 34, 58, 49, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 50, 125, 125, 44, 34, 83,1645			121, 109, 109, 101, 116, 114, 121, 32, 66, 114, 101, 97, 99, 104, 34, 58, 123, 34, 111,1646			112, 116, 105, 111, 110, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34,1647			123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 49, 92, 34, 125, 34, 44, 34, 102, 105, 101,1648			108, 100, 50, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 50, 92, 34, 125,1649			34, 125, 44, 34, 118, 97, 108, 117, 101, 115, 34, 58, 123, 34, 102, 105, 101, 108, 100,1650			49, 34, 58, 48, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 49, 125, 125, 44, 34, 86,1651			101, 114, 116, 105, 99, 101, 34, 58, 123, 34, 111, 112, 116, 105, 111, 110, 115, 34,1652			58, 123, 34, 102, 105, 101, 108, 100, 49, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34,1653			58, 92, 34, 54, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58, 34, 123,1654			92, 34, 101, 110, 92, 34, 58, 92, 34, 55, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108,1655			100, 51, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 56, 92, 34, 125, 34,1656			44, 34, 102, 105, 101, 108, 100, 52, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92,1657			34, 57, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108, 100, 53, 34, 58, 34, 123, 92, 34,1658			101, 110, 92, 34, 58, 92, 34, 49, 48, 92, 34, 125, 34, 44, 34, 102, 105, 101, 108, 100,1659			54, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34, 49, 49, 92, 34, 125, 34, 44,1660			34, 102, 105, 101, 108, 100, 55, 34, 58, 34, 123, 92, 34, 101, 110, 92, 34, 58, 92, 34,1661			49, 50, 92, 34, 125, 34, 125, 44, 34, 118, 97, 108, 117, 101, 115, 34, 58, 123, 34,1662			102, 105, 101, 108, 100, 49, 34, 58, 48, 44, 34, 102, 105, 101, 108, 100, 50, 34, 58,1663			49, 44, 34, 102, 105, 101, 108, 100, 51, 34, 58, 50, 44, 34, 102, 105, 101, 108, 100,1664			52, 34, 58, 51, 44, 34, 102, 105, 101, 108, 100, 53, 34, 58, 52, 44, 34, 102, 105, 101,1665			108, 100, 54, 34, 58, 53, 44, 34, 102, 105, 101, 108, 100, 55, 34, 58, 54, 125, 125,1666			125, 125, 125, 125, 72, 95, 111, 108, 100, 95, 115, 99, 104, 101, 109, 97, 86, 101,1667			114, 115, 105, 111, 110, 24, 85, 110, 105, 113, 117, 101, 104, 95, 111, 108, 100, 95,1668			118, 97, 114, 105, 97, 98, 108, 101, 79, 110, 67, 104, 97, 105, 110, 83, 99, 104, 101,1669			109, 97, 17, 1, 123, 34, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 67, 111, 118,1670			101, 114, 34, 58, 34, 81, 109, 82, 67, 77, 84, 109, 57, 118, 81, 107, 76, 89, 86, 65,1671			54, 54, 87, 80, 49, 75, 72, 57, 55, 106, 84, 76, 76, 115, 56, 74, 78, 86, 65, 114, 80,1672			66, 52, 56, 98, 106, 87, 84, 75, 74, 110, 34, 125, 0, 0, 0,1673		];1674		let mut bytes = IoReader(encoded_rpc_collection.as_slice());1675		let vec = RawEncoded::decode(&mut bytes).unwrap();1676		let mut bytes = IoReader(vec.as_slice());1677		RpcCollection::<[u8; 34]>::decode(&mut bytes).unwrap();1678	}1679}