difftreelog
fieat: add repair_item extrinsic + test
in: master
15 files changed
pallets/common/src/lib.rsdiffbeforeafterboth1816 /// The price of setting approval for all1816 /// The price of setting approval for all1817 fn set_allowance_for_all() -> Weight;1817 fn set_allowance_for_all() -> Weight;18181819 /// The price of repairing an item.1820 fn repair_item() -> Weight;1818}1821}181918221820/// Weight info extension trait for refungible pallet.1823/// Weight info extension trait for refungible pallet.2137 /// Tells whether the given `owner` approves the `operator`.2140 /// Tells whether the given `owner` approves the `operator`.2138 fn allowance_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool;2141 fn allowance_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool;21422143 /// Repairs a possibly broken item.2144 fn repair_item(&self, token: TokenId) -> DispatchResultWithPostInfo;2139}2145}214021462141/// Extension for RFT collection.2147/// Extension for RFT collection.pallets/fungible/src/common.rsdiffbeforeafterboth112 Weight::zero()112 Weight::zero()113 }113 }114115 fn repair_item() -> Weight {116 Weight::zero()117 }114}118}115119116/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete120/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete442 false446 false443 }447 }448449 /// Repairs a possibly broken item.450 fn repair_item(&self, _token: TokenId) -> DispatchResultWithPostInfo {451 fail!(<Error<T>>::FungibleTokensAreAlwaysValid)452 }444}453}445454pallets/fungible/src/lib.rsdiffbeforeafterboth129 SettingPropertiesNotAllowed,129 SettingPropertiesNotAllowed,130 /// Setting allowance for all is not allowed.130 /// Setting allowance for all is not allowed.131 SettingAllowanceForAllNotAllowed,131 SettingAllowanceForAllNotAllowed,132 /// Only a fungible collection could be possibly broken; any fungible token is valid.133 FungibleTokensAreAlwaysValid,132 }134 }133135134 #[pallet::config]136 #[pallet::config]pallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth237 };237 };238 }: {<Pallet<T>>::allowance_for_all(&collection, &owner, &operator)}238 }: {<Pallet<T>>::allowance_for_all(&collection, &owner, &operator)}239240 repair_item {241 bench_init!{242 owner: sub; collection: collection(owner);243 owner: cross_from_sub;244 };245 let item = create_max_item(&collection, &owner, owner.clone())?;246 }: {<Pallet<T>>::repair_item(&collection, item)?}239}247}240248pallets/nonfungible/src/common.rsdiffbeforeafterboth127 <SelfWeightOf<T>>::set_allowance_for_all()127 <SelfWeightOf<T>>::set_allowance_for_all()128 }128 }129130 fn repair_item() -> Weight {131 <SelfWeightOf<T>>::repair_item()132 }129}133}130134131fn map_create_data<T: Config>(135fn map_create_data<T: Config>(533 <Pallet<T>>::allowance_for_all(self, &owner, &operator)537 <Pallet<T>>::allowance_for_all(self, &owner, &operator)534 }538 }539540 fn repair_item(&self, token: TokenId) -> DispatchResultWithPostInfo {541 with_weight(542 <Pallet<T>>::repair_item(self, token),543 <CommonWeights<T>>::repair_item(),544 )545 }535}546}536547pallets/nonfungible/src/lib.rsdiffbeforeafterboth1399 <CollectionAllowance<T>>::get((collection.id, owner, operator))1399 <CollectionAllowance<T>>::get((collection.id, owner, operator))1400 }1400 }14011402 pub fn repair_item(collection: &NonfungibleHandle<T>, token: TokenId) -> DispatchResult {1403 <TokenProperties<T>>::mutate((collection.id, token), |properties| {1404 properties.recompute_consumed_space();1405 });14061407 Ok(())1408 }1401}1409}14021410pallets/nonfungible/src/weights.rsdiffbeforeafterboth50 fn token_owner() -> Weight;50 fn token_owner() -> Weight;51 fn set_allowance_for_all() -> Weight;51 fn set_allowance_for_all() -> Weight;52 fn allowance_for_all() -> Weight;52 fn allowance_for_all() -> Weight;53 fn repair_item() -> Weight;53}54}545555/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.56/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.208 Weight::from_ref_time(6_161_000 as u64)209 Weight::from_ref_time(6_161_000 as u64)209 .saturating_add(T::DbWeight::get().reads(1 as u64))210 .saturating_add(T::DbWeight::get().reads(1 as u64))210 }211 }212 // Storage: Nonfungible TokenProperties (r:1 w:1)213 fn repair_item() -> Weight {214 Weight::from_ref_time(5_701_000 as u64)215 .saturating_add(T::DbWeight::get().reads(1 as u64))216 .saturating_add(T::DbWeight::get().writes(1 as u64))217 }211}218}212219213// For backwards compatibility and tests220// For backwards compatibility and tests365 Weight::from_ref_time(6_161_000 as u64)372 Weight::from_ref_time(6_161_000 as u64)366 .saturating_add(RocksDbWeight::get().reads(1 as u64))373 .saturating_add(RocksDbWeight::get().reads(1 as u64))367 }374 }375 // Storage: Nonfungible TokenProperties (r:1 w:1)376 fn repair_item() -> Weight {377 Weight::from_ref_time(5_701_000 as u64)378 .saturating_add(RocksDbWeight::get().reads(1 as u64))379 .saturating_add(RocksDbWeight::get().writes(1 as u64))380 }368}381}369382pallets/refungible/src/benchmarking.rsdiffbeforeafterboth305 };305 };306 }: {<Pallet<T>>::allowance_for_all(&collection, &owner, &operator)}306 }: {<Pallet<T>>::allowance_for_all(&collection, &owner, &operator)}307308 repair_item {309 bench_init!{310 owner: sub; collection: collection(owner);311 owner: cross_from_sub;312 };313 let item = create_max_item(&collection, &owner, [(owner.clone(), 100)])?;314 }: {<Pallet<T>>::repair_item(&collection, item)?}307}315}308316pallets/refungible/src/common.rsdiffbeforeafterboth157 <SelfWeightOf<T>>::set_allowance_for_all()157 <SelfWeightOf<T>>::set_allowance_for_all()158 }158 }159160 fn repair_item() -> Weight {161 <SelfWeightOf<T>>::repair_item()162 }159}163}160164161fn map_create_data<T: Config>(165fn map_create_data<T: Config>(537 <Pallet<T>>::allowance_for_all(self, &owner, &operator)541 <Pallet<T>>::allowance_for_all(self, &owner, &operator)538 }542 }543544 fn repair_item(&self, token: TokenId) -> DispatchResultWithPostInfo {545 with_weight(546 <Pallet<T>>::repair_item(self, token),547 <CommonWeights<T>>::repair_item(),548 )549 }539}550}540551541impl<T: Config> RefungibleExtensions<T> for RefungibleHandle<T> {552impl<T: Config> RefungibleExtensions<T> for RefungibleHandle<T> {pallets/refungible/src/lib.rsdiffbeforeafterboth1462 <CollectionAllowance<T>>::get((collection.id, owner, operator))1462 <CollectionAllowance<T>>::get((collection.id, owner, operator))1463 }1463 }14641465 pub fn repair_item(collection: &RefungibleHandle<T>, token: TokenId) -> DispatchResult {1466 <TokenProperties<T>>::mutate((collection.id, token), |properties| {1467 properties.recompute_consumed_space();1468 });14691470 Ok(())1471 }1464}1472}14651473pallets/refungible/src/weights.rsdiffbeforeafterboth57 fn token_owner() -> Weight;57 fn token_owner() -> Weight;58 fn set_allowance_for_all() -> Weight;58 fn set_allowance_for_all() -> Weight;59 fn allowance_for_all() -> Weight;59 fn allowance_for_all() -> Weight;60 fn repair_item() -> Weight;60}61}616262/// Weights for pallet_refungible using the Substrate node and recommended hardware.63/// Weights for pallet_refungible using the Substrate node and recommended hardware.272 Weight::from_ref_time(5_901_000 as u64)273 Weight::from_ref_time(5_901_000 as u64)273 .saturating_add(T::DbWeight::get().reads(1 as u64))274 .saturating_add(T::DbWeight::get().reads(1 as u64))274 }275 }276 // Storage: Refungible TokenProperties (r:1 w:1)277 fn repair_item() -> Weight {278 Weight::from_ref_time(5_489_000 as u64)279 .saturating_add(T::DbWeight::get().reads(1 as u64))280 .saturating_add(T::DbWeight::get().writes(1 as u64))281 }275}282}276283277// For backwards compatibility and tests284// For backwards compatibility and tests486 Weight::from_ref_time(5_901_000 as u64)493 Weight::from_ref_time(5_901_000 as u64)487 .saturating_add(RocksDbWeight::get().reads(1 as u64))494 .saturating_add(RocksDbWeight::get().reads(1 as u64))488 }495 }496 // Storage: Refungible TokenProperties (r:1 w:1)497 fn repair_item() -> Weight {498 Weight::from_ref_time(5_489_000 as u64)499 .saturating_add(RocksDbWeight::get().reads(1 as u64))500 .saturating_add(RocksDbWeight::get().writes(1 as u64))501 }489}502}490503pallets/unique/src/lib.rsdiffbeforeafterboth983 })983 })984 }984 }985986 /// Repairs a broken item987 ///988 /// # Arguments989 ///990 /// * `collection_id`: ID of the collection the item belongs to.991 /// * `item_id`: ID of the item.992 #[weight = T::CommonWeightInfo::repair_item()]993 pub fn repair_item(994 _origin,995 collection_id: CollectionId,996 item_id: TokenId,997 ) -> DispatchResultWithPostInfo {998 dispatch_tx::<T, _>(collection_id, |d| {999 d.repair_item(item_id)1000 })1001 }985 }1002 }986}1003}9871004primitives/data-structs/src/lib.rsdiffbeforeafterboth1219 Ok(())1219 Ok(())1220 }1220 }12211222 pub fn values(&self) -> impl Iterator<Item = &Value> {1223 self.0.values()1224 }1221}1225}122212261223impl<Value> IntoIterator for PropertiesMap<Value> {1227impl<Value> IntoIterator for PropertiesMap<Value> {1291 self.map.get(key)1295 self.map.get(key)1292 }1296 }12971298 /// Recomputes the consumed space for the current properties state.1299 /// Needed to repair a token due to a bug fixed in the [PR #733](https://github.com/UniqueNetwork/unique-chain/pull/773).1300 pub fn recompute_consumed_space(&mut self) {1301 self.consumed_space = self.map.values().map(|value| value.len() as u32).sum();1302 }1293}1303}129413041295impl IntoIterator for Properties {1305impl IntoIterator for Properties {runtime/common/weights.rsdiffbeforeafterboth125 max_weight_of!(set_allowance_for_all())125 max_weight_of!(set_allowance_for_all())126 }126 }127128 fn repair_item() -> Weight {129 max_weight_of!(repair_item())130 }127}131}128132129#[cfg(feature = "refungible")]133#[cfg(feature = "refungible")]tests/src/nesting/tokenProperties.test.tsdiffbeforeafterboth28 before(async () => {28 before(async () => {29 await usingPlaygrounds(async (helper, privateKey) => {29 await usingPlaygrounds(async (helper, privateKey) => {30 const donor = await privateKey({filename: __filename});30 const donor = await privateKey({filename: __filename});31 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);31 [alice, bob, charlie] = await helper.arrange.createAccounts([200n, 100n, 100n], donor);32 });32 });333334 permissions = [34 permissions = [402 expect(consumedSpace).to.be.equal(originalSpace);402 expect(consumedSpace).to.be.equal(originalSpace);403 }));403 }));404405 [406 {mode: 'nft' as const, pieces: undefined, requiredPallets: []},407 {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]}, 408 ].map(testCase =>409 itSub.ifWithPallets(`repair_item preserves valid consumed space (${testCase.mode})`, testCase.requiredPallets, async({helper}) => {410 const propKey = 'tok-prop';411412 const collection = await helper[testCase.mode].mintCollection(alice, {413 tokenPropertyPermissions: [414 {415 key: propKey,416 permission: {mutable: true, tokenOwner: true},417 },418 ],419 });420 const token = await (421 testCase.pieces422 ? collection.mintToken(alice, testCase.pieces)423 : collection.mintToken(alice)424 );425426 const propDataSize = 4096;427 const propData = 'a'.repeat(propDataSize);428429 await token.setProperties(alice, [{key: propKey, value: propData}]);430 const originalSpace = await token.getTokenPropertiesConsumedSpace();431 expect(originalSpace).to.be.equal(propDataSize);432433 await helper.executeExtrinsic(alice, 'api.tx.unique.repairItem', [token.collectionId, token.tokenId], true);434 const recomputedSpace = await token.getTokenPropertiesConsumedSpace();435 expect(recomputedSpace).to.be.equal(originalSpace);436 }));404});437});405438406describe('Negative Integration Test: Token Properties', () => {439describe('Negative Integration Test: Token Properties', () => {