pub trait SessionHandler<ValidatorId> {
    const KEY_TYPE_IDS: &'static [KeyTypeId];

    fn on_genesis_session<Ks: OpaqueKeys>(validators: &[(ValidatorId, Ks)]);
    fn on_new_session<Ks: OpaqueKeys>(
        changed: bool,
        validators: &[(ValidatorId, Ks)],
        queued_validators: &[(ValidatorId, Ks)]
    ); fn on_disabled(validator_index: u32); fn on_before_session_ending() { ... } }
Expand description

Handler for session life cycle events.

Required Associated Constants§

All the key type ids this session handler can process.

The order must be the same as it expects them in on_new_session and on_genesis_session.

Required Methods§

The given validator set will be used for the genesis session. It is guaranteed that the given validator set will also be used for the second session, therefore the first call to on_new_session should provide the same validator set.

Session set has changed; act appropriately. Note that this can be called before initialization of your pallet.

changed is true whenever any of the session keys or underlying economic identities or weightings behind those keys has changed.

A validator got disabled. Act accordingly until a new session begins.

Provided Methods§

A notification for end of the session.

Note it is triggered before any SessionManager::end_session handlers, so we can still affect the validator set.

Examples found in repository?
src/lib.rs (line 645)
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
	pub fn rotate_session() {
		let session_index = <CurrentIndex<T>>::get();
		log::trace!(target: "runtime::session", "rotating session {:?}", session_index);

		let changed = <QueuedChanged<T>>::get();

		// Inform the session handlers that a session is going to end.
		T::SessionHandler::on_before_session_ending();
		T::SessionManager::end_session(session_index);

		// Get queued session keys and validators.
		let session_keys = <QueuedKeys<T>>::get();
		let validators =
			session_keys.iter().map(|(validator, _)| validator.clone()).collect::<Vec<_>>();
		Validators::<T>::put(&validators);

		if changed {
			// reset disabled validators
			<DisabledValidators<T>>::take();
		}

		// Increment session index.
		let session_index = session_index + 1;
		<CurrentIndex<T>>::put(session_index);

		T::SessionManager::start_session(session_index);

		// Get next validator set.
		let maybe_next_validators = T::SessionManager::new_session(session_index + 1);
		let (next_validators, next_identities_changed) =
			if let Some(validators) = maybe_next_validators {
				// NOTE: as per the documentation on `OnSessionEnding`, we consider
				// the validator set as having changed even if the validators are the
				// same as before, as underlying economic conditions may have changed.
				(validators, true)
			} else {
				(Validators::<T>::get(), false)
			};

		// Queue next session keys.
		let (queued_amalgamated, next_changed) = {
			// until we are certain there has been a change, iterate the prior
			// validators along with the current and check for changes
			let mut changed = next_identities_changed;

			let mut now_session_keys = session_keys.iter();
			let mut check_next_changed = |keys: &T::Keys| {
				if changed {
					return
				}
				// since a new validator set always leads to `changed` starting
				// as true, we can ensure that `now_session_keys` and `next_validators`
				// have the same length. this function is called once per iteration.
				if let Some(&(_, ref old_keys)) = now_session_keys.next() {
					if old_keys != keys {
						changed = true;
					}
				}
			};
			let queued_amalgamated = next_validators
				.into_iter()
				.filter_map(|a| {
					let k = Self::load_keys(&a)?;
					check_next_changed(&k);
					Some((a, k))
				})
				.collect::<Vec<_>>();

			(queued_amalgamated, changed)
		};

		<QueuedKeys<T>>::put(queued_amalgamated.clone());
		<QueuedChanged<T>>::put(next_changed);

		// Record that this happened.
		Self::deposit_event(Event::NewSession { session_index });

		// Tell everyone about the new session keys.
		T::SessionHandler::on_new_session::<T::Keys>(changed, &session_keys, &queued_amalgamated);
	}

Implementations on Foreign Types§

Implementors§