--- a/pallets/refungible/src/common.rs +++ b/pallets/refungible/src/common.rs @@ -10,8 +10,8 @@ use sp_std::vec::Vec; use crate::{ - AccountBalance, Allowance, Balance, Config, CreateItemData, DataKind, Error, Owned, Pallet, - RefungibleHandle, SelfWeightOf, TokenData, weights::WeightInfo, + AccountBalance, Allowance, Balance, Config, CreateItemData, Error, Owned, Pallet, + RefungibleHandle, SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted, }; pub struct CommonWeights(PhantomData); @@ -168,14 +168,18 @@ >::token_exists(self, token) } + fn last_token_id(&self) -> TokenId { + TokenId(>::get(self.id)) + } + fn token_owner(&self, _token: TokenId) -> T::CrossAccountId { T::CrossAccountId::default() } fn const_metadata(&self, token: TokenId) -> Vec { - >::get((self.id, token, DataKind::Constant)) + >::get((self.id, token)).const_data } fn variable_metadata(&self, token: TokenId) -> Vec { - >::get((self.id, token, DataKind::Variable)) + >::get((self.id, token)).variable_data } fn collection_tokens(&self) -> u32 { --- 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 = ::WeightInfo; +#[derive(Encode, Decode, Default)] +pub struct ItemData { + pub const_data: Vec, + pub variable_data: Vec, +} + #[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 = StorageMap; - #[derive(Encode, Decode)] - pub enum DataKind { - Constant, - Variable, - } - #[pallet::storage] pub(super) type TokenData = StorageNMap< - Key = ( - Key, - Key, - Key, - ), - Value = Vec, + Key = (Key, Key), + Value = ItemData, QueryKind = ValueQuery, >; @@ -185,7 +182,7 @@ .ok_or(ArithmeticError::Overflow)?; >::insert(collection.id, burnt); - >::remove_prefix((collection.id, token_id), None); + >::remove((collection.id, token_id)); >::remove((collection.id, token_id)); >::remove_prefix((collection.id, token_id), None); >::remove_prefix((collection.id, token_id), None); @@ -210,10 +207,15 @@ >::get((collection.id, token, owner.as_sub())) == amount, >::TokenValueTooLow ); + let account_balance = >::get((collection.id, owner.as_sub())) + .checked_sub(1) + // Should not occur + .ok_or(ArithmeticError::Underflow)?; // ========= >::remove((collection.id, owner.as_sub(), token)); + >::insert((collection.id, owner.as_sub()), account_balance); Self::burn_token(collection, token)?; >::deposit_event(CommonEvent::ItemDestroyed( collection.id, @@ -239,6 +241,7 @@ // ========= if balance == 0 { + >::remove((collection.id, owner.as_sub(), token)); >::remove((collection.id, token, owner.as_sub())); >::insert((collection.id, owner.as_sub()), account_balance); } else { @@ -330,13 +333,12 @@ >::insert((collection.id, token, to.as_sub()), balance_to); if let Some(account_balance_from) = account_balance_from { >::insert((collection.id, from.as_sub()), account_balance_from); + >::remove((collection.id, from.as_sub(), token)); } if let Some(account_balance_to) = account_balance_to { >::insert((collection.id, to.as_sub()), account_balance_to); + >::insert((collection.id, to.as_sub(), token), true); } - - >::remove((collection.id, from.as_sub(), token)); - >::insert((collection.id, to.as_sub(), token), true); } // TODO: ERC20 transfer event @@ -426,21 +428,16 @@ >::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; >::insert((collection.id, token_id), totals[i]); - if !token.const_data.is_empty() { - >::insert( - (collection.id, token_id, DataKind::Constant), - token.const_data, - ); - } - if !token.variable_data.is_empty() { - >::insert( - (collection.id, token_id, DataKind::Variable), - token.variable_data, - ); - } + >::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 = >::get((collection.id, token)); // ========= - >::insert((collection.id, token, DataKind::Variable), data); + >::insert( + (collection.id, token), + ItemData { + variable_data: data, + ..token_data + }, + ); Ok(()) }