difftreelog
refactor(refungible) merge TokenData
in: master
2 files changed
pallets/refungible/src/common.rsdiffbeforeafterboth1use core::marker::PhantomData;23use sp_std::collections::btree_map::BTreeMap;4use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight};5use nft_data_structs::TokenId;6use pallet_common::{7 CommonCollectionOperations, CommonWeightInfo, account::CrossAccountId, with_weight,8};9use sp_runtime::DispatchError;10use sp_std::vec::Vec;1112use crate::{13 AccountBalance, Allowance, Balance, Config, CreateItemData, DataKind, Error, Owned, Pallet,14 RefungibleHandle, SelfWeightOf, TokenData, weights::WeightInfo,15};1617pub struct CommonWeights<T: Config>(PhantomData<T>);18impl<T: Config> CommonWeightInfo for CommonWeights<T> {19 fn create_item() -> Weight {20 <SelfWeightOf<T>>::create_item()21 }2223 fn create_multiple_items(amount: u32) -> Weight {24 <SelfWeightOf<T>>::create_multiple_items(amount)25 }2627 fn burn_item() -> Weight {28 <SelfWeightOf<T>>::burn_item()29 }3031 fn transfer() -> Weight {32 <SelfWeightOf<T>>::transfer()33 }3435 fn approve() -> Weight {36 <SelfWeightOf<T>>::approve()37 }3839 fn transfer_from() -> Weight {40 <SelfWeightOf<T>>::transfer_from()41 }4243 fn set_variable_metadata(_bytes: u32) -> Weight {44 <SelfWeightOf<T>>::set_variable_metadata()45 }46}4748fn map_create_data<T: Config>(49 data: nft_data_structs::CreateItemData,50 to: &T::CrossAccountId,51) -> Result<CreateItemData<T>, DispatchError> {52 match data {53 nft_data_structs::CreateItemData::ReFungible(data) => Ok(CreateItemData {54 const_data: data.const_data,55 variable_data: data.variable_data,56 users: {57 let mut out = BTreeMap::new();58 out.insert(to.clone(), data.pieces);59 out60 },61 }),62 _ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),63 }64}6566impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {67 fn create_item(68 &self,69 sender: T::CrossAccountId,70 to: T::CrossAccountId,71 data: nft_data_structs::CreateItemData,72 ) -> DispatchResultWithPostInfo {73 with_weight(74 <Pallet<T>>::create_item(self, &sender, map_create_data(data, &to)?),75 <SelfWeightOf<T>>::create_item(),76 )77 }7879 fn create_multiple_items(80 &self,81 sender: T::CrossAccountId,82 to: T::CrossAccountId,83 data: Vec<nft_data_structs::CreateItemData>,84 ) -> DispatchResultWithPostInfo {85 let data = data86 .into_iter()87 .map(|d| map_create_data::<T>(d, &to))88 .collect::<Result<Vec<_>, DispatchError>>()?;8990 let amount = data.len();91 with_weight(92 <Pallet<T>>::create_multiple_items(self, &sender, data),93 <SelfWeightOf<T>>::create_multiple_items(amount as u32),94 )95 }9697 fn burn_item(98 &self,99 sender: T::CrossAccountId,100 token: TokenId,101 amount: u128,102 ) -> DispatchResultWithPostInfo {103 with_weight(104 <Pallet<T>>::burn(self, &sender, token, amount),105 <SelfWeightOf<T>>::burn_item(),106 )107 }108109 fn transfer(110 &self,111 from: T::CrossAccountId,112 to: T::CrossAccountId,113 token: TokenId,114 amount: u128,115 ) -> DispatchResultWithPostInfo {116 with_weight(117 <Pallet<T>>::transfer(&self, &from, &to, token, amount),118 <SelfWeightOf<T>>::transfer(),119 )120 }121122 fn approve(123 &self,124 sender: T::CrossAccountId,125 spender: T::CrossAccountId,126 token: TokenId,127 amount: u128,128 ) -> DispatchResultWithPostInfo {129 with_weight(130 <Pallet<T>>::set_allowance(&self, &sender, &spender, token, amount),131 <SelfWeightOf<T>>::approve(),132 )133 }134135 fn transfer_from(136 &self,137 sender: T::CrossAccountId,138 from: T::CrossAccountId,139 to: T::CrossAccountId,140 token: TokenId,141 amount: u128,142 ) -> DispatchResultWithPostInfo {143 with_weight(144 <Pallet<T>>::transfer_from(&self, &sender, &from, &to, token, amount),145 <SelfWeightOf<T>>::approve(),146 )147 }148149 fn set_variable_metadata(150 &self,151 sender: T::CrossAccountId,152 token: TokenId,153 data: Vec<u8>,154 ) -> DispatchResultWithPostInfo {155 with_weight(156 <Pallet<T>>::set_variable_metadata(&self, &sender, token, data),157 <SelfWeightOf<T>>::set_variable_metadata(),158 )159 }160161 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {162 <Owned<T>>::iter_prefix((self.id, account.as_sub()))163 .map(|(id, _)| id)164 .collect()165 }166167 fn token_exists(&self, token: TokenId) -> bool {168 <Pallet<T>>::token_exists(self, token)169 }170171 fn token_owner(&self, _token: TokenId) -> T::CrossAccountId {172 T::CrossAccountId::default()173 }174 fn const_metadata(&self, token: TokenId) -> Vec<u8> {175 <TokenData<T>>::get((self.id, token, DataKind::Constant))176 }177 fn variable_metadata(&self, token: TokenId) -> Vec<u8> {178 <TokenData<T>>::get((self.id, token, DataKind::Variable))179 }180181 fn collection_tokens(&self) -> u32 {182 <Pallet<T>>::total_supply(self)183 }184185 fn account_balance(&self, account: T::CrossAccountId) -> u32 {186 <AccountBalance<T>>::get((self.id, account.as_sub()))187 }188189 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {190 <Balance<T>>::get((self.id, token, account.as_sub()))191 }192193 fn allowance(194 &self,195 sender: T::CrossAccountId,196 spender: T::CrossAccountId,197 token: TokenId,198 ) -> u128 {199 <Allowance<T>>::get((self.id, token, sender.as_sub(), spender))200 }201}pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -11,6 +11,7 @@
use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
use core::ops::Deref;
+use codec::{Encode, Decode};
pub use pallet::*;
pub mod benchmarking;
@@ -24,10 +25,16 @@
}
pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
+#[derive(Encode, Decode, Default)]
+pub struct ItemData {
+ pub const_data: Vec<u8>,
+ pub variable_data: Vec<u8>,
+}
+
#[frame_support::pallet]
pub mod pallet {
+ use super::*;
use frame_support::{Blake2_128, Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key};
- use sp_std::vec::Vec;
use nft_data_structs::{CollectionId, TokenId};
use super::weights::WeightInfo;
@@ -55,20 +62,10 @@
pub(super) type TokensBurnt<T: Config> =
StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
- #[derive(Encode, Decode)]
- pub enum DataKind {
- Constant,
- Variable,
- }
-
#[pallet::storage]
pub(super) type TokenData<T: Config> = StorageNMap<
- Key = (
- Key<Twox64Concat, CollectionId>,
- Key<Twox64Concat, TokenId>,
- Key<Identity, DataKind>,
- ),
- Value = Vec<u8>,
+ Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
+ Value = ItemData,
QueryKind = ValueQuery,
>;
@@ -185,7 +182,7 @@
.ok_or(ArithmeticError::Overflow)?;
<TokensBurnt<T>>::insert(collection.id, burnt);
- <TokenData<T>>::remove_prefix((collection.id, token_id), None);
+ <TokenData<T>>::remove((collection.id, token_id));
<TotalSupply<T>>::remove((collection.id, token_id));
<Balance<T>>::remove_prefix((collection.id, token_id), None);
<Allowance<T>>::remove_prefix((collection.id, token_id), None);
@@ -210,10 +207,15 @@
<Balance<T>>::get((collection.id, token, owner.as_sub())) == amount,
<CommonError<T>>::TokenValueTooLow
);
+ let account_balance = <AccountBalance<T>>::get((collection.id, owner.as_sub()))
+ .checked_sub(1)
+ // Should not occur
+ .ok_or(ArithmeticError::Underflow)?;
// =========
<Owned<T>>::remove((collection.id, owner.as_sub(), token));
+ <AccountBalance<T>>::insert((collection.id, owner.as_sub()), account_balance);
Self::burn_token(collection, token)?;
<PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
collection.id,
@@ -239,6 +241,7 @@
// =========
if balance == 0 {
+ <Owned<T>>::remove((collection.id, owner.as_sub(), token));
<Balance<T>>::remove((collection.id, token, owner.as_sub()));
<AccountBalance<T>>::insert((collection.id, owner.as_sub()), account_balance);
} else {
@@ -330,13 +333,12 @@
<Balance<T>>::insert((collection.id, token, to.as_sub()), balance_to);
if let Some(account_balance_from) = account_balance_from {
<AccountBalance<T>>::insert((collection.id, from.as_sub()), account_balance_from);
+ <Owned<T>>::remove((collection.id, from.as_sub(), token));
}
if let Some(account_balance_to) = account_balance_to {
<AccountBalance<T>>::insert((collection.id, to.as_sub()), account_balance_to);
+ <Owned<T>>::insert((collection.id, to.as_sub(), token), true);
}
-
- <Owned<T>>::remove((collection.id, from.as_sub(), token));
- <Owned<T>>::insert((collection.id, to.as_sub(), token), true);
}
// TODO: ERC20 transfer event
@@ -426,21 +428,16 @@
<AccountBalance<T>>::insert((collection.id, account), balance);
}
for (i, token) in data.into_iter().enumerate() {
- let token_id = first_token_id + i as u32;
+ let token_id = first_token_id + i as u32 + 1;
<TotalSupply<T>>::insert((collection.id, token_id), totals[i]);
- if !token.const_data.is_empty() {
- <TokenData<T>>::insert(
- (collection.id, token_id, DataKind::Constant),
- token.const_data,
- );
- }
- if !token.variable_data.is_empty() {
- <TokenData<T>>::insert(
- (collection.id, token_id, DataKind::Variable),
- token.variable_data,
- );
- }
+ <TokenData<T>>::insert(
+ (collection.id, token_id),
+ ItemData {
+ const_data: token.const_data.into(),
+ variable_data: token.variable_data.into(),
+ },
+ );
for (user, amount) in token.users.into_iter() {
if amount == 0 {
continue;
@@ -554,10 +551,17 @@
)?;
collection.consume_sstore()?;
+ let token_data = <TokenData<T>>::get((collection.id, token));
// =========
- <TokenData<T>>::insert((collection.id, token, DataKind::Variable), data);
+ <TokenData<T>>::insert(
+ (collection.id, token),
+ ItemData {
+ variable_data: data,
+ ..token_data
+ },
+ );
Ok(())
}