diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index beb234518041e84020b5a7c32d48540c8220ee35..239395c95ccabb81b4b52f1bd509174254e13587 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -6329,8 +6329,8 @@ dependencies = [ "frame-support", "frame-system", "pallet-balances", - "pallet-root-testing", "pallet-collective", + "pallet-root-testing", "pallet-timestamp", "parity-scale-codec", "scale-info", diff --git a/substrate/frame/assets/src/impl_fungibles.rs b/substrate/frame/assets/src/impl_fungibles.rs index b005131176f4994d023a65a1c82a880910b3d077..6e0a9ac08ebb136c740d094121b00870d753262d 100644 --- a/substrate/frame/assets/src/impl_fungibles.rs +++ b/substrate/frame/assets/src/impl_fungibles.rs @@ -179,6 +179,24 @@ impl<T: Config<I>, I: 'static> fungibles::Create<T::AccountId> for Pallet<T, I> } } +impl<T: Config<I>, I: 'static> fungibles::Destroy<T::AccountId> for Pallet<T, I> { + fn start_destroy(id: T::AssetId, maybe_check_owner: Option<T::AccountId>) -> DispatchResult { + Self::do_start_destroy(id, maybe_check_owner) + } + + fn destroy_accounts(id: T::AssetId, max_items: u32) -> Result<u32, DispatchError> { + Self::do_destroy_accounts(id, max_items) + } + + fn destroy_approvals(id: T::AssetId, max_items: u32) -> Result<u32, DispatchError> { + Self::do_destroy_approvals(id, max_items) + } + + fn finish_destroy(id: T::AssetId) -> DispatchResult { + Self::do_finish_destroy(id) + } +} + impl<T: Config<I>, I: 'static> fungibles::metadata::Inspect<<T as SystemConfig>::AccountId> for Pallet<T, I> { diff --git a/substrate/frame/support/src/traits/tokens/fungibles.rs b/substrate/frame/support/src/traits/tokens/fungibles.rs index 9bdd5a10d794427f0194b3b32f7c369b115f2ce2..8c370e9a0d8b59d31bb59d12439f424cc23713b6 100644 --- a/substrate/frame/support/src/traits/tokens/fungibles.rs +++ b/substrate/frame/support/src/traits/tokens/fungibles.rs @@ -267,25 +267,51 @@ pub trait Create<AccountId>: Inspect<AccountId> { /// Trait for providing the ability to destroy existing fungible assets. pub trait Destroy<AccountId>: Inspect<AccountId> { - /// The witness data needed to destroy an asset. - type DestroyWitness; - - /// Provide the appropriate witness data needed to destroy an asset. - fn get_destroy_witness(id: &Self::AssetId) -> Option<Self::DestroyWitness>; - - /// Destroy an existing fungible asset. - /// * `id`: The `AssetId` to be destroyed. - /// * `witness`: Any witness data that needs to be provided to complete the operation - /// successfully. + /// Start the destruction an existing fungible asset. + /// * `id`: The `AssetId` to be destroyed. successfully. /// * `maybe_check_owner`: An optional account id that can be used to authorize the destroy - /// command. If not provided, we will not do any authorization checks before destroying the + /// command. If not provided, no authorization checks will be performed before destroying /// asset. + fn start_destroy(id: Self::AssetId, maybe_check_owner: Option<AccountId>) -> DispatchResult; + + /// Destroy all accounts associated with a given asset. + /// `destroy_accounts` should only be called after `start_destroy` has been called, and the + /// asset is in a `Destroying` state /// - /// If successful, this function will return the actual witness data from the destroyed asset. - /// This may be different than the witness data provided, and can be used to refund weight. - fn destroy( - id: Self::AssetId, - witness: Self::DestroyWitness, - maybe_check_owner: Option<AccountId>, - ) -> Result<Self::DestroyWitness, DispatchError>; + /// * `id`: The identifier of the asset to be destroyed. This must identify an existing asset. + /// * `max_items`: The maximum number of accounts to be destroyed for a given call of the + /// function. This value should be small enough to allow the operation fit into a logical + /// block. + /// + /// Response: + /// * u32: Total number of approvals which were actually destroyed + /// + /// Due to weight restrictions, this function may need to be called multiple + /// times to fully destroy all approvals. It will destroy `max_items` approvals at a + /// time. + fn destroy_accounts(id: Self::AssetId, max_items: u32) -> Result<u32, DispatchError>; + /// Destroy all approvals associated with a given asset up to the `max_items` + /// `destroy_approvals` should only be called after `start_destroy` has been called, and the + /// asset is in a `Destroying` state + /// + /// * `id`: The identifier of the asset to be destroyed. This must identify an existing asset. + /// * `max_items`: The maximum number of accounts to be destroyed for a given call of the + /// function. This value should be small enough to allow the operation fit into a logical + /// block. + /// + /// Response: + /// * u32: Total number of approvals which were actually destroyed + /// + /// Due to weight restrictions, this function may need to be called multiple + /// times to fully destroy all approvals. It will destroy `max_items` approvals at a + /// time. + fn destroy_approvals(id: Self::AssetId, max_items: u32) -> Result<u32, DispatchError>; + + /// Complete destroying asset and unreserve currency. + /// `finish_destroy` should only be called after `start_destroy` has been called, and the + /// asset is in a `Destroying` state. All accounts or approvals should be destroyed before + /// hand. + /// + /// * `id`: The identifier of the asset to be destroyed. This must identify an existing asset. + fn finish_destroy(id: Self::AssetId) -> DispatchResult; }