git.delta.rocks / unique-network / refs/commits / 9d51561e5bd0

difftreelog

Revert "feat: burn children when destroying a collection"

Daniel Shiposha2022-05-27parent: #2c83d97.patch.diff
in: master
This reverts commit 4b7f4d90a16f3a5ab26bed0511dabae078429724.

12 files changed

modifiedpallets/common/src/dispatch.rsdiffbeforeafterboth
6 weights::Pays,6 weights::Pays,
7 traits::Get,7 traits::Get,
8};8};
9use up_data_structs::{CollectionId, CreateCollectionData, budget::Budget};9use up_data_structs::{CollectionId, CreateCollectionData};
1010
11use crate::{pallet::Config, CommonCollectionOperations, CollectionHandle};11use crate::{pallet::Config, CommonCollectionOperations, CollectionHandle};
1212
59 fn create(sender: T::AccountId, data: CreateCollectionData<T::AccountId>) -> DispatchResult;59 fn create(sender: T::AccountId, data: CreateCollectionData<T::AccountId>) -> DispatchResult;
60 fn destroy(60 fn destroy(sender: T::CrossAccountId, handle: CollectionHandle<T>) -> DispatchResult;
61 sender: T::CrossAccountId,
62 handle: CollectionHandle<T>,
63 nesting_budget: &dyn Budget,
64 ) -> DispatchResult;
6561
66 fn dispatch(handle: CollectionHandle<T>) -> Self;62 fn dispatch(handle: CollectionHandle<T>) -> Self;
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
1169 token: TokenId,1169 token: TokenId,
1170 amount: u128,1170 amount: u128,
1171 ) -> DispatchResultWithPostInfo;1171 ) -> DispatchResultWithPostInfo;
1172 fn burn_item_unchecked(
1173 &self,
1174 owner: &T::CrossAccountId,
1175 token: TokenId,
1176 amount: u128,
1177 ) -> DispatchResult;
1178 fn set_collection_properties(1172 fn set_collection_properties(
1179 &self,1173 &self,
1180 sender: T::CrossAccountId,1174 sender: T::CrossAccountId,
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
170 )170 )
171 }171 }
172
173 fn burn_item_unchecked(
174 &self,
175 owner: &T::CrossAccountId,
176 _token: TokenId,
177 amount: u128,
178 ) -> sp_runtime::DispatchResult {
179 <Pallet<T>>::burn_item_unchecked(self, owner, amount)?;
180
181 Ok(())
182 }
183172
184 fn transfer(173 fn transfer(
185 &self,174 &self,
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
155 Ok(())155 Ok(())
156 }156 }
157
158 pub fn burn(
159 collection: &FungibleHandle<T>,
160 owner: &T::CrossAccountId,
161 amount: u128,
162 ) -> DispatchResult {
163 if collection.access == AccessMode::AllowList {
164 collection.check_allowlist(owner)?;
165 }
166
167 // =========
168
169 Self::burn_item_unchecked(collection, owner, amount)?;
170
171 <PalletEvm<T>>::deposit_log(
172 ERC20Events::Transfer {
173 from: *owner.as_eth(),
174 to: H160::default(),
175 value: amount.into(),
176 }
177 .to_log(collection_id_to_address(collection.id)),
178 );
179 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
180 collection.id,
181 TokenId::default(),
182 owner.clone(),
183 amount,
184 ));
185 Ok(())
186 }
187157
188 pub fn burn_item_unchecked(158 pub fn burn(
189 collection: &FungibleHandle<T>,159 collection: &FungibleHandle<T>,
190 owner: &T::CrossAccountId,160 owner: &T::CrossAccountId,
191 amount: u128,161 amount: u128,
216 }186 }
217 <TotalSupply<T>>::insert(collection.id, total_supply);187 <TotalSupply<T>>::insert(collection.id, total_supply);
218188
189 <PalletEvm<T>>::deposit_log(
190 ERC20Events::Transfer {
191 from: *owner.as_eth(),
192 to: H160::default(),
193 value: amount.into(),
194 }
195 .to_log(collection_id_to_address(collection.id)),
196 );
197 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
198 collection.id,
199 TokenId::default(),
200 owner.clone(),
201 amount,
202 ));
219 Ok(())203 Ok(())
220 }204 }
221205
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
264 }264 }
265 }265 }
266
267 fn burn_item_unchecked(
268 &self,
269 owner:& T::CrossAccountId,
270 token: TokenId,
271 amount: u128,
272 ) -> sp_runtime::DispatchResult {
273 if amount == 1 {
274 <Pallet<T>>::burn_item_unchecked(self, owner, token)
275 } else {
276 Ok(())
277 }
278 }
279266
280 fn transfer(267 fn transfer(
281 &self,268 &self,
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
27use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};27use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
28use pallet_common::{28use pallet_common::{
29 Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, CollectionHandle,29 Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, CollectionHandle,
30 dispatch::CollectionDispatch,
31 eth::collection_id_to_address,30 eth::collection_id_to_address,
32};31};
33use pallet_structure::Pallet as PalletStructure;32use pallet_structure::Pallet as PalletStructure;
80 NonfungibleItemsHaveNoAmount,79 NonfungibleItemsHaveNoAmount,
81 /// Unable to burn NFT with children80 /// Unable to burn NFT with children
82 CantBurnNftWithChildren,81 CantBurnNftWithChildren,
83 /// Too many children to burn when destroying a collection
84 TooManyChildrenToBurn,
85 }82 }
8683
87 #[pallet::config]84 #[pallet::config]
293 pub fn destroy_collection(290 pub fn destroy_collection(
294 collection: NonfungibleHandle<T>,291 collection: NonfungibleHandle<T>,
295 sender: &T::CrossAccountId,292 sender: &T::CrossAccountId,
296 nesting_budget: &dyn Budget,
297 ) -> DispatchResult {293 ) -> DispatchResult {
298 let id = collection.id;294 let id = collection.id;
299295
300 // =========296 // =========
301297
302 Self::burn_children_in_collection(id, nesting_budget)?;
303 PalletCommon::destroy_collection(collection.0, sender)?;298 PalletCommon::destroy_collection(collection.0, sender)?;
299
304 <TokenData<T>>::remove_prefix((id,), None);300 <TokenData<T>>::remove_prefix((id,), None);
311 Ok(())307 Ok(())
312 }308 }
313
314 #[transactional]
315 fn burn_children_in_collection(collection_id: CollectionId, nesting_budget: &dyn Budget) -> DispatchResult {
316 for (parent_id, child) in <TokenChildren<T>>::drain_prefix((collection_id,))
317 .map(|((parent_id, child), _)| (parent_id, child)) {
318
319 let parent_address = T::CrossTokenAddressMapping::token_to_address(collection_id, parent_id);
320 Self::burn_tree(parent_address, child.0, child.1, nesting_budget)?;
321 }
322
323 Ok(())
324 }
325
326 fn burn_tree(
327 parent: T::CrossAccountId,
328 collection_id: CollectionId,
329 token_id: TokenId,
330 nesting_budget: &dyn Budget
331 ) -> DispatchResult {
332 if !nesting_budget.consume() {
333 return Err(<Error<T>>::TooManyChildrenToBurn.into());
334 }
335
336 let handle = <CollectionHandle<T>>::try_get(collection_id)?;
337 let handle = T::CollectionDispatch::dispatch(handle);
338 let handle = handle.as_dyn();
339
340 let amount = handle.balance(parent.clone(), token_id);
341
342 handle.burn_item_unchecked(&parent, token_id, amount)?;
343
344 for child in <TokenChildren<T>>::drain_prefix((collection_id, token_id)).map(|(child, _)| child) {
345 let parent = T::CrossTokenAddressMapping::token_to_address(collection_id, token_id);
346 Self::burn_tree(parent, child.0, child.1, nesting_budget)?;
347 }
348
349 Ok(())
350 }
351309
352 pub fn burn(310 pub fn burn(
353 collection: &NonfungibleHandle<T>,311 collection: &NonfungibleHandle<T>,
370 return Err(<Error<T>>::CantBurnNftWithChildren.into());328 return Err(<Error<T>>::CantBurnNftWithChildren.into());
371 }329 }
372330
373 let old_spender = <Allowance<T>>::get((collection.id, token));331 let burnt = <TokensBurnt<T>>::get(collection.id)
332 .checked_add(1)
333 .ok_or(ArithmeticError::Overflow)?;
334
335 let balance = <AccountBalance<T>>::get((collection.id, token_data.owner.clone()))
336 .checked_sub(1)
337 .ok_or(ArithmeticError::Overflow)?;
338
339 if balance == 0 {
340 <AccountBalance<T>>::remove((collection.id, token_data.owner.clone()));
341 } else {
342 <AccountBalance<T>>::insert((collection.id, token_data.owner.clone()), balance);
343 }
344
345 if let Some(owner) = T::CrossTokenAddressMapping::address_to_token(&token_data.owner) {
346 Self::unnest(owner, (collection.id, token));
347 }
374348
375 // =========349 // =========
376350
377 Self::burn_item_unchecked(collection, &token_data.owner, token)?;351 <Owned<T>>::remove((collection.id, &token_data.owner, token));
352 <TokensBurnt<T>>::insert(collection.id, burnt);
353 <TokenData<T>>::remove((collection.id, token));
354 <TokenProperties<T>>::remove((collection.id, token));
355 let old_spender = <Allowance<T>>::take((collection.id, token));
378356
379 if let Some(old_spender) = old_spender {357 if let Some(old_spender) = old_spender {
380 <PalletCommon<T>>::deposit_event(CommonEvent::Approved(358 <PalletCommon<T>>::deposit_event(CommonEvent::Approved(
403 Ok(())381 Ok(())
404 }382 }
405
406 pub fn burn_item_unchecked(
407 collection: &NonfungibleHandle<T>,
408 owner: &T::CrossAccountId,
409 token: TokenId,
410 ) -> DispatchResult {
411 let burnt = <TokensBurnt<T>>::get(collection.id)
412 .checked_add(1)
413 .ok_or(ArithmeticError::Overflow)?;
414
415 let balance = <AccountBalance<T>>::get((collection.id, owner.clone()))
416 .checked_sub(1)
417 .ok_or(ArithmeticError::Overflow)?;
418
419 // =========
420
421 if let Some(owner) = T::CrossTokenAddressMapping::address_to_token(owner) {
422 Self::unnest(owner, (collection.id, token));
423 }
424
425 if balance == 0 {
426 <AccountBalance<T>>::remove((collection.id, owner.clone()));
427 } else {
428 <AccountBalance<T>>::insert((collection.id, owner.clone()), balance);
429 }
430
431 <Owned<T>>::remove((collection.id, owner, token));
432 <TokensBurnt<T>>::insert(collection.id, burnt);
433 <TokenData<T>>::remove((collection.id, token));
434 <TokenProperties<T>>::remove((collection.id, token));
435 <Allowance<T>>::remove((collection.id, token));
436
437 Ok(())
438 }
439383
440 pub fn set_token_property(384 pub fn set_token_property(
441 collection: &NonfungibleHandle<T>,385 collection: &NonfungibleHandle<T>,
modifiedpallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth
179179
180 ensure!(collection.total_supply() == 0, <Error<T>>::CollectionNotEmpty);180 ensure!(collection.total_supply() == 0, <Error<T>>::CollectionNotEmpty);
181181
182 let empty_budget = budget::Value::new(0);
183 <PalletNft<T>>::destroy_collection(collection, &cross_sender, &empty_budget)182 <PalletNft<T>>::destroy_collection(collection, &cross_sender)
184 .map_err(Self::map_common_err_to_proxy)?;183 .map_err(Self::map_common_err_to_proxy)?;
185184
186 Self::deposit_event(Event::CollectionDestroyed { issuer: sender, collection_id });185 Self::deposit_event(Event::CollectionDestroyed { issuer: sender, collection_id });
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
205 )205 )
206 }206 }
207
208 fn burn_item_unchecked(
209 &self,
210 owner: &T::CrossAccountId,
211 token: TokenId,
212 amount: u128,
213 ) -> sp_runtime::DispatchResult {
214 <Pallet<T>>::burn_item_unchecked(self, owner, token, amount)
215 }
216207
217 fn transfer(208 fn transfer(
218 &self,209 &self,
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
239 Ok(())239 Ok(())
240 }240 }
241
242 pub fn burn(
243 collection: &RefungibleHandle<T>,
244 owner: &T::CrossAccountId,
245 token: TokenId,
246 amount: u128,
247 ) -> DispatchResult {
248 Self::burn_item_unchecked(collection, owner, token, amount)?;
249
250 // TODO: ERC20 transfer event
251 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
252 collection.id,
253 token,
254 owner.clone(),
255 amount,
256 ));
257
258 Ok(())
259 }
260241
261 pub fn burn_item_unchecked(242 pub fn burn(
262 collection: &RefungibleHandle<T>,243 collection: &RefungibleHandle<T>,
263 owner: &T::CrossAccountId,244 owner: &T::CrossAccountId,
264 token: TokenId,245 token: TokenId,
318 <Balance<T>>::insert((collection.id, token, owner), balance);299 <Balance<T>>::insert((collection.id, token, owner), balance);
319 }300 }
320 <TotalSupply<T>>::insert((collection.id, token), total_supply);301 <TotalSupply<T>>::insert((collection.id, token), total_supply);
302 // TODO: ERC20 transfer event
303 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
304 collection.id,
305 token,
306 owner.clone(),
307 amount,
308 ));
321 Ok(())309 Ok(())
322 }310 }
323311
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
334 /// * collection_id: collection to destroy.334 /// * collection_id: collection to destroy.
335 #[weight =335 #[weight = <SelfWeightOf<T>>::destroy_collection()]
336 <SelfWeightOf<T>>::destroy_collection()
337 + <SelfWeightOf<T>>::burn_children_in_collection(*max_children_to_burn)
338 ]
339 #[transactional]336 #[transactional]
340 pub fn destroy_collection(337 pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {
341 origin,
342 collection_id: CollectionId,
343 max_children_to_burn: u32,
344 ) -> DispatchResult {
345 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);338 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
346 let collection = <CollectionHandle<T>>::try_get(collection_id)?;339 let collection = <CollectionHandle<T>>::try_get(collection_id)?;
347
348 let budget = budget::Value::new(max_children_to_burn);
349340
350 // =========341 // =========
351342
352 T::CollectionDispatch::destroy(sender, collection, &budget)?;343 T::CollectionDispatch::destroy(sender, collection)?;
353344
354 <NftTransferBasket<T>>::remove_prefix(collection_id, None);345 <NftTransferBasket<T>>::remove_prefix(collection_id, None);
355 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);346 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);
modifiedpallets/unique/src/weights.rsdiffbeforeafterboth
34pub trait WeightInfo {34pub trait WeightInfo {
35 fn create_collection() -> Weight;35 fn create_collection() -> Weight;
36 fn destroy_collection() -> Weight;36 fn destroy_collection() -> Weight;
37 fn burn_children_in_collection(max: u32) -> Weight;
38 fn add_to_allow_list() -> Weight;37 fn add_to_allow_list() -> Weight;
39 fn remove_from_allow_list() -> Weight;38 fn remove_from_allow_list() -> Weight;
40 fn set_public_access_mode() -> Weight;39 fn set_public_access_mode() -> Weight;
75 .saturating_add(T::DbWeight::get().writes(5 as Weight))74 .saturating_add(T::DbWeight::get().writes(5 as Weight))
76 }75 }
77
78 fn burn_children_in_collection(max: u32) -> Weight {
79 // TODO
80 (50_000_000 as Weight).saturating_mul(max as Weight)
81 }
82
83 // Storage: Common CollectionById (r:1 w:0)76 // Storage: Common CollectionById (r:1 w:0)
84 // Storage: Common Allowlist (r:0 w:1)77 // Storage: Common Allowlist (r:0 w:1)
200 .saturating_add(RocksDbWeight::get().writes(5 as Weight))193 .saturating_add(RocksDbWeight::get().writes(5 as Weight))
201 }194 }
202
203 fn burn_children_in_collection(max: u32) -> Weight {
204 // TODO
205 (50_000_000 as Weight).saturating_mul(max as Weight)
206 }
207
208 // Storage: Common CollectionById (r:1 w:0)195 // Storage: Common CollectionById (r:1 w:0)
209 // Storage: Common Allowlist (r:0 w:1)196 // Storage: Common Allowlist (r:0 w:1)
modifiedruntime/common/src/dispatch.rsdiffbeforeafterboth
1use frame_support::{dispatch::{DispatchResult}, ensure};1use frame_support::{dispatch::DispatchResult, ensure};
2use pallet_evm::PrecompileResult;2use pallet_evm::PrecompileResult;
3use sp_core::{H160, U256};3use sp_core::{H160, U256};
4use sp_std::{borrow::ToOwned, vec::Vec};4use sp_std::{borrow::ToOwned, vec::Vec};
12use pallet_refungible::{Pallet as PalletRefungible, RefungibleHandle, erc::RefungibleTokenHandle};12use pallet_refungible::{Pallet as PalletRefungible, RefungibleHandle, erc::RefungibleTokenHandle};
13use up_data_structs::{13use up_data_structs::{
14 CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,14 CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,
15 budget::Budget,
16};15};
1716
18pub enum CollectionDispatchT<T>17pub enum CollectionDispatchT<T>
4948
50 fn destroy(49 fn destroy(sender: T::CrossAccountId, collection: CollectionHandle<T>) -> DispatchResult {
51 sender: T::CrossAccountId,
52 collection: CollectionHandle<T>,
53 nesting_budget: &dyn Budget,
54 ) -> DispatchResult {
55 match collection.mode {50 match collection.mode {
56 CollectionMode::ReFungible => {51 CollectionMode::ReFungible => {
62 CollectionMode::NFT => {57 CollectionMode::NFT => {
63 PalletNonfungible::destroy_collection(58 PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?
64 NonfungibleHandle::cast(collection),
65 &sender,
66 nesting_budget,
67 )?
68 }59 }
69 }60 }