Skip to content

Commit

Permalink
More bioauth authentication related events (#649)
Browse files Browse the repository at this point in the history
* Introduce more bioauth events

* Add deauthentication reason at runtime

* Add docs

* Fix depositing event during deauthentication

* Add missed deauthentication reason type in tests config

* Emit one event for list of keys

* Use deauthentications once for slasher

* Return a vec of removed public keys during deauthentication

* Explicitly set up removed public keys capacity

Co-authored-by: MOZGIII <[email protected]>

* Preallocate all the memory we might need pessimistically

Co-authored-by: MOZGIII <[email protected]>

* Add comments

Co-authored-by: MOZGIII <[email protected]>

* Add explicit capacity for should_be_deauthenticated

Co-authored-by: MOZGIII <[email protected]>

* Explicit writes

Co-authored-by: MOZGIII <[email protected]>

* Edit expect message

---------

Co-authored-by: MOZGIII <[email protected]>
  • Loading branch information
dmitrylavrenov and MOZGIII authored Mar 20, 2024
1 parent aa87e96 commit 64052a5
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 15 deletions.
13 changes: 13 additions & 0 deletions crates/humanode-runtime/src/deauthentication_reason.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! `DeauthenticationReason` implementation to define reasons by which authentication is removed
//! before expected time expiration.
use codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_std::prelude::*;

/// Define a possible deauthentication reason.
#[derive(Clone, PartialEq, Debug, Encode, Decode, TypeInfo)]
pub enum DeauthenticationReason {
/// Some offence has been recevied.
Offence,
}
21 changes: 18 additions & 3 deletions crates/humanode-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ use frontier_precompiles::{precompiles_constants, FrontierPrecompiles};
mod benchmarking;
pub mod constants;
mod currency_swap;
mod deauthentication_reason;
#[cfg(test)]
mod dev_utils;
mod display_moment;
Expand All @@ -107,6 +108,7 @@ pub use constants::{
ethereum::EXTRA_DATA_LENGTH,
im_online::{MAX_KEYS, MAX_PEER_DATA_ENCODING_SIZE, MAX_PEER_IN_HEARTBEATS},
};
use deauthentication_reason::DeauthenticationReason;
use static_assertions::const_assert;

/// An index to a block.
Expand Down Expand Up @@ -530,6 +532,7 @@ impl pallet_bioauth::Config for Runtime {
type MaxNonces = ConstU32<MAX_NONCES>;
type BeforeAuthHook = ();
type AfterAuthHook = ();
type DeauthenticationReason = DeauthenticationReason;
}

#[cfg(feature = "runtime-benchmarks")]
Expand Down Expand Up @@ -580,19 +583,31 @@ impl
}
let mut weight: Weight = Weight::zero();
let weights = <Runtime as frame_system::Config>::DbWeight::get();
let mut should_be_deauthenticated = Vec::with_capacity(offenders.len());
for details in offenders {
let (_offender, identity) = &details.offender;
match identity {
pallet_humanode_session::Identification::Bioauth(authentication) => {
let has_deauthenticated = Bioauth::deauthenticate(&authentication.public_key);
weight = weight
.saturating_add(weights.reads_writes(1, u64::from(has_deauthenticated)));
should_be_deauthenticated.push(authentication.public_key.clone());
}
pallet_humanode_session::Identification::Bootnode(..) => {
// Never slash the bootnodes.
}
}
}
if !should_be_deauthenticated.is_empty() {
let deauthenticated_public_keys =
Bioauth::deauthenticate(should_be_deauthenticated, DeauthenticationReason::Offence);
weight = weight.saturating_add(
weights.reads_writes(
1,
deauthenticated_public_keys
.len()
.try_into()
.expect("casting usize to u64 never fails in 64bit and 32bit word cpus"),
),
);
}
weight
}
}
Expand Down
55 changes: 43 additions & 12 deletions crates/pallet-bioauth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ pub mod pallet {
type AfterAuthHook: AfterAuthHook<
<Self::BeforeAuthHook as BeforeAuthHook<Self::ValidatorPublicKey, Self::Moment>>::Data,
>;

/// Possible deauthentication reason.
type DeauthenticationReason: Clone + PartialEq + Debug;
}

#[pallet::pallet]
Expand Down Expand Up @@ -334,6 +337,13 @@ pub mod pallet {
NewAuthentication {
validator_public_key: T::ValidatorPublicKey,
},
/// The authentications has been expired.
AuthenticationsExpired { expired: Vec<T::ValidatorPublicKey> },
/// The authentications has been removed from the state for some reason.
AuthenticationsRemoved {
removed: Vec<T::ValidatorPublicKey>,
reason: T::DeauthenticationReason,
},
}

/// Possible error conditions during `authenticate` call processing.
Expand Down Expand Up @@ -393,18 +403,28 @@ pub mod pallet {
.any(|authentication| &authentication.public_key == public_key)
}

pub fn deauthenticate(public_key: &<T as Config>::ValidatorPublicKey) -> bool {
pub fn deauthenticate(
public_keys: Vec<<T as Config>::ValidatorPublicKey>,
reason: <T as Config>::DeauthenticationReason,
) -> Vec<<T as Config>::ValidatorPublicKey> {
let mut removed_public_keys = Vec::with_capacity(public_keys.len());
ActiveAuthentications::<T>::mutate(|active_authentications| {
let mut removed = false;
active_authentications.retain(|authentication| {
if &authentication.public_key == public_key {
removed = true;
if public_keys.contains(&authentication.public_key) {
removed_public_keys.push(authentication.public_key.clone());
return false;
}
true
});
removed
})
});
if !removed_public_keys.is_empty() {
// Emit an event.
Self::deposit_event(Event::AuthenticationsRemoved {
removed: removed_public_keys.clone(),
reason,
});
}
removed_public_keys
}
}

Expand Down Expand Up @@ -523,12 +543,19 @@ pub mod pallet {
let current_moment = T::CurrentMoment::now();
let possibly_expired_authentications = <ActiveAuthentications<T>>::get();
let possibly_expired_authentications_len = possibly_expired_authentications.len();
let active_authentications = possibly_expired_authentications
.into_iter()
.filter(|possibly_expired_authentication| {
possibly_expired_authentication.expires_at > current_moment
})
.collect::<Vec<_>>();
let mut expired_validator_public_keys =
Vec::with_capacity(possibly_expired_authentications_len);
let mut active_authentications =
Vec::with_capacity(possibly_expired_authentications_len);
for possibly_expired_authentication in possibly_expired_authentications {
if possibly_expired_authentication.expires_at > current_moment {
// Still active.
active_authentications.push(possibly_expired_authentication);
} else {
// Expired!
expired_validator_public_keys.push(possibly_expired_authentication.public_key)
}
}

let update_required =
possibly_expired_authentications_len != active_authentications.len();
Expand All @@ -541,6 +568,10 @@ pub mod pallet {
);
Self::issue_validators_set_update(active_authentications.as_slice());
<ActiveAuthentications<T>>::put(bounded_active_authentications);

Self::deposit_event(Event::AuthenticationsExpired {
expired: expired_validator_public_keys,
});
}

// Weight: O(M) where M is the number of auths.
Expand Down
1 change: 1 addition & 0 deletions crates/pallet-bioauth/src/mock/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ impl pallet_bioauth::Config for Benchmark {
type MaxNonces = ConstU32<MAX_NONCES>;
type BeforeAuthHook = ();
type AfterAuthHook = ();
type DeauthenticationReason = ();
}

#[cfg(feature = "runtime-benchmarks")]
Expand Down
1 change: 1 addition & 0 deletions crates/pallet-bioauth/src/mock/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ impl pallet_bioauth::Config for Test {
type MaxNonces = ConstU32<MAX_NONCES>;
type BeforeAuthHook = MockBeforeAuthHookProvider;
type AfterAuthHook = MockAfterAuthHookProvider;
type DeauthenticationReason = ();
}

/// Build test externalities from the default genesis.
Expand Down
1 change: 1 addition & 0 deletions crates/precompile-bioauth/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ impl pallet_bioauth::Config for Test {
type MaxNonces = ConstU32<MAX_NONCES>;
type BeforeAuthHook = ();
type AfterAuthHook = ();
type DeauthenticationReason = ();
}

mock! {
Expand Down

0 comments on commit 64052a5

Please sign in to comment.