diff --git a/pallets/index/src/lib.rs b/pallets/index/src/lib.rs index 5754c7c5..199b7745 100644 --- a/pallets/index/src/lib.rs +++ b/pallets/index/src/lib.rs @@ -45,6 +45,9 @@ pub mod pallet { pub trait Config: frame_system::Config + pallet_assets::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; type CommitteeOrigin: EnsureOrigin; + /// Fee reserve account + #[pallet::constant] + type FeeReserveAccount: Get; /// Asset adapter to do withdraw, deposit etc. type AssetTransactor: TransactAsset; /// Assets registry @@ -83,7 +86,7 @@ pub mod pallet { deposit_info: DepositInfo, }, /// Task has been claimed. - Claimed { tasks: Vec }, + Claimed { tasks: Vec, fee: u128 }, } #[pallet::error] @@ -96,6 +99,7 @@ pub mod pallet { NotFoundInTaskQueue, TaskQueueEmpty, TransactFailed, + FeeTooExpensive, } #[pallet::call] @@ -189,7 +193,7 @@ pub mod pallet { #[pallet::weight(Weight::from_parts(195_000_000, 0))] #[pallet::call_index(3)] #[transactional] - pub fn claim_task(origin: OriginFor, task_id: TaskId) -> DispatchResult { + pub fn claim_task(origin: OriginFor, task_id: TaskId, fee: u128) -> DispatchResult { // Check origin, must be the worker let worker: T::AccountId = ensure_signed(origin)?; ensure!( @@ -210,14 +214,21 @@ pub mod pallet { .collect(); ActivedTasks::::insert(&worker, &new_task_queue); let deposit_info = DepositRecords::::get(&task_id).unwrap(); + ensure!(deposit_info.amount > fee, Error::::FeeTooExpensive); // Withdraw from module account let module_account: T::AccountId = MODULE_ID.into_account_truncating(); Self::do_asset_transact( deposit_info.asset.clone(), - module_account, + module_account.clone(), worker, - deposit_info.amount, + deposit_info.amount - fee, + )?; + Self::do_asset_transact( + deposit_info.asset.clone(), + module_account, + ::FeeReserveAccount::get(), + fee, )?; // Delete deposit record @@ -225,43 +236,7 @@ pub mod pallet { Self::deposit_event(Event::Claimed { tasks: vec![task_id], - }); - Ok(()) - } - - #[pallet::weight(Weight::from_parts(195_000_000, 0))] - #[pallet::call_index(4)] - #[transactional] - pub fn claim_all_task(origin: OriginFor) -> DispatchResult { - // Check origin, must be the worker - let worker: T::AccountId = ensure_signed(origin)?; - ensure!( - Workers::::get(&worker) == true, - Error::::WorkerMismatch - ); - - // Take the task queue of the worker - let worker_task_queue = ActivedTasks::::take(&worker); - // Check reqeust exist in actived task queue - ensure!(worker_task_queue.len() > 0, Error::::NotFoundInTaskQueue); - for task_id in worker_task_queue.iter() { - let deposit_info = DepositRecords::::get(&task_id).unwrap(); - - // Withdraw from module account - let module_account: T::AccountId = MODULE_ID.into_account_truncating(); - Self::do_asset_transact( - deposit_info.asset.clone(), - module_account, - worker.clone(), - deposit_info.amount, - )?; - - // Delete deposit record - DepositRecords::::remove(&task_id); - } - - Self::deposit_event(Event::Claimed { - tasks: worker_task_queue.into(), + fee, }); Ok(()) } @@ -277,6 +252,10 @@ pub mod pallet { recipient: T::AccountId, amount: u128, ) -> DispatchResult { + if amount == 0 { + return Ok(()); + } + T::AssetTransactor::withdraw_asset( &(asset.clone(), amount).into(), &Junction::AccountId32 { @@ -310,8 +289,8 @@ pub mod pallet { use crate::{ActivedTasks, DepositRecords, Event as PalletIndexEvent, Workers, MODULE_ID}; use frame_support::{assert_noop, assert_ok}; use pallet_index::mock::{ - assert_events, new_test_ext, Assets, AssetsRegistry, Balances, PalletIndex, - RuntimeEvent as Event, RuntimeOrigin as Origin, Test, TestAssetAssetId, + assert_events, new_test_ext, Assets, AssetsRegistry, Balances, FeeReserveAccount, + PalletIndex, RuntimeEvent as Event, RuntimeOrigin as Origin, Test, TestAssetAssetId, TestAssetLocation, ALICE, BOB, ENDOWED_BALANCE, }; use sp_runtime::traits::AccountIdConversion; @@ -478,31 +457,38 @@ pub mod pallet { // Claim failed if sender is not worker assert_noop!( - PalletIndex::claim_task(Origin::signed(ALICE), request_id_1,), - pallet_index::Error::::WorkerMismatch - ); - assert_noop!( - PalletIndex::claim_all_task(Origin::signed(ALICE),), + PalletIndex::claim_task(Origin::signed(ALICE), request_id_1, 0), pallet_index::Error::::WorkerMismatch ); // Claim one task - assert_ok!(PalletIndex::claim_task(Origin::signed(BOB), request_id_1,)); + assert_ok!(PalletIndex::claim_task( + Origin::signed(BOB), + request_id_1, + 0 + )); assert_eq!(Balances::free_balance(module_account.clone()), 500); assert_eq!(Balances::free_balance(BOB), ENDOWED_BALANCE + 100); // Claim rest of tasks - assert_ok!(PalletIndex::claim_all_task(Origin::signed(BOB),)); + assert_ok!(PalletIndex::claim_task( + Origin::signed(BOB), + request_id_2, + 10 + )); + assert_ok!(PalletIndex::claim_task( + Origin::signed(BOB), + request_id_3, + 20 + )); + assert_eq!(Balances::free_balance(module_account), 0); - assert_eq!(Balances::free_balance(BOB), ENDOWED_BALANCE + 600); + assert_eq!(Balances::free_balance(FeeReserveAccount::get()), 30); + assert_eq!(Balances::free_balance(BOB), ENDOWED_BALANCE + 600 - 30); // Claim failed if no task exist assert_noop!( - PalletIndex::claim_task(Origin::signed(BOB), request_id_1,), - pallet_index::Error::::NotFoundInTaskQueue - ); - assert_noop!( - PalletIndex::claim_all_task(Origin::signed(BOB),), + PalletIndex::claim_task(Origin::signed(BOB), request_id_1, 0), pallet_index::Error::::NotFoundInTaskQueue ); }) diff --git a/pallets/index/src/mock.rs b/pallets/index/src/mock.rs index 4a9fa870..5133bb71 100644 --- a/pallets/index/src/mock.rs +++ b/pallets/index/src/mock.rs @@ -1,4 +1,5 @@ #![cfg(test)] +use crate as pallet_index; use frame_support::{ pallet_prelude::ConstU32, parameter_types, @@ -11,10 +12,9 @@ use frame_support::{ PalletId, }; use frame_system::{self as system, EnsureRoot, EnsureSigned}; -use sp_std::{marker::PhantomData, result}; -use crate as pallet_index; use polkadot_parachain_primitives::primitives::Sibling; use sp_runtime::BuildStorage; +use sp_std::{marker::PhantomData, result}; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, CurrencyAdapter, FungiblesAdapter, MintLocation, NoChecking, @@ -231,21 +231,30 @@ pub type FungiblesTransactor = FungiblesAdapter< CheckingAccountForFungibleAdapter, >; +parameter_types! { + pub const FeeReserveAccount: AccountId32 = AccountId32::new([3u8; 32]); +} + pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor); impl pallet_index::Config for Test { type RuntimeEvent = RuntimeEvent; type CommitteeOrigin = EnsureRoot; + type FeeReserveAccount = FeeReserveAccount; type AssetTransactor = AssetTransactors; type AssetsRegistry = AssetsRegistry; } pub fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap(); pallet_parachain_info::GenesisConfig:: { _mark: Default::default(), parachain_id: 2004u32.into(), - }.assimilate_storage(&mut t).unwrap(); + } + .assimilate_storage(&mut t) + .unwrap(); let assets_registry_account = assets_registry::ASSETS_REGISTRY_ID.into_account_truncating(); pallet_balances::GenesisConfig:: { diff --git a/runtime/khala/src/lib.rs b/runtime/khala/src/lib.rs index 1a67c7c8..3f7b6318 100644 --- a/runtime/khala/src/lib.rs +++ b/runtime/khala/src/lib.rs @@ -1872,6 +1872,7 @@ impl SortedMembers for InDexAdminMembers { impl pallet_index::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CommitteeOrigin = EnsureSignedBy; + type FeeReserveAccount = InDexAdminAccount; type AssetTransactor = (CurrencyTransactor, FungiblesTransactor); type AssetsRegistry = AssetsRegistry; } diff --git a/runtime/phala/src/lib.rs b/runtime/phala/src/lib.rs index 787a7968..205ad1c3 100644 --- a/runtime/phala/src/lib.rs +++ b/runtime/phala/src/lib.rs @@ -1830,6 +1830,7 @@ impl SortedMembers for InDexAdminMembers { impl pallet_index::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CommitteeOrigin = EnsureSignedBy; + type FeeReserveAccount = InDexAdminAccount; type AssetTransactor = (CurrencyTransactor, FungiblesTransactor); type AssetsRegistry = AssetsRegistry; } diff --git a/runtime/thala/src/lib.rs b/runtime/thala/src/lib.rs index 53d8a65e..c89aef99 100644 --- a/runtime/thala/src/lib.rs +++ b/runtime/thala/src/lib.rs @@ -1852,6 +1852,7 @@ impl pallet_phat_tokenomic::Config for Runtime { impl pallet_index::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CommitteeOrigin = EnsureRoot; + type FeeReserveAccount = ThalaTreasuryAccount; type AssetTransactor = (CurrencyTransactor, FungiblesTransactor); type AssetsRegistry = AssetsRegistry; }