diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 9fd0093840d3fb7008a8fd0f67cb55b858d8600a..37a6ea1d1c5fd806be58b7725ee518541cd2f413 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -832,7 +832,7 @@ impl_runtime_apis! { let begin = 0; let end = 42; - let region_id = pallet_broker::Pallet::<Runtime>::issue(core, begin, end, None, None); + let region_id = pallet_broker::Pallet::<Runtime>::issue(core, begin, pallet_broker::CoreMask::complete(), end, None, None); Some(( Asset { fun: NonFungible(Index(region_id.into())), diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 7907f252cf8e47a1d1694c7721f72a81e660dc74..b6847dddb6c0326a01bab0f1ef4349f8ae78239a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -823,7 +823,7 @@ impl_runtime_apis! { let begin = 0; let end = 42; - let region_id = pallet_broker::Pallet::<Runtime>::issue(core, begin, end, None, None); + let region_id = pallet_broker::Pallet::<Runtime>::issue(core, begin, pallet_broker::CoreMask::complete(), end, None, None); Some(( Asset { fun: NonFungible(Index(region_id.into())), diff --git a/prdoc/pr_5067.prdoc b/prdoc/pr_5067.prdoc new file mode 100644 index 0000000000000000000000000000000000000000..9a11f96b5104585aaad4f2c963ac6ebe0611f7b2 --- /dev/null +++ b/prdoc/pr_5067.prdoc @@ -0,0 +1,19 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Fix region nonfungible implementation + +doc: + - audience: Runtime User + description: | + PR fixes the issue with the current implementation where minting causes + the region coremask to be set to `Coremask::complete` regardless of the + actual coremask of the region. + +crates: +- name: pallet-broker + bump: major +- name: coretime-rococo-runtime + bump: patch +- name: coretime-westend-runtime + bump: patch \ No newline at end of file diff --git a/substrate/frame/broker/src/dispatchable_impls.rs b/substrate/frame/broker/src/dispatchable_impls.rs index 9e7a56e52812e578d12c709a4dafb85dcc0d041a..a8ded084a8010c22240c891016a1dec6d05fc265 100644 --- a/substrate/frame/broker/src/dispatchable_impls.rs +++ b/substrate/frame/broker/src/dispatchable_impls.rs @@ -128,8 +128,14 @@ impl<T: Config> Pallet<T> { let core = Self::purchase_core(&who, price, &mut sale)?; SaleInfo::<T>::put(&sale); - let id = - Self::issue(core, sale.region_begin, sale.region_end, Some(who.clone()), Some(price)); + let id = Self::issue( + core, + sale.region_begin, + CoreMask::complete(), + sale.region_end, + Some(who.clone()), + Some(price), + ); let duration = sale.region_end.saturating_sub(sale.region_begin); Self::deposit_event(Event::Purchased { who, region_id: id, price, duration }); Ok(id) diff --git a/substrate/frame/broker/src/nonfungible_impl.rs b/substrate/frame/broker/src/nonfungible_impl.rs index e272ecbe0081bcfe0dd97ec763fcfd77bb4f1ba4..acbcba1dae490771fe9717fbbf2a81fb48a94847 100644 --- a/substrate/frame/broker/src/nonfungible_impl.rs +++ b/substrate/frame/broker/src/nonfungible_impl.rs @@ -74,7 +74,14 @@ impl<T: Config> Mutate<T::AccountId> for Pallet<T> { // 'Minting' can only occur if the asset has previously been burned (i.e. moved to the // holding register) ensure!(record.owner.is_none(), Error::<T>::NotAllowed); - Self::issue(region_id.core, region_id.begin, record.end, Some(who.clone()), record.paid); + Self::issue( + region_id.core, + region_id.begin, + region_id.mask, + record.end, + Some(who.clone()), + record.paid, + ); Ok(()) } diff --git a/substrate/frame/broker/src/tests.rs b/substrate/frame/broker/src/tests.rs index 2a8ea24b447ada3660ee9e5852dcf3c9e469f0db..3ea68c5a74d62b00e71feb92b37d46ddb5aced6d 100644 --- a/substrate/frame/broker/src/tests.rs +++ b/substrate/frame/broker/src/tests.rs @@ -240,6 +240,49 @@ fn mutate_operations_work() { }); } +#[test] +fn mutate_operations_work_with_partitioned_region() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + let (region1, _region2) = Broker::do_partition(region, None, 2).unwrap(); + let record_1 = Regions::<Test>::get(region1).unwrap(); + + // 'withdraw' the region from user 1: + assert_ok!(<Broker as Mutate<_>>::burn(®ion1.into(), Some(&1))); + assert_eq!(Regions::<Test>::get(region1).unwrap().owner, None); + + // `mint_into` works after burning: + assert_ok!(<Broker as Mutate<_>>::mint_into(®ion1.into(), &1)); + + // Ensure the region minted is the same as the one we burned previously: + assert_eq!(Regions::<Test>::get(region1).unwrap(), record_1); + }); +} + +#[test] +fn mutate_operations_work_with_interlaced_region() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + let (region1, _region2) = + Broker::do_interlace(region, None, CoreMask::from_chunk(0, 40)).unwrap(); + let record_1 = Regions::<Test>::get(region1).unwrap(); + + // 'withdraw' the region from user 1: + assert_ok!(<Broker as Mutate<_>>::burn(®ion1.into(), Some(&1))); + assert_eq!(Regions::<Test>::get(region1).unwrap().owner, None); + + // `mint_into` works after burning: + assert_ok!(<Broker as Mutate<_>>::mint_into(®ion1.into(), &1)); + + // Ensure the region minted is the same as the one we burned previously: + assert_eq!(Regions::<Test>::get(region1).unwrap(), record_1); + }); +} + #[test] fn permanent_is_not_reassignable() { TestExt::new().endow(1, 1000).execute_with(|| { diff --git a/substrate/frame/broker/src/utility_impls.rs b/substrate/frame/broker/src/utility_impls.rs index 9cceb7f970a9f55bf8a9420937b1f8d2c7826479..5c66ebb9674bf673bc05c1eea3d44cebfbd996c5 100644 --- a/substrate/frame/broker/src/utility_impls.rs +++ b/substrate/frame/broker/src/utility_impls.rs @@ -94,11 +94,12 @@ impl<T: Config> Pallet<T> { pub fn issue( core: CoreIndex, begin: Timeslice, + mask: CoreMask, end: Timeslice, owner: Option<T::AccountId>, paid: Option<BalanceOf<T>>, ) -> RegionId { - let id = RegionId { begin, core, mask: CoreMask::complete() }; + let id = RegionId { begin, core, mask }; let record = RegionRecord { end, owner, paid }; Regions::<T>::insert(&id, &record); id