Repository: paritytech/substrate
File: frame/authority-discovery/src/lib.rs (Rust)

Code before:

impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Pallet<T> {
	type Public = AuthorityId;
}

impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
	type Key = AuthorityId;

	fn on_genesis_session<'a, I: 'a>(authorities: I)
	where
		I: Iterator<Item = (&'a T::AccountId, Self::Key)>,
	{
		Self::initialize_keys(&authorities.map(|x| x.1).collect::<Vec<_>>());
	}

	fn on_new_session<'a, I: 'a>(changed: bool, validators: I, queued_validators: I)
	where
		I: Iterator<Item = (&'a T::AccountId, Self::Key)>,
	{
		// Remember who the authorities are for the new and next session.
		if changed {
			let mut keys = validators.map(|x| x.1).collect::<Vec<_>>();

			if keys.len() >= T::MaxAuthorities::get() as usize {
				// Truncate to MaxAuthorities, to not fail the conversion
				keys.truncate(T::MaxAuthorities::get() as usize);

				log::warn!(
					"Provided validators vec size {} is too large (max size {})",
					keys.len(),
					T::MaxAuthorities::get()
				);
			}

			let bounded_keys = BoundedVec::<AuthorityId, T::MaxAuthorities>::try_from(keys)
				.expect("We truncated so this should never fail");

			Keys::<T>::put(bounded_keys);

			let mut next_keys = queued_validators.map(|x| x.1).collect::<Vec<_>>();

			if next_keys.len() >= T::MaxAuthorities::get() as usize {
				// Truncate to MaxAuthorities, to not fail the conversion
				next_keys.truncate(T::MaxAuthorities::get() as usize);

				log::warn!(
					"Provided queued_validators vec size {} is too large (max size {})",
					next_keys.len(),
					T::MaxAuthorities::get()
				);
			}

Review comment (bug):
similarly to https://github.com/paritytech/substrate/pull/9371 PR I would prefer to use WeakBoundedVec here. So that instead of truncating some authorities, resulting in some probably quite annoying result, we can only have a slight underestimate of PoV.
The WeakBoundedVec will log a warning. and any correctly configured chain should never overflow this weak bound.

Code after:
impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Pallet<T> {
	type Public = AuthorityId;
}

impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
	type Key = AuthorityId;

	fn on_genesis_session<'a, I: 'a>(authorities: I)
	where
		I: Iterator<Item = (&'a T::AccountId, Self::Key)>,
	{
		Self::initialize_keys(&authorities.map(|x| x.1).collect::<Vec<_>>());
	}

	fn on_new_session<'a, I: 'a>(changed: bool, validators: I, queued_validators: I)
	where
		I: Iterator<Item = (&'a T::AccountId, Self::Key)>,
	{
		// Remember who the authorities are for the new and next session.
		if changed {
			let keys = validators.map(|x| x.1).collect::<Vec<_>>();

			let bounded_keys = WeakBoundedVec::<_, T::MaxAuthorities>::force_from(
				keys,
				Some(
					"Warning: The session has more validators than expected. \
				A runtime configuration adjustment may be needed.",
				),
			);

			Keys::<T>::put(bounded_keys);

			let next_keys = queued_validators.map(|x| x.1).collect::<Vec<_>>();

			let next_bounded_keys = WeakBoundedVec::<_, T::MaxAuthorities>::force_from(
				next_keys,
				Some(
					"Warning: The session has more queued validators than expected. \
				A runtime configuration adjustment may be needed.",
				),
			);

			NextKeys::<T>::put(next_bounded_keys);
		}
	}

	fn on_disabled(_i: usize) {
		// ignore
	}
}