difftreelog
NFTPAR-288. Limit schema size
in: master
2 files changed
node/src/chain_spec.rsdiffbeforeafterboth1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56// use nft_runtime::{7// AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig,8// SystemConfig, WASM_BINARY,9// };10// use nft_runtime::{ContractsConfig, ContractsSchedule, NftConfig, CollectionType};11use nft_runtime::*;12use sc_service::ChainType;13use sp_consensus_aura::sr25519::AuthorityId as AuraId;14use sp_core::{sr25519, Pair, Public};15use sp_finality_grandpa::AuthorityId as GrandpaId;16use sp_runtime::traits::{IdentifyAccount, Verify};17use serde_json::map::Map;1819// Note this is the URL for the telemetry server20//const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";2122/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.23pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>;2425/// Helper function to generate a crypto pair from seed26pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {27 TPublic::Pair::from_string(&format!("//{}", seed), None)28 .expect("static values are valid; qed")29 .public()30}3132type AccountPublic = <Signature as Verify>::Signer;3334/// Helper function to generate an account ID from seed35pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId36where37 AccountPublic: From<<TPublic::Pair as Pair>::Public>,38{39 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()40}4142/// Helper function to generate an authority key for Aura43pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) {44 (get_from_seed::<AuraId>(s), get_from_seed::<GrandpaId>(s))45}4647pub fn development_config() -> Result<ChainSpec, String> {48 let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?;4950 let mut properties = Map::new();51 properties.insert("tokenSymbol".into(), "UniqueTest".into());52 properties.insert("tokenDecimals".into(), 15.into());53 properties.insert("ss58Format".into(), 42.into()); // Generic Substrate wildcard (SS58 checksum preimage)5455 Ok(ChainSpec::from_genesis(56 // Name57 "Development",58 // ID59 "dev",60 ChainType::Development,61 move || testnet_genesis(62 wasm_binary,63 // Initial PoA authorities64 vec![65 authority_keys_from_seed("Alice"),66 ],67 // Sudo account68 get_account_id_from_seed::<sr25519::Public>("Alice"),69 // Pre-funded accounts70 vec![71 get_account_id_from_seed::<sr25519::Public>("Alice"),72 get_account_id_from_seed::<sr25519::Public>("Bob"),73 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),74 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),75 ],76 true,77 ),78 // Bootnodes79 vec![],80 // Telemetry81 None,82 // Protocol ID83 None,84 // Properties85 Some(properties),86 // Extensions87 None,88 ))89}9091pub fn local_testnet_config() -> Result<ChainSpec, String> {92 let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?;9394 Ok(ChainSpec::from_genesis(95 // Name96 "Local Testnet",97 // ID98 "local_testnet",99 ChainType::Local,100 move || testnet_genesis(101 wasm_binary,102 // Initial PoA authorities103 vec![104 authority_keys_from_seed("Alice"),105 authority_keys_from_seed("Bob"),106 ],107 // Sudo account108 get_account_id_from_seed::<sr25519::Public>("Alice"),109 // Pre-funded accounts110 vec![111 get_account_id_from_seed::<sr25519::Public>("Alice"),112 get_account_id_from_seed::<sr25519::Public>("Bob"),113 get_account_id_from_seed::<sr25519::Public>("Charlie"),114 get_account_id_from_seed::<sr25519::Public>("Dave"),115 get_account_id_from_seed::<sr25519::Public>("Eve"),116 get_account_id_from_seed::<sr25519::Public>("Ferdie"),117 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),118 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),119 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),120 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),121 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),122 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),123 ],124 true,125 ),126 // Bootnodes127 vec![],128 // Telemetry129 None,130 // Protocol ID131 None,132 // Properties133 None,134 // Extensions135 None,136 ))137}138139fn testnet_genesis(140 wasm_binary: &[u8],141 initial_authorities: Vec<(AuraId, GrandpaId)>,142 root_key: AccountId,143 endowed_accounts: Vec<AccountId>,144 enable_println: bool,145) -> GenesisConfig {146147 let vested_accounts = vec![148 get_account_id_from_seed::<sr25519::Public>("Bob"),149 ];150151 GenesisConfig {152 system: Some(SystemConfig {153 code: wasm_binary.to_vec(),154 changes_trie_config: Default::default(),155 }),156 pallet_balances: Some(BalancesConfig {157 balances: endowed_accounts158 .iter()159 .cloned()160 .map(|k| (k, 1 << 100))161 .collect(),162 }),163 pallet_aura: Some(AuraConfig {164 authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(),165 }),166 pallet_grandpa: Some(GrandpaConfig {167 authorities: initial_authorities168 .iter()169 .map(|x| (x.1.clone(), 1))170 .collect(),171 }),172 pallet_treasury: Some(Default::default()),173 pallet_sudo: Some(SudoConfig { key: root_key }),174 pallet_vesting: Some(VestingConfig {175 vesting: vested_accounts176 .iter()177 .cloned()178 .map(|k| (k, 1000, 100, 1 << 98))179 .collect(),180 }),181 pallet_nft: Some(NftConfig {182 collection: vec![(183 1,184 CollectionType {185 owner: get_account_id_from_seed::<sr25519::Public>("Alice"),186 mode: CollectionMode::NFT,187 access: AccessMode::Normal,188 decimal_points: 0,189 name: vec![],190 description: vec![],191 token_prefix: vec![],192 mint_mode: false,193 offchain_schema: vec![],194 schema_version: SchemaVersion::default(),195 sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),196 sponsor_confirmed: true,197 const_on_chain_schema: vec![],198 variable_on_chain_schema: vec![],199 limits: CollectionLimits::default()200 },201 )],202 nft_item_id: vec![],203 fungible_item_id: vec![],204 refungible_item_id: vec![],205 chain_limit: ChainLimits {206 collection_numbers_limit: 100000,207 account_token_ownership_limit: 1000000,208 collections_admins_limit: 5,209 custom_data_limit: 2048,210 nft_sponsor_transfer_timeout: 15,211 fungible_sponsor_transfer_timeout: 15,212 refungible_sponsor_transfer_timeout: 15,213 },214 }),215 pallet_contracts: Some(ContractsConfig {216 current_schedule: ContractsSchedule {217 enable_println,218 ..Default::default()219 },220 }),221 }222}1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56// use nft_runtime::{7// AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig,8// SystemConfig, WASM_BINARY,9// };10// use nft_runtime::{ContractsConfig, ContractsSchedule, NftConfig, CollectionType};11use nft_runtime::*;12use sc_service::ChainType;13use sp_consensus_aura::sr25519::AuthorityId as AuraId;14use sp_core::{sr25519, Pair, Public};15use sp_finality_grandpa::AuthorityId as GrandpaId;16use sp_runtime::traits::{IdentifyAccount, Verify};17use serde_json::map::Map;1819// Note this is the URL for the telemetry server20//const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";2122/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.23pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>;2425/// Helper function to generate a crypto pair from seed26pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {27 TPublic::Pair::from_string(&format!("//{}", seed), None)28 .expect("static values are valid; qed")29 .public()30}3132type AccountPublic = <Signature as Verify>::Signer;3334/// Helper function to generate an account ID from seed35pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId36where37 AccountPublic: From<<TPublic::Pair as Pair>::Public>,38{39 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()40}4142/// Helper function to generate an authority key for Aura43pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) {44 (get_from_seed::<AuraId>(s), get_from_seed::<GrandpaId>(s))45}4647pub fn development_config() -> Result<ChainSpec, String> {48 let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?;4950 let mut properties = Map::new();51 properties.insert("tokenSymbol".into(), "UniqueTest".into());52 properties.insert("tokenDecimals".into(), 15.into());53 properties.insert("ss58Format".into(), 42.into()); // Generic Substrate wildcard (SS58 checksum preimage)5455 Ok(ChainSpec::from_genesis(56 // Name57 "Development",58 // ID59 "dev",60 ChainType::Development,61 move || testnet_genesis(62 wasm_binary,63 // Initial PoA authorities64 vec![65 authority_keys_from_seed("Alice"),66 ],67 // Sudo account68 get_account_id_from_seed::<sr25519::Public>("Alice"),69 // Pre-funded accounts70 vec![71 get_account_id_from_seed::<sr25519::Public>("Alice"),72 get_account_id_from_seed::<sr25519::Public>("Bob"),73 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),74 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),75 ],76 true,77 ),78 // Bootnodes79 vec![],80 // Telemetry81 None,82 // Protocol ID83 None,84 // Properties85 Some(properties),86 // Extensions87 None,88 ))89}9091pub fn local_testnet_config() -> Result<ChainSpec, String> {92 let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?;9394 Ok(ChainSpec::from_genesis(95 // Name96 "Local Testnet",97 // ID98 "local_testnet",99 ChainType::Local,100 move || testnet_genesis(101 wasm_binary,102 // Initial PoA authorities103 vec![104 authority_keys_from_seed("Alice"),105 authority_keys_from_seed("Bob"),106 ],107 // Sudo account108 get_account_id_from_seed::<sr25519::Public>("Alice"),109 // Pre-funded accounts110 vec![111 get_account_id_from_seed::<sr25519::Public>("Alice"),112 get_account_id_from_seed::<sr25519::Public>("Bob"),113 get_account_id_from_seed::<sr25519::Public>("Charlie"),114 get_account_id_from_seed::<sr25519::Public>("Dave"),115 get_account_id_from_seed::<sr25519::Public>("Eve"),116 get_account_id_from_seed::<sr25519::Public>("Ferdie"),117 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),118 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),119 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),120 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),121 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),122 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),123 ],124 true,125 ),126 // Bootnodes127 vec![],128 // Telemetry129 None,130 // Protocol ID131 None,132 // Properties133 None,134 // Extensions135 None,136 ))137}138139fn testnet_genesis(140 wasm_binary: &[u8],141 initial_authorities: Vec<(AuraId, GrandpaId)>,142 root_key: AccountId,143 endowed_accounts: Vec<AccountId>,144 enable_println: bool,145) -> GenesisConfig {146147 let vested_accounts = vec![148 get_account_id_from_seed::<sr25519::Public>("Bob"),149 ];150151 GenesisConfig {152 system: Some(SystemConfig {153 code: wasm_binary.to_vec(),154 changes_trie_config: Default::default(),155 }),156 pallet_balances: Some(BalancesConfig {157 balances: endowed_accounts158 .iter()159 .cloned()160 .map(|k| (k, 1 << 100))161 .collect(),162 }),163 pallet_aura: Some(AuraConfig {164 authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(),165 }),166 pallet_grandpa: Some(GrandpaConfig {167 authorities: initial_authorities168 .iter()169 .map(|x| (x.1.clone(), 1))170 .collect(),171 }),172 pallet_treasury: Some(Default::default()),173 pallet_sudo: Some(SudoConfig { key: root_key }),174 pallet_vesting: Some(VestingConfig {175 vesting: vested_accounts176 .iter()177 .cloned()178 .map(|k| (k, 1000, 100, 1 << 98))179 .collect(),180 }),181 pallet_nft: Some(NftConfig {182 collection: vec![(183 1,184 CollectionType {185 owner: get_account_id_from_seed::<sr25519::Public>("Alice"),186 mode: CollectionMode::NFT,187 access: AccessMode::Normal,188 decimal_points: 0,189 name: vec![],190 description: vec![],191 token_prefix: vec![],192 mint_mode: false,193 offchain_schema: vec![],194 schema_version: SchemaVersion::default(),195 sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),196 sponsor_confirmed: true,197 const_on_chain_schema: vec![],198 variable_on_chain_schema: vec![],199 limits: CollectionLimits::default()200 },201 )],202 nft_item_id: vec![],203 fungible_item_id: vec![],204 refungible_item_id: vec![],205 chain_limit: ChainLimits {206 collection_numbers_limit: 100000,207 account_token_ownership_limit: 1000000,208 collections_admins_limit: 5,209 custom_data_limit: 2048,210 nft_sponsor_transfer_timeout: 15,211 fungible_sponsor_transfer_timeout: 15,212 refungible_sponsor_transfer_timeout: 15,213 offchain_schema_limit: 1024,214 variable_on_chain_schema_limit: 1024,215 const_on_chain_schema_limit: 1024,216 },217 }),218 pallet_contracts: Some(ContractsConfig {219 current_schedule: ContractsSchedule {220 enable_println,221 ..Default::default()222 },223 }),224 }225}pallets/nft/src/lib.rsdiffbeforeafterboth--- 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<u8> 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 = <Collection<T>>::get(collection_id);
target_collection.offchain_schema = schema;
<Collection<T>>::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 = <Collection<T>>::get(collection_id);
target_collection.const_on_chain_schema = schema;
<Collection<T>>::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 = <Collection<T>>::get(collection_id);
target_collection.variable_on_chain_schema = schema;
<Collection<T>>::insert(collection_id, target_collection);