Skip to content
Snippets Groups Projects

smith-members

Merged Cédric Moreau requested to merge feature/smith-members into master
3 files
+ 219
42
Compare changes
  • Side-by-side
  • Inline
Files
3
@@ -56,6 +56,8 @@ pub enum SmithStatus {
Pending,
/// The identity has reached the requirements to become a smith and can now goGoOnline() or invite/certify other smiths
Smith,
/// The identity has been removed from the smiths set but is kept to keep track of its certifications
Excluded,
}
#[frame_support::pallet]
@@ -148,8 +150,7 @@ pub mod pallet {
impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
fn build(&self) {
CurrentSession::<T>::put(0);
let mut cert_meta_by_issuer =
BTreeMap::<T::IdtyIndex, SmithCertMeta<T::BlockNumber>>::new();
let mut cert_meta_by_issuer = BTreeMap::<T::IdtyIndex, Vec<T::IdtyIndex>>::new();
for (receiver, issuers) in &self.certs_by_receiver {
// Forbid self-cert
assert!(
@@ -157,18 +158,13 @@ pub mod pallet {
"Identity cannot certify it-self."
);
// We should insert cert_meta for receivers that have not issued any cert.
cert_meta_by_issuer
.entry(*receiver)
.or_insert(SmithCertMeta {
issued_count: 0,
next_issuable_on: sp_runtime::traits::Zero::zero(),
received_count: 0,
})
.received_count = issuers.len() as u32;
let mut issuers_: Vec<_> = Vec::with_capacity(issuers.len());
for (issuer, maybe_removable_on) in issuers {
// Count issued certs
cert_meta_by_issuer
.entry(*issuer)
.or_insert(vec![])
.push(*receiver);
issuers_.push(*issuer);
}
@@ -187,6 +183,7 @@ pub mod pallet {
expires_on: Some(
CurrentSession::<T>::get() + T::InactivityMaxDuration::get(),
),
issued_certs: vec![],
received_certs: issuers_,
},
);
@@ -195,6 +192,16 @@ pub mod pallet {
receiver,
);
}
for (issuer, issued_certs) in cert_meta_by_issuer {
// Write CertsByIssuer
Smiths::<T>::mutate(issuer, |maybe_smith_meta| {
let maybe_smith_meta = maybe_smith_meta
.as_mut()
.expect("issuers must have received certs as well");
maybe_smith_meta.issued_certs = issued_certs;
});
}
}
}
@@ -227,7 +234,7 @@ pub mod pallet {
/// Invitation must not have been accepted yet
AlreadyAcceptedInvitation,
/// Recevier must not be known among smiths
ReceveirAlreadyHasSmithStatus,
OnlyExcludedCanComeBack,
/// Recevier must have accepted to eventually become a smith
ReceveirMustAcceptInvitation,
/// Issuer must be a smith
@@ -292,24 +299,37 @@ impl<T: Config> Pallet<T> {
issuer_status == SmithStatus::Smith,
Error::<T>::CannotInvite
);
ensure!(
Smiths::<T>::get(receiver).is_none(),
Error::<T>::ReceveirAlreadyHasSmithStatus
);
if let Some(receiver_meta) = Smiths::<T>::get(receiver) {
ensure!(
receiver_meta.status == SmithStatus::Excluded,
Error::<T>::OnlyExcludedCanComeBack
);
}
Ok(().into())
}
fn do_invite_smith(receiver: T::IdtyIndex) {
let new_expires_on = CurrentSession::<T>::get() + T::InactivityMaxDuration::get();
Smiths::<T>::insert(
receiver,
SmithMeta {
status: SmithStatus::Invited,
expires_on: Some(new_expires_on),
received_certs: vec![],
},
);
// TODO: another way to write this?
if Smiths::<T>::get(receiver).is_some() {
Smiths::<T>::mutate(receiver, |maybe_smith_meta| {
let maybe_smith_meta = maybe_smith_meta.as_mut().expect("checked earlier");
maybe_smith_meta.status = SmithStatus::Invited;
maybe_smith_meta.expires_on = Some(new_expires_on);
maybe_smith_meta.received_certs = vec![];
});
} else {
Smiths::<T>::insert(
receiver,
SmithMeta {
status: SmithStatus::Invited,
expires_on: Some(new_expires_on),
issued_certs: vec![],
received_certs: vec![],
},
);
}
ExpiresOn::<T>::append(new_expires_on, receiver);
}
@@ -356,8 +376,13 @@ impl<T: Config> Pallet<T> {
}
fn do_certify_smith(receiver: T::IdtyIndex, issuer: T::IdtyIndex) {
Smiths::<T>::mutate(issuer, |maybe_smith_meta| {
let maybe_smith_meta = maybe_smith_meta.as_mut().expect("issuer checked earlier");
maybe_smith_meta.issued_certs.push(receiver);
maybe_smith_meta.issued_certs.sort();
});
Smiths::<T>::mutate(receiver, |maybe_smith_meta| {
let maybe_smith_meta = maybe_smith_meta.as_mut().expect("status checked earlier");
let maybe_smith_meta = maybe_smith_meta.as_mut().expect("receiver checked earlier");
maybe_smith_meta.received_certs.push(issuer);
maybe_smith_meta.received_certs.sort();
// TODO: "as u32" allowed?
@@ -381,11 +406,36 @@ impl<T: Config> Pallet<T> {
if let Some(smith_meta) = Smiths::<T>::get(smith) {
if let Some(expires_on) = smith_meta.expires_on {
if expires_on == at {
Smiths::<T>::remove(smith);
let mut lost_certs = vec![];
Smiths::<T>::mutate(smith, |maybe_smith_meta| {
let maybe_smith_meta =
maybe_smith_meta.as_mut().expect("checked earlier");
maybe_smith_meta.expires_on = None;
maybe_smith_meta.status = SmithStatus::Excluded;
for cert in &maybe_smith_meta.received_certs {
lost_certs.push(cert.clone());
}
maybe_smith_meta.received_certs = vec![];
// N.B.: the issued certs are kept in case the smith joins back
});
// We remove the lost certs from their issuer's stock
for lost_cert in lost_certs {
Smiths::<T>::mutate(lost_cert, |maybe_smith_meta| {
let maybe_smith_meta =
maybe_smith_meta.as_mut().expect("checked earlier");
if let Ok(index) =
maybe_smith_meta.issued_certs.binary_search(&smith)
{
maybe_smith_meta.issued_certs.remove(index);
}
});
}
// Deletion done
T::OnSmithDelete::on_smith_delete(
smith,
SmithRemovalReason::OfflineTooLong,
);
// TODO: add event? (+ add others too)
}
}
}
Loading