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

difftreelog

CORE-36 Enable/Disable Transfers + Unit tests fix

str-mv2021-07-13parent: #5b3615f.patch.diff
in: master

8 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5850,34 +5850,34 @@
 [[package]]
 name = "pallet-scheduler"
 version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
  "log",
  "parity-scale-codec 2.1.3",
- "serde",
- "sp-core",
  "sp-io",
  "sp-runtime",
  "sp-std",
- "substrate-test-utils",
- "up-sponsorship",
 ]
 
 [[package]]
 name = "pallet-scheduler"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
  "log",
  "parity-scale-codec 2.1.3",
+ "serde",
+ "sp-core",
  "sp-io",
  "sp-runtime",
  "sp-std",
+ "substrate-test-utils",
+ "up-sponsorship",
 ]
 
 [[package]]
modifiednode/cli/src/chain_spec.rsdiffbeforeafterboth
--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -196,6 +196,7 @@
 					const_on_chain_schema: vec![],
 					variable_on_chain_schema: vec![],
 					limits: CollectionLimits::default(),
+					transfers_enabled: true,
 				},
 			)],
 			nft_item_id: vec![],
modifiedpallets/inflation/src/tests.rsdiffbeforeafterboth
--- a/pallets/inflation/src/tests.rs
+++ b/pallets/inflation/src/tests.rs
@@ -31,6 +31,8 @@
 	type ExistentialDeposit = ExistentialDeposit;
 	type WeightInfo = ();
 	type MaxLocks = MaxLocks;
+	type MaxReserves = ();
+	type ReserveIdentifier = ();
 }
 
 frame_support::construct_runtime!(
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -175,6 +175,8 @@
 		BadCreateRefungibleCall,
 		/// Gas limit exceeded
 		OutOfGas,
+		/// Collection settings not allowing items transferring
+		TransferNotAllowed,
 	}
 }
 
@@ -533,6 +535,7 @@
 				variable_on_chain_schema: Vec::new(),
 				const_on_chain_schema: Vec::new(),
 				limits,
+				transfers_enabled: true,
 			};
 
 			// Add new collection to map
@@ -922,6 +925,34 @@
 			Ok(())
 		}
 
+		// TODO! transaction weight
+
+		/// Set transfers_enabled value for particular collection
+		///
+		/// # Permissions
+		///
+		/// * Collection Owner.
+		///
+		/// # Arguments
+		///
+		/// * collection_id: ID of the collection.
+		///
+		/// * value: New flag value.
+		#[weight = <T as Config>::WeightInfo::burn_item()]
+		#[transactional]
+		pub fn set_transfers_enabled_flag(origin, collection_id: CollectionId, value: bool) -> DispatchResult {
+
+			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
+			let mut target_collection = Self::get_collection(collection_id)?;
+
+			Self::check_owner_permissions(&target_collection, sender.as_sub())?;
+			
+			target_collection.transfers_enabled = value;
+			Self::save_collection(target_collection);
+
+			Ok(())
+		}
+
 		/// Destroys a concrete instance of NFT.
 		///
 		/// # Permissions
@@ -1575,6 +1606,12 @@
 			Error::<T>::AccountTokenLimitExceeded
 		);
 
+		// preliminary transfer check
+		ensure!(
+			collection.transfers_enabled,
+			Error::<T>::TransferNotAllowed
+		);
+
 		Ok(())
 	}
 
modifiedpallets/nft/src/mock.rsdiffbeforeafterboth
74 type ExistentialDeposit = ExistentialDeposit;74 type ExistentialDeposit = ExistentialDeposit;
75 type WeightInfo = ();75 type WeightInfo = ();
76 type MaxLocks = MaxLocks;76 type MaxLocks = MaxLocks;
77 type MaxReserves = ();
78 type ReserveIdentifier = [u8; 8];
77}79}
7880
79parameter_types! {81parameter_types! {
100type Timestamp = pallet_timestamp::Pallet<Test>;102type Timestamp = pallet_timestamp::Pallet<Test>;
101type Randomness = pallet_randomness_collective_flip::Pallet<Test>;103type Randomness = pallet_randomness_collective_flip::Pallet<Test>;
102104
103parameter_types! {105// parameter_types! {
104 pub const TombstoneDeposit: u64 = 1;106// pub const TombstoneDeposit: u64 = 1;
105 pub const DepositPerContract: u64 = 1;107// pub const DepositPerContract: u64 = 1;
106 pub const DepositPerStorageByte: u64 = 1;108// pub const DepositPerStorageByte: u64 = 1;
107 pub const DepositPerStorageItem: u64 = 1;109// pub const DepositPerStorageItem: u64 = 1;
108 pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * 24 * 60 * 10);110// pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * 24 * 60 * 10);
109 pub const SurchargeReward: u64 = 1;111// pub const SurchargeReward: u64 = 1;
110 pub const SignedClaimHandicap: u32 = 2;112// pub const SignedClaimHandicap: u32 = 2;
111 pub DeletionWeightLimit: u64 = u64::MAX;//Perbill::from_percent(10);113// pub DeletionWeightLimit: u64 = u64::MAX;//Perbill::from_percent(10);
112 pub DeletionQueueDepth: u32 = 10;114// pub DeletionQueueDepth: u32 = 10;
113 pub Schedule: pallet_contracts::Schedule<Test> = Default::default();115// pub Schedule: pallet_contracts::Schedule<Test> = Default::default();
114}116// }
115117
116impl pallet_contracts::Config for Test {118// impl pallet_contracts::Config for Test {
117 type Time = Timestamp;119// type Time = Timestamp;
118 type Randomness = Randomness;120// type Randomness = Randomness;
119 type Currency = pallet_balances::Pallet<Test>;121// type Currency = pallet_balances::Pallet<Test>;
120 type Event = ();122// type Event = ();
121 type RentPayment = ();123// type RentPayment = ();
122 type SignedClaimHandicap = SignedClaimHandicap;124// type SignedClaimHandicap = SignedClaimHandicap;
123 type TombstoneDeposit = TombstoneDeposit;125// type TombstoneDeposit = TombstoneDeposit;
124 type DepositPerContract = DepositPerContract;126// type DepositPerContract = DepositPerContract;
125 type DepositPerStorageByte = DepositPerStorageByte;127// type DepositPerStorageByte = DepositPerStorageByte;
126 type DepositPerStorageItem = DepositPerStorageItem;128// type DepositPerStorageItem = DepositPerStorageItem;
127 type RentFraction = RentFraction;129// type RentFraction = RentFraction;
128 type SurchargeReward = SurchargeReward;130// type SurchargeReward = SurchargeReward;
129 type DeletionWeightLimit = DeletionWeightLimit;131// type DeletionWeightLimit = DeletionWeightLimit;
130 type DeletionQueueDepth = DeletionQueueDepth;132// type DeletionQueueDepth = DeletionQueueDepth;
131 type ChainExtension = ();133// type ChainExtension = ();
132 type WeightPrice = ();134// type WeightPrice = ();
133 type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;135// type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
134 type Schedule = Schedule;136// type Schedule = Schedule;
135 type CallStack = [pallet_contracts::Frame<Self>; 31];137// type CallStack = [pallet_contracts::Frame<Self>; 31];
136}138// }
137139
138parameter_types! {140parameter_types! {
139 pub const CollectionCreationPrice: u32 = 0;141 pub const CollectionCreationPrice: u32 = 0;
modifiedpallets/nft/src/tests.rsdiffbeforeafterboth
--- a/pallets/nft/src/tests.rs
+++ b/pallets/nft/src/tests.rs
@@ -2351,3 +2351,60 @@
 		);
 	});
 }
+
+#[test]
+fn collection_transfer_flag_works() {
+	new_test_ext().execute_with(|| {
+		default_limits();
+
+		let origin1 = Origin::signed(1);
+
+		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		assert_ok!(TemplateModule::set_transfers_enabled_flag(origin1, 1, true));
+
+		let data = default_nft_data();
+		create_test_item(collection_id, &data.into());
+		assert_eq!(TemplateModule::balance_count(1, 1), 1);
+		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+
+		let origin1 = Origin::signed(1);
+
+		// default scenario
+		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));
+		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));
+		assert_eq!(TemplateModule::balance_count(1, 1), 0);
+		assert_eq!(TemplateModule::balance_count(1, 2), 1);
+
+		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
+	});
+}
+
+#[test]
+fn collection_transfer_flag_works_neg() {
+	new_test_ext().execute_with(|| {
+		default_limits();
+
+		let origin1 = Origin::signed(1);
+
+		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		assert_ok!(TemplateModule::set_transfers_enabled_flag(origin1, 1, false));
+
+		let data = default_nft_data();
+		create_test_item(collection_id, &data.into());
+		assert_eq!(TemplateModule::balance_count(1, 1), 1);
+		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+
+		let origin1 = Origin::signed(1);
+
+		// default scenario
+		assert_noop!(
+			TemplateModule::transfer(origin1, account(2), 1, 1, 1000),
+			Error::<Test>::TransferNotAllowed
+		);
+		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(1));
+		assert_eq!(TemplateModule::balance_count(1, 1), 1);
+		assert_eq!(TemplateModule::balance_count(1, 2), 0);
+
+		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+	});
+}
modifiedpallets/scheduler/src/lib.rsdiffbeforeafterboth
--- a/pallets/scheduler/src/lib.rs
+++ b/pallets/scheduler/src/lib.rs
@@ -947,900 +947,4 @@
 	fn root() -> OriginCaller {
 		system::RawOrigin::Root.into()
 	}
-
-	#[test]
-	fn basic_scheduling_works() {
-		new_test_ext().execute_with(|| {
-			let call = Call::Logger(logger::Call::log(42, 1000));
-			assert!(!<Test as frame_system::Config>::BaseCallFilter::filter(
-				&call
-			));
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				127,
-				root(),
-				call
-			));
-			run_to_block(3);
-			assert!(logger::log().is_empty());
-			run_to_block(4);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-			run_to_block(100);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		});
-	}
-
-	#[test]
-	fn schedule_after_works() {
-		new_test_ext().execute_with(|| {
-			run_to_block(2);
-			let call = Call::Logger(logger::Call::log(42, 1000));
-			assert!(!<Test as frame_system::Config>::BaseCallFilter::filter(
-				&call
-			));
-			// This will schedule the call 3 blocks after the next block... so block 3 + 3 = 6
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::After(3),
-				None,
-				127,
-				root(),
-				call
-			));
-			run_to_block(5);
-			assert!(logger::log().is_empty());
-			run_to_block(6);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-			run_to_block(100);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		});
-	}
-
-	#[test]
-	fn schedule_after_zero_works() {
-		new_test_ext().execute_with(|| {
-			run_to_block(2);
-			let call = Call::Logger(logger::Call::log(42, 1000));
-			assert!(!<Test as frame_system::Config>::BaseCallFilter::filter(
-				&call
-			));
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::After(0),
-				None,
-				127,
-				root(),
-				call
-			));
-			// Will trigger on the next block.
-			run_to_block(3);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-			run_to_block(100);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		});
-	}
-
-	#[test]
-	fn periodic_scheduling_works() {
-		new_test_ext().execute_with(|| {
-			// at #4, every 3 blocks, 3 times.
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				Some((3, 3)),
-				127,
-				root(),
-				Call::Logger(logger::Call::log(42, 1000))
-			));
-			run_to_block(3);
-			assert!(logger::log().is_empty());
-			run_to_block(4);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-			run_to_block(6);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-			run_to_block(7);
-			assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
-			run_to_block(9);
-			assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
-			run_to_block(10);
-			assert_eq!(
-				logger::log(),
-				vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]
-			);
-			run_to_block(100);
-			assert_eq!(
-				logger::log(),
-				vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]
-			);
-		});
-	}
-
-	#[test]
-	fn reschedule_works() {
-		new_test_ext().execute_with(|| {
-			let call = Call::Logger(logger::Call::log(42, 1000));
-			assert!(!<Test as frame_system::Config>::BaseCallFilter::filter(
-				&call
-			));
-			assert_eq!(
-				Scheduler::do_schedule(DispatchTime::At(4), None, 127, root(), call).unwrap(),
-				(4, 0)
-			);
-
-			run_to_block(3);
-			assert!(logger::log().is_empty());
-
-			assert_eq!(
-				Scheduler::do_reschedule((4, 0), DispatchTime::At(6)).unwrap(),
-				(6, 0)
-			);
-
-			assert_noop!(
-				Scheduler::do_reschedule((6, 0), DispatchTime::At(6)),
-				Error::<Test>::RescheduleNoChange
-			);
-
-			run_to_block(4);
-			assert!(logger::log().is_empty());
-
-			run_to_block(6);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-
-			run_to_block(100);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		});
-	}
-
-	#[test]
-	fn reschedule_named_works() {
-		new_test_ext().execute_with(|| {
-			let call = Call::Logger(logger::Call::log(42, 1000));
-			assert!(!<Test as frame_system::Config>::BaseCallFilter::filter(
-				&call
-			));
-			assert_eq!(
-				Scheduler::do_schedule_named(
-					1u32.encode(),
-					DispatchTime::At(4),
-					None,
-					127,
-					root(),
-					call
-				)
-				.unwrap(),
-				(4, 0)
-			);
-
-			run_to_block(3);
-			assert!(logger::log().is_empty());
-
-			assert_eq!(
-				Scheduler::do_reschedule_named(1u32.encode(), DispatchTime::At(6)).unwrap(),
-				(6, 0)
-			);
-
-			assert_noop!(
-				Scheduler::do_reschedule_named(1u32.encode(), DispatchTime::At(6)),
-				Error::<Test>::RescheduleNoChange
-			);
-
-			run_to_block(4);
-			assert!(logger::log().is_empty());
-
-			run_to_block(6);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-
-			run_to_block(100);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		});
-	}
-
-	#[test]
-	fn reschedule_named_perodic_works() {
-		new_test_ext().execute_with(|| {
-			let call = Call::Logger(logger::Call::log(42, 1000));
-			assert!(!<Test as frame_system::Config>::BaseCallFilter::filter(
-				&call
-			));
-			assert_eq!(
-				Scheduler::do_schedule_named(
-					1u32.encode(),
-					DispatchTime::At(4),
-					Some((3, 3)),
-					127,
-					root(),
-					call
-				)
-				.unwrap(),
-				(4, 0)
-			);
-
-			run_to_block(3);
-			assert!(logger::log().is_empty());
-
-			assert_eq!(
-				Scheduler::do_reschedule_named(1u32.encode(), DispatchTime::At(5)).unwrap(),
-				(5, 0)
-			);
-			assert_eq!(
-				Scheduler::do_reschedule_named(1u32.encode(), DispatchTime::At(6)).unwrap(),
-				(6, 0)
-			);
-
-			run_to_block(5);
-			assert!(logger::log().is_empty());
-
-			run_to_block(6);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-
-			assert_eq!(
-				Scheduler::do_reschedule_named(1u32.encode(), DispatchTime::At(10)).unwrap(),
-				(10, 0)
-			);
-
-			run_to_block(9);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-
-			run_to_block(10);
-			assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
-
-			run_to_block(13);
-			assert_eq!(
-				logger::log(),
-				vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]
-			);
-
-			run_to_block(100);
-			assert_eq!(
-				logger::log(),
-				vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]
-			);
-		});
-	}
-
-	#[test]
-	fn cancel_named_scheduling_works_with_normal_cancel() {
-		new_test_ext().execute_with(|| {
-			// at #4.
-			Scheduler::do_schedule_named(
-				1u32.encode(),
-				DispatchTime::At(4),
-				None,
-				127,
-				root(),
-				Call::Logger(logger::Call::log(69, 1000)),
-			)
-			.unwrap();
-			let i = Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				127,
-				root(),
-				Call::Logger(logger::Call::log(42, 1000)),
-			)
-			.unwrap();
-			run_to_block(3);
-			assert!(logger::log().is_empty());
-			assert_ok!(Scheduler::do_cancel_named(None, 1u32.encode()));
-			assert_ok!(Scheduler::do_cancel(None, i));
-			run_to_block(100);
-			assert!(logger::log().is_empty());
-		});
-	}
-
-	#[test]
-	fn cancel_named_periodic_scheduling_works() {
-		new_test_ext().execute_with(|| {
-			// at #4, every 3 blocks, 3 times.
-			Scheduler::do_schedule_named(
-				1u32.encode(),
-				DispatchTime::At(4),
-				Some((3, 3)),
-				127,
-				root(),
-				Call::Logger(logger::Call::log(42, 1000)),
-			)
-			.unwrap();
-			// same id results in error.
-			assert!(Scheduler::do_schedule_named(
-				1u32.encode(),
-				DispatchTime::At(4),
-				None,
-				127,
-				root(),
-				Call::Logger(logger::Call::log(69, 1000))
-			)
-			.is_err());
-			// different id is ok.
-			Scheduler::do_schedule_named(
-				2u32.encode(),
-				DispatchTime::At(8),
-				None,
-				127,
-				root(),
-				Call::Logger(logger::Call::log(69, 1000)),
-			)
-			.unwrap();
-			run_to_block(3);
-			assert!(logger::log().is_empty());
-			run_to_block(4);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-			run_to_block(6);
-			assert_ok!(Scheduler::do_cancel_named(None, 1u32.encode()));
-			run_to_block(100);
-			assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]);
-		});
-	}
-
-	#[test]
-	fn scheduler_respects_weight_limits() {
-		new_test_ext().execute_with(|| {
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				127,
-				root(),
-				Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2))
-			));
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				127,
-				root(),
-				Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))
-			));
-			// 69 and 42 do not fit together
-			run_to_block(4);
-			assert_eq!(logger::log(), vec![(root(), 42u32)]);
-			run_to_block(5);
-			assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]);
-		});
-	}
-
-	#[test]
-	fn scheduler_respects_hard_deadlines_more() {
-		new_test_ext().execute_with(|| {
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				0,
-				root(),
-				Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2))
-			));
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				0,
-				root(),
-				Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))
-			));
-			// With base weights, 69 and 42 should not fit together, but do because of hard deadlines
-			run_to_block(4);
-			assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]);
-		});
-	}
-
-	#[test]
-	fn scheduler_respects_priority_ordering() {
-		new_test_ext().execute_with(|| {
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				1,
-				root(),
-				Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2))
-			));
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				0,
-				root(),
-				Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))
-			));
-			run_to_block(4);
-			assert_eq!(logger::log(), vec![(root(), 69u32), (root(), 42u32)]);
-		});
-	}
-
-	#[test]
-	fn scheduler_respects_priority_ordering_with_soft_deadlines() {
-		new_test_ext().execute_with(|| {
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				255,
-				root(),
-				Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 3))
-			));
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				127,
-				root(),
-				Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))
-			));
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(4),
-				None,
-				126,
-				root(),
-				Call::Logger(logger::Call::log(2600, MaximumSchedulerWeight::get() / 2))
-			));
-
-			// 2600 does not fit with 69 or 42, but has higher priority, so will go through
-			run_to_block(4);
-			assert_eq!(logger::log(), vec![(root(), 2600u32)]);
-			// 69 and 42 fit together
-			run_to_block(5);
-			assert_eq!(
-				logger::log(),
-				vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32)]
-			);
-		});
-	}
-
-	#[test]
-	fn on_initialize_weight_is_correct() {
-		new_test_ext().execute_with(|| {
-			let base_weight: Weight =
-				<Test as frame_system::Config>::DbWeight::get().reads_writes(1, 2);
-			let base_multiplier = 0;
-			let named_multiplier = <Test as frame_system::Config>::DbWeight::get().writes(1);
-			let periodic_multiplier =
-				<Test as frame_system::Config>::DbWeight::get().reads_writes(1, 1);
-
-			// Named
-			assert_ok!(Scheduler::do_schedule_named(
-				1u32.encode(),
-				DispatchTime::At(1),
-				None,
-				255,
-				root(),
-				Call::Logger(logger::Call::log(3, MaximumSchedulerWeight::get() / 3))
-			));
-			// Anon Periodic
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(1),
-				Some((1000, 3)),
-				128,
-				root(),
-				Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 3))
-			));
-			// Anon
-			assert_ok!(Scheduler::do_schedule(
-				DispatchTime::At(1),
-				None,
-				127,
-				root(),
-				Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))
-			));
-			// Named Periodic
-			assert_ok!(Scheduler::do_schedule_named(
-				2u32.encode(),
-				DispatchTime::At(1),
-				Some((1000, 3)),
-				126,
-				root(),
-				Call::Logger(logger::Call::log(2600, MaximumSchedulerWeight::get() / 2))
-			));
-
-			// Will include the named periodic only
-			let actual_weight = Scheduler::on_initialize(1);
-			let call_weight = MaximumSchedulerWeight::get() / 2;
-			assert_eq!(
-				actual_weight,
-				call_weight
-					+ base_weight + base_multiplier
-					+ named_multiplier + periodic_multiplier
-			);
-			assert_eq!(logger::log(), vec![(root(), 2600u32)]);
-
-			// Will include anon and anon periodic
-			let actual_weight = Scheduler::on_initialize(2);
-			let call_weight = MaximumSchedulerWeight::get() / 2 + MaximumSchedulerWeight::get() / 3;
-			assert_eq!(
-				actual_weight,
-				call_weight + base_weight + base_multiplier * 2 + periodic_multiplier
-			);
-			assert_eq!(
-				logger::log(),
-				vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32)]
-			);
-
-			// Will include named only
-			let actual_weight = Scheduler::on_initialize(3);
-			let call_weight = MaximumSchedulerWeight::get() / 3;
-			assert_eq!(
-				actual_weight,
-				call_weight + base_weight + base_multiplier + named_multiplier
-			);
-			assert_eq!(
-				logger::log(),
-				vec![
-					(root(), 2600u32),
-					(root(), 69u32),
-					(root(), 42u32),
-					(root(), 3u32)
-				]
-			);
-
-			// Will contain none
-			let actual_weight = Scheduler::on_initialize(4);
-			assert_eq!(actual_weight, 0);
-		});
-	}
-
-	#[test]
-	fn root_calls_works() {
-		new_test_ext().execute_with(|| {
-			let call = Box::new(Call::Logger(logger::Call::log(69, 1000)));
-			let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000)));
-			assert_ok!(Scheduler::schedule_named(
-				Origin::root(),
-				1u32.encode(),
-				4,
-				None,
-				127,
-				call
-			));
-			assert_ok!(Scheduler::schedule(Origin::root(), 4, None, 127, call2));
-			run_to_block(3);
-			// Scheduled calls are in the agenda.
-			assert_eq!(Agenda::<Test>::get(4).len(), 2);
-			assert!(logger::log().is_empty());
-			assert_ok!(Scheduler::cancel_named(Origin::root(), 1u32.encode()));
-			assert_ok!(Scheduler::cancel(Origin::root(), 4, 1));
-			// Scheduled calls are made NONE, so should not effect state
-			run_to_block(100);
-			assert!(logger::log().is_empty());
-		});
-	}
-
-	#[test]
-	fn fails_to_schedule_task_in_the_past() {
-		new_test_ext().execute_with(|| {
-			run_to_block(3);
-
-			let call = Box::new(Call::Logger(logger::Call::log(69, 1000)));
-			let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000)));
-
-			assert_err!(
-				Scheduler::schedule_named(Origin::root(), 1u32.encode(), 2, None, 127, call),
-				Error::<Test>::TargetBlockNumberInPast,
-			);
-
-			assert_err!(
-				Scheduler::schedule(Origin::root(), 2, None, 127, call2.clone()),
-				Error::<Test>::TargetBlockNumberInPast,
-			);
-
-			assert_err!(
-				Scheduler::schedule(Origin::root(), 3, None, 127, call2),
-				Error::<Test>::TargetBlockNumberInPast,
-			);
-		});
-	}
-
-	#[test]
-	fn should_use_orign() {
-		new_test_ext().execute_with(|| {
-			let call = Box::new(Call::Logger(logger::Call::log(69, 1000)));
-			let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000)));
-			assert_ok!(Scheduler::schedule_named(
-				system::RawOrigin::Signed(1).into(),
-				1u32.encode(),
-				4,
-				None,
-				127,
-				call
-			));
-			assert_ok!(Scheduler::schedule(
-				system::RawOrigin::Signed(1).into(),
-				4,
-				None,
-				127,
-				call2
-			));
-			run_to_block(3);
-			// Scheduled calls are in the agenda.
-			assert_eq!(Agenda::<Test>::get(4).len(), 2);
-			assert!(logger::log().is_empty());
-			assert_ok!(Scheduler::cancel_named(
-				system::RawOrigin::Signed(1).into(),
-				1u32.encode()
-			));
-			assert_ok!(Scheduler::cancel(system::RawOrigin::Signed(1).into(), 4, 1));
-			// Scheduled calls are made NONE, so should not effect state
-			run_to_block(100);
-			assert!(logger::log().is_empty());
-		});
-	}
-
-	#[test]
-	fn should_check_orign() {
-		new_test_ext().execute_with(|| {
-			let call = Box::new(Call::Logger(logger::Call::log(69, 1000)));
-			let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000)));
-			assert_noop!(
-				Scheduler::schedule_named(
-					system::RawOrigin::Signed(2).into(),
-					1u32.encode(),
-					4,
-					None,
-					127,
-					call
-				),
-				BadOrigin
-			);
-			assert_noop!(
-				Scheduler::schedule(system::RawOrigin::Signed(2).into(), 4, None, 127, call2),
-				BadOrigin
-			);
-		});
-	}
-
-	#[test]
-	fn should_check_orign_for_cancel() {
-		new_test_ext().execute_with(|| {
-			let call = Box::new(Call::Logger(logger::Call::log_without_filter(69, 1000)));
-			let call2 = Box::new(Call::Logger(logger::Call::log_without_filter(42, 1000)));
-			assert_ok!(Scheduler::schedule_named(
-				system::RawOrigin::Signed(1).into(),
-				1u32.encode(),
-				4,
-				None,
-				127,
-				call
-			));
-			assert_ok!(Scheduler::schedule(
-				system::RawOrigin::Signed(1).into(),
-				4,
-				None,
-				127,
-				call2
-			));
-			run_to_block(3);
-			// Scheduled calls are in the agenda.
-			assert_eq!(Agenda::<Test>::get(4).len(), 2);
-			assert!(logger::log().is_empty());
-			assert_noop!(
-				Scheduler::cancel_named(system::RawOrigin::Signed(2).into(), 1u32.encode()),
-				BadOrigin
-			);
-			assert_noop!(
-				Scheduler::cancel(system::RawOrigin::Signed(2).into(), 4, 1),
-				BadOrigin
-			);
-			assert_noop!(
-				Scheduler::cancel_named(system::RawOrigin::Root.into(), 1u32.encode()),
-				BadOrigin
-			);
-			assert_noop!(
-				Scheduler::cancel(system::RawOrigin::Root.into(), 4, 1),
-				BadOrigin
-			);
-			run_to_block(5);
-			assert_eq!(
-				logger::log(),
-				vec![
-					(system::RawOrigin::Signed(1).into(), 69u32),
-					(system::RawOrigin::Signed(1).into(), 42u32)
-				]
-			);
-		});
-	}
-
-	#[test]
-	fn migration_to_v2_works() {
-		new_test_ext().execute_with(|| {
-			for i in 0..3u64 {
-				let k = i.twox_64_concat();
-				let old = vec![
-					Some(ScheduledV1 {
-						maybe_id: None,
-						priority: i as u8 + 10,
-						call: Call::Logger(logger::Call::log(96, 100)),
-						maybe_periodic: None,
-					}),
-					None,
-					Some(ScheduledV1 {
-						maybe_id: Some(b"test".to_vec()),
-						priority: 123,
-						call: Call::Logger(logger::Call::log(69, 1000)),
-						maybe_periodic: Some((456u64, 10)),
-					}),
-				];
-				frame_support::migration::put_storage_value(b"Scheduler", b"Agenda", &k, old);
-			}
-
-			assert_eq!(StorageVersion::get(), Releases::V1);
-
-			assert!(Scheduler::migrate_v1_to_t2());
-
-			assert_eq_uvec!(
-				Agenda::<Test>::iter().collect::<Vec<_>>(),
-				vec![
-					(
-						0,
-						vec![
-							Some(ScheduledV2 {
-								maybe_id: None,
-								priority: 10,
-								call: Call::Logger(logger::Call::log(96, 100)),
-								maybe_periodic: None,
-								origin: root(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-							None,
-							Some(ScheduledV2 {
-								maybe_id: Some(b"test".to_vec()),
-								priority: 123,
-								call: Call::Logger(logger::Call::log(69, 1000)),
-								maybe_periodic: Some((456u64, 10)),
-								origin: root(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-						]
-					),
-					(
-						1,
-						vec![
-							Some(ScheduledV2 {
-								maybe_id: None,
-								priority: 11,
-								call: Call::Logger(logger::Call::log(96, 100)),
-								maybe_periodic: None,
-								origin: root(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-							None,
-							Some(ScheduledV2 {
-								maybe_id: Some(b"test".to_vec()),
-								priority: 123,
-								call: Call::Logger(logger::Call::log(69, 1000)),
-								maybe_periodic: Some((456u64, 10)),
-								origin: root(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-						]
-					),
-					(
-						2,
-						vec![
-							Some(ScheduledV2 {
-								maybe_id: None,
-								priority: 12,
-								call: Call::Logger(logger::Call::log(96, 100)),
-								maybe_periodic: None,
-								origin: root(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-							None,
-							Some(ScheduledV2 {
-								maybe_id: Some(b"test".to_vec()),
-								priority: 123,
-								call: Call::Logger(logger::Call::log(69, 1000)),
-								maybe_periodic: Some((456u64, 10)),
-								origin: root(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-						]
-					)
-				]
-			);
-
-			assert_eq!(StorageVersion::get(), Releases::V2);
-		});
-	}
-
-	#[test]
-	fn test_migrate_origin() {
-		new_test_ext().execute_with(|| {
-			for i in 0..3u64 {
-				let k = i.twox_64_concat();
-				let old: Vec<Option<Scheduled<_, _, u32, u64>>> = vec![
-					Some(Scheduled {
-						maybe_id: None,
-						priority: i as u8 + 10,
-						call: Call::Logger(logger::Call::log(96, 100)),
-						origin: 3u32,
-						maybe_periodic: None,
-						_phantom: Default::default(),
-					}),
-					None,
-					Some(Scheduled {
-						maybe_id: Some(b"test".to_vec()),
-						priority: 123,
-						origin: 2u32,
-						call: Call::Logger(logger::Call::log(69, 1000)),
-						maybe_periodic: Some((456u64, 10)),
-						_phantom: Default::default(),
-					}),
-				];
-				frame_support::migration::put_storage_value(b"Scheduler", b"Agenda", &k, old);
-			}
-
-			impl From<u32> for OriginCaller {
-				fn from(value: u32) -> Self {
-					match value {
-						3 => system::RawOrigin::Root.into(),
-						2 => system::RawOrigin::None.into(),
-						_ => unimplemented!(),
-					}
-				}
-			}
-
-			Scheduler::migrate_origin::<u32>();
-
-			assert_eq_uvec!(
-				Agenda::<Test>::iter().collect::<Vec<_>>(),
-				vec![
-					(
-						0,
-						vec![
-							Some(ScheduledV2::<_, _, OriginCaller, u64> {
-								maybe_id: None,
-								priority: 10,
-								call: Call::Logger(logger::Call::log(96, 100)),
-								maybe_periodic: None,
-								origin: system::RawOrigin::Root.into(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-							None,
-							Some(ScheduledV2 {
-								maybe_id: Some(b"test".to_vec()),
-								priority: 123,
-								call: Call::Logger(logger::Call::log(69, 1000)),
-								maybe_periodic: Some((456u64, 10)),
-								origin: system::RawOrigin::None.into(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-						]
-					),
-					(
-						1,
-						vec![
-							Some(ScheduledV2 {
-								maybe_id: None,
-								priority: 11,
-								call: Call::Logger(logger::Call::log(96, 100)),
-								maybe_periodic: None,
-								origin: system::RawOrigin::Root.into(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-							None,
-							Some(ScheduledV2 {
-								maybe_id: Some(b"test".to_vec()),
-								priority: 123,
-								call: Call::Logger(logger::Call::log(69, 1000)),
-								maybe_periodic: Some((456u64, 10)),
-								origin: system::RawOrigin::None.into(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-						]
-					),
-					(
-						2,
-						vec![
-							Some(ScheduledV2 {
-								maybe_id: None,
-								priority: 12,
-								call: Call::Logger(logger::Call::log(96, 100)),
-								maybe_periodic: None,
-								origin: system::RawOrigin::Root.into(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-							None,
-							Some(ScheduledV2 {
-								maybe_id: Some(b"test".to_vec()),
-								priority: 123,
-								call: Call::Logger(logger::Call::log(69, 1000)),
-								maybe_periodic: Some((456u64, 10)),
-								origin: system::RawOrigin::None.into(),
-								_phantom: PhantomData::<u64>::default(),
-							}),
-						]
-					)
-				]
-			);
-		});
-	}
 }
modifiedprimitives/nft/src/lib.rsdiffbeforeafterboth
--- a/primitives/nft/src/lib.rs
+++ b/primitives/nft/src/lib.rs
@@ -144,6 +144,7 @@
 	pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions
 	pub variable_on_chain_schema: Vec<u8>,        //
 	pub const_on_chain_schema: Vec<u8>,           //
+	pub transfers_enabled: bool,
 }
 
 #[derive(Encode, Decode, Debug, Clone, PartialEq)]