Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor property writing + dev mode enhancements #1000

Merged
merged 27 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
81bcea4
fix: set token props only if something has changed
mrshiposha Sep 25, 2023
e3c9079
fix: dont read storage during minting when not needed
mrshiposha Sep 25, 2023
9c8e078
feat: add reset_token_properties benchmark
mrshiposha Sep 25, 2023
d63678e
feat: add integration-tests profile and use in CI
mrshiposha Sep 25, 2023
5ec8b82
chore: add temporary nft/rft weights
mrshiposha Sep 25, 2023
331f0fa
fix: cache chain build in CI
mrshiposha Sep 26, 2023
192f49d
fix: dont read tpp when not needed
mrshiposha Sep 26, 2023
9b4620c
chore: repeat temporary nft/rft benches
mrshiposha Sep 26, 2023
12a441c
fix: debug check if new token doesnt have any properties
mrshiposha Sep 26, 2023
915db56
chore: bench weights
mrshiposha Sep 26, 2023
cb1a9d8
fix: calibrate weights
mrshiposha Sep 26, 2023
7cc9052
fix: bench profile production
mrshiposha Sep 26, 2023
1acfc39
chore: bench weights repeats 400
mrshiposha Sep 27, 2023
d2c9363
tests: performance test for NFT tokens
uandysmith Sep 27, 2023
44071b6
refactor: use type-safe propertywriter to set/delete properties
mrshiposha Sep 30, 2023
2657b80
fix: EREFUSED due to ws://localhost (?)
mrshiposha Sep 30, 2023
0900b3d
chore: temporary bench nft/rft/common
mrshiposha Sep 30, 2023
42bd0c6
chore: bench nft/rft/common
mrshiposha Sep 30, 2023
74a28c8
chore: calibrate weight2fee
mrshiposha Sep 30, 2023
b6b1e0f
feat: add cli param disable-autoseal-on-tx
mrshiposha Oct 2, 2023
184b30a
feat: finalization can be enabled in dev mode
mrshiposha Oct 2, 2023
57b7f8c
fix: slightly fix broken pov-estimate
mrshiposha Oct 2, 2023
e105d72
fix: use config.ts for endpoints
mrshiposha Oct 2, 2023
5ef5e6b
fix: make perf test seq and remove unused functions
mrshiposha Oct 2, 2023
eebd0e2
fix: use OptionQuery for TokenProperties
mrshiposha Oct 2, 2023
6b27551
fix: unit tests
mrshiposha Oct 2, 2023
630fc89
fix: use lowercase letters in EVM errors
mrshiposha Oct 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions pallets/balances-adapter/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,18 +172,16 @@ impl<T: Config> CommonCollectionOperations<T> for NativeFungibleHandle<T> {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}

fn get_token_properties_map(&self, _token_id: TokenId) -> up_data_structs::TokenProperties {
// No token properties are defined on fungibles
up_data_structs::TokenProperties::new()
}

fn set_token_properties_map(&self, _token_id: TokenId, _map: up_data_structs::TokenProperties) {
fn get_token_properties_raw(
&self,
_token_id: TokenId,
) -> Option<up_data_structs::TokenProperties> {
// No token properties are defined on fungibles
None
}

fn properties_exist(&self, _token: TokenId) -> bool {
fn set_token_properties_raw(&self, _token_id: TokenId, _map: up_data_structs::TokenProperties) {
// No token properties are defined on fungibles
false
}

fn set_token_property_permissions(
Expand Down
19 changes: 9 additions & 10 deletions pallets/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2098,18 +2098,13 @@ pub trait CommonCollectionOperations<T: Config> {
/// Get token properties raw map.
///
/// * `token_id` - The token which properties are needed.
fn get_token_properties_map(&self, token_id: TokenId) -> TokenProperties;
fn get_token_properties_raw(&self, token_id: TokenId) -> Option<TokenProperties>;

/// Set token properties raw map.
///
/// * `token_id` - The token for which the properties are being set.
/// * `map` - The raw map containing the token's properties.
fn set_token_properties_map(&self, token_id: TokenId, map: TokenProperties);

/// Whether the given token has properties.
///
/// * `token_id` - The token in question.
fn properties_exist(&self, token: TokenId) -> bool;
fn set_token_properties_raw(&self, token_id: TokenId, map: TokenProperties);

/// Set token property permissions.
///
Expand Down Expand Up @@ -2590,7 +2585,7 @@ impl<
<PalletEvm<T>>::deposit_log(log);

self.collection
.set_token_properties_map(token_id, stored_properties.into_inner());
.set_token_properties_raw(token_id, stored_properties.into_inner());
}

Ok(())
Expand Down Expand Up @@ -2624,7 +2619,7 @@ where
true
},
get_properties: |token_id| {
debug_assert!(!collection.properties_exist(token_id));
debug_assert!(collection.get_token_properties_raw(token_id).is_none());
TokenProperties::new()
},
_phantom: PhantomData,
Expand Down Expand Up @@ -2686,7 +2681,11 @@ where
is_collection_admin: LazyValue::new(|| collection.is_owner_or_admin(sender)),
property_permissions: LazyValue::new(|| <Pallet<T>>::property_permissions(collection.id)),
check_token_exist: |token_id| collection.token_exists(token_id),
get_properties: |token_id| collection.get_token_properties_map(token_id),
get_properties: |token_id| {
collection
.get_token_properties_raw(token_id)
.unwrap_or_default()
},
_phantom: PhantomData,
}
}
Expand Down
14 changes: 6 additions & 8 deletions pallets/fungible/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,18 +364,16 @@ impl<T: Config> CommonCollectionOperations<T> for FungibleHandle<T> {
fail!(<Error<T>>::SettingPropertiesNotAllowed)
}

fn get_token_properties_map(&self, _token_id: TokenId) -> up_data_structs::TokenProperties {
// No token properties are defined on fungibles
up_data_structs::TokenProperties::new()
}

fn set_token_properties_map(&self, _token_id: TokenId, _map: up_data_structs::TokenProperties) {
fn get_token_properties_raw(
&self,
_token_id: TokenId,
) -> Option<up_data_structs::TokenProperties> {
// No token properties are defined on fungibles
None
}

fn properties_exist(&self, _token: TokenId) -> bool {
fn set_token_properties_raw(&self, _token_id: TokenId, _map: up_data_structs::TokenProperties) {
// No token properties are defined on fungibles
false
}

fn check_nesting(
Expand Down
19 changes: 10 additions & 9 deletions pallets/nonfungible/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,15 @@ impl<T: Config> CommonCollectionOperations<T> for NonfungibleHandle<T> {
)
}

fn get_token_properties_map(&self, token_id: TokenId) -> up_data_structs::TokenProperties {
fn get_token_properties_raw(
&self,
token_id: TokenId,
) -> Option<up_data_structs::TokenProperties> {
<TokenProperties<T>>::get((self.id, token_id))
}

fn set_token_properties_map(&self, token_id: TokenId, map: up_data_structs::TokenProperties) {
<TokenProperties<T>>::set((self.id, token_id), map)
fn set_token_properties_raw(&self, token_id: TokenId, map: up_data_structs::TokenProperties) {
<TokenProperties<T>>::insert((self.id, token_id), map)
}

fn set_token_property_permissions(
Expand All @@ -287,10 +290,6 @@ impl<T: Config> CommonCollectionOperations<T> for NonfungibleHandle<T> {
)
}

fn properties_exist(&self, token: TokenId) -> bool {
<TokenProperties<T>>::contains_key((self.id, token))
}

fn burn_item(
&self,
sender: T::CrossAccountId,
Expand Down Expand Up @@ -482,13 +481,15 @@ impl<T: Config> CommonCollectionOperations<T> for NonfungibleHandle<T> {
}

fn token_property(&self, token_id: TokenId, key: &PropertyKey) -> Option<PropertyValue> {
<Pallet<T>>::token_properties((self.id, token_id))
<Pallet<T>>::token_properties((self.id, token_id))?
.get(key)
.cloned()
}

fn token_properties(&self, token_id: TokenId, keys: Option<Vec<PropertyKey>>) -> Vec<Property> {
let properties = <Pallet<T>>::token_properties((self.id, token_id));
let Some(properties) = <Pallet<T>>::token_properties((self.id, token_id)) else {
return vec![];
};

keys.map(|keys| {
keys.into_iter()
Expand Down
3 changes: 2 additions & 1 deletion pallets/nonfungible/src/erc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ impl<T: Config> NonfungibleHandle<T> {
.try_into()
.map_err(|_| "key too long")?;

let props = <TokenProperties<T>>::get((self.id, token_id));
let props =
<TokenProperties<T>>::get((self.id, token_id)).ok_or("Token properties not found")?;
CertainLach marked this conversation as resolved.
Show resolved Hide resolved
let prop = props.get(&key).ok_or("key not found")?;

Ok(prop.to_vec().into())
Expand Down
42 changes: 6 additions & 36 deletions pallets/nonfungible/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ use frame_support::{
use up_data_structs::{
AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData, CreateNftExData,
mapping::TokenAddressMapping, budget::Budget, Property, PropertyKey, PropertyValue,
PropertyKeyPermission, PropertyScope, TrySetProperty, TokenChild, AuxPropertyValue,
PropertiesPermissionMap, TokenProperties as TokenPropertiesT,
PropertyKeyPermission, PropertyScope, TokenChild, AuxPropertyValue, PropertiesPermissionMap,
TokenProperties as TokenPropertiesT,
};
use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
use pallet_common::{
Expand Down Expand Up @@ -201,7 +201,7 @@ pub mod pallet {
pub type TokenProperties<T: Config> = StorageNMap<
Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
Value = TokenPropertiesT,
QueryKind = ValueQuery,
QueryKind = OptionQuery,
>;

/// Custom data of a token that is serialized to bytes,
Expand Down Expand Up @@ -342,38 +342,6 @@ impl<T: Config> Pallet<T> {
<TokenData<T>>::contains_key((collection.id, token))
}

/// Set the token property with the scope.
///
/// - `property`: Contains key-value pair.
pub fn set_scoped_token_property(
collection_id: CollectionId,
token_id: TokenId,
scope: PropertyScope,
property: Property,
) -> DispatchResult {
TokenProperties::<T>::try_mutate((collection_id, token_id), |properties| {
properties.try_scoped_set(scope, property.key, property.value)
})
.map_err(<CommonError<T>>::from)?;

Ok(())
}

/// Batch operation to set multiple properties with the same scope.
pub fn set_scoped_token_properties(
collection_id: CollectionId,
token_id: TokenId,
scope: PropertyScope,
properties: impl Iterator<Item = Property>,
) -> DispatchResult {
TokenProperties::<T>::try_mutate((collection_id, token_id), |stored_properties| {
stored_properties.try_scoped_set_from_iter(scope, properties)
})
.map_err(<CommonError<T>>::from)?;

Ok(())
}

/// Add or edit auxiliary data for the property.
///
/// - `f`: function that adds or edits auxiliary data.
Expand Down Expand Up @@ -1394,7 +1362,9 @@ impl<T: Config> Pallet<T> {

pub fn repair_item(collection: &NonfungibleHandle<T>, token: TokenId) -> DispatchResult {
<TokenProperties<T>>::mutate((collection.id, token), |properties| {
properties.recompute_consumed_space();
if let Some(properties) = properties {
properties.recompute_consumed_space();
}
});

Ok(())
Expand Down
19 changes: 10 additions & 9 deletions pallets/refungible/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,16 +435,15 @@ impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {
)
}

fn get_token_properties_map(&self, token_id: TokenId) -> up_data_structs::TokenProperties {
fn get_token_properties_raw(
&self,
token_id: TokenId,
) -> Option<up_data_structs::TokenProperties> {
<TokenProperties<T>>::get((self.id, token_id))
}

fn set_token_properties_map(&self, token_id: TokenId, map: up_data_structs::TokenProperties) {
<TokenProperties<T>>::set((self.id, token_id), map)
}

fn properties_exist(&self, token: TokenId) -> bool {
<TokenProperties<T>>::contains_key((self.id, token))
fn set_token_properties_raw(&self, token_id: TokenId, map: up_data_structs::TokenProperties) {
<TokenProperties<T>>::insert((self.id, token_id), map)
}

fn check_nesting(
Expand Down Expand Up @@ -514,13 +513,15 @@ impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {
}

fn token_property(&self, token_id: TokenId, key: &PropertyKey) -> Option<PropertyValue> {
<Pallet<T>>::token_properties((self.id, token_id))
<Pallet<T>>::token_properties((self.id, token_id))?
.get(key)
.cloned()
}

fn token_properties(&self, token_id: TokenId, keys: Option<Vec<PropertyKey>>) -> Vec<Property> {
let properties = <Pallet<T>>::token_properties((self.id, token_id));
let Some(properties) = <Pallet<T>>::token_properties((self.id, token_id)) else {
return vec![];
};

keys.map(|keys| {
keys.into_iter()
Expand Down
3 changes: 2 additions & 1 deletion pallets/refungible/src/erc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,8 @@ impl<T: Config> RefungibleHandle<T> {
.try_into()
.map_err(|_| "key too long")?;

let props = <TokenProperties<T>>::get((self.id, token_id));
let props =
CertainLach marked this conversation as resolved.
Show resolved Hide resolved
<TokenProperties<T>>::get((self.id, token_id)).ok_or("Token properties not found")?;
let prop = props.get(&key).ok_or("key not found")?;

Ok(prop.to_vec().into())
Expand Down
38 changes: 6 additions & 32 deletions pallets/refungible/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
use up_data_structs::{
AccessMode, budget::Budget, CollectionId, CreateCollectionData, mapping::TokenAddressMapping,
MAX_REFUNGIBLE_PIECES, Property, PropertyKey, PropertyKeyPermission, PropertyScope,
PropertyValue, TokenId, TrySetProperty, PropertiesPermissionMap,
CreateRefungibleExMultipleOwners, TokenOwnerError, TokenProperties as TokenPropertiesT,
PropertyValue, TokenId, PropertiesPermissionMap, CreateRefungibleExMultipleOwners,
TokenOwnerError, TokenProperties as TokenPropertiesT,
};

pub use pallet::*;
Expand Down Expand Up @@ -175,7 +175,7 @@ pub mod pallet {
pub type TokenProperties<T: Config> = StorageNMap<
Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
Value = TokenPropertiesT,
QueryKind = ValueQuery,
QueryKind = OptionQuery,
>;

/// Total amount of pieces for token
Expand Down Expand Up @@ -293,34 +293,6 @@ impl<T: Config> Pallet<T> {
pub fn token_exists(collection: &RefungibleHandle<T>, token: TokenId) -> bool {
<TotalSupply<T>>::contains_key((collection.id, token))
}

pub fn set_scoped_token_property(
collection_id: CollectionId,
token_id: TokenId,
scope: PropertyScope,
property: Property,
) -> DispatchResult {
TokenProperties::<T>::try_mutate((collection_id, token_id), |properties| {
properties.try_scoped_set(scope, property.key, property.value)
})
.map_err(<CommonError<T>>::from)?;

Ok(())
}

pub fn set_scoped_token_properties(
collection_id: CollectionId,
token_id: TokenId,
scope: PropertyScope,
properties: impl Iterator<Item = Property>,
) -> DispatchResult {
TokenProperties::<T>::try_mutate((collection_id, token_id), |stored_properties| {
stored_properties.try_scoped_set_from_iter(scope, properties)
})
.map_err(<CommonError<T>>::from)?;

Ok(())
}
}

// unchecked calls skips any permission checks
Expand Down Expand Up @@ -1426,7 +1398,9 @@ impl<T: Config> Pallet<T> {

pub fn repair_item(collection: &RefungibleHandle<T>, token: TokenId) -> DispatchResult {
<TokenProperties<T>>::mutate((collection.id, token), |properties| {
properties.recompute_consumed_space();
if let Some(properties) = properties {
properties.recompute_consumed_space();
}
});

Ok(())
Expand Down
Loading