git.delta.rocks / unique-network / refs/commits / 0999c791f8d4

difftreelog

fix correct gas metering

Yaroslav Bolyukin2021-08-18parent: #d614bc7.patch.diff
in: master

1 file changed

modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
34use frame_system::{self as system, ensure_signed, ensure_root};34use frame_system::{self as system, ensure_signed, ensure_root};
35use sp_core::H160;35use sp_core::H160;
36use sp_std::vec;36use sp_std::vec;
37use sp_runtime::sp_std::prelude::Vec;37use sp_runtime::{DispatchError, sp_std::prelude::Vec};
38use core::ops::{Deref, DerefMut};38use core::ops::{Deref, DerefMut};
39use nft_data_structs::{39use nft_data_structs::{
40 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, MAX_REFUNGIBLE_PIECES,40 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, MAX_REFUNGIBLE_PIECES,
202 pub fn log(&self, log: impl evm_coder::ToLog) -> DispatchResult {202 pub fn log(&self, log: impl evm_coder::ToLog) -> DispatchResult {
203 self.recorder.log_sub(log)203 self.recorder.log_sub(log)
204 }204 }
205 #[allow(dead_code)]
205 fn consume_gas(&self, gas: u64) -> DispatchResult {206 fn consume_gas(&self, gas: u64) -> DispatchResult {
206 self.recorder.consume_gas_sub(gas)207 self.recorder.consume_gas_sub(gas)
207 }208 }
209 fn consume_sload(&self) -> DispatchResult {
210 self.recorder.consume_sload_sub()
211 }
212 fn consume_sstore(&self) -> DispatchResult {
213 self.recorder.consume_sstore_sub()
214 }
208 pub fn submit_logs(self) -> DispatchResult {215 pub fn submit_logs(self) -> DispatchResult {
209 self.recorder.submit_logs()216 self.recorder.submit_logs()
210 }217 }
1276 item_id: TokenId,1283 item_id: TokenId,
1277 value: u128,1284 value: u128,
1278 ) -> DispatchResult {1285 ) -> DispatchResult {
1279 target_collection.consume_gas(2000000)?;
1280 // Limits check1286 // Limits check
1281 Self::is_correct_transfer(target_collection, recipient)?;1287 Self::is_correct_transfer(target_collection, recipient)?;
12821288
1283 // Transfer permissions check1289 // Transfer permissions check
1284 ensure!(1290 ensure!(
1285 Self::is_item_owner(sender, target_collection, item_id)1291 Self::is_item_owner(sender, target_collection, item_id)?
1286 || Self::is_owner_or_admin_permissions(target_collection, sender),1292 || Self::is_owner_or_admin_permissions(target_collection, sender)?,
1287 Error::<T>::NoPermission1293 Error::<T>::NoPermission
1288 );1294 );
12891295
1330 item_id: TokenId,1336 item_id: TokenId,
1331 amount: u128,1337 amount: u128,
1332 ) -> DispatchResult {1338 ) -> DispatchResult {
1333 collection.consume_gas(2000000)?;
1334 Self::token_exists(collection, item_id)?;1339 Self::token_exists(collection, item_id)?;
13351340
1336 // Transfer permissions check1341 // Transfer permissions check
1337 let bypasses_limits = collection.limits.owner_can_transfer1342 let bypasses_limits = collection.limits.owner_can_transfer
1338 && Self::is_owner_or_admin_permissions(collection, sender);1343 && Self::is_owner_or_admin_permissions(collection, sender)?;
13391344
1340 let allowance_limit = if bypasses_limits {1345 let allowance_limit = if bypasses_limits {
1341 None1346 None
1342 } else if let Some(amount) = Self::owned_amount(sender, collection, item_id) {1347 } else if let Some(amount) = Self::owned_amount(sender, collection, item_id)? {
1343 Some(amount)1348 Some(amount)
1344 } else {1349 } else {
1345 fail!(Error::<T>::NoPermission);1350 fail!(Error::<T>::NoPermission);
1350 Self::check_white_list(collection, spender)?;1355 Self::check_white_list(collection, spender)?;
1351 }1356 }
13521357
1358 collection.consume_sload()?;
1353 let allowance: u128 = amount1359 let allowance: u128 = amount
1354 .checked_add(<Allowances<T>>::get(1360 .checked_add(<Allowances<T>>::get(
1355 collection.id,1361 collection.id,
1359 if let Some(limit) = allowance_limit {1365 if let Some(limit) = allowance_limit {
1360 ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);1366 ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);
1361 }1367 }
1368 collection.consume_sstore()?;
1362 <Allowances<T>>::insert(1369 <Allowances<T>>::insert(
1363 collection.id,1370 collection.id,
1364 (item_id, sender.as_sub(), spender.as_sub()),1371 (item_id, sender.as_sub(), spender.as_sub()),
1401 item_id: TokenId,1408 item_id: TokenId,
1402 amount: u128,1409 amount: u128,
1403 ) -> DispatchResult {1410 ) -> DispatchResult {
1411 // Check approval
1404 collection.consume_gas(2000000)?;1412 collection.consume_sload()?;
1405 // Check approval
1406 let approval: u128 =1413 let approval: u128 =
1407 <Allowances<T>>::get(collection.id, (item_id, from.as_sub(), sender.as_sub()));1414 <Allowances<T>>::get(collection.id, (item_id, from.as_sub(), sender.as_sub()));
14081415
1413 ensure!(1420 ensure!(
1414 approval >= amount1421 approval >= amount
1415 || (collection.limits.owner_can_transfer1422 || (collection.limits.owner_can_transfer
1416 && Self::is_owner_or_admin_permissions(collection, sender)),1423 && Self::is_owner_or_admin_permissions(collection, sender)?),
1417 Error::<T>::NoPermission1424 Error::<T>::NoPermission
1418 );1425 );
14191426
14241431
1425 // Reduce approval by transferred amount or remove if remaining approval drops to 01432 // Reduce approval by transferred amount or remove if remaining approval drops to 0
1426 let allowance = approval.saturating_sub(amount);1433 let allowance = approval.saturating_sub(amount);
1434 collection.consume_sstore()?;
1427 if allowance > 0 {1435 if allowance > 0 {
1428 <Allowances<T>>::insert(1436 <Allowances<T>>::insert(
1429 collection.id,1437 collection.id,
14771485
1478 // Modify permissions check1486 // Modify permissions check
1479 ensure!(1487 ensure!(
1480 Self::is_item_owner(sender, collection, item_id)1488 Self::is_item_owner(sender, collection, item_id)?
1481 || Self::is_owner_or_admin_permissions(collection, sender),1489 || Self::is_owner_or_admin_permissions(collection, sender)?,
1482 Error::<T>::NoPermission1490 Error::<T>::NoPermission
1483 );1491 );
14841492
1519 value: u128,1527 value: u128,
1520 ) -> DispatchResult {1528 ) -> DispatchResult {
1521 ensure!(1529 ensure!(
1522 Self::is_item_owner(sender, collection, item_id)1530 Self::is_item_owner(sender, collection, item_id)?
1523 || (collection.limits.owner_can_transfer1531 || (collection.limits.owner_can_transfer
1524 && Self::is_owner_or_admin_permissions(collection, sender)),1532 && Self::is_owner_or_admin_permissions(collection, sender)?),
1525 Error::<T>::NoPermission1533 Error::<T>::NoPermission
1526 );1534 );
15271535
1563 let collection_id = collection.id;1571 let collection_id = collection.id;
15641572
1565 // check token limit and account token limit1573 // check token limit and account token limit
1574 collection.consume_sload()?;
1566 let account_items: u32 =1575 let account_items: u32 =
1567 <AddressTokens<T>>::get(collection_id, recipient.as_sub()).len() as u32;1576 <AddressTokens<T>>::get(collection_id, recipient.as_sub()).len() as u32;
1568 ensure!(1577 ensure!(
1601 Error::<T>::AccountTokenLimitExceeded1610 Error::<T>::AccountTokenLimitExceeded
1602 );1611 );
16031612
1604 if !Self::is_owner_or_admin_permissions(collection, sender) {1613 if !Self::is_owner_or_admin_permissions(collection, sender)? {
1605 ensure!(collection.mint_mode, Error::<T>::PublicMintingNotAllowed);1614 ensure!(collection.mint_mode, Error::<T>::PublicMintingNotAllowed);
1606 Self::check_white_list(collection, owner)?;1615 Self::check_white_list(collection, owner)?;
1607 Self::check_white_list(collection, sender)?;1616 Self::check_white_list(collection, sender)?;
1711 let collection_id = collection.id;1720 let collection_id = collection.id;
17121721
1713 // Does new owner already have an account?1722 // Does new owner already have an account?
1723 collection.consume_sload()?;
1714 let balance: u128 = <FungibleItemList<T>>::get(collection_id, owner.as_sub()).value;1724 let balance: u128 = <FungibleItemList<T>>::get(collection_id, owner.as_sub()).value;
17151725
1716 // Mint1726 // Mint
1717 let item = FungibleItemType {1727 let item = FungibleItemType {
1718 value: balance.checked_add(value).ok_or(Error::<T>::NumOverflow)?,1728 value: balance.checked_add(value).ok_or(Error::<T>::NumOverflow)?,
1719 };1729 };
1730 collection.consume_sstore()?;
1720 <FungibleItemList<T>>::insert(collection_id, owner.as_sub(), item);1731 <FungibleItemList<T>>::insert(collection_id, owner.as_sub(), item);
17211732
1722 // Update balance1733 // Update balance
1734 collection.consume_sload()?;
1723 let new_balance = <Balance<T>>::get(collection_id, owner.as_sub())1735 let new_balance = <Balance<T>>::get(collection_id, owner.as_sub())
1724 .checked_add(value)1736 .checked_add(value)
1725 .ok_or(Error::<T>::NumOverflow)?;1737 .ok_or(Error::<T>::NumOverflow)?;
1738 collection.consume_sstore()?;
1726 <Balance<T>>::insert(collection_id, owner.as_sub(), new_balance);1739 <Balance<T>>::insert(collection_id, owner.as_sub(), new_balance);
17271740
1741 collection.log(ERC20Events::Transfer {
1742 from: H160::default(),
1743 to: *owner.as_eth(),
1744 value: value.into(),
1745 })?;
1728 Self::deposit_event(RawEvent::ItemCreated(collection_id, 0, owner.clone()));1746 Self::deposit_event(RawEvent::ItemCreated(collection_id, 0, owner.clone()));
1729 Ok(())1747 Ok(())
1730 }1748 }
1746 let value = item_owner.fraction;1764 let value = item_owner.fraction;
1747 let owner = item_owner.owner.clone();1765 let owner = item_owner.owner.clone();
17481766
1749 Self::add_token_index(collection_id, current_index, &owner)?;1767 Self::add_token_index(collection, current_index, &owner)?;
17501768
1751 <ItemListIndex>::insert(collection_id, current_index);1769 <ItemListIndex>::insert(collection_id, current_index);
1752 <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);1770 <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);
1772 .ok_or(Error::<T>::NumOverflow)?;1790 .ok_or(Error::<T>::NumOverflow)?;
17731791
1774 let item_owner = item.owner.clone();1792 let item_owner = item.owner.clone();
1775 Self::add_token_index(collection_id, current_index, &item.owner)?;1793 Self::add_token_index(collection, current_index, &item.owner)?;
17761794
1777 <ItemListIndex>::insert(collection_id, current_index);1795 <ItemListIndex>::insert(collection_id, current_index);
1778 <NftItemList<T>>::insert(collection_id, current_index, item);1796 <NftItemList<T>>::insert(collection_id, current_index, item);
1810 .iter()1828 .iter()
1811 .find(|&i| i.owner == *owner)1829 .find(|&i| i.owner == *owner)
1812 .ok_or(Error::<T>::TokenNotFound)?;1830 .ok_or(Error::<T>::TokenNotFound)?;
1813 Self::remove_token_index(collection_id, item_id, owner)?;1831 Self::remove_token_index(collection, item_id, owner)?;
18141832
1815 // update balance1833 // update balance
1816 let new_balance = <Balance<T>>::get(collection_id, rft_balance.owner.as_sub())1834 let new_balance = <Balance<T>>::get(collection_id, rft_balance.owner.as_sub())
18431861
1844 let item =1862 let item =
1845 <NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;1863 <NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;
1846 Self::remove_token_index(collection_id, item_id, &item.owner)?;1864 Self::remove_token_index(collection, item_id, &item.owner)?;
18471865
1848 // update balance1866 // update balance
1849 let new_balance = <Balance<T>>::get(collection_id, item.owner.as_sub())1867 let new_balance = <Balance<T>>::get(collection_id, item.owner.as_sub())
1909 fn is_owner_or_admin_permissions(1927 fn is_owner_or_admin_permissions(
1910 collection: &CollectionHandle<T>,1928 collection: &CollectionHandle<T>,
1911 subject: &T::CrossAccountId,1929 subject: &T::CrossAccountId,
1912 ) -> bool {1930 ) -> Result<bool, DispatchError> {
1931 collection.consume_sload()?;
1913 *subject.as_sub() == collection.owner1932 Ok(*subject.as_sub() == collection.owner
1914 || <AdminList<T>>::get(collection.id).contains(subject)1933 || <AdminList<T>>::get(collection.id).contains(subject))
1915 }1934 }
19161935
1917 fn check_owner_or_admin_permissions(1936 fn check_owner_or_admin_permissions(
1918 collection: &CollectionHandle<T>,1937 collection: &CollectionHandle<T>,
1919 subject: &T::CrossAccountId,1938 subject: &T::CrossAccountId,
1920 ) -> DispatchResult {1939 ) -> DispatchResult {
1921 ensure!(1940 ensure!(
1922 Self::is_owner_or_admin_permissions(collection, subject),1941 Self::is_owner_or_admin_permissions(collection, subject)?,
1923 Error::<T>::NoPermission1942 Error::<T>::NoPermission
1924 );1943 );
19251944
1926 Ok(())1945 Ok(())
1927 }1946 }
19281947
1929 fn owned_amount(1948 fn owned_amount(
1949 subject: &T::CrossAccountId,
1950 collection: &CollectionHandle<T>,
1951 item_id: TokenId,
1952 ) -> Result<Option<u128>, DispatchError> {
1953 collection.consume_sload()?;
1954 Ok(Self::owned_amount_unchecked(subject, collection, item_id))
1955 }
1956
1957 fn owned_amount_unchecked(
1930 subject: &T::CrossAccountId,1958 subject: &T::CrossAccountId,
1931 target_collection: &CollectionHandle<T>,1959 target_collection: &CollectionHandle<T>,
1932 item_id: TokenId,1960 item_id: TokenId,
1953 subject: &T::CrossAccountId,1981 subject: &T::CrossAccountId,
1954 target_collection: &CollectionHandle<T>,1982 target_collection: &CollectionHandle<T>,
1955 item_id: TokenId,1983 item_id: TokenId,
1956 ) -> bool {1984 ) -> Result<bool, DispatchError> {
1957 match target_collection.mode {1985 Ok(match target_collection.mode {
1958 CollectionMode::Fungible(_) => true,1986 CollectionMode::Fungible(_) => true,
1959 _ => Self::owned_amount(subject, target_collection, item_id).is_some(),1987 _ => Self::owned_amount(subject, target_collection, item_id)?.is_some(),
1960 }1988 })
1961 }1989 }
19621990
1963 fn check_white_list(1991 fn check_white_list(
1964 collection: &CollectionHandle<T>,1992 collection: &CollectionHandle<T>,
1965 address: &T::CrossAccountId,1993 address: &T::CrossAccountId,
1966 ) -> DispatchResult {1994 ) -> DispatchResult {
1967 let collection_id = collection.id;1995 collection.consume_sload()?;
1968
1969 let mes = Error::<T>::AddresNotInWhiteList;
1970 ensure!(1996 ensure!(
1971 <WhiteList<T>>::contains_key(collection_id, address.as_sub()),1997 <WhiteList<T>>::contains_key(collection.id, address.as_sub()),
1972 mes1998 Error::<T>::AddresNotInWhiteList,
1973 );1999 );
1974
1975 Ok(())2000 Ok(())
2000 ) -> DispatchResult {2025 ) -> DispatchResult {
2001 let collection_id = collection.id;2026 let collection_id = collection.id;
20022027
2028 collection.consume_sload()?;
2003 let mut balance = <FungibleItemList<T>>::get(collection_id, owner.as_sub());2029 let mut balance = <FungibleItemList<T>>::get(collection_id, owner.as_sub());
2004 ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);2030 ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);
20052031
2006 // Send balance to recipient (updates balanceOf of recipient)2032 // Send balance to recipient (updates balanceOf of recipient)
2007 Self::add_fungible_item(collection, recipient, value)?;2033 Self::add_fungible_item(collection, recipient, value)?;
20082034
2009 // update balanceOf of sender2035 // update balanceOf of sender
2036 collection.consume_sstore()?;
2010 <Balance<T>>::insert(collection_id, owner.as_sub(), balance.value - value);2037 <Balance<T>>::insert(collection_id, owner.as_sub(), balance.value - value);
20112038
2012 // Reduce or remove sender2039 // Reduce or remove sender
2040 collection.consume_sstore()?;
2013 if balance.value == value {2041 if balance.value == value {
2014 <FungibleItemList<T>>::remove(collection_id, owner.as_sub());2042 <FungibleItemList<T>>::remove(collection_id, owner.as_sub());
2015 } else {2043 } else {
2041 new_owner: T::CrossAccountId,2069 new_owner: T::CrossAccountId,
2042 ) -> DispatchResult {2070 ) -> DispatchResult {
2043 let collection_id = collection.id;2071 let collection_id = collection.id;
2072 collection.consume_sload()?;
2044 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id)2073 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id)
2045 .ok_or(Error::<T>::TokenNotFound)?;2074 .ok_or(Error::<T>::TokenNotFound)?;
20462075
20532082
2054 ensure!(amount >= value, Error::<T>::TokenValueTooLow);2083 ensure!(amount >= value, Error::<T>::TokenValueTooLow);
20552084
2085 collection.consume_sload()?;
2056 // update balance2086 // update balance
2057 let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())2087 let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())
2058 .checked_sub(value)2088 .checked_sub(value)
2059 .ok_or(Error::<T>::NumOverflow)?;2089 .ok_or(Error::<T>::NumOverflow)?;
2090 collection.consume_sstore()?;
2060 <Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);2091 <Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);
20612092
2093 collection.consume_sload()?;
2062 let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())2094 let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())
2063 .checked_add(value)2095 .checked_add(value)
2064 .ok_or(Error::<T>::NumOverflow)?;2096 .ok_or(Error::<T>::NumOverflow)?;
2097 collection.consume_sstore()?;
2065 <Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);2098 <Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);
20662099
2067 let old_owner = item.owner.clone();2100 let old_owner = item.owner.clone();
2078 .find(|i| i.owner == owner)2111 .find(|i| i.owner == owner)
2079 .expect("old owner does present in refungible")2112 .expect("old owner does present in refungible")
2080 .owner = new_owner.clone();2113 .owner = new_owner.clone();
2114 collection.consume_sstore()?;
2081 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);2115 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);
20822116
2083 // update index collection2117 // update index collection
2084 Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;2118 Self::move_token_index(collection, item_id, &old_owner, &new_owner)?;
2085 } else {2119 } else {
2086 new_full_item2120 new_full_item
2087 .owner2121 .owner
2105 owner: new_owner.clone(),2139 owner: new_owner.clone(),
2106 fraction: value,2140 fraction: value,
2107 });2141 });
2108 Self::add_token_index(collection_id, item_id, &new_owner)?;2142 Self::add_token_index(collection, item_id, &new_owner)?;
2109 }2143 }
21102144
2145 collection.consume_sstore()?;
2111 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);2146 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);
2112 }2147 }
21132148
2129 new_owner: T::CrossAccountId,2164 new_owner: T::CrossAccountId,
2130 ) -> DispatchResult {2165 ) -> DispatchResult {
2131 let collection_id = collection.id;2166 let collection_id = collection.id;
2167 collection.consume_sload()?;
2132 let mut item =2168 let mut item =
2133 <NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;2169 <NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;
21342170
2135 ensure!(sender == item.owner, Error::<T>::MustBeTokenOwner);2171 ensure!(sender == item.owner, Error::<T>::MustBeTokenOwner);
21362172
2173 collection.consume_sload()?;
2137 // update balance2174 // update balance
2138 let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())2175 let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())
2139 .checked_sub(1)2176 .checked_sub(1)
2140 .ok_or(Error::<T>::NumOverflow)?;2177 .ok_or(Error::<T>::NumOverflow)?;
2178 collection.consume_sstore()?;
2141 <Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);2179 <Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);
21422180
2181 collection.consume_sload()?;
2143 let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())2182 let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())
2144 .checked_add(1)2183 .checked_add(1)
2145 .ok_or(Error::<T>::NumOverflow)?;2184 .ok_or(Error::<T>::NumOverflow)?;
2185 collection.consume_sstore()?;
2146 <Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);2186 <Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);
21472187
2148 // change owner2188 // change owner
2149 let old_owner = item.owner.clone();2189 let old_owner = item.owner.clone();
2150 item.owner = new_owner.clone();2190 item.owner = new_owner.clone();
2191 collection.consume_sstore()?;
2151 <NftItemList<T>>::insert(collection_id, item_id, item);2192 <NftItemList<T>>::insert(collection_id, item_id, item);
21522193
2153 // update index collection2194 // update index collection
2154 Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;2195 Self::move_token_index(collection, item_id, &old_owner, &new_owner)?;
21552196
2156 collection.log(ERC721Events::Transfer {2197 collection.log(ERC721Events::Transfer {
2157 from: *sender.as_eth(),2198 from: *sender.as_eth(),
2232 let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();2273 let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();
22332274
2234 Self::add_token_index(collection_id, current_index, &item.owner).unwrap();2275 Self::add_token_index(
2276 &CollectionHandle::get(collection_id).unwrap(),
2277 current_index,
2278 &item.owner,
2279 )
2280 .unwrap();
22352281
2251 let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();2297 let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();
22522298
2253 Self::add_token_index(collection_id, current_index, owner).unwrap();2299 Self::add_token_index(
2300 &CollectionHandle::get(collection_id).unwrap(),
2301 current_index,
2302 owner,
2303 )
2304 .unwrap();
22542305
2272 let owner = item.owner.first().unwrap().owner.clone();2323 let owner = item.owner.first().unwrap().owner.clone();
22732324
2274 Self::add_token_index(collection_id, current_index, &owner).unwrap();2325 Self::add_token_index(
2326 &CollectionHandle::get(collection_id).unwrap(),
2327 current_index,
2328 &owner,
2329 )
2330 .unwrap();
22752331
2283 }2339 }
22842340
2285 fn add_token_index(2341 fn add_token_index(
2286 collection_id: CollectionId,2342 collection: &CollectionHandle<T>,
2287 item_index: TokenId,2343 item_index: TokenId,
2288 owner: &T::CrossAccountId,2344 owner: &T::CrossAccountId,
2289 ) -> DispatchResult {2345 ) -> DispatchResult {
2290 // add to account limit2346 // add to account limit
2347 collection.consume_sload()?;
2291 if <AccountItemCount<T>>::contains_key(owner.as_sub()) {2348 if <AccountItemCount<T>>::contains_key(owner.as_sub()) {
2292 // bound Owned tokens by a single address2349 // bound Owned tokens by a single address
2350 collection.consume_sload()?;
2293 let count = <AccountItemCount<T>>::get(owner.as_sub());2351 let count = <AccountItemCount<T>>::get(owner.as_sub());
2294 ensure!(2352 ensure!(
2295 count < ChainLimit::get().account_token_ownership_limit,2353 count < ChainLimit::get().account_token_ownership_limit,
2296 Error::<T>::AddressOwnershipLimitExceeded2354 Error::<T>::AddressOwnershipLimitExceeded
2297 );2355 );
22982356
2357 collection.consume_sstore()?;
2299 <AccountItemCount<T>>::insert(2358 <AccountItemCount<T>>::insert(
2300 owner.as_sub(),2359 owner.as_sub(),
2301 count.checked_add(1).ok_or(Error::<T>::NumOverflow)?,2360 count.checked_add(1).ok_or(Error::<T>::NumOverflow)?,
2302 );2361 );
2303 } else {2362 } else {
2363 collection.consume_sstore()?;
2304 <AccountItemCount<T>>::insert(owner.as_sub(), 1);2364 <AccountItemCount<T>>::insert(owner.as_sub(), 1);
2305 }2365 }
23062366
2367 collection.consume_sload()?;
2307 let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.as_sub());2368 let list_exists = <AddressTokens<T>>::contains_key(collection.id, owner.as_sub());
2308 if list_exists {2369 if list_exists {
2370 collection.consume_sload()?;
2309 let mut list = <AddressTokens<T>>::get(collection_id, owner.as_sub());2371 let mut list = <AddressTokens<T>>::get(collection.id, owner.as_sub());
2310 let item_contains = list.contains(&item_index.clone());2372 let item_contains = list.contains(&item_index.clone());
23112373
2312 if !item_contains {2374 if !item_contains {
2313 list.push(item_index);2375 list.push(item_index);
2314 }2376 }
23152377
2378 collection.consume_sstore()?;
2316 <AddressTokens<T>>::insert(collection_id, owner.as_sub(), list);2379 <AddressTokens<T>>::insert(collection.id, owner.as_sub(), list);
2317 } else {2380 } else {
2318 let itm = vec![item_index];2381 let itm = vec![item_index];
2382 collection.consume_sstore()?;
2319 <AddressTokens<T>>::insert(collection_id, owner.as_sub(), itm);2383 <AddressTokens<T>>::insert(collection.id, owner.as_sub(), itm);
2320 }2384 }
23212385
2322 Ok(())2386 Ok(())
2323 }2387 }
23242388
2325 fn remove_token_index(2389 fn remove_token_index(
2326 collection_id: CollectionId,2390 collection: &CollectionHandle<T>,
2327 item_index: TokenId,2391 item_index: TokenId,
2328 owner: &T::CrossAccountId,2392 owner: &T::CrossAccountId,
2329 ) -> DispatchResult {2393 ) -> DispatchResult {
2330 // update counter2394 // update counter
2395 collection.consume_sload()?;
2396 collection.consume_sstore()?;
2331 <AccountItemCount<T>>::insert(2397 <AccountItemCount<T>>::insert(
2332 owner.as_sub(),2398 owner.as_sub(),
2333 <AccountItemCount<T>>::get(owner.as_sub())2399 <AccountItemCount<T>>::get(owner.as_sub())
2334 .checked_sub(1)2400 .checked_sub(1)
2335 .ok_or(Error::<T>::NumOverflow)?,2401 .ok_or(Error::<T>::NumOverflow)?,
2336 );2402 );
23372403
2404 collection.consume_sload()?;
2338 let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.as_sub());2405 let list_exists = <AddressTokens<T>>::contains_key(collection.id, owner.as_sub());
2339 if list_exists {2406 if list_exists {
2407 collection.consume_sload()?;
2340 let mut list = <AddressTokens<T>>::get(collection_id, owner.as_sub());2408 let mut list = <AddressTokens<T>>::get(collection.id, owner.as_sub());
2341 let item_contains = list.contains(&item_index.clone());2409 let item_contains = list.contains(&item_index.clone());
23422410
2343 if item_contains {2411 if item_contains {
2344 list.retain(|&item| item != item_index);2412 list.retain(|&item| item != item_index);
2413 collection.consume_sstore()?;
2345 <AddressTokens<T>>::insert(collection_id, owner.as_sub(), list);2414 <AddressTokens<T>>::insert(collection.id, owner.as_sub(), list);
2346 }2415 }
2347 }2416 }
23482417
2349 Ok(())2418 Ok(())
2350 }2419 }
23512420
2352 fn move_token_index(2421 fn move_token_index(
2353 collection_id: CollectionId,2422 collection: &CollectionHandle<T>,
2354 item_index: TokenId,2423 item_index: TokenId,
2355 old_owner: &T::CrossAccountId,2424 old_owner: &T::CrossAccountId,
2356 new_owner: &T::CrossAccountId,2425 new_owner: &T::CrossAccountId,
2357 ) -> DispatchResult {2426 ) -> DispatchResult {
2358 Self::remove_token_index(collection_id, item_index, old_owner)?;2427 Self::remove_token_index(collection, item_index, old_owner)?;
2359 Self::add_token_index(collection_id, item_index, new_owner)?;2428 Self::add_token_index(collection, item_index, new_owner)?;
23602429
2361 Ok(())2430 Ok(())
2362 }2431 }