git.delta.rocks / unique-network / refs/commits / bea0737bb7ad

difftreelog

feat add nesting

Trubnikov Sergey2023-05-05parent: #3293186.patch.diff
in: master

5 files changed

modifiedCargo.lockdiffbeforeafterboth
6264 "pallet-evm",6264 "pallet-evm",
6265 "pallet-evm-coder-substrate",6265 "pallet-evm-coder-substrate",
6266 "pallet-evm-transaction-payment",6266 "pallet-evm-transaction-payment",
6267 "pallet-structure",
6267 "parity-scale-codec",6268 "parity-scale-codec",
6268 "scale-info",6269 "scale-info",
6269 "sp-core",6270 "sp-core",
6271 "sp-runtime",
6270 "sp-std",6272 "sp-std",
6271 "up-data-structs",6273 "up-data-structs",
6272]6274]
modifiedpallets/balances-adapter/Cargo.tomldiffbeforeafterboth
9frame-support = { workspace = true }9frame-support = { workspace = true }
10frame-system = { workspace = true }10frame-system = { workspace = true }
11pallet-balances = { workspace = true }11pallet-balances = { workspace = true }
12pallet-structure = { workspace = true }
12sp-core = { workspace = true }13sp-core = { workspace = true }
14sp-runtime = { workspace = true }
13sp-std = { workspace = true }15sp-std = { workspace = true }
1416
15#Parity17#Parity
modifiedpallets/balances-adapter/src/common.rsdiffbeforeafterboth
1use alloc::{vec, vec::Vec};1use alloc::{vec, vec::Vec};
2use core::marker::PhantomData;2use core::marker::PhantomData;
3use crate::{Config, NativeFungibleHandle};3use crate::{Config, NativeFungibleHandle, Pallet};
4use frame_support::{4use frame_support::{fail, traits::Currency, weights::Weight};
5 fail,
6 traits::{Currency, ExistenceRequirement},
7 weights::Weight,
8};
9use pallet_balances::{weights::SubstrateWeight as BalancesWeight, WeightInfo};5use pallet_balances::{weights::SubstrateWeight as BalancesWeight, WeightInfo};
10use pallet_common::{erc::CrossAccountId, CommonCollectionOperations, CommonWeightInfo, with_weight};6use pallet_common::{erc::CrossAccountId, CommonCollectionOperations, CommonWeightInfo};
11use up_data_structs::TokenId;7use up_data_structs::TokenId;
128
13pub struct CommonWeights<T: Config>(PhantomData<T>);9pub struct CommonWeights<T: Config>(PhantomData<T>);
188 to: <T>::CrossAccountId,184 to: <T>::CrossAccountId,
189 _token: TokenId,185 _token: TokenId,
190 amount: u128,186 amount: u128,
191 _budget: &dyn up_data_structs::budget::Budget,187 budget: &dyn up_data_structs::budget::Budget,
192 ) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {188 ) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {
193 with_weight(
194 <T as Config>::Currency::transfer(189 <Pallet<T>>::transfer(self, &sender, &to, amount, budget)
195 sender.as_sub(),
196 to.as_sub(),
197 amount.into(),
198 ExistenceRequirement::KeepAlive,
199 ),
200 Default::default(),
201 )
202 }190 }
203191
204 fn approve(192 fn approve(
229 to: <T>::CrossAccountId,217 to: <T>::CrossAccountId,
230 _token: TokenId,218 _token: TokenId,
231 amount: u128,219 amount: u128,
232 _budget: &dyn up_data_structs::budget::Budget,220 budget: &dyn up_data_structs::budget::Budget,
233 ) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {221 ) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {
234 if sender != from {
235 fail!(<pallet_common::Error<T>>::NoPermission);
236 }
237 with_weight(
238 <T as Config>::Currency::transfer(222 <Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, budget)
239 from.as_sub(),
240 to.as_sub(),
241 amount.into(),
242 ExistenceRequirement::KeepAlive,
243 ),
244 Default::default(),
245 )
246 }223 }
247224
248 fn burn_from(225 fn burn_from(
modifiedpallets/balances-adapter/src/erc.rsdiffbeforeafterboth
1use crate::{Config, NativeFungibleHandle, SelfWeightOf};1use crate::{Config, NativeFungibleHandle, Pallet, SelfWeightOf};
2use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};2use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
3use frame_support::traits::{Currency, ExistenceRequirement};3use frame_support::traits::{Currency, ExistenceRequirement};
4use pallet_balances::WeightInfo;4use pallet_balances::WeightInfo;
10use pallet_evm_coder_substrate::{10use pallet_evm_coder_substrate::{
11 call, dispatch_to_evm,11 call, dispatch_to_evm,
12 execution::{PreDispatch, Result},12 execution::{PreDispatch, Result},
13 frontier_contract,13 frontier_contract, WithRecorder,
14};14};
15use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
15use sp_core::{U256, Get};16use sp_core::{U256, Get};
16use sp_std::vec::Vec;17use sp_std::vec::Vec;
1718
73 let caller = T::CrossAccountId::from_eth(caller);74 let caller = T::CrossAccountId::from_eth(caller);
74 let to = T::CrossAccountId::from_eth(to);75 let to = T::CrossAccountId::from_eth(to);
75 let amount = amount.try_into().map_err(|_| "amount overflow")?;76 let amount = amount.try_into().map_err(|_| "amount overflow")?;
76 // let budget = self77 let budget = self
77 // .recorder78 .recorder()
78 // .weight_calls_budget(<StructureWeight<T>>::find_parent());79 .weight_calls_budget(<StructureWeight<T>>::find_parent());
7980
80 // <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;
81 <T as Config>::Currency::transfer(81 <Pallet<T>>::transfer(self, &caller, &to, amount, &budget)
82 caller.as_sub(),
83 to.as_sub(),
84 amount,
85 ExistenceRequirement::KeepAlive,
86 )
87 .map_err(dispatch_to_evm::<T>)?;82 .map_err(|e| dispatch_to_evm::<T>(e.error))?;
88 Ok(true)83 Ok(true)
89 }84 }
9085
100 let from = T::CrossAccountId::from_eth(from);95 let from = T::CrossAccountId::from_eth(from);
101 let to = T::CrossAccountId::from_eth(to);96 let to = T::CrossAccountId::from_eth(to);
102 let amount = amount.try_into().map_err(|_| "amount overflow")?;97 let amount = amount.try_into().map_err(|_| "amount overflow")?;
10398 let budget = self
104 if from != caller {
105 return Err("no permission".into());99 .recorder()
106 }100 .weight_calls_budget(<StructureWeight<T>>::find_parent());
107 // let budget = self101
108 // .recorder
109 // .weight_calls_budget(<StructureWeight<T>>::find_parent());
110
111 // <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
112 // .map_err(dispatch_to_evm::<T>)?;
113 <T as Config>::Currency::transfer(102 <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
114 caller.as_sub(),
115 to.as_sub(),
116 amount,
117 ExistenceRequirement::KeepAlive,
118 )
119 .map_err(dispatch_to_evm::<T>)?;103 .map_err(|e| dispatch_to_evm::<T>(e.error))?;
120 Ok(true)104 Ok(true)
121 }105 }
122}106}
modifiedpallets/balances-adapter/src/lib.rsdiffbeforeafterboth
5use core::ops::Deref;5use core::ops::Deref;
66
7use frame_support::sp_runtime::DispatchResult;7use frame_support::sp_runtime::DispatchResult;
8pub use pallet::*;
9use pallet_evm_coder_substrate::{WithRecorder, SubstrateRecorder};8use pallet_evm_coder_substrate::{WithRecorder, SubstrateRecorder};
9pub use pallet::*;
1010
11pub mod common;11pub mod common;
12pub mod erc;12pub mod erc;
1313
14pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;14pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
15
16const NATIVE_FUNGIBLE_COLLECTION_ID: up_data_structs::CollectionId =
17 up_data_structs::CollectionId(0);
1518
16/// Handle for native fungible collection19/// Handle for native fungible collection
17pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);20pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);
45}48}
46#[frame_support::pallet]49#[frame_support::pallet]
47pub mod pallet {50pub mod pallet {
51 use super::*;
48 use alloc::string::String;52 use alloc::string::String;
49 use frame_support::{traits::Get};53 use frame_support::{
54 dispatch::PostDispatchInfo,
55 ensure,
56 pallet_prelude::{DispatchResultWithPostInfo, Pays},
57 traits::{Currency, ExistenceRequirement, Get},
58 };
50 use pallet_balances::WeightInfo;59 use pallet_balances::WeightInfo;
60 use pallet_common::{erc::CrossAccountId, Error as CommonError, Pallet as PalletCommon};
61 use pallet_structure::Pallet as PalletStructure;
51 use sp_core::U256;62 use sp_core::U256;
63 use sp_runtime::DispatchError;
64 use up_data_structs::{budget::Budget, mapping::TokenAddressMapping, TokenId};
5265
53 #[pallet::config]66 #[pallet::config]
54 pub trait Config:67 pub trait Config:
55 frame_system::Config + pallet_evm_coder_substrate::Config + pallet_common::Config68 frame_system::Config
69 + pallet_evm_coder_substrate::Config
70 + pallet_common::Config
71 + pallet_structure::Config
56 {72 {
57 /// Currency from `pallet_balances`73 /// Currency from `pallet_balances`
58 type Currency: frame_support::traits::Currency<74 type Currency: frame_support::traits::Currency<
75 #[pallet::pallet]91 #[pallet::pallet]
76 pub struct Pallet<T>(_);92 pub struct Pallet<T>(_);
93
94 impl<T: Config> Pallet<T> {
95 /// Checks if a non-owner has (enough) allowance from the owner to perform operations on the tokens.
96 /// Returns the expected remaining allowance - it should be set manually if the transaction proceeds.
97 ///
98 /// - `collection`: Collection that contains the token.
99 /// - `spender`: CrossAccountId who has the allowance rights.
100 /// - `from`: The owner of the tokens who sets the allowance.
101 /// - `amount`: Amount of tokens by which the allowance sholud be reduced.
102 fn check_allowed(
103 spender: &T::CrossAccountId,
104 from: &T::CrossAccountId,
105 nesting_budget: &dyn Budget,
106 ) -> Result<u128, DispatchError> {
107 if spender.conv_eq(from) {
108 return Ok(0);
109 }
110
111 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {
112 ensure!(
113 <PalletStructure<T>>::check_indirectly_owned(
114 spender.clone(),
115 source.0,
116 source.1,
117 None,
118 nesting_budget
119 )?,
120 <CommonError<T>>::ApprovedValueTooLow,
121 );
122 } else if spender != from {
123 return Ok(0);
124 }
125
126 Ok(<T as Config>::Currency::free_balance(from.as_sub()).into())
127 }
128
129 /// Transfers the specified amount of tokens. Will check that
130 /// the transfer is allowed for the token.
131 ///
132 /// - `from`: Owner of tokens to transfer.
133 /// - `to`: Recepient of transfered tokens.
134 /// - `amount`: Amount of tokens to transfer.
135 /// - `collection`: Collection that contains the token
136 pub fn transfer(
137 _collection: &NativeFungibleHandle<T>,
138 from: &T::CrossAccountId,
139 to: &T::CrossAccountId,
140 amount: u128,
141 nesting_budget: &dyn Budget,
142 ) -> DispatchResultWithPostInfo {
143 <PalletCommon<T>>::ensure_correct_receiver(to)?;
144
145 if from != to && amount != 0 {
146 <T as Config>::Currency::transfer(
147 from.as_sub(),
148 to.as_sub(),
149 amount.into(),
150 ExistenceRequirement::KeepAlive,
151 )?;
152
153 <PalletStructure<T>>::nest_if_sent_to_token(
154 from.clone(),
155 to,
156 NATIVE_FUNGIBLE_COLLECTION_ID,
157 TokenId::default(),
158 nesting_budget,
159 )?;
160
161 let balance_from: u128 =
162 <T as Config>::Currency::free_balance(from.as_sub()).into();
163 if balance_from == 0 {
164 <PalletStructure<T>>::unnest_if_nested(
165 from,
166 NATIVE_FUNGIBLE_COLLECTION_ID,
167 TokenId::default(),
168 );
169 }
170 };
171
172 Ok(PostDispatchInfo {
173 actual_weight: Some(<SelfWeightOf<T>>::transfer()),
174 pays_fee: Pays::Yes,
175 })
176 }
177
178 pub fn transfer_from(
179 collection: &NativeFungibleHandle<T>,
180 spender: &T::CrossAccountId,
181 from: &T::CrossAccountId,
182 to: &T::CrossAccountId,
183 amount: u128,
184 nesting_budget: &dyn Budget,
185 ) -> DispatchResultWithPostInfo {
186 let allowance = Self::check_allowed(collection, spender, from, amount, nesting_budget)?;
187 if allowance < amount {
188 return Err(<CommonError<T>>::ApprovedValueTooLow.into());
189 }
190 Self::transfer(collection, from, to, amount, nesting_budget)
191 }
192 }
77}193}
78194