Skip to content
Snippets Groups Projects
Commit 037f1494 authored by Éloïs's avatar Éloïs Committed by Éloïs
Browse files

fix(identity): handle sufficients counter when owner key change (!97)

* fix(identity): add a special call to fix sufficients counter

* fix(identity): handle sufficients counter when owner key change

* test: handle sufficients properly when owner key change
parent e079cab2
No related branches found
No related tags found
No related merge requests found
...@@ -402,6 +402,7 @@ pub mod pallet { ...@@ -402,6 +402,7 @@ pub mod pallet {
new_key: T::AccountId, new_key: T::AccountId,
new_key_sig: T::NewOwnerKeySignature, new_key_sig: T::NewOwnerKeySignature,
) -> DispatchResultWithPostInfo { ) -> DispatchResultWithPostInfo {
// verification phase
let who = ensure_signed(origin)?; let who = ensure_signed(origin)?;
let idty_index = let idty_index =
...@@ -415,12 +416,20 @@ pub mod pallet { ...@@ -415,12 +416,20 @@ pub mod pallet {
); );
let block_number = frame_system::Pallet::<T>::block_number(); let block_number = frame_system::Pallet::<T>::block_number();
if let Some((_, last_change)) = idty_value.old_owner_key { let maybe_old_old_owner_key =
if let Some((old_owner_key, last_change)) = idty_value.old_owner_key {
ensure!( ensure!(
block_number >= last_change + T::ChangeOwnerKeyPeriod::get(), block_number >= last_change + T::ChangeOwnerKeyPeriod::get(),
Error::<T>::OwnerKeyAlreadyRecentlyChanged Error::<T>::OwnerKeyAlreadyRecentlyChanged
); );
} ensure!(
old_owner_key != new_key,
Error::<T>::ProhibitedToRevertToAnOldKey
);
Some(old_owner_key)
} else {
None
};
let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero()); let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero());
let new_key_payload = NewOwnerKeyPayload { let new_key_payload = NewOwnerKeyPayload {
...@@ -435,9 +444,15 @@ pub mod pallet { ...@@ -435,9 +444,15 @@ pub mod pallet {
Error::<T>::InvalidNewOwnerKeySig Error::<T>::InvalidNewOwnerKeySig
); );
// Apply phase
if let Some(old_old_owner_key) = maybe_old_old_owner_key {
frame_system::Pallet::<T>::dec_sufficients(&old_old_owner_key);
}
IdentityIndexOf::<T>::remove(&idty_value.owner_key); IdentityIndexOf::<T>::remove(&idty_value.owner_key);
idty_value.old_owner_key = Some((idty_value.owner_key.clone(), block_number)); idty_value.old_owner_key = Some((idty_value.owner_key.clone(), block_number));
idty_value.owner_key = new_key.clone(); idty_value.owner_key = new_key.clone();
frame_system::Pallet::<T>::inc_sufficients(&idty_value.owner_key);
IdentityIndexOf::<T>::insert(&idty_value.owner_key, idty_index); IdentityIndexOf::<T>::insert(&idty_value.owner_key, idty_index);
Identities::<T>::insert(idty_index, idty_value); Identities::<T>::insert(idty_index, idty_value);
Self::deposit_event(Event::IdtyChangedOwnerKey { Self::deposit_event(Event::IdtyChangedOwnerKey {
...@@ -527,6 +542,23 @@ pub mod pallet { ...@@ -527,6 +542,23 @@ pub mod pallet {
Ok(().into()) Ok(().into())
} }
#[pallet::weight(1_000_000_000)]
pub fn fix_sufficients(
origin: OriginFor<T>,
owner_key: T::AccountId,
inc: bool,
) -> DispatchResultWithPostInfo {
ensure_root(origin)?;
if inc {
frame_system::Pallet::<T>::inc_sufficients(&owner_key);
} else {
frame_system::Pallet::<T>::dec_sufficients(&owner_key);
}
Ok(().into())
}
} }
// ERRORS // // ERRORS //
...@@ -577,6 +609,8 @@ pub mod pallet { ...@@ -577,6 +609,8 @@ pub mod pallet {
OwnerKeyAlreadyRecentlyChanged, OwnerKeyAlreadyRecentlyChanged,
/// Owner key already used /// Owner key already used
OwnerKeyAlreadyUsed, OwnerKeyAlreadyUsed,
/// Prohibited to revert to an old key
ProhibitedToRevertToAnOldKey,
/// Right already added /// Right already added
RightAlreadyAdded, RightAlreadyAdded,
/// Right does not exist /// Right does not exist
...@@ -601,6 +635,9 @@ pub mod pallet { ...@@ -601,6 +635,9 @@ pub mod pallet {
// Identity should be removed after the consumers of the identity // Identity should be removed after the consumers of the identity
Identities::<T>::remove(idty_index); Identities::<T>::remove(idty_index);
frame_system::Pallet::<T>::dec_sufficients(&idty_val.owner_key); frame_system::Pallet::<T>::dec_sufficients(&idty_val.owner_key);
if let Some((old_owner_key, _last_change)) = idty_val.old_owner_key {
frame_system::Pallet::<T>::dec_sufficients(&old_owner_key);
}
Self::deposit_event(Event::IdtyRemoved { idty_index }); Self::deposit_event(Event::IdtyRemoved { idty_index });
T::OnIdtyChange::on_idty_change( T::OnIdtyChange::on_idty_change(
idty_index, idty_index,
......
...@@ -117,6 +117,7 @@ pub fn new_test_ext(gen_conf: pallet_identity::GenesisConfig<Test>) -> sp_io::Te ...@@ -117,6 +117,7 @@ pub fn new_test_ext(gen_conf: pallet_identity::GenesisConfig<Test>) -> sp_io::Te
frame_support::BasicExternalities::execute_with_storage(&mut t, || { frame_support::BasicExternalities::execute_with_storage(&mut t, || {
// Some dedicated test account // Some dedicated test account
frame_system::Pallet::<Test>::inc_sufficients(&1);
frame_system::Pallet::<Test>::inc_providers(&2); frame_system::Pallet::<Test>::inc_providers(&2);
frame_system::Pallet::<Test>::inc_providers(&3); frame_system::Pallet::<Test>::inc_providers(&3);
}); });
......
...@@ -198,7 +198,7 @@ fn test_change_owner_key() { ...@@ -198,7 +198,7 @@ fn test_change_owner_key() {
.execute_with(|| { .execute_with(|| {
let genesis_hash = System::block_hash(0); let genesis_hash = System::block_hash(0);
let old_owner_key = 1u64; let old_owner_key = 1u64;
let new_key_payload = NewOwnerKeyPayload { let mut new_key_payload = NewOwnerKeyPayload {
genesis_hash: &genesis_hash, genesis_hash: &genesis_hash,
idty_index: 1u64, idty_index: 1u64,
old_owner_key: &old_owner_key, old_owner_key: &old_owner_key,
...@@ -207,7 +207,11 @@ fn test_change_owner_key() { ...@@ -207,7 +207,11 @@ fn test_change_owner_key() {
// We need to initialize at least one block before any call // We need to initialize at least one block before any call
run_to_block(1); run_to_block(1);
// Caller should have an asoociated identity // Verify genesis data
assert_eq!(System::sufficients(&1), 1);
assert_eq!(System::sufficients(&10), 0);
// Caller should have an associated identity
assert_err!( assert_err!(
Identity::change_owner_key( Identity::change_owner_key(
Origin::signed(42), Origin::signed(42),
...@@ -264,10 +268,15 @@ fn test_change_owner_key() { ...@@ -264,10 +268,15 @@ fn test_change_owner_key() {
status: crate::IdtyStatus::Validated, status: crate::IdtyStatus::Validated,
}) })
); );
// Alice still sufficient
assert_eq!(System::sufficients(&1), 1);
// New owner key should become a sufficient account
assert_eq!(System::sufficients(&10), 1);
run_to_block(2); run_to_block(2);
// Alice can't re-change her owner key too early // Alice can't re-change her owner key too early
new_key_payload.old_owner_key = &10;
assert_err!( assert_err!(
Identity::change_owner_key( Identity::change_owner_key(
Origin::signed(10), Origin::signed(10),
...@@ -279,6 +288,45 @@ fn test_change_owner_key() { ...@@ -279,6 +288,45 @@ fn test_change_owner_key() {
), ),
Error::<Test>::OwnerKeyAlreadyRecentlyChanged Error::<Test>::OwnerKeyAlreadyRecentlyChanged
); );
// Alice can re-change her owner key after ChangeOwnerKeyPeriod blocs
run_to_block(2 + <Test as crate::Config>::ChangeOwnerKeyPeriod::get());
assert_ok!(Identity::change_owner_key(
Origin::signed(10),
100,
TestSignature(
100,
(NEW_OWNER_KEY_PAYLOAD_PREFIX, new_key_payload).encode()
)
));
// Old old owner key should not be sufficient anymore
assert_eq!(System::sufficients(&1), 0);
// Old owner key should still sufficient
assert_eq!(System::sufficients(&10), 1);
// New owner key should become a sufficient account
assert_eq!(System::sufficients(&100), 1);
// Revoke identity 1
assert_ok!(Identity::revoke_identity(
Origin::signed(42),
1,
100,
TestSignature(
100,
(
REVOCATION_PAYLOAD_PREFIX,
RevocationPayload {
idty_index: 1u64,
genesis_hash: System::block_hash(0),
}
)
.encode()
)
));
// Old owner key should not be sufficient anymore
assert_eq!(System::sufficients(&10), 0);
// Last owner key should not be sufficient anymore
assert_eq!(System::sufficients(&100), 0);
}); });
} }
...@@ -327,9 +375,17 @@ fn test_idty_revocation() { ...@@ -327,9 +375,17 @@ fn test_idty_revocation() {
)); ));
let events = System::events(); let events = System::events();
assert_eq!(events.len(), 1); assert_eq!(events.len(), 2);
assert_eq!( assert_eq!(
events[0], events[0],
EventRecord {
phase: Phase::Initialization,
event: Event::System(frame_system::Event::KilledAccount { account: 1 }),
topics: vec![],
}
);
assert_eq!(
events[1],
EventRecord { EventRecord {
phase: Phase::Initialization, phase: Phase::Initialization,
event: Event::Identity(crate::Event::IdtyRemoved { idty_index: 1 }), event: Event::Identity(crate::Event::IdtyRemoved { idty_index: 1 }),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment