mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 21:21:11 +00:00
Add CallbackHandle to pallet-assets (#12307)
* Add CallbackHandle to pallet-assets * Address review comments * Add use for sp_io::storage * Rebase & review comments * Fix UT Co-authored-by: Hoon Kim <mail@hoonkim.me>
This commit is contained in:
@@ -1478,6 +1478,7 @@ impl pallet_assets::Config for Runtime {
|
||||
type StringLimit = StringLimit;
|
||||
type Freezer = ();
|
||||
type Extra = ();
|
||||
type CallbackHandle = ();
|
||||
type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
|
||||
type RemoveItemsLimit = ConstU32<1000>;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
|
||||
@@ -664,7 +664,8 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
status: AssetStatus::Live,
|
||||
},
|
||||
);
|
||||
Self::deposit_event(Event::ForceCreated { asset_id: id, owner });
|
||||
Self::deposit_event(Event::ForceCreated { asset_id: id, owner: owner.clone() });
|
||||
T::CallbackHandle::created(&id, &owner);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -754,6 +755,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
approvals_destroyed: removed_approvals as u32,
|
||||
approvals_remaining: details.approvals as u32,
|
||||
});
|
||||
T::CallbackHandle::destroyed(&id);
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(removed_approvals)
|
||||
|
||||
@@ -116,6 +116,11 @@
|
||||
//!
|
||||
//! Please refer to the [`Pallet`] struct for details on publicly available functions.
|
||||
//!
|
||||
//! ### Callbacks
|
||||
//!
|
||||
//! Using `CallbackHandle` associated type, user can configure custom callback functions which are
|
||||
//! executed when new asset is created or an existing asset is destroyed.
|
||||
//!
|
||||
//! ## Related Modules
|
||||
//!
|
||||
//! * [`System`](../frame_system/index.html)
|
||||
@@ -171,6 +176,18 @@ pub use weights::WeightInfo;
|
||||
|
||||
type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
|
||||
|
||||
/// Trait with callbacks that are executed after successfull asset creation or destruction.
|
||||
pub trait AssetsCallback<AssetId, AccountId> {
|
||||
/// Indicates that asset with `id` was successfully created by the `owner`
|
||||
fn created(_id: &AssetId, _owner: &AccountId) {}
|
||||
|
||||
/// Indicates that asset with `id` has just been destroyed
|
||||
fn destroyed(_id: &AssetId) {}
|
||||
}
|
||||
|
||||
/// Empty implementation in case no callbacks are required.
|
||||
impl<AssetId, AccountId> AssetsCallback<AssetId, AccountId> for () {}
|
||||
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
@@ -283,6 +300,9 @@ pub mod pallet {
|
||||
/// Additional data to be stored with an account's asset balance.
|
||||
type Extra: Member + Parameter + Default + MaxEncodedLen;
|
||||
|
||||
/// Callback methods for asset state change (e.g. asset created or destroyed)
|
||||
type CallbackHandle: AssetsCallback<Self::AssetId, Self::AccountId>;
|
||||
|
||||
/// Weight information for extrinsics in this pallet.
|
||||
type WeightInfo: WeightInfo;
|
||||
|
||||
@@ -598,7 +618,14 @@ pub mod pallet {
|
||||
status: AssetStatus::Live,
|
||||
},
|
||||
);
|
||||
Self::deposit_event(Event::Created { asset_id: id, creator: owner, owner: admin });
|
||||
|
||||
Self::deposit_event(Event::Created {
|
||||
asset_id: id,
|
||||
creator: owner.clone(),
|
||||
owner: admin,
|
||||
});
|
||||
T::CallbackHandle::created(&id, &owner);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
use super::*;
|
||||
use crate as pallet_assets;
|
||||
|
||||
use codec::Encode;
|
||||
use frame_support::{
|
||||
construct_runtime, parameter_types,
|
||||
traits::{AsEnsureOriginWithArg, ConstU32, ConstU64, GenesisBuild},
|
||||
};
|
||||
use sp_core::H256;
|
||||
use sp_io::storage;
|
||||
use sp_runtime::{
|
||||
testing::Header,
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
@@ -45,6 +47,9 @@ construct_runtime!(
|
||||
}
|
||||
);
|
||||
|
||||
type AccountId = u64;
|
||||
type AssetId = u32;
|
||||
|
||||
impl frame_system::Config for Test {
|
||||
type BaseCallFilter = frame_support::traits::Everything;
|
||||
type BlockWeights = ();
|
||||
@@ -55,7 +60,7 @@ impl frame_system::Config for Test {
|
||||
type BlockNumber = u64;
|
||||
type Hash = H256;
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = u64;
|
||||
type AccountId = AccountId;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Header = Header;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
@@ -84,6 +89,17 @@ impl pallet_balances::Config for Test {
|
||||
type ReserveIdentifier = [u8; 8];
|
||||
}
|
||||
|
||||
pub struct AssetsCallbackHandle;
|
||||
impl AssetsCallback<AssetId, AccountId> for AssetsCallbackHandle {
|
||||
fn created(_id: &AssetId, _owner: &AccountId) {
|
||||
storage::set(b"asset_created", &().encode());
|
||||
}
|
||||
|
||||
fn destroyed(_id: &AssetId) {
|
||||
storage::set(b"asset_destroyed", &().encode());
|
||||
}
|
||||
}
|
||||
|
||||
impl Config for Test {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Balance = u64;
|
||||
@@ -100,6 +116,7 @@ impl Config for Test {
|
||||
type StringLimit = ConstU32<50>;
|
||||
type Freezer = TestFreezer;
|
||||
type WeightInfo = ();
|
||||
type CallbackHandle = AssetsCallbackHandle;
|
||||
type Extra = ();
|
||||
type RemoveItemsLimit = ConstU32<5>;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
|
||||
@@ -24,6 +24,7 @@ use frame_support::{
|
||||
traits::{fungibles::InspectEnumerable, Currency},
|
||||
};
|
||||
use pallet_balances::Error as BalancesError;
|
||||
use sp_io::storage;
|
||||
use sp_runtime::{traits::ConvertInto, TokenError};
|
||||
|
||||
fn asset_ids() -> Vec<u32> {
|
||||
@@ -1194,3 +1195,32 @@ fn querying_roles_should_work() {
|
||||
assert_eq!(Assets::freezer(0), Some(4));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn normal_asset_create_and_destroy_callbacks_should_work() {
|
||||
new_test_ext().execute_with(|| {
|
||||
assert!(storage::get(b"asset_created").is_none());
|
||||
assert!(storage::get(b"asset_destroyed").is_none());
|
||||
|
||||
Balances::make_free_balance_be(&1, 100);
|
||||
assert_ok!(Assets::create(RuntimeOrigin::signed(1), 0, 1, 1));
|
||||
assert!(storage::get(b"asset_created").is_some());
|
||||
assert!(storage::get(b"asset_destroyed").is_none());
|
||||
|
||||
assert_ok!(Assets::start_destroy(RuntimeOrigin::signed(1), 0));
|
||||
assert_ok!(Assets::destroy_accounts(RuntimeOrigin::signed(1), 0));
|
||||
assert_ok!(Assets::destroy_approvals(RuntimeOrigin::signed(1), 0));
|
||||
assert_ok!(Assets::finish_destroy(RuntimeOrigin::signed(1), 0));
|
||||
assert!(storage::get(b"asset_destroyed").is_some());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn root_asset_create_should_work() {
|
||||
new_test_ext().execute_with(|| {
|
||||
assert!(storage::get(b"asset_created").is_none());
|
||||
assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1));
|
||||
assert!(storage::get(b"asset_created").is_some());
|
||||
assert!(storage::get(b"asset_destroyed").is_none());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -171,6 +171,7 @@ impl pallet_assets::Config for Runtime {
|
||||
type StringLimit = ConstU32<20>;
|
||||
type Freezer = ();
|
||||
type Extra = ();
|
||||
type CallbackHandle = ();
|
||||
type WeightInfo = ();
|
||||
type RemoveItemsLimit = ConstU32<1000>;
|
||||
pallet_assets::runtime_benchmarks_enabled! {
|
||||
|
||||
Reference in New Issue
Block a user