difftreelog
refactor Remove variable data from tokens
in: master
23 files changed
client/rpc/src/lib.rsdiffbeforeafterboth--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -71,13 +71,6 @@
token: TokenId,
at: Option<BlockHash>,
) -> Result<Vec<u8>>;
- #[rpc(name = "unique_variableMetadata")]
- fn variable_metadata(
- &self,
- collection: CollectionId,
- token: TokenId,
- at: Option<BlockHash>,
- ) -> Result<Vec<u8>>;
#[rpc(name = "unique_collectionProperties")]
fn collection_properties(
@@ -279,7 +272,6 @@
);
pass_method!(topmost_token_owner(collection: CollectionId, token: TokenId) -> Option<CrossAccountId>);
pass_method!(const_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);
- pass_method!(variable_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);
pass_method!(collection_properties(
collection: CollectionId,
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -33,7 +33,7 @@
MAX_TOKEN_PREFIX_LENGTH, COLLECTION_ADMINS_LIMIT, MetaUpdatePermission, TokenId,
CollectionStats, MAX_TOKEN_OWNERSHIP, CollectionMode, NFT_SPONSOR_TRANSFER_TIMEOUT,
FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MAX_SPONSOR_TIMEOUT,
- CUSTOM_DATA_LIMIT, CollectionLimits, CustomDataLimit, CreateCollectionData, SponsorshipState,
+ CUSTOM_DATA_LIMIT, CollectionLimits, CreateCollectionData, SponsorshipState,
CreateItemExData, SponsoringRateLimit, budget::Budget, COLLECTION_FIELD_LIMIT, CollectionField,
PhantomType, Property, Properties, PropertiesPermissionMap, PropertyKey, PropertyPermission,
PropertiesError, PropertyKeyPermission, TokenData, TrySet,
@@ -312,8 +312,6 @@
CollectionTokenPrefixLimitExceeded,
/// Total collections bound exceeded.
TotalCollectionsLimitExceeded,
- /// variable_data exceeded data limit.
- TokenVariableDataLimitExceeded,
/// Exceeded max admin count
CollectionAdminCountExceeded,
/// Collection limit bounds per collection exceeded
@@ -1073,7 +1071,6 @@
fn approve() -> Weight;
fn transfer_from() -> Weight;
fn burn_from() -> Weight;
- fn set_variable_metadata(bytes: u32) -> Weight;
}
pub trait CommonCollectionOperations<T: Config> {
@@ -1163,13 +1160,6 @@
nesting_budget: &dyn Budget,
) -> DispatchResultWithPostInfo;
- fn set_variable_metadata(
- &self,
- sender: T::CrossAccountId,
- token: TokenId,
- data: BoundedVec<u8, CustomDataLimit>,
- ) -> DispatchResultWithPostInfo;
-
fn check_nesting(
&self,
sender: T::CrossAccountId,
@@ -1185,7 +1175,6 @@
fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId>;
fn const_metadata(&self, token: TokenId) -> Vec<u8>;
- fn variable_metadata(&self, token: TokenId) -> Vec<u8>;
fn token_properties(&self, token_id: TokenId, keys: Vec<PropertyKey>) -> Vec<Property>;
/// Amount of unique collection tokens
fn total_supply(&self) -> u32;
pallets/fungible/src/common.rsdiffbeforeafterboth--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -16,12 +16,12 @@
use core::marker::PhantomData;
-use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};
+use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
use up_data_structs::{TokenId, CollectionId, CreateItemExData, budget::Budget};
use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
use sp_runtime::ArithmeticError;
use sp_std::{vec::Vec, vec};
-use up_data_structs::{CustomDataLimit, Property, PropertyKey, PropertyKeyPermission};
+use up_data_structs::{Property, PropertyKey, PropertyKeyPermission};
use crate::{
Allowance, Balance, Config, Error, FungibleHandle, Pallet, SelfWeightOf, weights::WeightInfo,
@@ -85,11 +85,6 @@
fn burn_from() -> Weight {
<SelfWeightOf<T>>::burn_from()
}
-
- fn set_variable_metadata(_bytes: u32) -> Weight {
- // Error
- 0
- }
}
impl<T: Config> CommonCollectionOperations<T> for FungibleHandle<T> {
@@ -287,15 +282,6 @@
fail!(<Error<T>>::SettingPropertiesNotAllowed)
}
- fn set_variable_metadata(
- &self,
- _sender: T::CrossAccountId,
- _token: TokenId,
- _data: BoundedVec<u8, CustomDataLimit>,
- ) -> DispatchResultWithPostInfo {
- fail!(<Error<T>>::FungibleItemsDontHaveData)
- }
-
fn check_nesting(
&self,
_sender: <T>::CrossAccountId,
@@ -330,9 +316,6 @@
None
}
fn const_metadata(&self, _token: TokenId) -> Vec<u8> {
- Vec::new()
- }
- fn variable_metadata(&self, _token: TokenId) -> Vec<u8> {
Vec::new()
}
pallets/nonfungible/Cargo.tomldiffbeforeafterboth--- a/pallets/nonfungible/Cargo.toml
+++ b/pallets/nonfungible/Cargo.toml
@@ -27,6 +27,7 @@
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
+struct-versioning = { path = "../../crates/struct-versioning" }
[features]
default = ["std"]
pallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -28,10 +28,8 @@
fn create_max_item_data<T: Config>(owner: T::CrossAccountId) -> CreateItemData<T> {
let const_data = create_data::<CUSTOM_DATA_LIMIT>();
- let variable_data = create_data::<CUSTOM_DATA_LIMIT>();
CreateItemData::<T> {
const_data,
- variable_data,
owner,
}
}
@@ -125,14 +123,4 @@
let item = create_max_item(&collection, &owner, sender.clone())?;
<Pallet<T>>::set_allowance(&collection, &sender, item, Some(&burner))?;
}: {<Pallet<T>>::burn_from(&collection, &burner, &sender, item, &Unlimited)?}
-
- set_variable_metadata {
- let b in 0..CUSTOM_DATA_LIMIT;
- bench_init!{
- owner: sub; collection: collection(owner);
- owner: cross_from_sub; sender: cross_sub;
- };
- let item = create_max_item(&collection, &owner, sender.clone())?;
- let data = create_var_data(b).try_into().unwrap();
- }: {<Pallet<T>>::set_variable_metadata(&collection, &sender, item, data)?}
}
pallets/nonfungible/src/common.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -16,9 +16,9 @@
use core::marker::PhantomData;
-use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};
+use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
use up_data_structs::{
- TokenId, CustomDataLimit, CreateItemExData, CollectionId, budget::Budget, Property,
+ TokenId, CreateItemExData, CollectionId, budget::Budget, Property,
PropertyKey, PropertyKeyPermission,
};
use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
@@ -85,10 +85,6 @@
fn burn_from() -> Weight {
<SelfWeightOf<T>>::burn_from()
- }
-
- fn set_variable_metadata(bytes: u32) -> Weight {
- <SelfWeightOf<T>>::set_variable_metadata(bytes)
}
}
@@ -99,7 +95,6 @@
match data {
up_data_structs::CreateItemData::NFT(data) => Ok(CreateItemData::<T> {
const_data: data.const_data,
- variable_data: data.variable_data,
properties: data.properties,
owner: to.clone(),
}),
@@ -325,19 +320,6 @@
} else {
Ok(().into())
}
- }
-
- fn set_variable_metadata(
- &self,
- sender: T::CrossAccountId,
- token: TokenId,
- data: BoundedVec<u8, CustomDataLimit>,
- ) -> DispatchResultWithPostInfo {
- let len = data.len();
- with_weight(
- <Pallet<T>>::set_variable_metadata(self, &sender, token, data),
- <CommonWeights<T>>::set_variable_metadata(len as u32),
- )
}
fn check_nesting(
@@ -376,12 +358,6 @@
fn const_metadata(&self, token: TokenId) -> Vec<u8> {
<TokenData<T>>::get((self.id, token))
.map(|t| t.const_data)
- .unwrap_or_default()
- .into_inner()
- }
- fn variable_metadata(&self, token: TokenId) -> Vec<u8> {
- <TokenData<T>>::get((self.id, token))
- .map(|t| t.variable_data)
.unwrap_or_default()
.into_inner()
}
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -24,7 +24,7 @@
use up_data_structs::{TokenId, SchemaVersion};
use pallet_evm_coder_substrate::dispatch_to_evm;
use sp_core::{H160, U256};
-use sp_std::{vec::Vec, vec};
+use sp_std::vec::Vec;
use pallet_common::{
erc::{CommonEvmHandler, PrecompileResult, CollectionPropertiesCall},
CollectionHandle,
@@ -274,7 +274,6 @@
&caller,
CreateItemData::<T> {
const_data: BoundedVec::default(),
- variable_data: BoundedVec::default(),
properties: BoundedVec::default(),
owner: to,
},
@@ -322,7 +321,6 @@
const_data: Vec::<u8>::from(token_uri)
.try_into()
.map_err(|_| "token uri is too long")?,
- variable_data: BoundedVec::default(),
properties: BoundedVec::default(),
owner: to,
},
@@ -387,37 +385,6 @@
.into())
}
- #[weight(<SelfWeightOf<T>>::set_variable_metadata(data.len() as u32))]
- fn set_variable_metadata(
- &mut self,
- caller: caller,
- token_id: uint256,
- data: bytes,
- ) -> Result<void> {
- let caller = T::CrossAccountId::from_eth(caller);
- let token = token_id.try_into()?;
-
- <Pallet<T>>::set_variable_metadata(
- self,
- &caller,
- token,
- data.try_into()
- .map_err(|_| "metadata size exceeded limit")?,
- )
- .map_err(dispatch_to_evm::<T>)?;
- Ok(())
- }
-
- fn get_variable_metadata(&self, token_id: uint256) -> Result<bytes> {
- self.consume_store_reads(1)?;
- let token: TokenId = token_id.try_into()?;
-
- Ok(<TokenData<T>>::get((self.id, token))
- .ok_or("token not found")?
- .variable_data
- .into_inner())
- }
-
#[weight(<SelfWeightOf<T>>::create_multiple_items(token_ids.len() as u32))]
fn mint_bulk(&mut self, caller: caller, to: address, token_ids: Vec<uint256>) -> Result<bool> {
let caller = T::CrossAccountId::from_eth(caller);
@@ -440,7 +407,6 @@
let data = (0..total_tokens)
.map(|_| CreateItemData::<T> {
const_data: BoundedVec::default(),
- variable_data: BoundedVec::default(),
properties: BoundedVec::default(),
owner: to.clone(),
})
@@ -484,7 +450,6 @@
const_data: Vec::<u8>::from(token_uri)
.try_into()
.map_err(|_| "token uri is too long")?,
- variable_data: vec![].try_into().unwrap(),
properties: BoundedVec::default(),
owner: to.clone(),
});
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -49,17 +49,22 @@
pub type CreateItemData<T> = CreateNftExData<<T as pallet_evm::account::Config>::CrossAccountId>;
pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
+#[struct_versioning::versioned(version = 2, upper)]
#[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct ItemData<CrossAccountId> {
pub const_data: BoundedVec<u8, CustomDataLimit>,
+
+ #[version(..2)]
pub variable_data: BoundedVec<u8, CustomDataLimit>,
+
pub owner: CrossAccountId,
}
#[frame_support::pallet]
pub mod pallet {
use super::*;
- use frame_support::{Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key};
+ use frame_support::{Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key, traits::StorageVersion};
+ use frame_system::pallet_prelude::*;
use up_data_structs::{CollectionId, TokenId};
use super::weights::WeightInfo;
@@ -78,7 +83,10 @@
type WeightInfo: WeightInfo;
}
+ const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
+
#[pallet::pallet]
+ #[pallet::storage_version(STORAGE_VERSION)]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
@@ -133,6 +141,19 @@
Value = T::CrossAccountId,
QueryKind = OptionQuery,
>;
+
+ #[pallet::hooks]
+ impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
+ fn on_runtime_upgrade() -> Weight {
+ if StorageVersion::get::<Pallet<T>>() < StorageVersion::new(1) {
+ <TokenData<T>>::translate_values::<ItemDataVersion1<T::CrossAccountId>, _>(|v| {
+ Some(<ItemDataVersion2<T::CrossAccountId>>::from(v))
+ })
+ }
+
+ 0
+ }
+ }
}
pub struct NonfungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);
@@ -577,7 +598,6 @@
(collection.id, token),
ItemData {
const_data: data.const_data,
- variable_data: data.variable_data,
owner: data.owner.clone(),
},
);
@@ -773,28 +793,6 @@
// =========
Self::burn(collection, from, token)
- }
-
- pub fn set_variable_metadata(
- collection: &NonfungibleHandle<T>,
- sender: &T::CrossAccountId,
- token: TokenId,
- data: BoundedVec<u8, CustomDataLimit>,
- ) -> DispatchResult {
- let token_data =
- <TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;
- collection.check_can_update_meta(sender, &token_data.owner)?;
-
- // =========
-
- <TokenData<T>>::insert(
- (collection.id, token),
- ItemData {
- variable_data: data,
- ..token_data
- },
- );
- Ok(())
}
pub fn check_nesting(
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -61,6 +61,24 @@
}
}
+// Selector: 56fd500b
+contract CollectionProperties is Dummy, ERC165 {
+ // Selector: setProperty(string,string) 62d9491f
+ function setProperty(string memory key, string memory value) public {
+ require(false, stub_error);
+ key;
+ value;
+ dummy = 0;
+ }
+
+ // Selector: deleteProperty(string) 34241914
+ function deleteProperty(string memory key) public {
+ require(false, stub_error);
+ key;
+ dummy = 0;
+ }
+}
+
// Selector: 58800161
contract ERC721 is Dummy, ERC165, ERC721Events {
// Selector: balanceOf(address) 70a08231
@@ -276,7 +294,7 @@
}
}
-// Selector: e562194d
+// Selector: d74d154f
contract ERC721UniqueExtensions is Dummy, ERC165 {
// Selector: transfer(address,uint256) a9059cbb
function transfer(address to, uint256 tokenId) public {
@@ -301,26 +319,6 @@
return 0;
}
- // Selector: setVariableMetadata(uint256,bytes) d4eac26d
- function setVariableMetadata(uint256 tokenId, bytes memory data) public {
- require(false, stub_error);
- tokenId;
- data;
- dummy = 0;
- }
-
- // Selector: getVariableMetadata(uint256) e6c5ce6f
- function getVariableMetadata(uint256 tokenId)
- public
- view
- returns (bytes memory)
- {
- require(false, stub_error);
- tokenId;
- dummy;
- return hex"";
- }
-
// Selector: mintBulk(address,uint256[]) 44a9945e
function mintBulk(address to, uint256[] memory tokenIds)
public
@@ -354,5 +352,6 @@
ERC721Enumerable,
ERC721UniqueExtensions,
ERC721Mintable,
- ERC721Burnable
+ ERC721Burnable,
+ CollectionProperties
{}
pallets/nonfungible/src/weights.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/weights.rs
+++ b/pallets/nonfungible/src/weights.rs
@@ -45,7 +45,6 @@
fn approve() -> Weight;
fn transfer_from() -> Weight;
fn burn_from() -> Weight;
- fn set_variable_metadata(b: u32, ) -> Weight;
}
/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.
@@ -155,12 +154,6 @@
(27_580_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
- }
- // Storage: Nonfungible TokenData (r:1 w:1)
- fn set_variable_metadata(_b: u32, ) -> Weight {
- (7_700_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(1 as Weight))
- .saturating_add(T::DbWeight::get().writes(1 as Weight))
}
}
@@ -270,11 +263,5 @@
(27_580_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
- }
- // Storage: Nonfungible TokenData (r:1 w:1)
- fn set_variable_metadata(_b: u32, ) -> Weight {
- (7_700_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(1 as Weight))
- .saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
}
pallets/refungible/Cargo.tomldiffbeforeafterboth--- a/pallets/refungible/Cargo.toml
+++ b/pallets/refungible/Cargo.toml
@@ -24,6 +24,7 @@
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
+struct-versioning = { path = "../../crates/struct-versioning" }
[features]
default = ["std"]
pallets/refungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/refungible/src/benchmarking.rs
+++ b/pallets/refungible/src/benchmarking.rs
@@ -31,10 +31,8 @@
users: impl IntoIterator<Item = (CrossAccountId, u128)>,
) -> CreateRefungibleExData<CrossAccountId> {
let const_data = create_data::<CUSTOM_DATA_LIMIT>();
- let variable_data = create_data::<CUSTOM_DATA_LIMIT>();
CreateRefungibleExData {
const_data,
- variable_data,
users: users
.into_iter()
.collect::<BTreeMap<_, _>>()
@@ -203,14 +201,4 @@
let item = create_max_item(&collection, &owner, [(sender.clone(), 200)])?;
<Pallet<T>>::set_allowance(&collection, &sender, &burner, item, 200)?;
}: {<Pallet<T>>::burn_from(&collection, &burner, &sender, item, 200, &Unlimited)?}
-
- set_variable_metadata {
- let b in 0..CUSTOM_DATA_LIMIT;
- bench_init!{
- owner: sub; collection: collection(owner);
- sender: cross_from_sub(owner);
- };
- let item = create_max_item(&collection, &sender, [(sender.clone(), 200)])?;
- let data = create_var_data(b).try_into().unwrap();
- }: {<Pallet<T>>::set_variable_metadata(&collection, &sender, item, data)?}
}
pallets/refungible/src/common.rsdiffbeforeafterboth--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -17,9 +17,9 @@
use core::marker::PhantomData;
use sp_std::collections::btree_map::BTreeMap;
-use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};
+use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight};
use up_data_structs::{
- CollectionId, TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData,
+ CollectionId, TokenId, CreateItemExData, CreateRefungibleExData,
budget::Budget, Property, PropertyKey, PropertyKeyPermission,
};
use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
@@ -110,10 +110,6 @@
fn burn_from() -> Weight {
<SelfWeightOf<T>>::burn_from()
- }
-
- fn set_variable_metadata(bytes: u32) -> Weight {
- <SelfWeightOf<T>>::set_variable_metadata(bytes)
}
}
@@ -124,7 +120,6 @@
match data {
up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateRefungibleExData {
const_data: data.const_data,
- variable_data: data.variable_data,
users: {
let mut out = BTreeMap::new();
out.insert(to.clone(), data.pieces);
@@ -306,19 +301,6 @@
fail!(<Error<T>>::SettingPropertiesNotAllowed)
}
- fn set_variable_metadata(
- &self,
- sender: T::CrossAccountId,
- token: TokenId,
- data: BoundedVec<u8, CustomDataLimit>,
- ) -> DispatchResultWithPostInfo {
- let len = data.len();
- with_weight(
- <Pallet<T>>::set_variable_metadata(self, &sender, token, data),
- <CommonWeights<T>>::set_variable_metadata(len as u32),
- )
- }
-
fn check_nesting(
&self,
_sender: <T>::CrossAccountId,
@@ -355,11 +337,6 @@
fn const_metadata(&self, token: TokenId) -> Vec<u8> {
<TokenData<T>>::get((self.id, token))
.const_data
- .into_inner()
- }
- fn variable_metadata(&self, token: TokenId) -> Vec<u8> {
- <TokenData<T>>::get((self.id, token))
- .variable_data
.into_inner()
}
pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -41,16 +41,20 @@
pub mod weights;
pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
+#[struct_versioning::versioned(version = 2, upper)]
#[derive(Encode, Decode, Default, TypeInfo, MaxEncodedLen)]
pub struct ItemData {
pub const_data: BoundedVec<u8, CustomDataLimit>,
+
+ #[version(..2)]
pub variable_data: BoundedVec<u8, CustomDataLimit>,
}
#[frame_support::pallet]
pub mod pallet {
use super::*;
- use frame_support::{Blake2_128, Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key};
+ use frame_support::{Blake2_128, Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key, traits::StorageVersion};
+ use frame_system::pallet_prelude::*;
use up_data_structs::{CollectionId, TokenId};
use super::weights::WeightInfo;
@@ -73,7 +77,10 @@
type WeightInfo: WeightInfo;
}
+ const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
+
#[pallet::pallet]
+ #[pallet::storage_version(STORAGE_VERSION)]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
@@ -146,6 +153,19 @@
Value = u128,
QueryKind = ValueQuery,
>;
+
+ #[pallet::hooks]
+ impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
+ fn on_runtime_upgrade() -> Weight {
+ if StorageVersion::get::<Pallet<T>>() < StorageVersion::new(1) {
+ <TokenData<T>>::translate_values::<ItemDataVersion1, _>(|v| {
+ Some(<ItemDataVersion2>::from(v))
+ })
+ }
+
+ 0
+ }
+ }
}
pub struct RefungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);
@@ -494,7 +514,6 @@
(collection.id, token_id),
ItemData {
const_data: token.const_data,
- variable_data: token.variable_data,
},
);
for (user, amount) in token.users.into_iter() {
@@ -643,31 +662,6 @@
if let Some(allowance) = allowance {
Self::set_allowance_unchecked(collection, from, spender, token, allowance);
}
- Ok(())
- }
-
- pub fn set_variable_metadata(
- collection: &RefungibleHandle<T>,
- sender: &T::CrossAccountId,
- token: TokenId,
- data: BoundedVec<u8, CustomDataLimit>,
- ) -> DispatchResult {
- collection.check_can_update_meta(
- sender,
- &T::CrossAccountId::from_sub(collection.owner.clone()),
- )?;
-
- let token_data = <TokenData<T>>::get((collection.id, token));
-
- // =========
-
- <TokenData<T>>::insert(
- (collection.id, token),
- ItemData {
- variable_data: data,
- ..token_data
- },
- );
Ok(())
}
pallets/refungible/src/weights.rsdiffbeforeafterboth--- a/pallets/refungible/src/weights.rs
+++ b/pallets/refungible/src/weights.rs
@@ -53,7 +53,6 @@
fn transfer_from_removing() -> Weight;
fn transfer_from_creating_removing() -> Weight;
fn burn_from() -> Weight;
- fn set_variable_metadata(b: u32, ) -> Weight;
}
/// Weights for pallet_refungible using the Substrate node and recommended hardware.
@@ -242,12 +241,6 @@
(42_043_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(7 as Weight))
- }
- // Storage: Refungible TokenData (r:1 w:1)
- fn set_variable_metadata(_b: u32, ) -> Weight {
- (7_364_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(1 as Weight))
- .saturating_add(T::DbWeight::get().writes(1 as Weight))
}
}
@@ -436,11 +429,5 @@
(42_043_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(7 as Weight))
- }
- // Storage: Refungible TokenData (r:1 w:1)
- fn set_variable_metadata(_b: u32, ) -> Weight {
- (7_364_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(1 as Weight))
- .saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
}
pallets/unique/src/lib.rsdiffbeforeafterboth--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -38,7 +38,7 @@
CONST_ON_CHAIN_SCHEMA_LIMIT, OFFCHAIN_SCHEMA_LIMIT,
MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
AccessMode, CreateItemData, CollectionLimits, CollectionId, CollectionMode, TokenId,
- SchemaVersion, SponsorshipState, MetaUpdatePermission, CreateCollectionData, CustomDataLimit,
+ SchemaVersion, SponsorshipState, MetaUpdatePermission, CreateCollectionData,
CreateItemExData, budget, CollectionField, Property, PropertyKey, PropertyKeyPermission,
};
use pallet_evm::account::CrossAccountId;
@@ -238,9 +238,6 @@
pub ReFungibleTransferBasket get(fn refungible_transfer_basket): nmap hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;
//#endregion
- /// Variable metadata sponsoring
- /// Collection id (controlled?2), token id (controlled?2)
- pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;
/// Approval sponsoring
pub NftApproveBasket get(fn nft_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;
pub FungibleApproveBasket get(fn fungible_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;
@@ -333,7 +330,6 @@
<FungibleTransferBasket<T>>::remove_prefix(collection_id, None);
<ReFungibleTransferBasket<T>>::remove_prefix((collection_id,), None);
- <VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);
<NftApproveBasket<T>>::remove_prefix(collection_id, None);
<FungibleApproveBasket<T>>::remove_prefix(collection_id, None);
<RefungibleApproveBasket<T>>::remove_prefix((collection_id,), None);
@@ -929,31 +925,6 @@
let budget = budget::Value::new(2);
dispatch_call::<T, _>(collection_id, |d| d.transfer_from(sender, from, recipient, item_id, value, &budget))
- }
-
- /// Set off-chain data schema.
- ///
- /// # Permissions
- ///
- /// * Collection Owner
- /// * Collection Admin
- ///
- /// # Arguments
- ///
- /// * collection_id.
- ///
- /// * schema: String representing the offchain data schema.
- #[weight = T::CommonWeightInfo::set_variable_metadata(data.len() as u32)]
- #[transactional]
- pub fn set_variable_meta_data (
- origin,
- collection_id: CollectionId,
- item_id: TokenId,
- data: BoundedVec<u8, CustomDataLimit>,
- ) -> DispatchResultWithPostInfo {
- let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
-
- dispatch_call::<T, _>(collection_id, |d| d.set_variable_metadata(sender, item_id, data))
}
/// Set meta_update_permission value for particular collection
primitives/data-structs/src/lib.rsdiffbeforeafterboth--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -364,28 +364,6 @@
pub type CollectionPropertiesVec =
BoundedVec<Property, ConstU32<MAX_COLLECTION_PROPERTIES_ENCODE_LEN>>;
-#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]
-#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
-pub struct NftItemType<AccountId> {
- pub owner: AccountId,
- pub const_data: Vec<u8>,
- pub variable_data: Vec<u8>,
-}
-
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, TypeInfo)]
-#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
-pub struct FungibleItemType {
- pub value: u128,
-}
-
-#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]
-#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
-pub struct ReFungibleItemType<AccountId> {
- pub owner: Vec<Ownership<AccountId>>,
- pub const_data: Vec<u8>,
- pub variable_data: Vec<u8>,
-}
-
/// All fields are wrapped in `Option`s, where None means chain default
#[struct_versioning::versioned(version = 2, upper)]
#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
@@ -393,6 +371,8 @@
pub struct CollectionLimits {
pub account_token_ownership_limit: Option<u32>,
pub sponsored_data_size: Option<u32>,
+
+ /// FIXME should we delete this or repurpose it?
/// None - setVariableMetadata is not sponsored
/// Some(v) - setVariableMetadata is sponsored
/// if there is v block between txs
@@ -490,9 +470,6 @@
#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
#[derivative(Debug(format_with = "bounded::vec_debug"))]
pub const_data: BoundedVec<u8, CustomDataLimit>,
- #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
- #[derivative(Debug(format_with = "bounded::vec_debug"))]
- pub variable_data: BoundedVec<u8, CustomDataLimit>,
#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
#[derivative(Debug(format_with = "bounded::vec_debug"))]
@@ -512,9 +489,6 @@
#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
#[derivative(Debug(format_with = "bounded::vec_debug"))]
pub const_data: BoundedVec<u8, CustomDataLimit>,
- #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
- #[derivative(Debug(format_with = "bounded::vec_debug"))]
- pub variable_data: BoundedVec<u8, CustomDataLimit>,
pub pieces: u128,
}
@@ -545,8 +519,6 @@
pub struct CreateNftExData<CrossAccountId> {
#[derivative(Debug(format_with = "bounded::vec_debug"))]
pub const_data: BoundedVec<u8, CustomDataLimit>,
- #[derivative(Debug(format_with = "bounded::vec_debug"))]
- pub variable_data: BoundedVec<u8, CustomDataLimit>,
#[derivative(Debug(format_with = "bounded::vec_debug"))]
pub properties: CollectionPropertiesVec,
pub owner: CrossAccountId,
@@ -557,8 +529,6 @@
pub struct CreateRefungibleExData<CrossAccountId> {
#[derivative(Debug(format_with = "bounded::vec_debug"))]
pub const_data: BoundedVec<u8, CustomDataLimit>,
- #[derivative(Debug(format_with = "bounded::vec_debug"))]
- pub variable_data: BoundedVec<u8, CustomDataLimit>,
#[derivative(Debug(format_with = "bounded::map_debug"))]
pub users: BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,
}
@@ -586,8 +556,8 @@
impl CreateItemData {
pub fn data_size(&self) -> usize {
match self {
- CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),
- CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),
+ CreateItemData::NFT(data) => data.const_data.len(),
+ CreateItemData::ReFungible(data) => data.const_data.len(),
_ => 0,
}
}
primitives/rpc/src/lib.rsdiffbeforeafterboth--- a/primitives/rpc/src/lib.rs
+++ b/primitives/rpc/src/lib.rs
@@ -42,7 +42,6 @@
fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;
fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;
fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;
- fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;
fn collection_properties(collection: CollectionId, properties: Vec<Vec<u8>>) -> Result<Vec<Property>>;
runtime/common/src/runtime_apis.rsdiffbeforeafterboth--- a/runtime/common/src/runtime_apis.rs
+++ b/runtime/common/src/runtime_apis.rs
@@ -32,9 +32,6 @@
fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>, DispatchError> {
dispatch_unique_runtime!(collection.const_metadata(token))
}
- fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>, DispatchError> {
- dispatch_unique_runtime!(collection.variable_metadata(token))
- }
fn collection_properties(
collection: CollectionId,
runtime/common/src/sponsoring.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use core::marker::PhantomData;18use up_sponsorship::SponsorshipHandler;19use frame_support::{20 traits::{IsSubType},21 storage::{StorageMap, StorageDoubleMap, StorageNMap},22};23use up_data_structs::{24 CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MetaUpdatePermission,25 NFT_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId, CollectionMode,26 CreateItemData,27};28use sp_runtime::traits::Saturating;29use pallet_common::{CollectionHandle};30use pallet_evm::account::CrossAccountId;31use pallet_unique::{32 Call as UniqueCall, Config as UniqueConfig, FungibleApproveBasket, RefungibleApproveBasket,33 NftApproveBasket, VariableMetaDataBasket, CreateItemBasket, ReFungibleTransferBasket,34 FungibleTransferBasket, NftTransferBasket,35};36use pallet_fungible::Config as FungibleConfig;37use pallet_nonfungible::Config as NonfungibleConfig;38use pallet_refungible::Config as RefungibleConfig;3940pub trait Config: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}41impl<T> Config for T where T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}4243pub fn withdraw_transfer<T: Config>(44 collection: &CollectionHandle<T>,45 who: &T::CrossAccountId,46 item_id: &TokenId,47) -> Option<()> {48 // preliminary sponsoring correctness check49 match collection.mode {50 CollectionMode::NFT => {51 let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;52 if !owner.conv_eq(who) {53 return None;54 }55 }56 CollectionMode::Fungible(_) => {57 if item_id != &TokenId::default() {58 return None;59 }60 if <pallet_fungible::Balance<T>>::get((collection.id, who)) == 0 {61 return None;62 }63 }64 CollectionMode::ReFungible => {65 if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {66 return None;67 }68 }69 }7071 // sponsor timeout72 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;73 let limit = collection74 .limits75 .sponsor_transfer_timeout(match collection.mode {76 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,77 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,78 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,79 });8081 let last_tx_block = match collection.mode {82 CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, item_id),83 CollectionMode::Fungible(_) => {84 <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())85 }86 CollectionMode::ReFungible => {87 <ReFungibleTransferBasket<T>>::get((collection.id, item_id, who.as_sub()))88 }89 };9091 if let Some(last_tx_block) = last_tx_block {92 let timeout = last_tx_block + limit.into();93 if block_number < timeout {94 return None;95 }96 }9798 match collection.mode {99 CollectionMode::NFT => <NftTransferBasket<T>>::insert(collection.id, item_id, block_number),100 CollectionMode::Fungible(_) => {101 <FungibleTransferBasket<T>>::insert(collection.id, who.as_sub(), block_number)102 }103 CollectionMode::ReFungible => <ReFungibleTransferBasket<T>>::insert(104 (collection.id, item_id, who.as_sub()),105 block_number,106 ),107 };108109 Some(())110}111112pub fn withdraw_create_item<T: Config>(113 collection: &CollectionHandle<T>,114 who: &T::CrossAccountId,115 _properties: &CreateItemData,116) -> Option<()> {117 if _properties.data_size() as u32 > collection.limits.sponsored_data_size() {118 return None;119 }120121 // sponsor timeout122 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;123 let limit = collection124 .limits125 .sponsor_transfer_timeout(match _properties {126 CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,127 CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,128 CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,129 });130131 if let Some(last_tx_block) = <CreateItemBasket<T>>::get((collection.id, who.as_sub())) {132 let timeout = last_tx_block + limit.into();133 if block_number < timeout {134 return None;135 }136 }137138 CreateItemBasket::<T>::insert((collection.id, who.as_sub()), block_number);139140 Some(())141}142143pub fn withdraw_set_variable_meta_data<T: Config>(144 who: &T::CrossAccountId,145 collection: &CollectionHandle<T>,146 item_id: &TokenId,147 data: &[u8],148) -> Option<()> {149 // TODO: make it work for admins150 if collection.meta_update_permission != MetaUpdatePermission::ItemOwner {151 return None;152 }153 // preliminary sponsoring correctness check154 match collection.mode {155 CollectionMode::NFT => {156 let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;157 if !owner.conv_eq(who) {158 return None;159 }160 }161 CollectionMode::Fungible(_) => {162 if item_id != &TokenId::default() {163 return None;164 }165 if <pallet_fungible::Balance<T>>::get((collection.id, who)) == 0 {166 return None;167 }168 }169 CollectionMode::ReFungible => {170 if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {171 return None;172 }173 }174 }175176 // Can't sponsor fungible collection, this tx will be rejected177 // as invalid178 if matches!(collection.mode, CollectionMode::Fungible(_)) {179 return None;180 }181 if data.len() > collection.limits.sponsored_data_size() as usize {182 return None;183 }184185 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;186 let limit = collection.limits.sponsored_data_rate_limit()?;187188 if let Some(last_tx_block) = VariableMetaDataBasket::<T>::get(collection.id, item_id) {189 let timeout = last_tx_block + limit.into();190 if block_number < timeout {191 return None;192 }193 }194195 <VariableMetaDataBasket<T>>::insert(collection.id, item_id, block_number);196197 Some(())198}199200pub fn withdraw_approve<T: Config>(201 collection: &CollectionHandle<T>,202 who: &T::AccountId,203 item_id: &TokenId,204) -> Option<()> {205 // sponsor timeout206 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;207 let limit = collection.limits.sponsor_approve_timeout();208209 let last_tx_block = match collection.mode {210 CollectionMode::NFT => <NftApproveBasket<T>>::get(collection.id, item_id),211 CollectionMode::Fungible(_) => <FungibleApproveBasket<T>>::get(collection.id, who),212 CollectionMode::ReFungible => {213 <RefungibleApproveBasket<T>>::get((collection.id, item_id, who))214 }215 };216217 if let Some(last_tx_block) = last_tx_block {218 let timeout = last_tx_block + limit.into();219 if block_number < timeout {220 return None;221 }222 }223224 match collection.mode {225 CollectionMode::NFT => <NftApproveBasket<T>>::insert(collection.id, item_id, block_number),226 CollectionMode::Fungible(_) => {227 <FungibleApproveBasket<T>>::insert(collection.id, who, block_number)228 }229 CollectionMode::ReFungible => {230 <RefungibleApproveBasket<T>>::insert((collection.id, item_id, who), block_number)231 }232 };233234 Some(())235}236237fn load<T: UniqueConfig>(id: CollectionId) -> Option<(T::AccountId, CollectionHandle<T>)> {238 let collection = CollectionHandle::new(id)?;239 let sponsor = collection.sponsorship.sponsor().cloned()?;240 Some((sponsor, collection))241}242243pub struct UniqueSponsorshipHandler<T>(PhantomData<T>);244impl<T, C> SponsorshipHandler<T::AccountId, C> for UniqueSponsorshipHandler<T>245where246 T: Config,247 C: IsSubType<UniqueCall<T>>,248{249 fn get_sponsor(who: &T::AccountId, call: &C) -> Option<T::AccountId> {250 match IsSubType::<UniqueCall<T>>::is_sub_type(call)? {251 UniqueCall::create_item {252 collection_id,253 data,254 ..255 } => {256 let (sponsor, collection) = load(*collection_id)?;257 withdraw_create_item::<T>(258 &collection,259 &T::CrossAccountId::from_sub(who.clone()),260 data,261 )262 .map(|()| sponsor)263 }264 UniqueCall::transfer {265 collection_id,266 item_id,267 ..268 } => {269 let (sponsor, collection) = load(*collection_id)?;270 withdraw_transfer::<T>(271 &collection,272 &T::CrossAccountId::from_sub(who.clone()),273 item_id,274 )275 .map(|()| sponsor)276 }277 UniqueCall::transfer_from {278 collection_id,279 item_id,280 from,281 ..282 } => {283 let (sponsor, collection) = load(*collection_id)?;284 withdraw_transfer::<T>(&collection, from, item_id).map(|()| sponsor)285 }286 UniqueCall::approve {287 collection_id,288 item_id,289 ..290 } => {291 let (sponsor, collection) = load(*collection_id)?;292 withdraw_approve::<T>(&collection, who, item_id).map(|()| sponsor)293 }294 UniqueCall::set_variable_meta_data {295 collection_id,296 item_id,297 data,298 } => {299 let (sponsor, collection) = load(*collection_id)?;300 withdraw_set_variable_meta_data::<T>(301 &T::CrossAccountId::from_sub(who.clone()),302 &collection,303 item_id,304 data,305 )306 .map(|()| sponsor)307 }308 _ => None,309 }310 }311}312313pub trait SponsorshipPredict<T: Config> {314 fn predict(collection: CollectionId, account: T::CrossAccountId, token: TokenId) -> Option<u64>315 where316 u64: From<<T as frame_system::Config>::BlockNumber>;317}318319pub struct UniqueSponsorshipPredict<T>(PhantomData<T>);320321impl<T: Config> SponsorshipPredict<T> for UniqueSponsorshipPredict<T> {322 fn predict(collection_id: CollectionId, who: T::CrossAccountId, token: TokenId) -> Option<u64>323 where324 u64: From<<T as frame_system::Config>::BlockNumber>,325 {326 let collection = <CollectionHandle<T>>::try_get(collection_id).ok()?;327 let _ = collection.sponsorship.sponsor()?;328329 // sponsor timeout330 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;331 let limit = collection332 .limits333 .sponsor_transfer_timeout(match collection.mode {334 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,335 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,336 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,337 });338339 let last_tx_block = match collection.mode {340 CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, token),341 CollectionMode::Fungible(_) => {342 <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())343 }344 CollectionMode::ReFungible => {345 <ReFungibleTransferBasket<T>>::get((collection.id, token, who.as_sub()))346 }347 };348349 if let Some(last_tx_block) = last_tx_block {350 return Some(351 last_tx_block352 .saturating_add(limit.into())353 .saturating_sub(block_number)354 .into(),355 );356 }357358 let token_exists = match collection.mode {359 CollectionMode::NFT => {360 <pallet_nonfungible::TokenData<T>>::contains_key((collection.id, token))361 }362 CollectionMode::Fungible(_) => token == TokenId::default(),363 CollectionMode::ReFungible => {364 <pallet_refungible::TotalSupply<T>>::contains_key((collection.id, token))365 }366 };367368 if token_exists {369 Some(0)370 } else {371 None372 }373 }374}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use core::marker::PhantomData;18use up_sponsorship::SponsorshipHandler;19use frame_support::{20 traits::{IsSubType},21 storage::{StorageMap, StorageDoubleMap, StorageNMap},22};23use up_data_structs::{24 CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,25 NFT_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId, CollectionMode,26 CreateItemData,27};28use sp_runtime::traits::Saturating;29use pallet_common::{CollectionHandle};30use pallet_evm::account::CrossAccountId;31use pallet_unique::{32 Call as UniqueCall, Config as UniqueConfig, FungibleApproveBasket, RefungibleApproveBasket,33 NftApproveBasket, CreateItemBasket, ReFungibleTransferBasket,34 FungibleTransferBasket, NftTransferBasket,35};36use pallet_fungible::Config as FungibleConfig;37use pallet_nonfungible::Config as NonfungibleConfig;38use pallet_refungible::Config as RefungibleConfig;3940pub trait Config: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}41impl<T> Config for T where T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig {}4243pub fn withdraw_transfer<T: Config>(44 collection: &CollectionHandle<T>,45 who: &T::CrossAccountId,46 item_id: &TokenId,47) -> Option<()> {48 // preliminary sponsoring correctness check49 match collection.mode {50 CollectionMode::NFT => {51 let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;52 if !owner.conv_eq(who) {53 return None;54 }55 }56 CollectionMode::Fungible(_) => {57 if item_id != &TokenId::default() {58 return None;59 }60 if <pallet_fungible::Balance<T>>::get((collection.id, who)) == 0 {61 return None;62 }63 }64 CollectionMode::ReFungible => {65 if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {66 return None;67 }68 }69 }7071 // sponsor timeout72 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;73 let limit = collection74 .limits75 .sponsor_transfer_timeout(match collection.mode {76 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,77 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,78 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,79 });8081 let last_tx_block = match collection.mode {82 CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, item_id),83 CollectionMode::Fungible(_) => {84 <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())85 }86 CollectionMode::ReFungible => {87 <ReFungibleTransferBasket<T>>::get((collection.id, item_id, who.as_sub()))88 }89 };9091 if let Some(last_tx_block) = last_tx_block {92 let timeout = last_tx_block + limit.into();93 if block_number < timeout {94 return None;95 }96 }9798 match collection.mode {99 CollectionMode::NFT => <NftTransferBasket<T>>::insert(collection.id, item_id, block_number),100 CollectionMode::Fungible(_) => {101 <FungibleTransferBasket<T>>::insert(collection.id, who.as_sub(), block_number)102 }103 CollectionMode::ReFungible => <ReFungibleTransferBasket<T>>::insert(104 (collection.id, item_id, who.as_sub()),105 block_number,106 ),107 };108109 Some(())110}111112pub fn withdraw_create_item<T: Config>(113 collection: &CollectionHandle<T>,114 who: &T::CrossAccountId,115 _properties: &CreateItemData,116) -> Option<()> {117 if _properties.data_size() as u32 > collection.limits.sponsored_data_size() {118 return None;119 }120121 // sponsor timeout122 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;123 let limit = collection124 .limits125 .sponsor_transfer_timeout(match _properties {126 CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,127 CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,128 CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,129 });130131 if let Some(last_tx_block) = <CreateItemBasket<T>>::get((collection.id, who.as_sub())) {132 let timeout = last_tx_block + limit.into();133 if block_number < timeout {134 return None;135 }136 }137138 CreateItemBasket::<T>::insert((collection.id, who.as_sub()), block_number);139140 Some(())141}142143pub fn withdraw_approve<T: Config>(144 collection: &CollectionHandle<T>,145 who: &T::AccountId,146 item_id: &TokenId,147) -> Option<()> {148 // sponsor timeout149 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;150 let limit = collection.limits.sponsor_approve_timeout();151152 let last_tx_block = match collection.mode {153 CollectionMode::NFT => <NftApproveBasket<T>>::get(collection.id, item_id),154 CollectionMode::Fungible(_) => <FungibleApproveBasket<T>>::get(collection.id, who),155 CollectionMode::ReFungible => {156 <RefungibleApproveBasket<T>>::get((collection.id, item_id, who))157 }158 };159160 if let Some(last_tx_block) = last_tx_block {161 let timeout = last_tx_block + limit.into();162 if block_number < timeout {163 return None;164 }165 }166167 match collection.mode {168 CollectionMode::NFT => <NftApproveBasket<T>>::insert(collection.id, item_id, block_number),169 CollectionMode::Fungible(_) => {170 <FungibleApproveBasket<T>>::insert(collection.id, who, block_number)171 }172 CollectionMode::ReFungible => {173 <RefungibleApproveBasket<T>>::insert((collection.id, item_id, who), block_number)174 }175 };176177 Some(())178}179180fn load<T: UniqueConfig>(id: CollectionId) -> Option<(T::AccountId, CollectionHandle<T>)> {181 let collection = CollectionHandle::new(id)?;182 let sponsor = collection.sponsorship.sponsor().cloned()?;183 Some((sponsor, collection))184}185186pub struct UniqueSponsorshipHandler<T>(PhantomData<T>);187impl<T, C> SponsorshipHandler<T::AccountId, C> for UniqueSponsorshipHandler<T>188where189 T: Config,190 C: IsSubType<UniqueCall<T>>,191{192 fn get_sponsor(who: &T::AccountId, call: &C) -> Option<T::AccountId> {193 match IsSubType::<UniqueCall<T>>::is_sub_type(call)? {194 UniqueCall::create_item {195 collection_id,196 data,197 ..198 } => {199 let (sponsor, collection) = load(*collection_id)?;200 withdraw_create_item::<T>(201 &collection,202 &T::CrossAccountId::from_sub(who.clone()),203 data,204 )205 .map(|()| sponsor)206 }207 UniqueCall::transfer {208 collection_id,209 item_id,210 ..211 } => {212 let (sponsor, collection) = load(*collection_id)?;213 withdraw_transfer::<T>(214 &collection,215 &T::CrossAccountId::from_sub(who.clone()),216 item_id,217 )218 .map(|()| sponsor)219 }220 UniqueCall::transfer_from {221 collection_id,222 item_id,223 from,224 ..225 } => {226 let (sponsor, collection) = load(*collection_id)?;227 withdraw_transfer::<T>(&collection, from, item_id).map(|()| sponsor)228 }229 UniqueCall::approve {230 collection_id,231 item_id,232 ..233 } => {234 let (sponsor, collection) = load(*collection_id)?;235 withdraw_approve::<T>(&collection, who, item_id).map(|()| sponsor)236 }237 _ => None,238 }239 }240}241242pub trait SponsorshipPredict<T: Config> {243 fn predict(collection: CollectionId, account: T::CrossAccountId, token: TokenId) -> Option<u64>244 where245 u64: From<<T as frame_system::Config>::BlockNumber>;246}247248pub struct UniqueSponsorshipPredict<T>(PhantomData<T>);249250impl<T: Config> SponsorshipPredict<T> for UniqueSponsorshipPredict<T> {251 fn predict(collection_id: CollectionId, who: T::CrossAccountId, token: TokenId) -> Option<u64>252 where253 u64: From<<T as frame_system::Config>::BlockNumber>,254 {255 let collection = <CollectionHandle<T>>::try_get(collection_id).ok()?;256 let _ = collection.sponsorship.sponsor()?;257258 // sponsor timeout259 let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;260 let limit = collection261 .limits262 .sponsor_transfer_timeout(match collection.mode {263 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,264 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,265 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,266 });267268 let last_tx_block = match collection.mode {269 CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, token),270 CollectionMode::Fungible(_) => {271 <FungibleTransferBasket<T>>::get(collection.id, who.as_sub())272 }273 CollectionMode::ReFungible => {274 <ReFungibleTransferBasket<T>>::get((collection.id, token, who.as_sub()))275 }276 };277278 if let Some(last_tx_block) = last_tx_block {279 return Some(280 last_tx_block281 .saturating_add(limit.into())282 .saturating_sub(block_number)283 .into(),284 );285 }286287 let token_exists = match collection.mode {288 CollectionMode::NFT => {289 <pallet_nonfungible::TokenData<T>>::contains_key((collection.id, token))290 }291 CollectionMode::Fungible(_) => token == TokenId::default(),292 CollectionMode::ReFungible => {293 <pallet_refungible::TotalSupply<T>>::contains_key((collection.id, token))294 }295 };296297 if token_exists {298 Some(0)299 } else {300 None301 }302 }303}runtime/common/src/weights.rsdiffbeforeafterboth--- a/runtime/common/src/weights.rs
+++ b/runtime/common/src/weights.rs
@@ -86,10 +86,6 @@
dispatch_weight::<T>() + max_weight_of!(transfer_from())
}
- fn set_variable_metadata(bytes: u32) -> Weight {
- dispatch_weight::<T>() + max_weight_of!(set_variable_metadata(bytes))
- }
-
fn burn_from() -> Weight {
dispatch_weight::<T>() + max_weight_of!(burn_from())
}
runtime/tests/src/tests.rsdiffbeforeafterboth--- a/runtime/tests/src/tests.rs
+++ b/runtime/tests/src/tests.rs
@@ -47,7 +47,6 @@
fn default_nft_data() -> CreateNftData {
CreateNftData {
const_data: vec![1, 2, 3].try_into().unwrap(),
- variable_data: vec![3, 2, 1].try_into().unwrap(),
}
}
@@ -58,7 +57,6 @@
fn default_re_fungible_data() -> CreateReFungibleData {
CreateReFungibleData {
const_data: vec![1, 2, 3].try_into().unwrap(),
- variable_data: vec![3, 2, 1].try_into().unwrap(),
pieces: 1023,
}
}
@@ -215,7 +213,6 @@
let item = <pallet_nonfungible::TokenData<Test>>::get((collection_id, 1)).unwrap();
assert_eq!(item.const_data, data.const_data.into_inner());
- assert_eq!(item.variable_data, data.variable_data.into_inner());
});
}
@@ -247,7 +244,6 @@
))
.unwrap();
assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
- assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
}
});
}
@@ -263,7 +259,6 @@
let balance =
<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));
assert_eq!(item.const_data, data.const_data.into_inner());
- assert_eq!(item.variable_data, data.variable_data.into_inner());
assert_eq!(balance, 1023);
});
}
@@ -299,7 +294,6 @@
let balance =
<pallet_refungible::Balance<Test>>::get((CollectionId(1), TokenId(1), account(1)));
assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
- assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
assert_eq!(balance, 1023);
}
});
@@ -413,7 +407,6 @@
create_test_item(collection_id, &data.clone().into());
let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));
assert_eq!(item.const_data, data.const_data.into_inner());
- assert_eq!(item.variable_data, data.variable_data.into_inner());
assert_eq!(
<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),
1
@@ -2427,117 +2420,6 @@
}
#[test]
-fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {
- new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
-
- let origin1 = Origin::signed(1);
-
- let data = default_nft_data();
- create_test_item(CollectionId(1), &data.into());
-
- let variable_data = b"test data".to_vec();
- assert_ok!(Unique::set_variable_meta_data(
- origin1,
- collection_id,
- TokenId(1),
- variable_data.clone().try_into().unwrap()
- ));
-
- assert_eq!(
- <pallet_nonfungible::TokenData<Test>>::get((collection_id, 1))
- .unwrap()
- .variable_data,
- variable_data
- );
- });
-}
-
-#[test]
-fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {
- new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
-
- let origin1 = Origin::signed(1);
-
- let data = default_re_fungible_data();
- create_test_item(collection_id, &data.into());
-
- let variable_data = b"test data".to_vec();
- assert_ok!(Unique::set_variable_meta_data(
- origin1,
- collection_id,
- TokenId(1),
- variable_data.clone().try_into().unwrap()
- ));
-
- assert_eq!(
- <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1))).variable_data,
- variable_data
- );
- });
-}
-
-#[test]
-fn set_variable_meta_data_on_fungible_token_fails() {
- new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
-
- let origin1 = Origin::signed(1);
-
- let data = default_fungible_data();
- create_test_item(collection_id, &data.into());
-
- let variable_data = b"test data".to_vec();
- assert_noop!(
- Unique::set_variable_meta_data(
- origin1,
- collection_id,
- TokenId(0),
- variable_data.try_into().unwrap()
- )
- .map_err(|e| e.error),
- <pallet_fungible::Error<Test>>::FungibleItemsDontHaveData
- );
- });
-}
-
-#[test]
-fn set_variable_meta_data_on_nft_with_item_owner_permission_flag() {
- new_test_ext().execute_with(|| {
- //default_limits();
-
- let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
-
- let origin1 = Origin::signed(1);
-
- let data = default_nft_data();
- create_test_item(collection_id, &data.into());
-
- assert_ok!(Unique::set_meta_update_permission_flag(
- origin1.clone(),
- collection_id,
- MetaUpdatePermission::ItemOwner,
- ));
-
- let variable_data = b"ten chars.".to_vec();
- assert_ok!(Unique::set_variable_meta_data(
- origin1,
- collection_id,
- TokenId(1),
- variable_data.clone().try_into().unwrap()
- ));
-
- assert_eq!(
- <pallet_nonfungible::TokenData<Test>>::get((collection_id, TokenId(1)))
- .unwrap()
- .variable_data,
- variable_data
- );
- });
-}
-
-#[test]
fn collection_transfer_flag_works() {
new_test_ext().execute_with(|| {
let origin1 = Origin::signed(1);
@@ -2590,105 +2472,6 @@
}
#[test]
-fn set_variable_meta_data_on_nft_with_admin_flag() {
- new_test_ext().execute_with(|| {
- // default_limits();
-
- let collection_id =
- create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
-
- let origin1 = Origin::signed(1);
- let origin2 = Origin::signed(2);
-
- assert_ok!(Unique::set_mint_permission(
- origin2.clone(),
- collection_id,
- true
- ));
- assert_ok!(Unique::add_to_allow_list(
- origin2.clone(),
- collection_id,
- account(1)
- ));
-
- assert_ok!(Unique::add_collection_admin(
- origin2.clone(),
- collection_id,
- account(1)
- ));
-
- let data = default_nft_data();
- create_test_item(collection_id, &data.into());
-
- assert_ok!(Unique::set_meta_update_permission_flag(
- origin2.clone(),
- collection_id,
- MetaUpdatePermission::Admin,
- ));
-
- let variable_data = b"test.".to_vec();
- assert_ok!(Unique::set_variable_meta_data(
- origin1,
- collection_id,
- TokenId(1),
- variable_data.clone().try_into().unwrap()
- ));
-
- assert_eq!(
- <pallet_nonfungible::TokenData<Test>>::get((collection_id, 1))
- .unwrap()
- .variable_data,
- variable_data
- );
- });
-}
-
-#[test]
-fn set_variable_meta_data_on_nft_with_admin_flag_neg() {
- new_test_ext().execute_with(|| {
- // default_limits();
-
- let collection_id =
- create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
-
- let origin1 = Origin::signed(1);
- let origin2 = Origin::signed(2);
-
- assert_ok!(Unique::set_mint_permission(
- origin2.clone(),
- collection_id,
- true
- ));
- assert_ok!(Unique::add_to_allow_list(
- origin2.clone(),
- collection_id,
- account(1)
- ));
-
- let data = default_nft_data();
- create_test_item(collection_id, &data.into());
-
- assert_ok!(Unique::set_meta_update_permission_flag(
- origin2.clone(),
- collection_id,
- MetaUpdatePermission::Admin,
- ));
-
- let variable_data = b"test.".to_vec();
- assert_noop!(
- Unique::set_variable_meta_data(
- origin1,
- collection_id,
- TokenId(1),
- variable_data.try_into().unwrap()
- )
- .map_err(|e| e.error),
- CommonError::<Test>::NoPermission
- );
- });
-}
-
-#[test]
fn set_variable_meta_flag_after_freeze() {
new_test_ext().execute_with(|| {
// default_limits();
@@ -2710,38 +2493,6 @@
MetaUpdatePermission::Admin
),
CommonError::<Test>::MetadataFlagFrozen
- );
- });
-}
-
-#[test]
-fn set_variable_meta_data_on_nft_with_none_flag_neg() {
- new_test_ext().execute_with(|| {
- // default_limits();
-
- let collection_id =
- create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
- let origin1 = Origin::signed(1);
-
- let data = default_nft_data();
- create_test_item(collection_id, &data.into());
-
- assert_ok!(Unique::set_meta_update_permission_flag(
- origin1.clone(),
- collection_id,
- MetaUpdatePermission::None,
- ));
-
- let variable_data = b"test.".to_vec();
- assert_noop!(
- Unique::set_variable_meta_data(
- origin1.clone(),
- collection_id,
- TokenId(1),
- variable_data.try_into().unwrap()
- )
- .map_err(|e| e.error),
- CommonError::<Test>::NoPermission
);
});
}
smart_contracs/transfer/lib.rsdiffbeforeafterboth--- a/smart_contracs/transfer/lib.rs
+++ b/smart_contracs/transfer/lib.rs
@@ -58,14 +58,12 @@
pub enum CreateItemData {
Nft {
const_data: Vec<u8>,
- variable_data: Vec<u8>,
},
Fungible {
value: u128,
},
ReFungible {
const_data: Vec<u8>,
- variable_data: Vec<u8>,
pieces: u128,
},
}
@@ -88,8 +86,6 @@
fn approve(spender: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128);
#[ink(extension = 4, returns_result = false)]
fn transfer_from(owner: DefaultAccountId, recipient: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128);
- #[ink(extension = 5, returns_result = false)]
- fn set_variable_meta_data(collection_id: u32, item_id: u32, data: Vec<u8>);
#[ink(extension = 6, returns_result = false)]
fn toggle_allow_list(collection_id: u32, address: DefaultAccountId, allowlisted: bool);
}
@@ -143,12 +139,6 @@
let _ = self.env()
.extension()
.transfer_from(owner, recipient, collection_id, item_id, amount);
- }
- #[ink(message)]
- pub fn set_variable_meta_data(&mut self, collection_id: u32, item_id: u32, data: Vec<u8>) {
- let _ = self.env()
- .extension()
- .set_variable_meta_data(collection_id, item_id, data);
}
#[ink(message)]
pub fn toggle_allow_list(&mut self, collection_id: u32, address: AccountId, allowlisted: bool) {