use frame_support::traits::Get;
use pallet_deposit_storage::{
traits::DepositStorageHooks, DepositEntryOf, DepositKeyOf, FixedDepositCollectorViaDepositsPallet,
};
use pallet_dip_provider::IdentityCommitmentVersion;
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::{ConstU128, RuntimeDebug};
use crate::{constants::dip_provider::COMMITMENT_DEPOSIT, AccountId, DidIdentifier};
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Clone, PartialEq, Eq, RuntimeDebug)]
pub enum DepositNamespace {
DipProvider,
}
#[cfg(feature = "runtime-benchmarks")]
impl Default for DepositNamespace {
fn default() -> Self {
Self::DipProvider
}
}
pub struct DipProviderDepositNamespace;
impl Get<DepositNamespace> for DipProviderDepositNamespace {
fn get() -> DepositNamespace {
DepositNamespace::DipProvider
}
}
#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Clone, PartialEq, Eq, RuntimeDebug)]
pub enum DepositKey {
DipProvider {
identifier: DidIdentifier,
version: IdentityCommitmentVersion,
},
}
impl From<(DidIdentifier, AccountId, IdentityCommitmentVersion)> for DepositKey {
fn from((identifier, _, version): (DidIdentifier, AccountId, IdentityCommitmentVersion)) -> Self {
Self::DipProvider { identifier, version }
}
}
pub type DepositCollectorHooks =
FixedDepositCollectorViaDepositsPallet<DipProviderDepositNamespace, ConstU128<COMMITMENT_DEPOSIT>, DepositKey>;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum CommitmentDepositRemovalHookError {
DecodeKey,
Internal,
}
impl From<CommitmentDepositRemovalHookError> for u16 {
fn from(value: CommitmentDepositRemovalHookError) -> Self {
match value {
CommitmentDepositRemovalHookError::DecodeKey => 1,
CommitmentDepositRemovalHookError::Internal => u16::MAX,
}
}
}
const LOG_TARGET: &str = "dip::provider::DepositHooks";
pub struct DepositHooks;
impl<Runtime> DepositStorageHooks<Runtime> for DepositHooks
where
Runtime: pallet_deposit_storage::Config + pallet_dip_provider::Config<Identifier = DidIdentifier>,
{
type Error = CommitmentDepositRemovalHookError;
fn on_deposit_reclaimed(
_namespace: &<Runtime as pallet_deposit_storage::Config>::Namespace,
key: &DepositKeyOf<Runtime>,
_deposit: DepositEntryOf<Runtime>,
) -> Result<(), Self::Error> {
let DepositKey::DipProvider { identifier, version } =
DepositKey::decode(&mut &key[..]).map_err(|_| CommitmentDepositRemovalHookError::DecodeKey)?;
pallet_dip_provider::Pallet::<Runtime>::delete_identity_commitment_storage_entry_without_hook(
&identifier,
version,
)
.map_err(|_| {
log::error!(
target: LOG_TARGET,
"Failed to remove commitment for identifier {:#?} and version {:#?}",
identifier,
version
);
CommitmentDepositRemovalHookError::Internal
})?;
Ok(())
}
}
#[cfg(feature = "runtime-benchmarks")]
pub struct PalletDepositStorageBenchmarkHooks;
#[cfg(feature = "runtime-benchmarks")]
impl<Runtime> pallet_deposit_storage::traits::BenchmarkHooks<Runtime> for PalletDepositStorageBenchmarkHooks
where
Runtime: pallet_deposit_storage::Config<Namespace = DepositNamespace>
+ pallet_dip_provider::Config<Identifier = DidIdentifier, AccountId = AccountId>,
pallet_dip_provider::IdentityCommitmentOf<Runtime>: From<crate::Hash>,
{
fn pre_reclaim_deposit() -> (
<Runtime as frame_system::Config>::AccountId,
<Runtime as pallet_deposit_storage::Config>::Namespace,
sp_runtime::BoundedVec<u8, <Runtime as pallet_deposit_storage::Config>::MaxKeyLength>,
) {
let submitter = AccountId::from([100u8; 32]);
let namespace = DepositNamespace::DipProvider;
let did_identifier = DidIdentifier::from([200u8; 32]);
let commitment_version = 0u16;
let key: DepositKeyOf<Runtime> =
DepositKey::from((did_identifier.clone(), submitter.clone(), commitment_version))
.encode()
.try_into()
.expect("Should not fail to create a key for a DIP commitment.");
pallet_dip_provider::IdentityCommitments::<Runtime>::insert(
&did_identifier,
commitment_version,
pallet_dip_provider::IdentityCommitmentOf::<Runtime>::from(crate::Hash::default()),
);
assert!(pallet_dip_provider::IdentityCommitments::<Runtime>::get(did_identifier, commitment_version).is_some());
(submitter, namespace, key)
}
fn post_reclaim_deposit() {
let did_identifier = DidIdentifier::from([200u8; 32]);
let commitment_version = 0u16;
assert!(pallet_dip_provider::IdentityCommitments::<Runtime>::get(did_identifier, commitment_version).is_none());
}
}