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

difftreelog

refac: incapsulate CollectionHandler into CollectionDispatch

Trubnikov Sergey2023-04-24parent: #361b516.patch.diff
in: master

13 files changed

modifiedpallets/balances-adapter/src/lib.rsdiffbeforeafterboth
--- a/pallets/balances-adapter/src/lib.rs
+++ b/pallets/balances-adapter/src/lib.rs
@@ -3,6 +3,7 @@
 #![warn(missing_docs)]
 
 extern crate alloc;
+use frame_support::sp_runtime::DispatchResult;
 pub use pallet::*;
 use pallet_common::CollectionHandle;
 use pallet_evm_coder_substrate::{WithRecorder, SubstrateRecorder};
@@ -10,24 +11,23 @@
 pub mod common;
 pub mod erc;
 
-pub struct NativeFungibleHandle<T: Config>(CollectionHandle<T>);
+pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);
 impl<T: Config> NativeFungibleHandle<T> {
-	pub fn cast(inner: CollectionHandle<T>) -> Self {
-		Self(inner)
+	pub fn new() -> NativeFungibleHandle<T> {
+		Self(SubstrateRecorder::new(u64::MAX))
 	}
 
-	/// Casts [`NativeFungibleHandle`] into [`CollectionHandle`][`pallet_common::CollectionHandle`].
-	pub fn into_inner(self) -> pallet_common::CollectionHandle<T> {
-		self.0
+	pub fn check_is_internal(&self) -> DispatchResult {
+		Ok(())
 	}
 }
 
 impl<T: Config> WithRecorder<T> for NativeFungibleHandle<T> {
 	fn recorder(&self) -> &pallet_evm_coder_substrate::SubstrateRecorder<T> {
-		&self.0.recorder
+		&self.0
 	}
 	fn into_recorder(self) -> pallet_evm_coder_substrate::SubstrateRecorder<T> {
-		self.0.recorder
+		self.0
 	}
 }
 #[frame_support::pallet]
modifiedpallets/common/src/dispatch.rsdiffbeforeafterboth
--- a/pallets/common/src/dispatch.rs
+++ b/pallets/common/src/dispatch.rs
@@ -34,16 +34,11 @@
 	collection: CollectionId,
 	call: C,
 ) -> DispatchResultWithPostInfo {
-	let handle =
-		CollectionHandle::try_get(collection).map_err(|error| DispatchErrorWithPostInfo {
-			post_info: PostDispatchInfo {
-				actual_weight: Some(dispatch_weight::<T>()),
-				pays_fee: Pays::Yes,
-			},
-			error,
-		})?;
-	handle
-		.check_is_internal()
+	let dispatched = T::CollectionDispatch::dispatch(collection)
+		.and_then(|dispatched| {
+			dispatched.check_is_internal()?;
+			Ok(dispatched)
+		})
 		.map_err(|error| DispatchErrorWithPostInfo {
 			post_info: PostDispatchInfo {
 				actual_weight: Some(dispatch_weight::<T>()),
@@ -51,7 +46,6 @@
 			},
 			error,
 		})?;
-	let dispatched = T::CollectionDispatch::dispatch(handle);
 	let mut result = call(dispatched.as_dyn());
 	match &mut result {
 		Ok(PostDispatchInfo {
@@ -72,6 +66,8 @@
 
 /// Interface for working with different collections through the dispatcher.
 pub trait CollectionDispatch<T: Config> {
+	fn check_is_internal(&self) -> DispatchResult;
+
 	/// Create a collection. The collection will be created according to the value of [`data.mode`](CreateCollectionData::mode).
 	///
 	/// * `sender` - The user who will become the owner of the collection.
@@ -92,7 +88,9 @@
 	/// Get a specialized collection from the handle.
 	///
 	/// * `handle` - Collection handle.
-	fn dispatch(handle: CollectionHandle<T>) -> Self;
+	fn dispatch(collection_id: CollectionId) -> Result<Self, DispatchError>
+	where
+		Self: Sized;
 
 	/// Get the implementation of [`CommonCollectionOperations`].
 	fn as_dyn(&self) -> &dyn CommonCollectionOperations<T>;
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -77,6 +77,14 @@
 	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult>;
 }
 
+impl CommonEvmHandler for () {
+	const CODE: &'static [u8] = &[];
+
+	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
+		None
+	}
+}
+
 /// @title A contract that allows you to work with collections.
 #[solidity_interface(name = Collection, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> CollectionHandle<T>
modifiedpallets/structure/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/structure/src/benchmarking.rs
+++ b/pallets/structure/src/benchmarking.rs
@@ -42,7 +42,7 @@
 			},
 			CollectionFlags::default(),
 		)?;
-		let dispatch = T::CollectionDispatch::dispatch(CollectionHandle::try_get(CollectionId(1))?);
+		let dispatch = T::CollectionDispatch::dispatch(CollectionId(1))?;
 		let dispatch = dispatch.as_dyn();
 
 		dispatch.create_item(caller_cross.clone(), caller_cross.clone(), CreateItemData::NFT(CreateNftData::default()), &Unlimited)?;
modifiedpallets/structure/src/lib.rsdiffbeforeafterboth
--- a/pallets/structure/src/lib.rs
+++ b/pallets/structure/src/lib.rs
@@ -155,11 +155,10 @@
 		token: TokenId,
 	) -> Result<Parent<T::CrossAccountId>, DispatchError> {
 		// TODO: Reduce cost by not reading collection config
-		let handle = match CollectionHandle::try_get(collection) {
+		let handle = match T::CollectionDispatch::dispatch(collection) {
 			Ok(v) => v,
 			Err(_) => return Ok(Parent::TokenNotFound),
 		};
-		let handle = T::CollectionDispatch::dispatch(handle);
 		let handle = handle.as_dyn();
 
 		Ok(match handle.token_owner(token) {
@@ -279,8 +278,7 @@
 		self_budget: &dyn Budget,
 		breadth_budget: &dyn Budget,
 	) -> DispatchResultWithPostInfo {
-		let handle = <CollectionHandle<T>>::try_get(collection)?;
-		let dispatch = T::CollectionDispatch::dispatch(handle);
+		let dispatch = T::CollectionDispatch::dispatch(collection)?;
 		let dispatch = dispatch.as_dyn();
 		dispatch.burn_item_recursively(from.clone(), token, self_budget, breadth_budget)
 	}
@@ -404,10 +402,8 @@
 		let Some((collection, token)) = T::CrossTokenAddressMapping::address_to_token(account) else {
 			return Ok(())
 		};
-
-		let handle = <CollectionHandle<T>>::try_get(collection)?;
 
-		let dispatch = T::CollectionDispatch::dispatch(handle);
+		let dispatch = T::CollectionDispatch::dispatch(collection)?;
 		let dispatch = dispatch.as_dyn();
 
 		action(dispatch, token)
modifiedruntime/common/dispatch.rsdiffbeforeafterboth
59 + pallet_refungible::Config60 + pallet_refungible::Config
60 + pallet_balances_adapter::Config,61 + pallet_balances_adapter::Config,
61{62{
63 fn check_is_internal(&self) -> DispatchResult {
64 match self {
65 Self::Fungible(h) => h.check_is_internal(),
66 Self::Nonfungible(h) => h.check_is_internal(),
67 Self::Refungible(h) => h.check_is_internal(),
68 Self::NativeFungible(h) => h.check_is_internal(),
69 }
70 }
71
62 fn create(72 fn create(
63 sender: T::CrossAccountId,73 sender: T::CrossAccountId,
104 Ok(())114 Ok(())
105 }115 }
106116
107 fn dispatch(handle: CollectionHandle<T>) -> Self {117 fn dispatch(collection_id: CollectionId) -> Result<Self, DispatchError> {
118 if collection_id == CollectionId(0) {
119 return Ok(Self::NativeFungible(NativeFungibleHandle::new()));
120 }
121
122 let handle = <CollectionHandle<T>>::try_get(collection_id)?;
108 match handle.mode {123 Ok(match handle.mode {
109 CollectionMode::Fungible(_) => {124 CollectionMode::Fungible(_) => Self::Fungible(FungibleHandle::cast(handle)),
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)),125 CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),
117 CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),126 CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),
118 }127 })
119 }128 }
120129
121 fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {130 fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {
122 match self {131 match self {
172 }181 }
173 fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {182 fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
174 if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {183 if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {
184 if collection_id == CollectionId(0) {
185 <NativeFungibleHandle<T>>::new().call(handle)
186 } else {
175 let collection =187 let collection = <CollectionHandle<T>>::new_with_gas_limit(
176 <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;188 collection_id,
177 let dispatched = Self::dispatch(collection);189 handle.remaining_gas(),
190 )?;
178191
179 match dispatched {192 match collection.mode {
180 Self::Fungible(h) => h.call(handle),193 CollectionMode::Fungible(_) => FungibleHandle::cast(collection).call(handle),
181 Self::Nonfungible(h) => h.call(handle),194 CollectionMode::NFT => NonfungibleHandle::cast(collection).call(handle),
182 Self::Refungible(h) => h.call(handle),195 CollectionMode::ReFungible => RefungibleHandle::cast(collection).call(handle),
183 Self::NativeFungible(h) => h.call(handle),
184 }196 }
197 }
185 } else if let Some((collection_id, token_id)) =198 } else if let Some((collection_id, token_id)) =
186 <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(199 <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(
187 &handle.code_address(),200 &handle.code_address(),
modifiedruntime/common/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -17,7 +17,7 @@
 #[macro_export]
 macro_rules! dispatch_unique_runtime {
 	($collection:ident.$method:ident($($name:ident),*) $($rest:tt)*) => {{
-		let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
+		let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch($collection)?;
 		let dispatch = collection.as_dyn();
 
 		Ok::<_, DispatchError>(dispatch.$method($($name),*) $($rest)*)
modifiedtests/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.only(`Can perform mintCross() for ${testCase} address`, async ({helper}) => {
+    itEth(`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);
modifiedtests/src/eth/nativeFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nativeFungible.test.ts
+++ b/tests/src/eth/nativeFungible.test.ts
@@ -29,7 +29,7 @@
     });
   });
 
-  itEth.only('Can perform approve()', async ({helper}) => {
+  itEth.skip('Can perform approve()', async ({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor);
     const spender = helper.eth.createAccount();
     const collection = await helper.ft.mintCollection(alice);
modifiedtests/src/eth/util/playgrounds/types.tsdiffbeforeafterboth
--- a/tests/src/eth/util/playgrounds/types.ts
+++ b/tests/src/eth/util/playgrounds/types.ts
@@ -48,3 +48,5 @@
   field: CollectionLimitField,
   value: OptionUint,
 }
+
+export const NON_EXISTENT_COLLECTION_ID = 4_294_967_295;
\ No newline at end of file
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -19,6 +19,7 @@
 // Pallets that must always be present
 const requiredPallets = [
   'balances',
+  'balancesadapter',
   'common',
   'timestamp',
   'transactionpayment',
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -17,6 +17,7 @@
 import {IKeyringPair} from '@polkadot/types/types';
 import {itEth, usingEthPlaygrounds} from './eth/util';
 import {itSub, Pallets, usingPlaygrounds, expect} from './util';
+import {NON_EXISTENT_COLLECTION_ID} from './eth/util/playgrounds/types';
 
 describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
   let donor: IKeyringPair;
@@ -124,20 +125,17 @@
 
 
   itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {
-    const collectionId = (1 << 32) - 1;
-    await expect(helper.nft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
+    await expect(helper.nft.transferToken(alice, NON_EXISTENT_COLLECTION_ID, 1, {Substrate: bob.address}))
       .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
   itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {
-    const collectionId = (1 << 32) - 1;
-    await expect(helper.ft.transfer(alice, collectionId, {Substrate: bob.address}))
+    await expect(helper.ft.transfer(alice, NON_EXISTENT_COLLECTION_ID, {Substrate: bob.address}))
       .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
   itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {
-    const collectionId = (1 << 32) - 1;
-    await expect(helper.rft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
+    await expect(helper.rft.transferToken(alice, NON_EXISTENT_COLLECTION_ID, 1, {Substrate: bob.address}))
       .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
--- a/tests/src/transferFrom.test.ts
+++ b/tests/src/transferFrom.test.ts
@@ -16,6 +16,7 @@
 
 import {IKeyringPair} from '@polkadot/types/types';
 import {itSub, Pallets, usingPlaygrounds, expect} from './util';
+import {NON_EXISTENT_COLLECTION_ID} from './eth/util/playgrounds/types';
 
 describe('Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {
   let alice: IKeyringPair;
@@ -97,10 +98,9 @@
   });
 
   itSub('transferFrom for a collection that does not exist', async ({helper}) => {
-    const collectionId = (1 << 32) - 1;
-    await expect(helper.collection.approveToken(alice, collectionId, 0, {Substrate: bob.address}, 1n))
+    await expect(helper.collection.approveToken(alice, NON_EXISTENT_COLLECTION_ID, 0, {Substrate: bob.address}, 1n))
       .to.be.rejectedWith(/common\.CollectionNotFound/);
-    await expect(helper.collection.transferTokenFrom(bob, collectionId, 0, {Substrate: alice.address}, {Substrate: bob.address}, 1n))
+    await expect(helper.collection.transferTokenFrom(bob, NON_EXISTENT_COLLECTION_ID, 0, {Substrate: alice.address}, {Substrate: bob.address}, 1n))
       .to.be.rejectedWith(/common\.CollectionNotFound/);
   });