Skip to content

Commit

Permalink
add OnAssetCreated and OnAssetDestroyed hook
Browse files Browse the repository at this point in the history
  • Loading branch information
ParthDesai committed Mar 19, 2024
1 parent 8f94158 commit ad1fbb0
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 4 deletions.
28 changes: 28 additions & 0 deletions pallets/foreign-asset-creator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ pub mod mock;
#[cfg(test)]
pub mod tests;

/// Trait for the OnForeignAssetRegistered hook
pub trait ForeignAssetCreatedHook<ForeignAsset, AssetId, AssetBalance> {
fn on_asset_created(
foreign_asset: &ForeignAsset,
asset_id: &AssetId,
min_balance: &AssetBalance,
);
}

/// Trait for the OnForeignAssetDeregistered hook
pub trait ForeignAssetDestroyedHook<ForeignAsset, AssetId> {
fn on_asset_destroyed(foreign_asset: &ForeignAsset, asset_id: &AssetId);
}

#[pallet]
pub mod pallet {
use super::*;
Expand Down Expand Up @@ -66,6 +80,16 @@ pub mod pallet {

/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;

/// Hook to be called when new foreign asset is registered.
type OnForeignAssetCreated: ForeignAssetCreatedHook<
Self::ForeignAsset,
AssetId<Self>,
AssetBalance<Self>,
>;

/// Hook to be called when foreign asset is de-registered.
type OnForeignAssetDestroyed: ForeignAssetDestroyedHook<Self::ForeignAsset, AssetId<Self>>;
}

pub type AssetBalance<T> = <<T as Config>::Fungibles as fungibles::Inspect<
Expand Down Expand Up @@ -152,6 +176,8 @@ pub mod pallet {
AssetIdToForeignAsset::<T>::insert(&asset_id, &foreign_asset);
ForeignAssetToAssetId::<T>::insert(&foreign_asset, &asset_id);

T::OnForeignAssetCreated::on_asset_created(&foreign_asset, &asset_id, &min_balance);

Self::deposit_event(Event::ForeignAssetCreated {
asset_id,
foreign_asset,
Expand Down Expand Up @@ -233,6 +259,8 @@ pub mod pallet {
// Remove from ForeignAssetToAssetId
ForeignAssetToAssetId::<T>::remove(&foreign_asset);

T::OnForeignAssetDestroyed::on_asset_destroyed(&foreign_asset, &asset_id);

Self::deposit_event(Event::ForeignAssetDestroyed {
asset_id,
foreign_asset,
Expand Down
77 changes: 76 additions & 1 deletion pallets/foreign-asset-creator/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@

use super::*;
use crate as pallet_foreign_asset_creator;
use std::marker::PhantomData;

use frame_support::{
construct_runtime, parameter_types,
construct_runtime, parameter_types, storage,
traits::{ConstU32, Everything},
};
use frame_system::EnsureRoot;
use parity_scale_codec::{Decode, Encode};
use sp_core::H256;
use sp_runtime::traits::{BlakeTwo256, IdentityLookup};
use sp_runtime::BuildStorage;
Expand Down Expand Up @@ -126,6 +128,77 @@ impl pallet_assets::Config for Test {
}
}

/// Gets parameters of last `ForeignAssetCreatedHook::on_asset_created` hook invocation
pub fn get_asset_created_hook_invocation<
ForeignAsset: Decode,
AssetId: Decode,
AssetBalance: Decode,
>() -> Option<(ForeignAsset, AssetId, AssetBalance)> {
storage::unhashed::get_raw(b"____on_foreign_asset_created")
.map(|output| Decode::decode(&mut output.as_slice()).expect("Decoding should work"))
}

/// Notes down parameters of current `ForeignAssetCreatedHook::on_asset_created` hook invocation
fn note_on_asset_created_hook_invocation<
ForeignAsset: Encode,
AssetId: Encode,
AssetBalance: Encode,
>(
foreign_asset: &ForeignAsset,
asset_id: &AssetId,
min_balance: &AssetBalance,
) {
storage::unhashed::put_raw(
b"____on_foreign_asset_created",
(foreign_asset, asset_id, min_balance).encode().as_slice(),
);
}

/// Gets parameters of last `ForeignAssetDestroyedHook::on_asset_destroyed` hook invocation
pub fn get_asset_destroyed_hook_invocation<ForeignAsset: Decode, AssetId: Decode>(
) -> Option<(ForeignAsset, AssetId)> {
storage::unhashed::get_raw(b"____on_foreign_asset_destroyed")
.map(|output| Decode::decode(&mut output.as_slice()).expect("Decoding should work"))
}

/// Notes down parameters of current `ForeignAssetDestroyedHook::on_asset_destroyed` hook invocation
fn note_on_asset_destroyed_hook_invocation<ForeignAsset: Encode, AssetId: Encode>(
foreign_asset: &ForeignAsset,
asset_id: &AssetId,
) {
storage::unhashed::put_raw(
b"____on_foreign_asset_destroyed",
(foreign_asset, asset_id).encode().as_slice(),
);
}

/// Test hook that records the hook invocation with exact params
pub struct NoteDownHook<ForeignAsset, AssetId, AssetBalance>(
PhantomData<(ForeignAsset, AssetId, AssetBalance)>,
);

impl<ForeignAsset: Encode, AssetId: Encode, AssetBalance: Encode>
ForeignAssetCreatedHook<ForeignAsset, AssetId, AssetBalance>
for NoteDownHook<ForeignAsset, AssetId, AssetBalance>
{
fn on_asset_created(
foreign_asset: &ForeignAsset,
asset_id: &AssetId,
min_balance: &AssetBalance,
) {
note_on_asset_created_hook_invocation(foreign_asset, asset_id, min_balance);
}
}

impl<ForeignAsset: Encode, AssetId: Encode, AssetBalance>
ForeignAssetDestroyedHook<ForeignAsset, AssetId>
for NoteDownHook<ForeignAsset, AssetId, AssetBalance>
{
fn on_asset_destroyed(foreign_asset: &ForeignAsset, asset_id: &AssetId) {
note_on_asset_destroyed_hook_invocation(foreign_asset, asset_id);
}
}

impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type ForeignAsset = Location;
Expand All @@ -134,6 +207,8 @@ impl Config for Test {
type ForeignAssetDestroyerOrigin = EnsureRoot<AccountId>;
type Fungibles = Assets;
type WeightInfo = ();
type OnForeignAssetCreated = NoteDownHook<MultiLocation, AssetId, Balance>;
type OnForeignAssetDestroyed = NoteDownHook<MultiLocation, AssetId, Balance>;
}

pub(crate) struct ExtBuilder {
Expand Down
25 changes: 22 additions & 3 deletions pallets/foreign-asset-creator/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,15 @@ fn creating_foreign_works() {
);
expect_events(vec![crate::Event::ForeignAssetCreated {
asset_id: 1,
foreign_asset: Location::parent(),
}])
foreign_asset: MultiLocation::parent(),
}]);

let (foreign_asset, asset_id, min_balance): (MultiLocation, u32, u64) =
get_asset_created_hook_invocation()
.expect("Decoding of invocation data should not fail");
assert_eq!(foreign_asset, MultiLocation::parent());
assert_eq!(asset_id, 1u32);
assert_eq!(min_balance, 1u64);
});
}

Expand Down Expand Up @@ -205,6 +212,13 @@ fn test_destroy_foreign_asset_also_removes_everything() {
1u64,
));

let (foreign_asset, asset_id, min_balance): (MultiLocation, u32, u64) =
get_asset_created_hook_invocation()
.expect("Decoding of invocation data should not fail");
assert_eq!(foreign_asset, MultiLocation::parent());
assert_eq!(asset_id, 1u32);
assert_eq!(min_balance, 1u64);

assert_ok!(ForeignAssetCreator::destroy_foreign_asset(
RuntimeOrigin::root(),
1
Expand All @@ -223,6 +237,11 @@ fn test_destroy_foreign_asset_also_removes_everything() {
asset_id: 1,
foreign_asset: Location::parent(),
},
])
]);

let (foreign_asset, asset_id): (MultiLocation, u32) = get_asset_destroyed_hook_invocation()
.expect("Decoding of invocation data should not fail");
assert_eq!(foreign_asset, MultiLocation::parent());
assert_eq!(asset_id, 1u32);
});
}

0 comments on commit ad1fbb0

Please sign in to comment.