difftreelog
feat dispatch call to Native fingible
in: master
6 files changed
pallets/common/src/dispatch.rsdiffbeforeafterboth1//! Module with interfaces for dispatching collections.23use frame_support::{4 dispatch::{5 DispatchResultWithPostInfo, PostDispatchInfo, Weight, DispatchErrorWithPostInfo,6 DispatchResult,7 },8 dispatch::Pays,9 traits::Get,10};11use sp_runtime::DispatchError;12use up_data_structs::{CollectionId, CreateCollectionData, CollectionFlags};1314use crate::{pallet::Config, CommonCollectionOperations, CollectionHandle};1516// TODO: move to benchmarking17/// Price of [`dispatch_tx`] call with noop `call` argument18pub fn dispatch_weight<T: Config>() -> Weight {19 // Read collection20 <T as frame_system::Config>::DbWeight::get().reads(1)21 // Dynamic dispatch?22 + Weight::from_parts(6_000_000, 0)23 // submit_logs is measured as part of collection pallets24}2526/// Helper function to implement substrate calls for common collection methods.27///28/// * `collection` - The collection on which to call the method.29/// * `call` - The function in which to call the corresponding method from [`CommonCollectionOperations`].30pub fn dispatch_tx<31 T: Config,32 C: FnOnce(&dyn CommonCollectionOperations<T>) -> DispatchResultWithPostInfo,33>(34 collection: CollectionId,35 call: C,36) -> DispatchResultWithPostInfo {37 let handle =38 CollectionHandle::try_get(collection).map_err(|error| DispatchErrorWithPostInfo {39 post_info: PostDispatchInfo {40 actual_weight: Some(dispatch_weight::<T>()),41 pays_fee: Pays::Yes,42 },43 error,44 })?;45 handle46 .check_is_internal()47 .map_err(|error| DispatchErrorWithPostInfo {48 post_info: PostDispatchInfo {49 actual_weight: Some(dispatch_weight::<T>()),50 pays_fee: Pays::Yes,51 },52 error,53 })?;54 let dispatched = T::CollectionDispatch::dispatch(handle);55 let mut result = call(dispatched.as_dyn());56 match &mut result {57 Ok(PostDispatchInfo {58 actual_weight: Some(weight),59 ..60 })61 | Err(DispatchErrorWithPostInfo {62 post_info: PostDispatchInfo {63 actual_weight: Some(weight),64 ..65 },66 ..67 }) => *weight += dispatch_weight::<T>(),68 _ => {}69 }70 result71}7273/// Interface for working with different collections through the dispatcher.74pub trait CollectionDispatch<T: Config> {75 /// Create a collection. The collection will be created according to the value of [`data.mode`](CreateCollectionData::mode).76 ///77 /// * `sender` - The user who will become the owner of the collection.78 /// * `data` - Description of the created collection.79 fn create(80 sender: T::CrossAccountId,81 payer: T::CrossAccountId,82 data: CreateCollectionData<T::AccountId>,83 flags: CollectionFlags,84 ) -> Result<CollectionId, DispatchError>;8586 /// Delete the collection.87 ///88 /// * `sender` - The owner of the collection.89 /// * `handle` - Collection handle.90 fn destroy(sender: T::CrossAccountId, handle: CollectionHandle<T>) -> DispatchResult;9192 /// Get a specialized collection from the handle.93 ///94 /// * `handle` - Collection handle.95 fn dispatch(handle: CollectionHandle<T>) -> Self;9697 /// Get the collection handle for the corresponding implementation.98 fn into_inner(self) -> CollectionHandle<T>;99100 /// Get the implementation of [`CommonCollectionOperations`].101 fn as_dyn(&self) -> &dyn CommonCollectionOperations<T>;102}1//! Module with interfaces for dispatching collections.23use frame_support::{4 dispatch::{5 DispatchResultWithPostInfo, PostDispatchInfo, Weight, DispatchErrorWithPostInfo,6 DispatchResult,7 },8 dispatch::Pays,9 traits::Get,10};11use sp_runtime::DispatchError;12use up_data_structs::{CollectionId, CreateCollectionData, CollectionFlags};1314use crate::{pallet::Config, CommonCollectionOperations, CollectionHandle};1516// TODO: move to benchmarking17/// Price of [`dispatch_tx`] call with noop `call` argument18pub fn dispatch_weight<T: Config>() -> Weight {19 // Read collection20 <T as frame_system::Config>::DbWeight::get().reads(1)21 // Dynamic dispatch?22 + Weight::from_parts(6_000_000, 0)23 // submit_logs is measured as part of collection pallets24}2526/// Helper function to implement substrate calls for common collection methods.27///28/// * `collection` - The collection on which to call the method.29/// * `call` - The function in which to call the corresponding method from [`CommonCollectionOperations`].30pub fn dispatch_tx<31 T: Config,32 C: FnOnce(&dyn CommonCollectionOperations<T>) -> DispatchResultWithPostInfo,33>(34 collection: CollectionId,35 call: C,36) -> DispatchResultWithPostInfo {37 let handle =38 CollectionHandle::try_get(collection).map_err(|error| DispatchErrorWithPostInfo {39 post_info: PostDispatchInfo {40 actual_weight: Some(dispatch_weight::<T>()),41 pays_fee: Pays::Yes,42 },43 error,44 })?;45 handle46 .check_is_internal()47 .map_err(|error| DispatchErrorWithPostInfo {48 post_info: PostDispatchInfo {49 actual_weight: Some(dispatch_weight::<T>()),50 pays_fee: Pays::Yes,51 },52 error,53 })?;54 let dispatched = T::CollectionDispatch::dispatch(handle);55 let mut result = call(dispatched.as_dyn());56 match &mut result {57 Ok(PostDispatchInfo {58 actual_weight: Some(weight),59 ..60 })61 | Err(DispatchErrorWithPostInfo {62 post_info: PostDispatchInfo {63 actual_weight: Some(weight),64 ..65 },66 ..67 }) => *weight += dispatch_weight::<T>(),68 _ => {}69 }70 result71}7273/// Interface for working with different collections through the dispatcher.74pub trait CollectionDispatch<T: Config> {75 /// Create a collection. The collection will be created according to the value of [`data.mode`](CreateCollectionData::mode).76 ///77 /// * `sender` - The user who will become the owner of the collection.78 /// * `data` - Description of the created collection.79 fn create(80 sender: T::CrossAccountId,81 payer: T::CrossAccountId,82 data: CreateCollectionData<T::AccountId>,83 flags: CollectionFlags,84 ) -> Result<CollectionId, DispatchError>;8586 /// Delete the collection.87 ///88 /// * `sender` - The owner of the collection.89 /// * `handle` - Collection handle.90 fn destroy(sender: T::CrossAccountId, handle: CollectionHandle<T>) -> DispatchResult;9192 /// Get a specialized collection from the handle.93 ///94 /// * `handle` - Collection handle.95 fn dispatch(handle: CollectionHandle<T>) -> Self;9697 /// Get the implementation of [`CommonCollectionOperations`].98 fn as_dyn(&self) -> &dyn CommonCollectionOperations<T>;99}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.rsdiffbeforeafterboth--- a/runtime/common/dispatch.rs
+++ b/runtime/common/dispatch.rs
@@ -118,15 +118,6 @@
}
}
- fn into_inner(self) -> CollectionHandle<T> {
- match self {
- Self::Fungible(f) => f.into_inner(),
- Self::Nonfungible(f) => f.into_inner(),
- Self::Refungible(f) => f.into_inner(),
- Self::NativeFungible(f) => f.into_inner(),
- }
- }
-
fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {
match self {
Self::Fungible(h) => h,
@@ -189,7 +180,7 @@
Self::Fungible(h) => h.call(handle),
Self::Nonfungible(h) => h.call(handle),
Self::Refungible(h) => h.call(handle),
- Self::NativeFungible(f) => todo!(),
+ Self::NativeFungible(h) => h.call(handle),
}
} else if let Some((collection_id, token_id)) =
<T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(
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 ={