difftreelog
feat dispatch call to Native fingible
in: master
6 files changed
pallets/common/src/dispatch.rsdiffbeforeafterboth--- a/pallets/common/src/dispatch.rs
+++ b/pallets/common/src/dispatch.rs
@@ -94,9 +94,6 @@
/// * `handle` - Collection handle.
fn dispatch(handle: CollectionHandle<T>) -> Self;
- /// Get the collection handle for the corresponding implementation.
- fn into_inner(self) -> CollectionHandle<T>;
-
/// Get the implementation of [`CommonCollectionOperations`].
fn as_dyn(&self) -> &dyn CommonCollectionOperations<T>;
}
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -125,11 +125,7 @@
impl<T: Config> CollectionHandle<T> {
/// Same as [CollectionHandle::new] but with an explicit gas limit.
pub fn new_with_gas_limit(id: CollectionId, gas_limit: u64) -> Option<Self> {
- <CollectionById<T>>::get(id).map(|collection| Self {
- id,
- collection,
- recorder: SubstrateRecorder::new(gas_limit),
- })
+ Self::new_with_recorder(id, SubstrateRecorder::new(gas_limit))
}
/// Same as [CollectionHandle::new] but with an existed [`SubstrateRecorder`].
runtime/common/dispatch.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use frame_support::{dispatch::DispatchResult, ensure};18use pallet_evm::{PrecompileHandle, PrecompileResult};19use sp_core::H160;20use sp_runtime::DispatchError;21use sp_std::{borrow::ToOwned, vec::Vec};22use pallet_common::{23 CollectionById, CollectionHandle, CommonCollectionOperations, erc::CommonEvmHandler,24 eth::map_eth_to_id,25};26pub use pallet_common::dispatch::CollectionDispatch;27use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};28use pallet_balances_adapter::{Pallet as PalletNativeFungible, NativeFungibleHandle};29use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};30use pallet_refungible::{31 Pallet as PalletRefungible, RefungibleHandle, erc_token::RefungibleTokenHandle,32};33use up_data_structs::{34 CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,35 CollectionId, CollectionFlags,36};3738#[cfg(not(feature = "refungible"))]39use pallet_common::unsupported;4041pub enum CollectionDispatchT<T>42where43 T: pallet_fungible::Config44 + pallet_nonfungible::Config45 + pallet_refungible::Config46 + pallet_balances_adapter::Config,47{48 Fungible(FungibleHandle<T>),49 Nonfungible(NonfungibleHandle<T>),50 Refungible(RefungibleHandle<T>),51 NativeFungible(NativeFungibleHandle<T>),52}53impl<T> CollectionDispatch<T> for CollectionDispatchT<T>54where55 T: pallet_common::Config56 + pallet_unique::Config57 + pallet_fungible::Config58 + pallet_nonfungible::Config59 + pallet_refungible::Config60 + pallet_balances_adapter::Config,61{62 fn create(63 sender: T::CrossAccountId,64 payer: T::CrossAccountId,65 data: CreateCollectionData<T::AccountId>,66 flags: CollectionFlags,67 ) -> Result<CollectionId, DispatchError> {68 let id = match data.mode {69 CollectionMode::NFT => {70 <PalletNonfungible<T>>::init_collection(sender, payer, data, flags)?71 }72 CollectionMode::Fungible(decimal_points) => {73 // check params74 ensure!(75 decimal_points <= MAX_DECIMAL_POINTS,76 pallet_unique::Error::<T>::CollectionDecimalPointLimitExceeded77 );78 <PalletFungible<T>>::init_collection(sender, payer, data, flags)?79 }8081 #[cfg(feature = "refungible")]82 CollectionMode::ReFungible => {83 <PalletRefungible<T>>::init_collection(sender, payer, data, flags)?84 }8586 #[cfg(not(feature = "refungible"))]87 CollectionMode::ReFungible => return unsupported!(T),88 };89 Ok(id)90 }9192 fn destroy(sender: T::CrossAccountId, collection: CollectionHandle<T>) -> DispatchResult {93 match collection.mode {94 CollectionMode::ReFungible => {95 PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?96 }97 CollectionMode::Fungible(_) => {98 PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?99 }100 CollectionMode::NFT => {101 PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?102 }103 }104 Ok(())105 }106107 fn dispatch(handle: CollectionHandle<T>) -> Self {108 match handle.mode {109 CollectionMode::Fungible(_) => {110 if handle.id != up_data_structs::CollectionId(0) {111 Self::Fungible(FungibleHandle::cast(handle))112 } else {113 Self::NativeFungible(NativeFungibleHandle::cast(handle))114 }115 }116 CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),117 CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),118 }119 }120121 fn into_inner(self) -> CollectionHandle<T> {122 match self {123 Self::Fungible(f) => f.into_inner(),124 Self::Nonfungible(f) => f.into_inner(),125 Self::Refungible(f) => f.into_inner(),126 Self::NativeFungible(f) => f.into_inner(),127 }128 }129130 fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {131 match self {132 Self::Fungible(h) => h,133 Self::Nonfungible(h) => h,134 Self::Refungible(h) => h,135 Self::NativeFungible(h) => h,136 }137 }138}139140impl<T> pallet_evm::OnMethodCall<T> for CollectionDispatchT<T>141where142 T: pallet_common::Config143 + pallet_unique::Config144 + pallet_fungible::Config145 + pallet_nonfungible::Config146 + pallet_refungible::Config147 + pallet_balances_adapter::Config,148 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,149{150 fn is_reserved(target: &H160) -> bool {151 map_eth_to_id(target).is_some()152 }153 fn is_used(target: &H160) -> bool {154 map_eth_to_id(target)155 .map(<CollectionById<T>>::contains_key)156 .unwrap_or(false)157 }158 fn get_code(target: &H160) -> Option<Vec<u8>> {159 if let Some(collection_id) = map_eth_to_id(target) {160 let collection = <CollectionById<T>>::get(collection_id)?;161 Some(162 match collection.mode {163 CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,164 CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,165 CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,166 }167 .to_owned(),168 )169 } else if let Some((collection_id, _token_id)) =170 <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)171 {172 let collection = <CollectionById<T>>::get(collection_id)?;173 if collection.mode != CollectionMode::ReFungible {174 return None;175 }176 // TODO: check token existence177 Some(<RefungibleTokenHandle<T>>::CODE.to_owned())178 } else {179 None180 }181 }182 fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {183 if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {184 let collection =185 <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;186 let dispatched = Self::dispatch(collection);187188 match dispatched {189 Self::Fungible(h) => h.call(handle),190 Self::Nonfungible(h) => h.call(handle),191 Self::Refungible(h) => h.call(handle),192 Self::NativeFungible(f) => todo!(),193 }194 } else if let Some((collection_id, token_id)) =195 <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(196 &handle.code_address(),197 ) {198 let collection =199 <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;200 if collection.mode != CollectionMode::ReFungible {201 return None;202 }203204 let h = RefungibleHandle::cast(collection);205 // TODO: check token existence206 RefungibleTokenHandle(h, token_id).call(handle)207 } else {208 None209 }210 }211}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use frame_support::{dispatch::DispatchResult, ensure};18use pallet_evm::{PrecompileHandle, PrecompileResult};19use sp_core::H160;20use sp_runtime::DispatchError;21use sp_std::{borrow::ToOwned, vec::Vec};22use pallet_common::{23 CollectionById, CollectionHandle, CommonCollectionOperations, erc::CommonEvmHandler,24 eth::map_eth_to_id,25};26pub use pallet_common::dispatch::CollectionDispatch;27use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};28use pallet_balances_adapter::{Pallet as PalletNativeFungible, NativeFungibleHandle};29use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};30use pallet_refungible::{31 Pallet as PalletRefungible, RefungibleHandle, erc_token::RefungibleTokenHandle,32};33use up_data_structs::{34 CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,35 CollectionId, CollectionFlags,36};3738#[cfg(not(feature = "refungible"))]39use pallet_common::unsupported;4041pub enum CollectionDispatchT<T>42where43 T: pallet_fungible::Config44 + pallet_nonfungible::Config45 + pallet_refungible::Config46 + pallet_balances_adapter::Config,47{48 Fungible(FungibleHandle<T>),49 Nonfungible(NonfungibleHandle<T>),50 Refungible(RefungibleHandle<T>),51 NativeFungible(NativeFungibleHandle<T>),52}53impl<T> CollectionDispatch<T> for CollectionDispatchT<T>54where55 T: pallet_common::Config56 + pallet_unique::Config57 + pallet_fungible::Config58 + pallet_nonfungible::Config59 + pallet_refungible::Config60 + pallet_balances_adapter::Config,61{62 fn create(63 sender: T::CrossAccountId,64 payer: T::CrossAccountId,65 data: CreateCollectionData<T::AccountId>,66 flags: CollectionFlags,67 ) -> Result<CollectionId, DispatchError> {68 let id = match data.mode {69 CollectionMode::NFT => {70 <PalletNonfungible<T>>::init_collection(sender, payer, data, flags)?71 }72 CollectionMode::Fungible(decimal_points) => {73 // check params74 ensure!(75 decimal_points <= MAX_DECIMAL_POINTS,76 pallet_unique::Error::<T>::CollectionDecimalPointLimitExceeded77 );78 <PalletFungible<T>>::init_collection(sender, payer, data, flags)?79 }8081 #[cfg(feature = "refungible")]82 CollectionMode::ReFungible => {83 <PalletRefungible<T>>::init_collection(sender, payer, data, flags)?84 }8586 #[cfg(not(feature = "refungible"))]87 CollectionMode::ReFungible => return unsupported!(T),88 };89 Ok(id)90 }9192 fn destroy(sender: T::CrossAccountId, collection: CollectionHandle<T>) -> DispatchResult {93 match collection.mode {94 CollectionMode::ReFungible => {95 PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?96 }97 CollectionMode::Fungible(_) => {98 PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?99 }100 CollectionMode::NFT => {101 PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?102 }103 }104 Ok(())105 }106107 fn dispatch(handle: CollectionHandle<T>) -> Self {108 match handle.mode {109 CollectionMode::Fungible(_) => {110 if handle.id != up_data_structs::CollectionId(0) {111 Self::Fungible(FungibleHandle::cast(handle))112 } else {113 Self::NativeFungible(NativeFungibleHandle::cast(handle))114 }115 }116 CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),117 CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),118 }119 }120121 fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {122 match self {123 Self::Fungible(h) => h,124 Self::Nonfungible(h) => h,125 Self::Refungible(h) => h,126 Self::NativeFungible(h) => h,127 }128 }129}130131impl<T> pallet_evm::OnMethodCall<T> for CollectionDispatchT<T>132where133 T: pallet_common::Config134 + pallet_unique::Config135 + pallet_fungible::Config136 + pallet_nonfungible::Config137 + pallet_refungible::Config138 + pallet_balances_adapter::Config,139 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,140{141 fn is_reserved(target: &H160) -> bool {142 map_eth_to_id(target).is_some()143 }144 fn is_used(target: &H160) -> bool {145 map_eth_to_id(target)146 .map(<CollectionById<T>>::contains_key)147 .unwrap_or(false)148 }149 fn get_code(target: &H160) -> Option<Vec<u8>> {150 if let Some(collection_id) = map_eth_to_id(target) {151 let collection = <CollectionById<T>>::get(collection_id)?;152 Some(153 match collection.mode {154 CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,155 CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,156 CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,157 }158 .to_owned(),159 )160 } else if let Some((collection_id, _token_id)) =161 <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)162 {163 let collection = <CollectionById<T>>::get(collection_id)?;164 if collection.mode != CollectionMode::ReFungible {165 return None;166 }167 // TODO: check token existence168 Some(<RefungibleTokenHandle<T>>::CODE.to_owned())169 } else {170 None171 }172 }173 fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {174 if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {175 let collection =176 <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;177 let dispatched = Self::dispatch(collection);178179 match dispatched {180 Self::Fungible(h) => h.call(handle),181 Self::Nonfungible(h) => h.call(handle),182 Self::Refungible(h) => h.call(handle),183 Self::NativeFungible(h) => h.call(handle),184 }185 } else if let Some((collection_id, token_id)) =186 <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(187 &handle.code_address(),188 ) {189 let collection =190 <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;191 if collection.mode != CollectionMode::ReFungible {192 return None;193 }194195 let h = RefungibleHandle::cast(collection);196 // TODO: check token existence197 RefungibleTokenHandle(h, token_id).call(handle)198 } else {199 None200 }201 }202}tests/src/eth/fungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -33,7 +33,7 @@
'substrate' as const,
'ethereum' as const,
].map(testCase => {
- itEth(`Can perform mintCross() for ${testCase} address`, async ({helper}) => {
+ itEth.only(`Can perform mintCross() for ${testCase} address`, async ({helper}) => {
// 1. Create receiver depending on the test case:
const receiverEth = helper.eth.createAccount();
const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiverEth);
tests/src/eth/nativeFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/nativeFungible.test.ts
+++ b/tests/src/eth/nativeFungible.test.ts
@@ -38,7 +38,6 @@
const collectionAddress = helper.ethAddress.fromCollectionId(0);
const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
-
await contract.methods.approve(spender, 100).send({from: owner});
});
});
\ No newline at end of file
tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -142,7 +142,7 @@
async collection(address: string, mode: TCollectionMode, caller?: string, mergeDeprecated = false) {
let abi;
- if (address === '0' && mode === 'ft') {
+ if (address === '0x17C4e6453cC49aaAAEaCA894E6d9683e00000000' && mode === 'ft') {
abi = nativeFungibleAbi;
} else {
abi ={