JoshOrndorff
JoshOrndorff

Reputation: 1701

Substrate: How to integrate with the session module

I'm working on a toy validator addition module to better understand the workings of the session module. Here is my complete attempt on github.

I've got my code nearly working but I'm running into type-checking errors in my implementation of OnSessionEnding.

impl<T: Trait> OnSessionEnding<T::AccountId> for Module<T> {
    fn on_session_ending(_ending_index: SessionIndex, _will_apply_at: SessionIndex) -> Option<Vec<T::AccountId>> {
        match <QueuedValidator<T>>::get() {
            Some(n00b) => {
                // Get the list of current validators from the session module
                let mut validators = session::Module::<T>::validators();
                validators.push(T::ValidatorIdOf::convert(n00b.clone()).unwrap());
                Some(validators.into())
            }
            None => None
        }

    }
}
// https://github.com/paritytech/substrate/blob/4a17a8aaa5042759d934abb10b1703ffdff7d902/bin/node-template/runtime/src/add_validator.rs#L66-L79

I'm not sure what the type-checker needs to understand that ValidatorId and AccountId are truly the same type as I've declared them to be.

impl session::Trait for Runtime {
    // --snip--
    type ValidatorId = <Self as system::Trait>::AccountId;
    type ValidatorIdOf = ConvertInto;
}
// https://github.com/paritytech/substrate/blob/4a17a8aaa5042759d934abb10b1703ffdff7d902/bin/node-template/runtime/src/lib.rs#L250-L262

The exact error is

error[E0277]: the trait bound `add_validator::sr_api_hidden_includes_decl_storage::hidden_include::sr_primitives::substrate_application_crypto::substrate_primitives::sr_std::prelude::Vec<<T as palette_system::Trait>::AccountId>: core::convert::From<add_validator::sr_api_hidden_includes_decl_storage::hidden_include::sr_primitives::substrate_application_crypto::substrate_primitives::sr_std::prelude::Vec<<T as pallet_session::Trait>::ValidatorId>>` is not satisfied
  --> /home/joshy/ProgrammingProjects/substrate/bin/node-template/runtime/src/add_validator.rs:73:10
   |
73 |                 Some(validators.into())
   |                      ^^^^^^^^^^^^^^^^^ the trait `core::convert::From<add_validator::sr_api_hidden_includes_decl_storage::hidden_include::sr_primitives::substrate_application_crypto::substrate_primitives::sr_std::prelude::Vec<<T as pallet_session::Trait>::ValidatorId>>` is not implemented for `add_validator::sr_api_hidden_includes_decl_storage::hidden_include::sr_primitives::substrate_application_crypto::substrate_primitives::sr_std::prelude::Vec<<T as palette_system::Trait>::AccountId>`
   |
   = note: required because of the requirements on the impl of `core::convert::Into<add_validator::sr_api_hidden_includes_decl_storage::hidden_include::sr_primitives::substrate_application_crypto::substrate_primitives::sr_std::prelude::Vec<<T as palette_system::Trait>::AccountId>>` for `add_validator::sr_api_hidden_includes_decl_storage::hidden_include::sr_primitives::substrate_application_crypto::substrate_primitives::sr_std::prelude::Vec<<T as pallet_session::Trait>::ValidatorId>`

Or without the final .into() it becomes

error[E0308]: mismatched types
  --> /home/joshy/ProgrammingProjects/substrate/bin/node-template/runtime/src/add_validator.rs:73:10
   |
73 |                 Some(validators)
   |                      ^^^^^^^^^^ expected palette_system::Trait::AccountId, found pallet_session::Trait::ValidatorId
   |
   = note: expected type `add_validator::sr_api_hidden_includes_decl_storage::hidden_include::sr_primitives::substrate_application_crypto::substrate_primitives::sr_std::prelude::Vec<<T as palette_system::Trait>::AccountId>`
              found type `add_validator::sr_api_hidden_includes_decl_storage::hidden_include::sr_primitives::substrate_application_crypto::substrate_primitives::sr_std::prelude::Vec<<T as pallet_session::Trait>::ValidatorId>`

Upvotes: 2

Views: 372

Answers (1)

JoshOrndorff
JoshOrndorff

Reputation: 1701

To fix the build above, change the OnSessionEnding's type parameter to T::ValidatorId.

- impl<T: Trait> OnSessionEnding<T::AccountId> for Module<T> {
+ impl<T: Trait> OnSessionEnding<T::ValidatorId> for Module<T> {

Here is the full working implementation

impl<T: Trait> OnSessionEnding<T::ValidatorId> for Module<T> {
    fn on_session_ending(_ending_index: SessionIndex, _will_apply_at: SessionIndex) -> Option<Vec<T::ValidatorId>> {
        match <QueuedValidator<T>>::get() {
            Some(n00b) => {
                // Get the list of current validators from the session module
                let mut validators = session::Module::<T>::validators();

                // Add the new validator to the list
                //TODO handle the unwrapping better
                validators.push(T::ValidatorIdOf::convert(n00b.clone()).unwrap());

                // Clear the queued validator from local storage
                <QueuedValidator<T>>::kill();

                // Return the vector of new validators
                Some(validators)
            }
            None => None
        }

    }
}

(This answer is courtesy of @sushisource:matrix.org)

Upvotes: 2

Related Questions