Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLOCKCHAIN-260 Allow company owner to request unregistration #337

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions frame/registry/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ benchmarks_instance_pallet! {
}: _<T::RuntimeOrigin>(origin, 0, data.clone(), false)
verify {
let entity_id: T::EntityId = 0u8.into();
assert!(matches!(Registry::<T, I>::requests(0, entity_id), Some(Request { data: ndata, .. }) if ndata == data));
assert!(matches!(Registry::<T, I>::requests(0, entity_id), Some(Some(Request { data: ndata, .. })) if ndata == data));
}

request_registration {
Expand All @@ -59,7 +59,7 @@ benchmarks_instance_pallet! {
Registry::<T, I>::request_entity(origin.clone(), 0, data.clone(), false).unwrap();
}: _<T::RuntimeOrigin>(origin, 0, entity_id.clone(), data.clone(), false)
verify {
assert!(matches!(Registry::<T, I>::requests(0, entity_id), Some(Request { data: ndata, .. }) if ndata == data));
assert!(matches!(Registry::<T, I>::requests(0, entity_id), Some(Some(Request { data: ndata, .. })) if ndata == data));
}

cancel_request {
Expand All @@ -69,7 +69,7 @@ benchmarks_instance_pallet! {
let data = get_data::<T, I>(1, 100 as usize);
Registry::<T, I>::request_entity(origin.clone(), 0, data.clone(), false).unwrap();
let entity_id: T::EntityId = 0u8.into();
assert!(matches!(Registry::<T, I>::requests(0, entity_id.clone()), Some(Request { data: ndata, .. }) if ndata == data));
assert!(matches!(Registry::<T, I>::requests(0, entity_id.clone()), Some(Some(Request { data: ndata, .. })) if ndata == data));
}: _<T::RuntimeOrigin>(origin, 0, entity_id.clone())
verify {
assert_eq!(Registry::<T, I>::requests(0, entity_id), None);
Expand Down Expand Up @@ -116,7 +116,7 @@ benchmarks_instance_pallet! {
Some(Registration { data: ndata, .. }) if ndata == data
)
);
}: _<T::RuntimeOrigin>(registrar, reg_idx, entity_id.clone())
}: _<T::RuntimeOrigin>(registrar, reg_idx, entity_id.clone(), false)
verify {
assert_eq!(Registry::<T, I>::registries(reg_idx, entity_id), None);
}
Expand Down Expand Up @@ -183,6 +183,27 @@ benchmarks_instance_pallet! {
Some(Registration { data: ndata, .. }) if ndata == reg_data
));
}

request_entity_unregister {
let registrar: T::RuntimeOrigin = RawOrigin::Signed(account("registrar", 1, SEED)).into();
add_registries::<T, I>(1)?;
let reg_idx: u32 = Registry::<T, I>::registrars().len() as u32 - 1;
let acc: T::AccountId = account("owner", 0, SEED);
let origin: T::RuntimeOrigin = RawOrigin::Signed(acc.clone()).into();
let _ = T::Currency::make_free_balance_be(&acc, BalanceOf::<T, I>::max_value() / 2u32.into());
let entity_id: T::EntityId = 0u8.into();
let data = get_data::<T, I>(1, 1000);

Registry::<T, I>::request_entity(origin.clone(), reg_idx, data.clone(), true).unwrap();
Registry::<T, I>::register_entity(registrar.clone(), reg_idx, entity_id.clone(), T::Hashing::hash_of(&data)).unwrap();
assert!(matches!(
Registry::<T, I>::registries(reg_idx, entity_id.clone()),
Some(Registration { data: ndata, .. }) if ndata == data
));
}: _<T::RuntimeOrigin>(origin.clone(), reg_idx, entity_id.clone())
verify {
assert!(matches!(Registry::<T, I>::requests(reg_idx, entity_id), Some(None)));
}
}

impl_benchmark_test_suite!(Registry, crate::mock::new_test_ext(), crate::mock::Test,);
85 changes: 49 additions & 36 deletions frame/registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ pub mod pallet {
InsufficientDeposit,
/// Entity doesn't allow edits by registrars
NotEditableByRegistrar,
/// Trying to register entity that requested to be deregistered
EntityIsNone,
/// Trying to soft unregister company that do not apply for that
NotRequestedToUnregister,
}

#[pallet::event]
Expand All @@ -246,13 +250,15 @@ pub mod pallet {
#[pallet::storage]
#[pallet::getter(fn requests)]
/// Registration requests. See `request_registration` and `cancel_request`
/// If Request data is None it means a request to remove entity from registry
/// Some means request to add or to change data in registry
pub(super) type Requests<T: Config<I>, I: 'static = ()> = StorageDoubleMap<
_,
Blake2_128Concat,
RegistryIndex,
Blake2_128Concat,
T::EntityId,
RequestOf<T, I>,
Option<RequestOf<T, I>>,
MichalLustykNeti marked this conversation as resolved.
Show resolved Hide resolved
OptionQuery,
>;

Expand Down Expand Up @@ -458,10 +464,13 @@ pub mod pallet {
let owner = T::EntityOrigin::ensure_origin(origin)?;
Self::ensure_entity_owner(&owner, &entity_id)?;

if let Some(Request { deposit, .. }) = Self::requests(&registry_index, &entity_id) {
// refund deposit
let owner = Self::entity_owner(&entity_id).ok_or(Error::<T, I>::InvalidEntity)?;
T::Currency::unreserve_named(T::ReserveIdentifier::get(), &owner, deposit);
if let Some(req) = Self::requests(&registry_index, &entity_id) {
if let Some(Request { deposit, .. }) = req {
// refund deposit
let owner =
Self::entity_owner(&entity_id).ok_or(Error::<T, I>::InvalidEntity)?;
T::Currency::unreserve_named(T::ReserveIdentifier::get(), &owner, deposit);
}
} else {
return Err(Error::<T, I>::InvalidEntity.into());
}
Expand All @@ -476,6 +485,7 @@ pub mod pallet {
///
/// * `registry_index` - Registry index to remove from
/// * `entity_id` - AccountId of entity to unregister
/// * `soft` - Boolean information should we accept delete request or hard unregister Registries
///
/// Will refund deposit of stored data.
///
Expand All @@ -489,6 +499,7 @@ pub mod pallet {
origin: OriginFor<T>,
registry_index: RegistryIndex,
entity_id: T::EntityId,
soft: bool,
DorianSternVukotic marked this conversation as resolved.
Show resolved Hide resolved
) -> DispatchResult {
let sender = T::RegistrarOrigin::ensure_origin(origin)?;
Self::ensure_registrar(&sender, registry_index)?;
Expand All @@ -502,10 +513,17 @@ pub mod pallet {
} else {
return Err(Error::<T, I>::InvalidEntity.into());
}
Registries::<T, I>::remove(&registry_index, &entity_id);

Self::deposit_event(Event::EntityUnregistered { entity_id, registry_index });
if soft {
if let Some(None) = Self::requests(registry_index, &entity_id) {
Requests::<T, I>::remove(registry_index, &entity_id);
} else {
return Err(Error::<T, I>::NotRequestedToUnregister.into());
}
}

Registries::<T, I>::remove(registry_index, &entity_id);
Self::deposit_event(Event::EntityUnregistered { entity_id, registry_index });
Ok(())
}

Expand Down Expand Up @@ -536,7 +554,9 @@ pub mod pallet {

// get the request and verify it matches what we want to register
let Request { data: request_data, deposit: request_deposit, editable_by_registrar } =
Self::requests(&registry_index, &entity_id).ok_or(Error::<T, I>::InvalidEntity)?;
Self::requests(&registry_index, &entity_id)
.ok_or(Error::<T, I>::InvalidEntity)?
.ok_or(Error::<T, I>::EntityIsNone)?;
ensure!(T::Hashing::hash_of(&request_data) == data, Error::<T, I>::MismatchedData);

// ensure deposit is ok - mostly defensive, it should never fail,
Expand Down Expand Up @@ -587,7 +607,6 @@ pub mod pallet {
entity_id: T::EntityId,
data: T::EntityData,
) -> DispatchResult {
// make sure origin is ok for registry_index
let sender = T::RegistrarOrigin::ensure_origin(origin)?;
Self::ensure_registrar(&sender, registry_index)?;

Expand All @@ -612,33 +631,28 @@ pub mod pallet {
Ok(())
}

/* see https://github.com/liberland/liberland_substrate/issues/250
/// Remove Entity from given registry.
///
/// * `registry_index` - Registry index to remove from
///
/// Will refund deposit of stored data.
///
/// Emits `EntityUnregistered`.
///
/// Must be called by `EntityOrigin`
#[pallet::call_index(3)]
#[pallet::weight(T::WeightInfo::unregister())]
pub fn unregister(origin: OriginFor<T>, registry_index: RegistryIndex) -> DispatchResult {
let entity = T::EntityOrigin::ensure_origin(origin)?;
if let Some(Registration { deposit, .. }) = Self::registries(&entity, registry_index) {
// refund deposit
T::Currency::unreserve_named(T::ReserveIdentifier::get(), &entity, deposit);
} else {
return Err(Error::<T, I>::InvalidEntity.into())
#[pallet::call_index(7)]
#[pallet::weight(T::WeightInfo::request_entity_unregister())]
pub fn request_entity_unregister(
origin: OriginFor<T>,
registry_index: RegistryIndex,
entity_id: T::EntityId,
) -> DispatchResult {
let sender = T::EntityOrigin::ensure_origin(origin)?;
Self::ensure_entity_owner(&sender, &entity_id)?;

if let Some(Some(req)) = Self::requests(&registry_index, &entity_id) {
T::Currency::unreserve_named(T::ReserveIdentifier::get(), &sender, req.deposit);
}
if Self::registries(&registry_index, entity_id.clone()).is_none() {
return Err(Error::<T, I>::InvalidEntity.into());
}
EntityRegistries::<T, I>::remove(&entity, registry_index);

Self::deposit_event(Event::EntityUnregistered { entity, registry_index });
Requests::<T, I>::insert(&registry_index, &entity_id, None::<RequestOf<T, I>>);

Self::deposit_event(Event::RegistrationRequested { registry_index, entity_id });
Ok(())
}
*/
}

impl<T: Config<I>, I: 'static> Pallet<T, I> {
Expand Down Expand Up @@ -683,20 +697,19 @@ pub mod pallet {
editable_by_registrar: bool,
) -> DispatchResult {
let required_deposit = Self::calculate_deposit(&data);
let old_deposit = Self::requests(&registry_index, &entity_id)
.map(|Request { deposit, .. }| deposit)
.unwrap_or_default();

// refund old deposit, if any
T::Currency::unreserve_named(T::ReserveIdentifier::get(), &owner, old_deposit);
if let Some(Some(req)) = Self::requests(&registry_index, &entity_id) {
T::Currency::unreserve_named(T::ReserveIdentifier::get(), &owner, req.deposit);
}

// reserve new deposit
T::Currency::reserve_named(T::ReserveIdentifier::get(), &owner, required_deposit)?;

Requests::<T, I>::insert(
&registry_index,
&entity_id,
Request { deposit: required_deposit, data, editable_by_registrar },
Some(Request { deposit: required_deposit, data, editable_by_registrar }),
);

Self::deposit_event(Event::RegistrationRequested { registry_index, entity_id });
Expand Down
Loading