difftreelog
feat nest on create/transfer
in: master
12 files changed
pallets/common/src/lib.rsdiffbeforeafterboth723 sender: T::CrossAccountId,723 sender: T::CrossAccountId,724 to: T::CrossAccountId,724 to: T::CrossAccountId,725 data: CreateItemData,725 data: CreateItemData,726 nesting_budget: &dyn Budget,726 ) -> DispatchResultWithPostInfo;727 ) -> DispatchResultWithPostInfo;727 fn create_multiple_items(728 fn create_multiple_items(728 &self,729 &self,729 sender: T::CrossAccountId,730 sender: T::CrossAccountId,730 to: T::CrossAccountId,731 to: T::CrossAccountId,731 data: Vec<CreateItemData>,732 data: Vec<CreateItemData>,733 nesting_budget: &dyn Budget,732 ) -> DispatchResultWithPostInfo;734 ) -> DispatchResultWithPostInfo;733 fn create_multiple_items_ex(735 fn create_multiple_items_ex(734 &self,736 &self,735 sender: T::CrossAccountId,737 sender: T::CrossAccountId,736 data: CreateItemExData<T::CrossAccountId>,738 data: CreateItemExData<T::CrossAccountId>,739 nesting_budget: &dyn Budget,737 ) -> DispatchResultWithPostInfo;740 ) -> DispatchResultWithPostInfo;738 fn burn_item(741 fn burn_item(739 &self,742 &self,748 to: T::CrossAccountId,751 to: T::CrossAccountId,749 token: TokenId,752 token: TokenId,750 amount: u128,753 amount: u128,754 nesting_budget: &dyn Budget,751 ) -> DispatchResultWithPostInfo;755 ) -> DispatchResultWithPostInfo;752 fn approve(756 fn approve(753 &self,757 &self,781 data: BoundedVec<u8, CustomDataLimit>,785 data: BoundedVec<u8, CustomDataLimit>,782 ) -> DispatchResultWithPostInfo;786 ) -> DispatchResultWithPostInfo;783787784 fn nest_token(788 fn check_nesting(785 &self,789 &self,786 sender: T::CrossAccountId,790 sender: T::CrossAccountId,787 from: (CollectionId, TokenId),791 from: CollectionId,788 under: TokenId,792 under: TokenId,793 budget: &dyn Budget,789 ) -> DispatchResult;794 ) -> DispatchResult;790795791 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId>;796 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId>;pallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth555556 use frame_system::ensure_signed;56 use frame_system::ensure_signed;57 pub use frame_support::dispatch::DispatchResult;57 pub use frame_support::dispatch::DispatchResult;58 use frame_support::{pallet_prelude::*, traits::PalletInfo};59 use frame_system::pallet_prelude::*;58 use frame_system::pallet_prelude::*;605961 /// DispatchError is opaque, but we need to somehow extract correct error in case of OutOfGas failure60 /// DispatchError is opaque, but we need to somehow extract correct error in case of OutOfGas failurepallets/fungible/src/common.rsdiffbeforeafterboth17use core::marker::PhantomData;17use core::marker::PhantomData;181819use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};19use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};20use up_data_structs::{TokenId, CreateItemExData, budget::Budget};20use up_data_structs::{TokenId, CollectionId, CreateItemExData, budget::Budget};21use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};21use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};22use sp_runtime::ArithmeticError;22use sp_runtime::ArithmeticError;23use sp_std::{vec::Vec, vec};23use sp_std::{vec::Vec, vec};78 sender: T::CrossAccountId,78 sender: T::CrossAccountId,79 to: T::CrossAccountId,79 to: T::CrossAccountId,80 data: up_data_structs::CreateItemData,80 data: up_data_structs::CreateItemData,81 nesting_budget: &dyn Budget,81 ) -> DispatchResultWithPostInfo {82 ) -> DispatchResultWithPostInfo {82 match data {83 match data {83 up_data_structs::CreateItemData::Fungible(data) => with_weight(84 up_data_structs::CreateItemData::Fungible(data) => with_weight(84 <Pallet<T>>::create_item(self, &sender, (to, data.value)),85 <Pallet<T>>::create_item(self, &sender, (to, data.value), nesting_budget),85 <CommonWeights<T>>::create_item(),86 <CommonWeights<T>>::create_item(),86 ),87 ),87 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),88 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),93 sender: T::CrossAccountId,94 sender: T::CrossAccountId,94 to: T::CrossAccountId,95 to: T::CrossAccountId,95 data: Vec<up_data_structs::CreateItemData>,96 data: Vec<up_data_structs::CreateItemData>,97 nesting_budget: &dyn Budget,96 ) -> DispatchResultWithPostInfo {98 ) -> DispatchResultWithPostInfo {97 let mut sum: u128 = 0;99 let mut sum: u128 = 0;98 for data in data {100 for data in data {107 }109 }108110109 with_weight(111 with_weight(110 <Pallet<T>>::create_item(self, &sender, (to, sum)),112 <Pallet<T>>::create_item(self, &sender, (to, sum), nesting_budget),111 <CommonWeights<T>>::create_item(),113 <CommonWeights<T>>::create_item(),112 )114 )113 }115 }116 &self,118 &self,117 sender: <T>::CrossAccountId,119 sender: <T>::CrossAccountId,118 data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,120 data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,121 nesting_budget: &dyn Budget,119 ) -> DispatchResultWithPostInfo {122 ) -> DispatchResultWithPostInfo {120 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);123 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);121 let data = match data {124 let data = match data {124 };127 };125128126 with_weight(129 with_weight(127 <Pallet<T>>::create_multiple_items(self, &sender, data.into_inner()),130 <Pallet<T>>::create_multiple_items(self, &sender, data.into_inner(), nesting_budget),128 weight,131 weight,129 )132 )130 }133 }152 to: T::CrossAccountId,155 to: T::CrossAccountId,153 token: TokenId,156 token: TokenId,154 amount: u128,157 amount: u128,158 nesting_budget: &dyn Budget,155 ) -> DispatchResultWithPostInfo {159 ) -> DispatchResultWithPostInfo {156 ensure!(160 ensure!(157 token == TokenId::default(),161 token == TokenId::default(),158 <Error<T>>::FungibleItemsHaveNoId162 <Error<T>>::FungibleItemsHaveNoId159 );163 );160164161 with_weight(165 with_weight(162 <Pallet<T>>::transfer(self, &from, &to, amount),166 <Pallet<T>>::transfer(self, &from, &to, amount, nesting_budget),163 <CommonWeights<T>>::transfer(),167 <CommonWeights<T>>::transfer(),164 )168 )165 }169 }230 fail!(<Error<T>>::FungibleItemsDontHaveData)234 fail!(<Error<T>>::FungibleItemsDontHaveData)231 }235 }232236233 fn nest_token(237 fn check_nesting(234 &self,238 &self,235 _sender: <T>::CrossAccountId,239 _sender: <T>::CrossAccountId,236 _from: (up_data_structs::CollectionId, TokenId),240 _from: CollectionId,237 _under: TokenId,241 _under: TokenId,242 _budget: &dyn Budget,238 ) -> sp_runtime::DispatchResult {243 ) -> sp_runtime::DispatchResult {239 fail!(<Error<T>>::FungibleDisallowsNesting)244 fail!(<Error<T>>::FungibleDisallowsNesting)240 }245 }pallets/fungible/src/erc.rsdiffbeforeafterboth81 let caller = T::CrossAccountId::from_eth(caller);81 let caller = T::CrossAccountId::from_eth(caller);82 let to = T::CrossAccountId::from_eth(to);82 let to = T::CrossAccountId::from_eth(to);83 let amount = amount.try_into().map_err(|_| "amount overflow")?;83 let amount = amount.try_into().map_err(|_| "amount overflow")?;84 let budget = self85 .recorder86 .weight_calls_budget(<StructureWeight<T>>::find_parent());848785 <Pallet<T>>::transfer(self, &caller, &to, amount).map_err(|_| "transfer error")?;88 <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;86 Ok(true)89 Ok(true)87 }90 }88 #[weight(<SelfWeightOf<T>>::transfer_from())]91 #[weight(<SelfWeightOf<T>>::transfer_from())]pallets/fungible/src/lib.rsdiffbeforeafterboth193 from: &T::CrossAccountId,193 from: &T::CrossAccountId,194 to: &T::CrossAccountId,194 to: &T::CrossAccountId,195 amount: u128,195 amount: u128,196 nesting_budget: &dyn Budget,196 ) -> DispatchResult {197 ) -> DispatchResult {197 ensure!(198 ensure!(198 collection.limits.transfers_enabled(),199 collection.limits.transfers_enabled(),223 let dispatch = T::CollectionDispatch::dispatch(handle);224 let dispatch = T::CollectionDispatch::dispatch(handle);224 let dispatch = dispatch.as_dyn();225 let dispatch = dispatch.as_dyn();225226 // =========227226228 dispatch.nest_token(from.clone(), (collection.id, TokenId::default()), target.1)?;227 dispatch.check_nesting(from.clone(), collection.id, target.1, nesting_budget)?;229 }228 }229230 // =========230231231 if let Some(balance_to) = balance_to {232 if let Some(balance_to) = balance_to {232 // from != to233 // from != to257 collection: &FungibleHandle<T>,258 collection: &FungibleHandle<T>,258 sender: &T::CrossAccountId,259 sender: &T::CrossAccountId,259 data: BTreeMap<T::CrossAccountId, u128>,260 data: BTreeMap<T::CrossAccountId, u128>,261 nesting_budget: &dyn Budget,260 ) -> DispatchResult {262 ) -> DispatchResult {261 if !collection.is_owner_or_admin(sender) {263 if !collection.is_owner_or_admin(sender) {262 ensure!(264 ensure!(285 .ok_or(ArithmeticError::Overflow)?;287 .ok_or(ArithmeticError::Overflow)?;286 }288 }289290 for (to, _) in balances.iter() {291 if let Some(target) = T::CrossTokenAddressMapping::address_to_token(to) {292 let handle = <CollectionHandle<T>>::try_get(target.0)?;293 let dispatch = T::CollectionDispatch::dispatch(handle);294 let dispatch = dispatch.as_dyn();295296 dispatch.check_nesting(sender.clone(), collection.id, target.1, nesting_budget)?;297 }298 }287299288 // =========300 // =========289301407419408 // =========420 // =========409421410 Self::transfer(collection, from, to, amount)?;422 Self::transfer(collection, from, to, amount, nesting_budget)?;411 if let Some(allowance) = allowance {423 if let Some(allowance) = allowance {412 Self::set_allowance_unchecked(collection, from, spender, allowance);424 Self::set_allowance_unchecked(collection, from, spender, allowance);413 }425 }437 collection: &FungibleHandle<T>,449 collection: &FungibleHandle<T>,438 sender: &T::CrossAccountId,450 sender: &T::CrossAccountId,439 data: CreateItemData<T>,451 data: CreateItemData<T>,452 nesting_budget: &dyn Budget,440 ) -> DispatchResult {453 ) -> DispatchResult {441 Self::create_multiple_items(collection, sender, [(data.0, data.1)].into_iter().collect())454 Self::create_multiple_items(455 collection,456 sender,457 [(data.0, data.1)].into_iter().collect(),458 nesting_budget,459 )442 }460 }443}461}pallets/nonfungible/src/common.rsdiffbeforeafterboth89 sender: T::CrossAccountId,89 sender: T::CrossAccountId,90 to: T::CrossAccountId,90 to: T::CrossAccountId,91 data: up_data_structs::CreateItemData,91 data: up_data_structs::CreateItemData,92 nesting_budget: &dyn Budget,92 ) -> DispatchResultWithPostInfo {93 ) -> DispatchResultWithPostInfo {93 with_weight(94 with_weight(94 <Pallet<T>>::create_item(self, &sender, map_create_data::<T>(data, &to)?),95 <Pallet<T>>::create_item(96 self,97 &sender,98 map_create_data::<T>(data, &to)?,99 nesting_budget,100 ),95 <CommonWeights<T>>::create_item(),101 <CommonWeights<T>>::create_item(),96 )102 )101 sender: T::CrossAccountId,107 sender: T::CrossAccountId,102 to: T::CrossAccountId,108 to: T::CrossAccountId,103 data: Vec<up_data_structs::CreateItemData>,109 data: Vec<up_data_structs::CreateItemData>,110 nesting_budget: &dyn Budget,104 ) -> DispatchResultWithPostInfo {111 ) -> DispatchResultWithPostInfo {105 let data = data112 let data = data106 .into_iter()113 .into_iter()109116110 let amount = data.len();117 let amount = data.len();111 with_weight(118 with_weight(112 <Pallet<T>>::create_multiple_items(self, &sender, data),119 <Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),113 <CommonWeights<T>>::create_multiple_items(amount as u32),120 <CommonWeights<T>>::create_multiple_items(amount as u32),114 )121 )115 }122 }118 &self,125 &self,119 sender: <T>::CrossAccountId,126 sender: <T>::CrossAccountId,120 data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,127 data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,128 nesting_budget: &dyn Budget,121 ) -> DispatchResultWithPostInfo {129 ) -> DispatchResultWithPostInfo {122 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);130 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);123 let data = match data {131 let data = match data {126 };134 };127135128 with_weight(136 with_weight(129 <Pallet<T>>::create_multiple_items(self, &sender, data.into_inner()),137 <Pallet<T>>::create_multiple_items(self, &sender, data.into_inner(), nesting_budget),130 weight,138 weight,131 )139 )132 }140 }154 to: T::CrossAccountId,162 to: T::CrossAccountId,155 token: TokenId,163 token: TokenId,156 amount: u128,164 amount: u128,165 nesting_budget: &dyn Budget,157 ) -> DispatchResultWithPostInfo {166 ) -> DispatchResultWithPostInfo {158 ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);167 ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);159 if amount == 1 {168 if amount == 1 {160 with_weight(169 with_weight(161 <Pallet<T>>::transfer(self, &from, &to, token),170 <Pallet<T>>::transfer(self, &from, &to, token, nesting_budget),162 <CommonWeights<T>>::transfer(),171 <CommonWeights<T>>::transfer(),163 )172 )164 } else {173 } else {239 )248 )240 }249 }241250242 fn nest_token(251 fn check_nesting(243 &self,252 &self,244 sender: T::CrossAccountId,253 sender: T::CrossAccountId,245 (from, _): (CollectionId, TokenId),254 from: CollectionId,246 under: TokenId,255 under: TokenId,256 budget: &dyn Budget,247 ) -> sp_runtime::DispatchResult {257 ) -> sp_runtime::DispatchResult {248 <Pallet<T>>::nest_token(self, sender, from, under)258 <Pallet<T>>::check_nesting(self, sender, from, under, budget)249 }259 }250260251 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {261 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {pallets/nonfungible/src/erc.rsdiffbeforeafterboth256 let caller = T::CrossAccountId::from_eth(caller);256 let caller = T::CrossAccountId::from_eth(caller);257 let to = T::CrossAccountId::from_eth(to);257 let to = T::CrossAccountId::from_eth(to);258 let token_id: u32 = token_id.try_into()?;258 let token_id: u32 = token_id.try_into()?;259 let budget = self260 .recorder261 .weight_calls_budget(<StructureWeight<T>>::find_parent());262259 if <TokensMinted<T>>::get(self.id)263 if <TokensMinted<T>>::get(self.id)260 .checked_add(1)264 .checked_add(1)272 variable_data: BoundedVec::default(),276 variable_data: BoundedVec::default(),273 owner: to,277 owner: to,274 },278 },279 &budget,275 )280 )276 .map_err(dispatch_to_evm::<T>)?;281 .map_err(dispatch_to_evm::<T>)?;277282296 let caller = T::CrossAccountId::from_eth(caller);301 let caller = T::CrossAccountId::from_eth(caller);297 let to = T::CrossAccountId::from_eth(to);302 let to = T::CrossAccountId::from_eth(to);298 let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;303 let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;304 let budget = self305 .recorder306 .weight_calls_budget(<StructureWeight<T>>::find_parent());307299 if <TokensMinted<T>>::get(self.id)308 if <TokensMinted<T>>::get(self.id)300 .checked_add(1)309 .checked_add(1)314 variable_data: BoundedVec::default(),323 variable_data: BoundedVec::default(),315 owner: to,324 owner: to,316 },325 },326 &budget,317 )327 )318 .map_err(dispatch_to_evm::<T>)?;328 .map_err(dispatch_to_evm::<T>)?;319 Ok(true)329 Ok(true)338 let caller = T::CrossAccountId::from_eth(caller);348 let caller = T::CrossAccountId::from_eth(caller);339 let to = T::CrossAccountId::from_eth(to);349 let to = T::CrossAccountId::from_eth(to);340 let token = token_id.try_into()?;350 let token = token_id.try_into()?;351 let budget = self352 .recorder353 .weight_calls_budget(<StructureWeight<T>>::find_parent());341354342 <Pallet<T>>::transfer(self, &caller, &to, token).map_err(dispatch_to_evm::<T>)?;355 <Pallet<T>>::transfer(self, &caller, &to, token, &budget).map_err(dispatch_to_evm::<T>)?;343 Ok(())356 Ok(())344 }357 }345358409 let mut expected_index = <TokensMinted<T>>::get(self.id)422 let mut expected_index = <TokensMinted<T>>::get(self.id)410 .checked_add(1)423 .checked_add(1)411 .ok_or("item id overflow")?;424 .ok_or("item id overflow")?;425 let budget = self426 .recorder427 .weight_calls_budget(<StructureWeight<T>>::find_parent());412428413 let total_tokens = token_ids.len();429 let total_tokens = token_ids.len();414 for id in token_ids.into_iter() {430 for id in token_ids.into_iter() {426 })442 })427 .collect();443 .collect();428444429 <Pallet<T>>::create_multiple_items(self, &caller, data).map_err(dispatch_to_evm::<T>)?;445 <Pallet<T>>::create_multiple_items(self, &caller, data, &budget)446 .map_err(dispatch_to_evm::<T>)?;430 Ok(true)447 Ok(true)431 }448 }447 let mut expected_index = <TokensMinted<T>>::get(self.id)464 let mut expected_index = <TokensMinted<T>>::get(self.id)448 .checked_add(1)465 .checked_add(1)449 .ok_or("item id overflow")?;466 .ok_or("item id overflow")?;467 let budget = self468 .recorder469 .weight_calls_budget(<StructureWeight<T>>::find_parent());450470451 let mut data = Vec::with_capacity(tokens.len());471 let mut data = Vec::with_capacity(tokens.len());452 for (id, token_uri) in tokens {472 for (id, token_uri) in tokens {465 });485 });466 }486 }467487468 <Pallet<T>>::create_multiple_items(self, &caller, data).map_err(dispatch_to_evm::<T>)?;488 <Pallet<T>>::create_multiple_items(self, &caller, data, &budget)489 .map_err(dispatch_to_evm::<T>)?;469 Ok(true)490 Ok(true)470 }491 }pallets/nonfungible/src/lib.rsdiffbeforeafterboth251 from: &T::CrossAccountId,251 from: &T::CrossAccountId,252 to: &T::CrossAccountId,252 to: &T::CrossAccountId,253 token: TokenId,253 token: TokenId,254 nesting_budget: &dyn Budget,254 ) -> DispatchResult {255 ) -> DispatchResult {255 ensure!(256 ensure!(256 collection.limits.transfers_enabled(),257 collection.limits.transfers_enabled(),295 let dispatch = T::CollectionDispatch::dispatch(handle);296 let dispatch = T::CollectionDispatch::dispatch(handle);296 let dispatch = dispatch.as_dyn();297 let dispatch = dispatch.as_dyn();297298 // =========299298300 dispatch.nest_token(from.clone(), (collection.id, token), target.1)?;299 dispatch.check_nesting(from.clone(), collection.id, target.1, nesting_budget)?;301 }300 }301302 // =========302303303 <TokenData<T>>::insert(304 <TokenData<T>>::insert(304 (collection.id, token),305 (collection.id, token),340 collection: &NonfungibleHandle<T>,341 collection: &NonfungibleHandle<T>,341 sender: &T::CrossAccountId,342 sender: &T::CrossAccountId,342 data: Vec<CreateItemData<T>>,343 data: Vec<CreateItemData<T>>,344 nesting_budget: &dyn Budget,343 ) -> DispatchResult {345 ) -> DispatchResult {344 if !collection.is_owner_or_admin(sender) {346 if !collection.is_owner_or_admin(sender) {345 ensure!(347 ensure!(379 );381 );380 }382 }383384 for (to, _) in balances.iter() {385 if let Some(target) = T::CrossTokenAddressMapping::address_to_token(to) {386 let handle = <CollectionHandle<T>>::try_get(target.0)?;387 let dispatch = T::CollectionDispatch::dispatch(handle);388 let dispatch = dispatch.as_dyn();389390 dispatch.check_nesting(sender.clone(), collection.id, target.1, nesting_budget)?;391 }392 }381393382 // =========394 // =========383395556 // =========568 // =========557569558 // Allowance is reset in [`transfer`]570 // Allowance is reset in [`transfer`]559 Self::transfer(collection, from, to, token)571 Self::transfer(collection, from, to, token, nesting_budget)560 }572 }561573562 pub fn burn_from(574 pub fn burn_from(595 Ok(())607 Ok(())596 }608 }597609598 pub fn nest_token(610 pub fn check_nesting(599 handle: &NonfungibleHandle<T>,611 handle: &NonfungibleHandle<T>,600 sender: T::CrossAccountId,612 sender: T::CrossAccountId,601 from: CollectionId,613 from: CollectionId,602 under: TokenId,614 under: TokenId,615 nesting_budget: &dyn Budget,603 ) -> DispatchResult {616 ) -> DispatchResult {604 fn ensure_sender_allowed<T: Config>(617 fn ensure_sender_allowed<T: Config>(605 collection: CollectionId,618 collection: CollectionId,606 token: TokenId,619 token: TokenId,607 sender: T::CrossAccountId,620 sender: T::CrossAccountId,621 budget: &dyn Budget,608 ) -> DispatchResult {622 ) -> DispatchResult {609 ensure!(623 ensure!(610 <TokenData<T>>::get((collection, token))624 <PalletStructure<T>>::indirectly_owned(sender, collection, token, budget)?,611 .ok_or(<CommonError<T>>::TokenNotFound)?612 .owner613 .conv_eq(&sender),614 <CommonError<T>>::OnlyOwnerAllowedToNest,625 <CommonError<T>>::OnlyOwnerAllowedToNest,615 );626 );616 Ok(())627 Ok(())617 }628 }618 match handle.limits.nesting_rule() {629 match handle.limits.nesting_rule() {619 NestingRule::Disabled => fail!(<CommonError<T>>::NestingIsDisabled),630 NestingRule::Disabled => fail!(<CommonError<T>>::NestingIsDisabled),620 NestingRule::Owner => ensure_sender_allowed::<T>(from, under, sender)?,631 NestingRule::Owner => ensure_sender_allowed::<T>(from, under, sender, nesting_budget)?,621 NestingRule::OwnerRestricted(whitelist) => {632 NestingRule::OwnerRestricted(whitelist) => {622 ensure!(633 ensure!(623 whitelist.contains(&from),634 whitelist.contains(&from),624 <CommonError<T>>::SourceCollectionIsNotAllowedToNest635 <CommonError<T>>::SourceCollectionIsNotAllowedToNest625 );636 );626 ensure_sender_allowed::<T>(from, under, sender)?637 ensure_sender_allowed::<T>(from, under, sender, nesting_budget)?627 }638 }628 }639 }629 Ok(())640 Ok(())634 collection: &NonfungibleHandle<T>,645 collection: &NonfungibleHandle<T>,635 sender: &T::CrossAccountId,646 sender: &T::CrossAccountId,636 data: CreateItemData<T>,647 data: CreateItemData<T>,648 nesting_budget: &dyn Budget,637 ) -> DispatchResult {649 ) -> DispatchResult {638 Self::create_multiple_items(collection, sender, vec![data])650 Self::create_multiple_items(collection, sender, vec![data], nesting_budget)639 }651 }640}652}641653pallets/refungible/src/common.rsdiffbeforeafterboth19use sp_std::collections::btree_map::BTreeMap;19use sp_std::collections::btree_map::BTreeMap;20use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};20use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};21use up_data_structs::{21use up_data_structs::{22 TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData, budget::Budget,22 CollectionId, TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData,23 budget::Budget,23};24};24use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};25use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};120 sender: T::CrossAccountId,121 sender: T::CrossAccountId,121 to: T::CrossAccountId,122 to: T::CrossAccountId,122 data: up_data_structs::CreateItemData,123 data: up_data_structs::CreateItemData,124 nesting_budget: &dyn Budget,123 ) -> DispatchResultWithPostInfo {125 ) -> DispatchResultWithPostInfo {124 with_weight(126 with_weight(125 <Pallet<T>>::create_item(self, &sender, map_create_data::<T>(data, &to)?),127 <Pallet<T>>::create_item(128 self,129 &sender,130 map_create_data::<T>(data, &to)?,131 nesting_budget,132 ),126 <CommonWeights<T>>::create_item(),133 <CommonWeights<T>>::create_item(),127 )134 )132 sender: T::CrossAccountId,139 sender: T::CrossAccountId,133 to: T::CrossAccountId,140 to: T::CrossAccountId,134 data: Vec<up_data_structs::CreateItemData>,141 data: Vec<up_data_structs::CreateItemData>,142 nesting_budget: &dyn Budget,135 ) -> DispatchResultWithPostInfo {143 ) -> DispatchResultWithPostInfo {136 let data = data144 let data = data137 .into_iter()145 .into_iter()140148141 let amount = data.len();149 let amount = data.len();142 with_weight(150 with_weight(143 <Pallet<T>>::create_multiple_items(self, &sender, data),151 <Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),144 <CommonWeights<T>>::create_multiple_items(amount as u32),152 <CommonWeights<T>>::create_multiple_items(amount as u32),145 )153 )146 }154 }149 &self,157 &self,150 sender: <T>::CrossAccountId,158 sender: <T>::CrossAccountId,151 data: CreateItemExData<T::CrossAccountId>,159 data: CreateItemExData<T::CrossAccountId>,160 nesting_budget: &dyn Budget,152 ) -> DispatchResultWithPostInfo {161 ) -> DispatchResultWithPostInfo {153 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);162 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);154 let data = match data {163 let data = match data {162 };171 };163172164 with_weight(173 with_weight(165 <Pallet<T>>::create_multiple_items(self, &sender, data),174 <Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),166 weight,175 weight,167 )176 )168 }177 }185 to: T::CrossAccountId,194 to: T::CrossAccountId,186 token: TokenId,195 token: TokenId,187 amount: u128,196 amount: u128,197 nesting_budget: &dyn Budget,188 ) -> DispatchResultWithPostInfo {198 ) -> DispatchResultWithPostInfo {189 with_weight(199 with_weight(190 <Pallet<T>>::transfer(self, &from, &to, token, amount),200 <Pallet<T>>::transfer(self, &from, &to, token, amount, nesting_budget),191 <CommonWeights<T>>::transfer(),201 <CommonWeights<T>>::transfer(),192 )202 )193 }203 }247 )257 )248 }258 }249259250 fn nest_token(260 fn check_nesting(251 &self,261 &self,252 _sender: <T>::CrossAccountId,262 _sender: <T>::CrossAccountId,253 _from: (up_data_structs::CollectionId, TokenId),263 _from: CollectionId,254 _under: TokenId,264 _under: TokenId,265 _budget: &dyn Budget,255 ) -> sp_runtime::DispatchResult {266 ) -> sp_runtime::DispatchResult {256 fail!(<Error<T>>::RefungibleDisallowsNesting)267 fail!(<Error<T>>::RefungibleDisallowsNesting)257 }268 }pallets/refungible/src/lib.rsdiffbeforeafterboth289 to: &T::CrossAccountId,289 to: &T::CrossAccountId,290 token: TokenId,290 token: TokenId,291 amount: u128,291 amount: u128,292 nesting_budget: &dyn Budget,292 ) -> DispatchResult {293 ) -> DispatchResult {293 ensure!(294 ensure!(294 collection.limits.transfers_enabled(),295 collection.limits.transfers_enabled(),351 let dispatch = T::CollectionDispatch::dispatch(handle);352 let dispatch = T::CollectionDispatch::dispatch(handle);352 let dispatch = dispatch.as_dyn();353 let dispatch = dispatch.as_dyn();353354 // =========355354356 dispatch.nest_token(from.clone(), (collection.id, token), target.1)?;355 dispatch.check_nesting(from.clone(), collection.id, target.1, nesting_budget)?;357 }356 }357358 // =========358359359 if let Some(balance_to) = balance_to {360 if let Some(balance_to) = balance_to {360 // from != to361 // from != to389 collection: &RefungibleHandle<T>,390 collection: &RefungibleHandle<T>,390 sender: &T::CrossAccountId,391 sender: &T::CrossAccountId,391 data: Vec<CreateRefungibleExData<T::CrossAccountId>>,392 data: Vec<CreateRefungibleExData<T::CrossAccountId>>,393 nesting_budget: &dyn Budget,392 ) -> DispatchResult {394 ) -> DispatchResult {393 if !collection.is_owner_or_admin(sender) {395 if !collection.is_owner_or_admin(sender) {394 ensure!(396 ensure!(453 }455 }454 }456 }457458 for token in data.iter() {459 for (to, _) in token.users.iter() {460 if let Some(target) = T::CrossTokenAddressMapping::address_to_token(to) {461 let handle = <CollectionHandle<T>>::try_get(target.0)?;462 let dispatch = T::CollectionDispatch::dispatch(handle);463 let dispatch = dispatch.as_dyn();464465 dispatch.check_nesting(466 sender.clone(),467 collection.id,468 target.1,469 nesting_budget,470 )?;471 }472 }473 }455474456 // =========475 // =========457476591610592 // =========611 // =========593612594 Self::transfer(collection, from, to, token, amount)?;613 Self::transfer(collection, from, to, token, amount, nesting_budget)?;595 if let Some(allowance) = allowance {614 if let Some(allowance) = allowance {596 Self::set_allowance_unchecked(collection, from, spender, token, allowance);615 Self::set_allowance_unchecked(collection, from, spender, token, allowance);597 }616 }648 collection: &RefungibleHandle<T>,667 collection: &RefungibleHandle<T>,649 sender: &T::CrossAccountId,668 sender: &T::CrossAccountId,650 data: CreateRefungibleExData<T::CrossAccountId>,669 data: CreateRefungibleExData<T::CrossAccountId>,670 nesting_budget: &dyn Budget,651 ) -> DispatchResult {671 ) -> DispatchResult {652 Self::create_multiple_items(collection, sender, vec![data])672 Self::create_multiple_items(collection, sender, vec![data], nesting_budget)653 }673 }654}674}655675pallets/structure/src/lib.rsdiffbeforeafterboth19 use frame_support::Parameter;19 use frame_support::Parameter;20 use frame_support::dispatch::{GetDispatchInfo, UnfilteredDispatchable};20 use frame_support::dispatch::{GetDispatchInfo, UnfilteredDispatchable};21 use frame_support::pallet_prelude::*;21 use frame_support::pallet_prelude::*;22 use frame_system::pallet_prelude::*;232224 use super::*;23 use super::*;2524pallets/unique/src/lib.rsdiffbeforeafterboth693 #[transactional]693 #[transactional]694 pub fn create_item(origin, collection_id: CollectionId, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResultWithPostInfo {694 pub fn create_item(origin, collection_id: CollectionId, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResultWithPostInfo {695 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);695 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);696 let budget = budget::Value::new(2);696697697 dispatch_call::<T, _>(collection_id, |d| d.create_item(sender, owner, data))698 dispatch_call::<T, _>(collection_id, |d| d.create_item(sender, owner, data, &budget))698 }699 }699700700 /// This method creates multiple items in a collection created with CreateCollection method.701 /// This method creates multiple items in a collection created with CreateCollection method.720 pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::CrossAccountId, items_data: Vec<CreateItemData>) -> DispatchResultWithPostInfo {721 pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::CrossAccountId, items_data: Vec<CreateItemData>) -> DispatchResultWithPostInfo {721 ensure!(!items_data.is_empty(), Error::<T>::EmptyArgument);722 ensure!(!items_data.is_empty(), Error::<T>::EmptyArgument);722 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);723 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);724 let budget = budget::Value::new(2);723725724 dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data))726 dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data, &budget))725 }727 }726728727 #[weight = <CommonWeights<T>>::create_multiple_items_ex(&data)]729 #[weight = <CommonWeights<T>>::create_multiple_items_ex(&data)]728 #[transactional]730 #[transactional]729 pub fn create_multiple_items_ex(origin, collection_id: CollectionId, data: CreateItemExData<T::CrossAccountId>) -> DispatchResultWithPostInfo {731 pub fn create_multiple_items_ex(origin, collection_id: CollectionId, data: CreateItemExData<T::CrossAccountId>) -> DispatchResultWithPostInfo {730 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);732 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);733 let budget = budget::Value::new(2);731734732 dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items_ex(sender, data))735 dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items_ex(sender, data, &budget))733 }736 }734737735 // TODO! transaction weight738 // TODO! transaction weight839 #[transactional]842 #[transactional]840 pub fn transfer(origin, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {843 pub fn transfer(origin, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {841 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);844 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);845 let budget = budget::Value::new(2);842846843 dispatch_call::<T, _>(collection_id, |d| d.transfer(sender, recipient, item_id, value))847 dispatch_call::<T, _>(collection_id, |d| d.transfer(sender, recipient, item_id, value, &budget))844 }848 }845849846 /// Set, change, or remove approved address to transfer the ownership of the NFT.850 /// Set, change, or remove approved address to transfer the ownership of the NFT.