Skip to content

Commit 437ae7f

Browse files
authored
Merge pull request #211 from Phala-Network/polkadot-v0.9.28
Refactor User/Internal Functions for RMRK Core
2 parents aeec493 + a479b92 commit 437ae7f

File tree

11 files changed

+193
-118
lines changed

11 files changed

+193
-118
lines changed

pallets/rmrk-core/src/functions.rs

Lines changed: 86 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66

77
use super::*;
88
use codec::{Codec, Decode, Encode};
9-
use frame_support::traits::{tokens::Locker, Get};
9+
use frame_support::{
10+
pallet_prelude::*,
11+
traits::{tokens::Locker, Get},
12+
};
1013

1114
use sp_runtime::{
1215
traits::{Saturating, TrailingZeroInput},
@@ -24,15 +27,11 @@ where
2427
T: pallet_uniques::Config<CollectionId = CollectionId, ItemId = NftId>,
2528
{
2629
fn priority_set(
27-
sender: T::AccountId,
30+
_sender: T::AccountId,
2831
collection_id: CollectionId,
2932
nft_id: NftId,
3033
priorities: BoundedVec<ResourceId, T::MaxPriorities>,
3134
) -> DispatchResult {
32-
let (root_owner, _) = Pallet::<T>::lookup_root_owner(collection_id, nft_id)?;
33-
ensure!(sender == root_owner, Error::<T>::NoPermission);
34-
// Check NFT lock status
35-
ensure!(!Pallet::<T>::is_locked(collection_id, nft_id), pallet_uniques::Error::<T>::Locked);
3635
let _multi_removal_results =
3736
Priorities::<T>::clear_prefix((collection_id, nft_id), T::MaxPriorities::get(), None);
3837
let mut priority_index = 0;
@@ -107,25 +106,18 @@ where
107106
T: pallet_uniques::Config<CollectionId = CollectionId, ItemId = NftId>,
108107
{
109108
fn resource_add(
110-
sender: T::AccountId,
109+
_sender: T::AccountId,
111110
collection_id: CollectionId,
112111
nft_id: NftId,
113112
resource: ResourceTypes<BoundedVec<u8, T::StringLimit>, BoundedVec<PartId, T::PartsLimit>>,
114-
adding_on_mint: bool,
113+
pending: bool,
115114
resource_id: ResourceId,
116115
) -> Result<ResourceId, DispatchError> {
117116
ensure!(
118117
Resources::<T>::get((collection_id, nft_id, resource_id)).is_none(),
119118
Error::<T>::ResourceAlreadyExists
120119
);
121120

122-
let collection = Self::collections(collection_id).ok_or(Error::<T>::CollectionUnknown)?;
123-
124-
ensure!(collection.issuer == sender, Error::<T>::NoPermission);
125-
let (root_owner, _) = Pallet::<T>::lookup_root_owner(collection_id, nft_id)?;
126-
// Check NFT lock status
127-
ensure!(!Pallet::<T>::is_locked(collection_id, nft_id), pallet_uniques::Error::<T>::Locked);
128-
129121
match resource.clone() {
130122
ResourceTypes::Basic(_r) => (),
131123
ResourceTypes::Composable(r) => {
@@ -145,15 +137,6 @@ where
145137
},
146138
}
147139

148-
// Resource should be in a pending state if the rootowner of the resource is not the sender
149-
// of the transaction, unless the resource is being added on mint. This prevents the
150-
// situation where an NFT being minted *directly to* a non-owned NFT *with resources* will
151-
// have those resources be *pending*. While the minted NFT itself will be pending, it is
152-
// inefficent and unnecessary to have the resources also be pending. Otherwise, in such a
153-
// case, the owner would have to accept not only the NFT but also all originally-added
154-
// resources.
155-
let pending = (root_owner != sender) && !adding_on_mint;
156-
157140
let res: ResourceInfo<BoundedVec<u8, T::StringLimit>, BoundedVec<PartId, T::PartsLimit>> =
158141
ResourceInfo::<BoundedVec<u8, T::StringLimit>, BoundedVec<PartId, T::PartsLimit>> {
159142
id: resource_id,
@@ -163,50 +146,50 @@ where
163146
};
164147
Resources::<T>::insert((collection_id, nft_id, resource_id), res);
165148

149+
Self::deposit_event(Event::ResourceAdded { nft_id, resource_id, collection_id });
150+
166151
Ok(resource_id)
167152
}
168153

169154
fn accept(
170-
sender: T::AccountId,
155+
_sender: T::AccountId,
171156
collection_id: CollectionId,
172157
nft_id: NftId,
173158
resource_id: ResourceId,
174159
) -> DispatchResult {
175-
let (root_owner, _) = Pallet::<T>::lookup_root_owner(collection_id, nft_id)?;
176-
ensure!(root_owner == sender, Error::<T>::NoPermission);
177-
// Check NFT lock status
178-
ensure!(!Pallet::<T>::is_locked(collection_id, nft_id), pallet_uniques::Error::<T>::Locked);
160+
ensure!(
161+
Resources::<T>::get((collection_id, nft_id, resource_id)).is_some(),
162+
Error::<T>::ResourceDoesntExist
163+
);
179164
Resources::<T>::try_mutate_exists(
180165
(collection_id, nft_id, resource_id),
181166
|resource| -> DispatchResult {
182-
if let Some(res) = resource {
167+
if let Some(res) = resource.into_mut() {
168+
ensure!(res.pending, Error::<T>::ResourceNotPending);
183169
res.pending = false;
184170
}
185171
Ok(())
186172
},
187173
)?;
188174

189-
Self::deposit_event(Event::ResourceAccepted { nft_id, resource_id });
175+
Self::deposit_event(Event::ResourceAccepted { nft_id, resource_id, collection_id });
176+
190177
Ok(())
191178
}
192179

193180
fn resource_remove(
194-
sender: T::AccountId,
181+
_sender: T::AccountId,
195182
collection_id: CollectionId,
196183
nft_id: NftId,
197184
resource_id: ResourceId,
185+
pending_resource: bool,
198186
) -> DispatchResult {
199-
let collection = Self::collections(collection_id).ok_or(Error::<T>::CollectionUnknown)?;
200-
let (root_owner, _) = Pallet::<T>::lookup_root_owner(collection_id, nft_id)?;
201-
ensure!(collection.issuer == sender, Error::<T>::NoPermission);
202187
ensure!(
203188
Resources::<T>::contains_key((collection_id, nft_id, resource_id)),
204189
Error::<T>::ResourceDoesntExist
205190
);
206191

207-
if root_owner == sender {
208-
Resources::<T>::remove((collection_id, nft_id, resource_id));
209-
} else {
192+
if pending_resource {
210193
Resources::<T>::try_mutate_exists(
211194
(collection_id, nft_id, resource_id),
212195
|resource| -> DispatchResult {
@@ -216,19 +199,21 @@ where
216199
Ok(())
217200
},
218201
)?;
202+
} else {
203+
Resources::<T>::remove((collection_id, nft_id, resource_id));
219204
}
220205

206+
Self::deposit_event(Event::ResourceRemoval { nft_id, resource_id, collection_id });
207+
221208
Ok(())
222209
}
223210

224211
fn accept_removal(
225-
sender: T::AccountId,
212+
_sender: T::AccountId,
226213
collection_id: CollectionId,
227214
nft_id: NftId,
228215
resource_id: ResourceId,
229216
) -> DispatchResult {
230-
let (root_owner, _) = Pallet::<T>::lookup_root_owner(collection_id, nft_id)?;
231-
ensure!(root_owner == sender, Error::<T>::NoPermission);
232217
ensure!(
233218
Resources::<T>::contains_key((collection_id, nft_id, &resource_id)),
234219
Error::<T>::ResourceDoesntExist
@@ -245,6 +230,8 @@ where
245230
},
246231
)?;
247232

233+
Self::deposit_event(Event::ResourceRemovalAccepted { nft_id, resource_id, collection_id });
234+
248235
Ok(())
249236
}
250237
}
@@ -290,10 +277,23 @@ where
290277
Ok(collection_id)
291278
}
292279

293-
fn collection_burn(_issuer: T::AccountId, collection_id: CollectionId) -> DispatchResult {
280+
fn collection_burn(issuer: T::AccountId, collection_id: CollectionId) -> DispatchResult {
294281
let collection = Self::collections(collection_id).ok_or(Error::<T>::CollectionUnknown)?;
295282
ensure!(collection.nfts_count == 0, Error::<T>::CollectionNotEmpty);
283+
// Get DestroyWitness for Uniques pallet
284+
let witness = pallet_uniques::Pallet::<T>::get_destroy_witness(&collection_id)
285+
.ok_or(Error::<T>::NoWitness)?;
286+
ensure!(witness.items == 0u32, Error::<T>::CollectionNotEmpty);
287+
// Remove from RMRK storage
296288
Collections::<T>::remove(collection_id);
289+
290+
pallet_uniques::Pallet::<T>::do_destroy_collection(
291+
collection_id,
292+
witness,
293+
issuer.clone().into(),
294+
)?;
295+
296+
Self::deposit_event(Event::CollectionDestroyed { issuer, collection_id });
297297
Ok(())
298298
}
299299

@@ -319,10 +319,12 @@ where
319319
) -> Result<CollectionId, DispatchError> {
320320
Collections::<T>::try_mutate_exists(collection_id, |collection| -> DispatchResult {
321321
let collection = collection.as_mut().ok_or(Error::<T>::CollectionUnknown)?;
322-
ensure!(collection.issuer == sender, Error::<T>::NoPermission);
323322
collection.max = Some(collection.nfts_count);
324323
Ok(())
325324
})?;
325+
326+
Self::deposit_event(Event::CollectionLocked { issuer: sender, collection_id });
327+
326328
Ok(collection_id)
327329
}
328330
}
@@ -401,7 +403,7 @@ where
401403
collection_id,
402404
nft_id,
403405
res.resource,
404-
true,
406+
false,
405407
res.id,
406408
)?;
407409
}
@@ -488,7 +490,7 @@ where
488490
collection_id,
489491
nft_id,
490492
res.resource,
491-
true,
493+
false,
492494
res.id,
493495
)?;
494496
}
@@ -504,6 +506,7 @@ where
504506
}
505507

506508
fn nft_burn(
509+
owner: T::AccountId,
507510
collection_id: CollectionId,
508511
nft_id: NftId,
509512
max_recursions: u32,
@@ -530,7 +533,7 @@ where
530533
for ((child_collection_id, child_nft_id), _) in
531534
Children::<T>::drain_prefix((collection_id, nft_id))
532535
{
533-
Self::nft_burn(child_collection_id, child_nft_id, max_recursions - 1)?;
536+
Self::nft_burn(owner.clone(), child_collection_id, child_nft_id, max_recursions - 1)?;
534537
}
535538

536539
// decrement nfts counter
@@ -540,6 +543,11 @@ where
540543
Ok(())
541544
})?;
542545

546+
// Call pallet uniques to ensure NFT is burned
547+
pallet_uniques::Pallet::<T>::do_burn(collection_id, nft_id, |_, _| Ok(()))?;
548+
549+
Self::deposit_event(Event::NFTBurned { owner, nft_id, collection_id });
550+
543551
Ok((collection_id, nft_id))
544552
}
545553

@@ -599,7 +607,7 @@ where
599607
},
600608
};
601609

602-
sending_nft.owner = new_owner;
610+
sending_nft.owner = new_owner.clone();
603611
// Nfts::<T>::insert(collection_id, nft_id, sending_nft);
604612

605613
if approval_required {
@@ -630,6 +638,21 @@ where
630638
Pallet::<T>::add_child(new_owner_cid_nid, (collection_id, nft_id));
631639
}
632640

641+
pallet_uniques::Pallet::<T>::do_transfer(
642+
collection_id,
643+
nft_id,
644+
new_owner_account.clone(),
645+
|_class_details, _details| Ok(()),
646+
)?;
647+
648+
Self::deposit_event(Event::NFTSent {
649+
sender,
650+
recipient: new_owner,
651+
collection_id,
652+
nft_id,
653+
approval_required,
654+
});
655+
633656
Ok((new_owner_account, approval_required))
634657
}
635658

@@ -649,7 +672,7 @@ where
649672
Nfts::<T>::get(collection_id, nft_id).ok_or(Error::<T>::NoAvailableNftId)?;
650673

651674
// Prepare acceptance
652-
let new_owner_account = match new_owner {
675+
let new_owner_account = match new_owner.clone() {
653676
AccountIdOrCollectionNftTuple::AccountId(id) => id,
654677
AccountIdOrCollectionNftTuple::CollectionAndNftTuple(cid, nid) => {
655678
// Check if NFT target exists
@@ -682,6 +705,20 @@ where
682705
Ok(())
683706
})?;
684707

708+
pallet_uniques::Pallet::<T>::do_transfer(
709+
collection_id,
710+
nft_id,
711+
new_owner_account.clone(),
712+
|_class_details, _details| Ok(()),
713+
)?;
714+
715+
Self::deposit_event(Event::NFTAccepted {
716+
sender,
717+
recipient: new_owner,
718+
collection_id,
719+
nft_id,
720+
});
721+
685722
Ok((new_owner_account, collection_id, nft_id))
686723
}
687724

@@ -720,7 +757,7 @@ where
720757
let _rejecting_nft =
721758
Nfts::<T>::get(collection_id, nft_id).ok_or(Error::<T>::NoAvailableNftId)?;
722759

723-
Self::nft_burn(collection_id, nft_id, max_recursions)?;
760+
Self::nft_burn(sender.clone(), collection_id, nft_id, max_recursions)?;
724761

725762
Ok((sender, collection_id, nft_id))
726763
}

0 commit comments

Comments
 (0)