diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index 2f2367416..bcc112edf 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -331,6 +331,28 @@ impl pallet_bioauth::TryConvert for AuraValidatorSetUpdater { + fn update_validators_set<'a, I: Iterator + 'a>(validator_public_keys: I) + where + AuraId: 'a, + { + let dummy = ::AccountId::default(); + + // clippy is just too dumb here, but we need two iterators passed to `on_new_session` to be + // the same type. The easiest is to use Vec's iter for both. + #[allow(clippy::needless_collect)] + let authorities = validator_public_keys + .map(|public_key| (&dummy, public_key.clone())) + .collect::>(); + + as frame_support::traits::OneSessionHandler< + ::AccountId, + >>::on_new_session(true, authorities.into_iter(), Vec::new().into_iter()) + } +} + impl pallet_bioauth::Config for Runtime { type Event = Event; type RobonodePublicKey = RobonodePublicKeyWrapper; @@ -338,6 +360,7 @@ impl pallet_bioauth::Config for Runtime { type ValidatorPublicKey = AuraId; type OpaqueAuthTicket = primitives_auth_ticket::OpaqueAuthTicket; type AuthTicketCoverter = PrimitiveAuthTicketConverter; + type ValidatorSetUpdater = AuraValidatorSetUpdater; } // Create the runtime by composing the FRAME pallets that were previously diff --git a/crates/pallet-bioauth/src/lib.rs b/crates/pallet-bioauth/src/lib.rs index 8cd945d40..ecb19efd2 100644 --- a/crates/pallet-bioauth/src/lib.rs +++ b/crates/pallet-bioauth/src/lib.rs @@ -54,6 +54,14 @@ pub trait TryConvert { fn try_convert(value: A) -> Result; } +/// Provides the capability to update the current validators set. +pub trait ValidatorSetUpdater { + /// Updated the validators set for the of consensus. + fn update_validators_set<'a, I: Iterator + 'a>(validator_public_keys: I) + where + T: 'a; +} + /// Authentication extrinsic playload. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug)] @@ -92,7 +100,7 @@ sp_api::decl_runtime_apis! { )] #[frame_support::pallet] pub mod pallet { - use crate::{StoredAuthTicket, TryConvert, Verifier}; + use crate::{StoredAuthTicket, TryConvert, ValidatorSetUpdater, Verifier}; use super::Authenticate; use frame_support::{dispatch::DispatchResult, pallet_prelude::*, storage::types::ValueQuery}; @@ -127,6 +135,9 @@ pub mod pallet { Self::OpaqueAuthTicket, StoredAuthTicket, >; + + /// The validator set updater to invoke at auth the ticket acceptace. + type ValidatorSetUpdater: ValidatorSetUpdater; } #[pallet::pallet] @@ -253,6 +264,7 @@ pub mod pallet { Ok(()) => { // Authentication was successfull, add the incoming auth ticket to the list. list.push(stored_auth_ticket); + Self::issue_validators_set_update(list.as_slice()); Ok(()) } } @@ -326,6 +338,13 @@ pub mod pallet { .propagate(true) .build() } + + fn issue_validators_set_update( + stored_auth_tickets: &[StoredAuthTicket], + ) { + let validator_public_keys = stored_auth_tickets.iter().map(|ticket| &ticket.public_key); + T::ValidatorSetUpdater::update_validators_set(validator_public_keys); + } } #[pallet::validate_unsigned] diff --git a/crates/pallet-bioauth/src/mock.rs b/crates/pallet-bioauth/src/mock.rs index 4efa5c5e6..0fe0397be 100644 --- a/crates/pallet-bioauth/src/mock.rs +++ b/crates/pallet-bioauth/src/mock.rs @@ -60,6 +60,20 @@ impl super::Verifier> for MockVerifier { } } +pub struct MockValidatorSetUpdater; + +impl super::ValidatorSetUpdater> for MockValidatorSetUpdater { + fn update_validators_set<'a, I: Iterator> + 'a>(mut validator_public_keys: I) + where + Vec: 'a, + { + assert!( + validator_public_keys.next().is_some(), + "We should get non-empty set every time at each of the test cases" + ); + } +} + parameter_types! { pub const BlockHashCount: u64 = 250; pub const SS58Prefix: u8 = 42; @@ -98,6 +112,7 @@ impl pallet_bioauth::Config for Test { type ValidatorPublicKey = Vec; type OpaqueAuthTicket = MockOpaqueAuthTicket; type AuthTicketCoverter = MockAuthTicketConverter; + type ValidatorSetUpdater = MockValidatorSetUpdater; } // Build genesis storage according to the mock runtime.