diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index e29afe582..67ac152ad 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -297,9 +297,36 @@ impl pallet_sudo::Config for Runtime { type Call = Call; } +pub struct AuraValidatorSetUpdater; + +impl pallet_bioauth::ValidatorSetUpdater for AuraValidatorSetUpdater { + fn update_validators_set(validator_public_keys: &[&[u8]]) { + 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 + .iter() + .map(|&public_key| { + use core::convert::TryInto; + ( + &dummy, + public_key.try_into().expect("key has to be aura id"), + ) + }) + .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; + 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 28e30a115..1911e0994 100644 --- a/crates/pallet-bioauth/src/lib.rs +++ b/crates/pallet-bioauth/src/lib.rs @@ -75,6 +75,12 @@ pub trait Verifier { D: AsRef<[u8]> + Send + 'a; } +/// Provides the capability to update the current validators set. +pub trait ValidatorSetUpdater { + /// Updated the validators set for the of consensus. + fn update_validators_set(validator_public_keys: &[&[u8]]); +} + sp_api::decl_runtime_apis! { /// We need to provide a trait using decl_runtime_apis! macro to be able to call required methods @@ -97,7 +103,7 @@ sp_api::decl_runtime_apis! { pub mod pallet { use core::convert::TryInto; - use super::{Authenticate, StoredAuthTicket, Verifier}; + use super::{Authenticate, StoredAuthTicket, ValidatorSetUpdater, Verifier}; use frame_support::{dispatch::DispatchResult, pallet_prelude::*, storage::types::ValueQuery}; use frame_system::pallet_prelude::*; use primitives_auth_ticket::{AuthTicket, OpaqueAuthTicket}; @@ -111,6 +117,9 @@ pub mod pallet { /// The public key of the robonode. type RobonodePublicKey: Verifier> + codec::FullCodec + Default + serde_nostd::SerDe; + + /// The validator set updater to invoke at auth the ticket acceptace. + type ValidatorSetUpdater: ValidatorSetUpdater; } #[pallet::pallet] @@ -233,6 +242,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(()) } } @@ -307,6 +317,14 @@ 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.as_slice()) + .collect::>(); + T::ValidatorSetUpdater::update_validators_set(validator_public_keys.as_slice()); + } } #[pallet::validate_unsigned] diff --git a/crates/pallet-bioauth/src/mock.rs b/crates/pallet-bioauth/src/mock.rs index bdfe503c4..00bad8cd7 100644 --- a/crates/pallet-bioauth/src/mock.rs +++ b/crates/pallet-bioauth/src/mock.rs @@ -40,6 +40,17 @@ impl super::Verifier> for MockVerifier { } } +pub struct MockValidatorSetUpdater; + +impl super::ValidatorSetUpdater for MockValidatorSetUpdater { + fn update_validators_set(validator_public_keys: &[&[u8]]) { + assert!( + !validator_public_keys.is_empty(), + "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; @@ -74,6 +85,7 @@ impl system::Config for Test { impl pallet_bioauth::Config for Test { type Event = Event; type RobonodePublicKey = MockVerifier; + type ValidatorSetUpdater = MockValidatorSetUpdater; } // Build genesis storage according to the mock runtime.