This repository has been archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
[Uniques V2] Refactor roles #12437
Merged
jsidorenko
merged 78 commits into
js/uniques-v2-main-branch
from
js/uniques-v2-roles-refactoring
Oct 20, 2022
Merged
[Uniques V2] Refactor roles #12437
Changes from all commits
Commits
Show all changes
78 commits
Select commit
Hold shift + click to select a range
97a7e30
Basics
jsidorenko a85608f
WIP: change the data format
jsidorenko 6db840a
Refactor
jsidorenko fa3a2a7
Remove redundant new() method
jsidorenko 472a753
Rename settings
jsidorenko 2611dd4
Enable tests
jsidorenko 52d7d38
Merge branch 'js/uniques-v2-main-branch' into js/uniques-v2-feature-f…
jsidorenko 46a6b7e
Chore
jsidorenko 5ff7048
Change params order
jsidorenko f7ddfed
Delete the config on collection removal
jsidorenko d0d1d60
Chore
jsidorenko 7d4b31f
Remove redundant system features
jsidorenko dd84637
Rename force_item_status to force_collection_status
jsidorenko 4920a0c
Update node runtime
jsidorenko 7456e73
Chore
jsidorenko 9ff45b8
Remove thaw_collection
jsidorenko c41a48c
Chore
jsidorenko fee3ade
Connect collection.is_frozen to config
jsidorenko a9ab6f8
Allow to lock the collection in a new way
jsidorenko 254816d
Move free_holding into settings
jsidorenko 5878197
Connect collection's metadata locker to feature flags
jsidorenko 95e21fb
DRY
jsidorenko 17b7c9e
Chore
jsidorenko dc6d2f0
Connect pallet level feature flags
jsidorenko cc64873
Prepare tests for the new changes
jsidorenko 5153080
Implement Item settings
jsidorenko 08a2048
Allow to lock the metadata or attributes of an item
jsidorenko 1551714
Common -> Settings
jsidorenko 8830a4c
Extract settings related code to a separate file
jsidorenko f8800df
Move feature flag checks inside the do_* methods
jsidorenko 3ccf04e
Split settings.rs into parts
jsidorenko f83fb73
Extract repeated code into macro
jsidorenko df97cce
Extract macros into their own file
jsidorenko 3bb6eb5
Chore
jsidorenko 8563a31
Fix traits
jsidorenko 09aca13
Fix traits
jsidorenko 114e519
Test SystemFeatures
jsidorenko d6536fc
Fix benchmarks
jsidorenko 09a4ed6
Add missing benchmark
jsidorenko d408b32
Fix node/runtime/lib.rs
jsidorenko fd86e41
".git/.scripts/bench-bot.sh" pallet dev pallet_nfts
c002f8b
Keep item's config on burn if it's not empty
jsidorenko b16435a
Merge branch 'js/uniques-v2-main-branch' into js/uniques-v2-feature-f…
jsidorenko d0ee824
Fix the merge artifacts
jsidorenko 0eb568e
Fmt
jsidorenko 998691e
Add SystemFeature::NoSwaps check
jsidorenko fbc7906
Refactor roles structure
jsidorenko b8c6f5e
Rename SystemFeatures to PalletFeatures
jsidorenko 8bef776
Rename errors
jsidorenko ddaa884
Add docs
jsidorenko 4c01fc5
Change error message
jsidorenko fa9d471
Rework pallet features
jsidorenko ad980de
Move macros
jsidorenko 8532179
Change comments
jsidorenko fc09bbd
Fmt
jsidorenko e3f67ad
Refactor Incrementable
jsidorenko 1966a58
Use pub(crate) for do_* functions
jsidorenko 39c84b4
Update comments
jsidorenko 71ff09e
Refactor freeze and lock functions
jsidorenko e3778ad
Rework Collection config and Item confg api
jsidorenko f84563d
Chore
jsidorenko 5d5cc1c
Merge branch 'js/uniques-v2-main-branch' into js/uniques-v2-feature-f…
jsidorenko 05b6d11
Make clippy happy
jsidorenko 08ca688
Chore
jsidorenko 1760e7e
Merge branch 'js/uniques-v2-feature-flags' into js/uniques-v2-roles-r…
jsidorenko 26adcc9
Fix artifacts
jsidorenko 0225479
Address comments
jsidorenko c944afc
Further refactoring
jsidorenko a665764
Add comments
jsidorenko 2461bc0
Add tests for group_roles_by_account()
jsidorenko 6608f87
Update frame/nfts/src/impl_nonfungibles.rs
jsidorenko e6c56d6
Add test
jsidorenko 414bd8b
Replace Itertools group_by with a custom implementation
jsidorenko 7ee0d2e
Merge branch 'js/uniques-v2-main-branch' into js/uniques-v2-roles-ref…
jsidorenko e688ad5
ItemsNotTransferable => ItemsNonTransferable
jsidorenko fc8d341
Update frame/nfts/src/features/roles.rs
jsidorenko 2a3d11e
Address PR comments
jsidorenko e3ba2b2
Add missed comment
jsidorenko File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,4 +18,5 @@ | |
pub mod atomic_swap; | ||
pub mod buy_sell; | ||
pub mod lock; | ||
pub mod roles; | ||
pub mod settings; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// This file is part of Substrate. | ||
|
||
// Copyright (C) 2022 Parity Technologies (UK) Ltd. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
use crate::*; | ||
use frame_support::pallet_prelude::*; | ||
use sp_std::collections::btree_map::BTreeMap; | ||
|
||
impl<T: Config<I>, I: 'static> Pallet<T, I> { | ||
/// Clears all the roles in a specified collection. | ||
/// | ||
/// - `collection_id`: A collection to clear the roles in. | ||
/// | ||
/// Throws an error if some of the roles were left in storage. | ||
/// This means the `CollectionRoles::max_roles()` needs to be adjusted. | ||
pub(crate) fn clear_roles(collection_id: &T::CollectionId) -> Result<(), DispatchError> { | ||
let res = CollectionRoleOf::<T, I>::clear_prefix( | ||
&collection_id, | ||
CollectionRoles::max_roles() as u32, | ||
None, | ||
); | ||
ensure!(res.maybe_cursor.is_none(), Error::<T, I>::RolesNotCleared); | ||
Ok(()) | ||
} | ||
|
||
/// Returns true if a specified account has a provided role within that collection. | ||
/// | ||
/// - `collection_id`: A collection to check the role in. | ||
/// - `account_id`: An account to check the role for. | ||
/// - `role`: A role to validate. | ||
/// | ||
/// Returns boolean. | ||
pub(crate) fn has_role( | ||
jsidorenko marked this conversation as resolved.
Show resolved
Hide resolved
|
||
collection_id: &T::CollectionId, | ||
account_id: &T::AccountId, | ||
role: CollectionRole, | ||
) -> bool { | ||
CollectionRoleOf::<T, I>::get(&collection_id, &account_id) | ||
.map_or(false, |roles| roles.has_role(role)) | ||
} | ||
|
||
/// Groups provided roles by account, given one account could have multiple roles. | ||
/// | ||
/// - `input`: A vector of (Account, Role) tuples. | ||
/// | ||
/// Returns a grouped vector. | ||
pub fn group_roles_by_account( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would be nice to have a doc and tests for this functions |
||
input: Vec<(T::AccountId, CollectionRole)>, | ||
) -> Vec<(T::AccountId, CollectionRoles)> { | ||
let mut result = BTreeMap::new(); | ||
for (account, role) in input.into_iter() { | ||
result.entry(account).or_insert(CollectionRoles::none()).add_role(role); | ||
} | ||
result.into_iter().collect() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,7 +41,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { | |
let collection_config = Self::get_collection_config(&collection)?; | ||
ensure!( | ||
collection_config.is_setting_enabled(CollectionSetting::TransferableItems), | ||
Error::<T, I>::ItemsNotTransferable | ||
Error::<T, I>::ItemsNonTransferable | ||
); | ||
|
||
let item_config = Self::get_item_config(&collection, &item)?; | ||
|
@@ -93,15 +93,19 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { | |
collection, | ||
CollectionDetails { | ||
owner: owner.clone(), | ||
issuer: admin.clone(), | ||
admin: admin.clone(), | ||
freezer: admin, | ||
total_deposit: deposit, | ||
items: 0, | ||
item_metadatas: 0, | ||
attributes: 0, | ||
}, | ||
); | ||
CollectionRoleOf::<T, I>::insert( | ||
collection, | ||
admin, | ||
CollectionRoles( | ||
CollectionRole::Admin | CollectionRole::Freezer | CollectionRole::Issuer, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't the admin be able to perform all the operations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to the prev logic - no :) I only reworked the existing data structure into a new one without changing the business rules |
||
), | ||
); | ||
|
||
let next_id = collection.increment(); | ||
|
||
|
@@ -142,6 +146,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { | |
#[allow(deprecated)] | ||
PendingSwapOf::<T, I>::remove_prefix(&collection, None); | ||
CollectionMetadataOf::<T, I>::remove(&collection); | ||
Self::clear_roles(&collection)?; | ||
#[allow(deprecated)] | ||
Attribute::<T, I>::remove_prefix((&collection,), None); | ||
CollectionAccount::<T, I>::remove(&collection_details.owner, &collection); | ||
|
@@ -165,7 +170,6 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { | |
item: T::ItemId, | ||
owner: T::AccountId, | ||
config: ItemConfig, | ||
with_details: impl FnOnce(&CollectionDetailsFor<T, I>) -> DispatchResult, | ||
) -> DispatchResult { | ||
ensure!(!Item::<T, I>::contains_key(collection, item), Error::<T, I>::AlreadyExists); | ||
|
||
|
@@ -175,8 +179,6 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { | |
let collection_details = | ||
maybe_collection_details.as_mut().ok_or(Error::<T, I>::UnknownCollection)?; | ||
|
||
with_details(collection_details)?; | ||
|
||
if let Ok(max_supply) = CollectionMaxSupply::<T, I>::try_get(&collection) { | ||
ensure!(collection_details.items < max_supply, Error::<T, I>::MaxSupplyReached); | ||
} | ||
|
@@ -218,7 +220,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { | |
pub fn do_burn( | ||
collection: T::CollectionId, | ||
item: T::ItemId, | ||
with_details: impl FnOnce(&CollectionDetailsFor<T, I>, &ItemDetailsFor<T, I>) -> DispatchResult, | ||
with_details: impl FnOnce(&ItemDetailsFor<T, I>) -> DispatchResult, | ||
) -> DispatchResult { | ||
let owner = Collection::<T, I>::try_mutate( | ||
&collection, | ||
|
@@ -227,7 +229,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { | |
maybe_collection_details.as_mut().ok_or(Error::<T, I>::UnknownCollection)?; | ||
let details = Item::<T, I>::get(&collection, &item) | ||
.ok_or(Error::<T, I>::UnknownCollection)?; | ||
with_details(collection_details, &details)?; | ||
with_details(&details)?; | ||
|
||
// Return the deposit. | ||
T::Currency::unreserve(&collection_details.owner, details.deposit); | ||
|
@@ -271,7 +273,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { | |
let collection_config = Self::get_collection_config(&collection)?; | ||
ensure!( | ||
collection_config.is_setting_enabled(CollectionSetting::TransferableItems), | ||
Error::<T, I>::ItemsNotTransferable | ||
Error::<T, I>::ItemsNonTransferable | ||
); | ||
|
||
let item_config = Self::get_item_config(&collection, &item)?; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With multiple files the pallet structure looks unfamiliar to me.
The way we structure the code is a matter of taste, but keeping the structure similar within one project helps a lot.
I would rather keep the structure similar to the other pallets or have a well defined proposal with the new structure.
When I see this new structure, I have many questions, like why i see see impl of one type Pallet in different modules, why we dont have roles types in roles module, whats difference between functions.rs and features/*?
This is not a blocker.