git.delta.rocks / unique-network / refs/commits / 3db55eb8a3c0

difftreelog

feat nest on create/transfer

Yaroslav Bolyukin2022-04-07parent: #b69837d.patch.diff
in: master

12 files changed

modifiedpallets/common/src/lib.rsdiffbeforeafterboth
723 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;
783787
784 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;
790795
791 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId>;796 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId>;
modifiedpallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth
5555
56 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::*;
6059
61 /// 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 failure
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
17use core::marker::PhantomData;17use core::marker::PhantomData;
1818
19use 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 }
108110
109 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 };
125128
126 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>>::FungibleItemsHaveNoId
159 );163 );
160164
161 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 }
232236
233 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 }
modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
81 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 = self
85 .recorder
86 .weight_calls_budget(<StructureWeight<T>>::find_parent());
8487
85 <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())]
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
193 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();
225
226 // =========
227226
228 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 }
229
230 // =========
230231
231 if let Some(balance_to) = balance_to {232 if let Some(balance_to) = balance_to {
232 // from != to233 // from != to
257 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 }
289
290 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();
295
296 dispatch.check_nesting(sender.clone(), collection.id, target.1, nesting_budget)?;
297 }
298 }
287299
288 // =========300 // =========
289301
407419
408 // =========420 // =========
409421
410 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}
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
89 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 = data
106 .into_iter()113 .into_iter()
109116
110 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 };
127135
128 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 }
241250
242 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 }
250260
251 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {261 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
256 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 = self
260 .recorder
261 .weight_calls_budget(<StructureWeight<T>>::find_parent());
262
259 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>)?;
277282
296 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 = self
305 .recorder
306 .weight_calls_budget(<StructureWeight<T>>::find_parent());
307
299 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 = self
352 .recorder
353 .weight_calls_budget(<StructureWeight<T>>::find_parent());
341354
342 <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 }
345358
409 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 = self
426 .recorder
427 .weight_calls_budget(<StructureWeight<T>>::find_parent());
412428
413 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();
428444
429 <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 = self
468 .recorder
469 .weight_calls_budget(<StructureWeight<T>>::find_parent());
450470
451 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 }
467487
468 <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 }
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
251 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();
297
298 // =========
299298
300 dispatch.nest_token(from.clone(), (collection.id, token), target.1)?;299 dispatch.check_nesting(from.clone(), collection.id, target.1, nesting_budget)?;
301 }300 }
301
302 // =========
302303
303 <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 }
383
384 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();
389
390 dispatch.check_nesting(sender.clone(), collection.id, target.1, nesting_budget)?;
391 }
392 }
381393
382 // =========394 // =========
383395
556 // =========568 // =========
557569
558 // 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 }
561573
562 pub fn burn_from(574 pub fn burn_from(
595 Ok(())607 Ok(())
596 }608 }
597609
598 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 .owner
613 .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>>::SourceCollectionIsNotAllowedToNest
625 );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}
641653
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
19use 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 = data
137 .into_iter()145 .into_iter()
140148
141 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 };
163172
164 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 }
249259
250 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 }
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
289 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();
353
354 // =========
355354
356 dispatch.nest_token(from.clone(), (collection.id, token), target.1)?;355 dispatch.check_nesting(from.clone(), collection.id, target.1, nesting_budget)?;
357 }356 }
357
358 // =========
358359
359 if let Some(balance_to) = balance_to {360 if let Some(balance_to) = balance_to {
360 // from != to361 // from != to
389 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 }
457
458 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();
464
465 dispatch.check_nesting(
466 sender.clone(),
467 collection.id,
468 target.1,
469 nesting_budget,
470 )?;
471 }
472 }
473 }
455474
456 // =========475 // =========
457476
591610
592 // =========611 // =========
593612
594 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}
655675
modifiedpallets/structure/src/lib.rsdiffbeforeafterboth
19 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::*;
2322
24 use super::*;23 use super::*;
2524
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
693 #[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);
696697
697 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 }
699700
700 /// 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);
723725
724 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 }
726728
727 #[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);
731734
732 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 }
734737
735 // TODO! transaction weight738 // TODO! transaction weight
839 #[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);
842846
843 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 }
845849
846 /// 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.