diff --git a/Cargo.lock b/Cargo.lock index a0ff536aa..96b05a48d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1531,7 +1531,7 @@ checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ "serde", "termcolor", - "unicode-width 0.2.1", + "unicode-width 0.1.14", ] [[package]] @@ -3012,6 +3012,34 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "frame-election-provider-solution-type" +version = "16.1.1" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2506#6fd693e6d9cfa46cd2acbcb41cd5b0451a62d67c" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "frame-election-provider-support" +version = "41.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2506#6fd693e6d9cfa46cd2acbcb41cd5b0451a62d67c" +dependencies = [ + "frame-election-provider-solution-type", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-npos-elections", + "sp-runtime", + "sp-std", +] + [[package]] name = "frame-executive" version = "41.0.0" @@ -6697,6 +6725,23 @@ dependencies = [ "sp-trie", ] +[[package]] +name = "pallet-session-keys-registration" +version = "1.7.0" +dependencies = [ + "frame-support", + "frame-system", + "pallet-session", + "pallet-staking", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-tracing", +] + [[package]] name = "pallet-session-validator-management" version = "1.7.0" @@ -6795,6 +6840,27 @@ dependencies = [ "tokio", ] +[[package]] +name = "pallet-staking" +version = "41.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2506#6fd693e6d9cfa46cd2acbcb41cd5b0451a62d67c" +dependencies = [ + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", + "parity-scale-codec", + "scale-info", + "serde", + "sp-application-crypto", + "sp-io", + "sp-runtime", + "sp-staking", +] + [[package]] name = "pallet-sudo" version = "41.0.0" @@ -6894,7 +6960,7 @@ checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9" dependencies = [ "bitcoin_hashes 0.13.0", "rand 0.8.5", - "rand_core 0.6.4", + "rand_core 0.4.2", "serde", "unicode-normalization", ] @@ -7256,6 +7322,7 @@ dependencies = [ "pallet-native-token-management", "pallet-partner-chains-session", "pallet-session", + "pallet-session-keys-registration", "pallet-session-validator-management", "pallet-session-validator-management-benchmarking", "pallet-sidechain", @@ -11026,6 +11093,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "sp-npos-elections" +version = "37.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2506#6fd693e6d9cfa46cd2acbcb41cd5b0451a62d67c" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-arithmetic", + "sp-core", + "sp-runtime", +] + [[package]] name = "sp-offchain" version = "37.0.0" diff --git a/Cargo.toml b/Cargo.toml index a8f1bf905..b3ae8b1af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ members = [ "toolkit/governed-map/primitives", "toolkit/governed-map/pallet", "toolkit/committee-selection/selection-simulator", + "toolkit/session_keys_registration", ] resolver = "2" @@ -198,6 +199,7 @@ pallet-aura = { default-features = false, git = "https://github.com/paritytech/p pallet-balances = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" } pallet-grandpa = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" } pallet-session = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" } +pallet-staking = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" } pallet-sudo = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" } pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" } pallet-transaction-payment = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" } @@ -330,5 +332,8 @@ partner-chains-mock-data-sources = { path = "toolkit/data-sources/mock", default sp-governed-map = { path = "toolkit/governed-map/primitives", default-features = false } pallet-governed-map = { path = "toolkit/governed-map/pallet", default-features = false } +# Session Keys Registration +pallet-session-keys-registration = { path = "toolkit/session_keys_registration", default-features = false } + # demo node partner-chains-demo-runtime = { path = "demo/runtime" } diff --git a/demo/node/src/chain_spec.rs b/demo/node/src/chain_spec.rs index 41581e532..a90baee87 100644 --- a/demo/node/src/chain_spec.rs +++ b/demo/node/src/chain_spec.rs @@ -46,9 +46,8 @@ pub fn pc_create_chain_spec(config: &CreateChainSpecConfig) -> serd grandpa: partner_chains_demo_runtime::GrandpaConfig::default(), sudo: partner_chains_demo_runtime::SudoConfig::default(), transaction_payment: Default::default(), - session: config.pallet_partner_chains_session_config(), + session: Default::default(), sidechain: config.pallet_sidechain_config(SlotsPerEpoch::default()), - pallet_session: Default::default(), session_committee_management: config.pallet_session_validator_management_config(), native_token_management: config.native_token_management_config(), governed_map: config.governed_map_config(), diff --git a/demo/node/src/staging.rs b/demo/node/src/staging.rs index 894db2b8a..2602dc490 100644 --- a/demo/node/src/staging.rs +++ b/demo/node/src/staging.rs @@ -130,18 +130,22 @@ pub fn staging_genesis( }, transaction_payment: Default::default(), session: SessionConfig { - initial_validators: initial_authorities + keys: initial_authorities .iter() .map(|authority_keys| { - (authority_keys.cross_chain.clone().into(), authority_keys.session.clone()) + ( + authority_keys.cross_chain.clone().into(), + authority_keys.cross_chain.clone().into(), + authority_keys.session.clone(), + ) }) .collect(), + non_authority_keys: Default::default(), }, sidechain: SidechainConfig { genesis_utxo: sp_sidechain::read_genesis_utxo_from_env_with_defaults()?, ..Default::default() }, - pallet_session: Default::default(), session_committee_management: SessionCommitteeManagementConfig { initial_authorities: initial_authorities .into_iter() diff --git a/demo/node/src/template_chain_spec.rs b/demo/node/src/template_chain_spec.rs index 10997b8f7..1c8e2e993 100644 --- a/demo/node/src/template_chain_spec.rs +++ b/demo/node/src/template_chain_spec.rs @@ -27,13 +27,13 @@ pub fn chain_spec() -> Result { transaction_payment: Default::default(), session: SessionConfig { // Initial validators are meant to be updated in the chain spec file, so it is empty here. - initial_validators: vec![], + keys: vec![], + non_authority_keys: Default::default(), }, sidechain: SidechainConfig { genesis_utxo: sp_sidechain::read_genesis_utxo_from_env_with_defaults()?, ..Default::default() }, - pallet_session: Default::default(), session_committee_management: SessionCommitteeManagementConfig { // Same as SessionConfig initial_authorities: vec![], diff --git a/demo/node/src/testnet.rs b/demo/node/src/testnet.rs index 94a1649c8..557a9f5d7 100644 --- a/demo/node/src/testnet.rs +++ b/demo/node/src/testnet.rs @@ -181,19 +181,23 @@ pub fn testnet_genesis( }, transaction_payment: Default::default(), session: SessionConfig { - initial_validators: initial_authorities + keys: initial_authorities .iter() .map(|authority_keys| { - (authority_keys.cross_chain.clone().into(), authority_keys.session.clone()) + ( + authority_keys.cross_chain.clone().into(), + authority_keys.cross_chain.clone().into(), + authority_keys.session.clone(), + ) }) .collect(), + non_authority_keys: Default::default(), }, sidechain: SidechainConfig { genesis_utxo: sp_sidechain::read_genesis_utxo_from_env_with_defaults()?, slots_per_epoch: SlotsPerEpoch::read_from_env()?, ..Default::default() }, - pallet_session: Default::default(), session_committee_management: SessionCommitteeManagementConfig { initial_authorities: initial_authorities .into_iter() diff --git a/demo/runtime/Cargo.toml b/demo/runtime/Cargo.toml index 7b1f063d3..8b9d5b1cf 100644 --- a/demo/runtime/Cargo.toml +++ b/demo/runtime/Cargo.toml @@ -32,7 +32,7 @@ pallet-grandpa = { workspace = true } pallet-partner-chains-session = { workspace = true, features = [ "pallet-session-compat", ] } -pallet-session = { workspace = true } +pallet-session = { workspace = true, features = ["historical"] } pallet-sudo = { workspace = true } frame-system = { workspace = true } frame-try-runtime = { workspace = true, optional = true } @@ -93,6 +93,7 @@ pallet-governed-map = { workspace = true } sp-governed-map = { workspace = true } sp-block-producer-fees = { workspace = true } pallet-block-producer-fees = { workspace = true } +pallet-session-keys-registration = { workspace = true } [dev-dependencies] sp-io = { workspace = true } @@ -139,6 +140,7 @@ std = [ "pallet-transaction-payment/std", "pallet-address-associations/std", "pallet-block-producer-metadata/std", + "pallet-session-keys-registration/std", "sp-block-producer-metadata/std", "sp-api/std", "sp-block-builder/std", diff --git a/demo/runtime/src/genesis_config_presets.rs b/demo/runtime/src/genesis_config_presets.rs index d43be0368..a5ba4f781 100644 --- a/demo/runtime/src/genesis_config_presets.rs +++ b/demo/runtime/src/genesis_config_presets.rs @@ -58,7 +58,6 @@ fn testnet_genesis( transaction_payment: Default::default(), sidechain: Default::default(), session_committee_management: Default::default(), - pallet_session: Default::default(), session: Default::default(), native_token_management: Default::default(), governed_map: GovernedMapConfig { diff --git a/demo/runtime/src/lib.rs b/demo/runtime/src/lib.rs index de70ad099..9537ff0ed 100644 --- a/demo/runtime/src/lib.rs +++ b/demo/runtime/src/lib.rs @@ -46,6 +46,7 @@ use sp_core::ByteArray; use sp_core::{OpaqueMetadata, crypto::KeyTypeId}; use sp_governed_map::MainChainScriptsV1; use sp_inherents::InherentIdentifier; +use sp_runtime::traits::ConvertInto; use sp_runtime::{ ApplyExtrinsicResult, MultiSignature, Perbill, generic, impl_opaque_keys, traits::{ @@ -309,7 +310,24 @@ impl pallet_aura::Config for Runtime { type SlotDuration = ConstU64; } -pallet_partner_chains_session::impl_pallet_session_config!(Runtime); +impl pallet_session::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = AccountId; + type ValidatorIdOf = ConvertInto; + type ShouldEndSession = ValidatorManagementSessionManager; + type NextSessionRotation = (); + type SessionManager = ValidatorManagementSessionManager; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type DisablingStrategy = pallet_session::disabling::UpToLimitWithReEnablingDisablingStrategy; + + type WeightInfo = pallet_session::weights::SubstrateWeight; +} + +// impl pallet_session::historical::Config for Runtime { +// type FullIdentification = (); +// type FullIdentificationOf = (); +// } impl pallet_grandpa::Config for Runtime { type RuntimeEvent = RuntimeEvent; @@ -373,15 +391,6 @@ impl pallet_sudo::Config for Runtime { type WeightInfo = pallet_sudo::weights::SubstrateWeight; } -impl pallet_partner_chains_session::Config for Runtime { - type ValidatorId = ::AccountId; - type ShouldEndSession = ValidatorManagementSessionManager; - type NextSessionRotation = (); - type SessionManager = ValidatorManagementSessionManager; - type SessionHandler = ::KeyTypeIdProviders; - type Keys = opaque::SessionKeys; -} - parameter_types! { pub const MaxValidators: u32 = 1024; } @@ -672,6 +681,10 @@ impl pallet_governed_map::Config for Runtime { type BenchmarkHelper = (); } +impl pallet_session_keys_registration::Config for Runtime { + type PalletsOrigin = OriginCaller; +} + impl crate::test_helper_pallet::Config for Runtime {} // Create the runtime by composing the FRAME pallets that were previously configured. @@ -693,13 +706,9 @@ construct_runtime!( BlockProducerMetadata: pallet_block_producer_metadata, BlockProductionLog: pallet_block_production_log, BlockParticipation: pallet_block_participation, - // pallet_grandpa reads pallet_session::pallet::CurrentIndex storage. - // Only stub implementation of pallet_session should be wired. - // Partner Chains session_manager ValidatorManagementSessionManager writes to pallet_session::pallet::CurrentIndex. - // ValidatorManagementSessionManager is wired in by pallet_partner_chains_session. - PalletSession: pallet_session, - // The order matters!! pallet_partner_chains_session needs to come last for correct initialization order - Session: pallet_partner_chains_session, + Session: pallet_session exclude_parts { Call }, + SessionKeysRegistration: pallet_session_keys_registration, + // Historical: pallet_session::historical, NativeTokenManagement: pallet_native_token_management, GovernedMap: pallet_governed_map, TestHelperPallet: crate::test_helper_pallet, @@ -895,7 +904,6 @@ impl_runtime_apis! { } } - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Nonce { System::account_nonce(account) diff --git a/dev/local-environment/configurations/partner-chains-setup/entrypoint.sh b/dev/local-environment/configurations/partner-chains-setup/entrypoint.sh index b2d397010..cc4ef3b4f 100644 --- a/dev/local-environment/configurations/partner-chains-setup/entrypoint.sh +++ b/dev/local-environment/configurations/partner-chains-setup/entrypoint.sh @@ -192,8 +192,9 @@ echo "Generating chain-spec.json file for Partner chain Nodes..." ./partner-chains-node build-spec --disable-default-bootnode > chain-spec.json echo "Configuring Initial Validators..." -jq '.genesis.runtimeGenesis.config.session.initialValidators = [ +jq '.genesis.runtimeGenesis.config.session.keys = [ [ + "5FnXTMg8UnfeGsMaGg24o3NY21VRFRDRdgxuLGmXuYLeZmin", "5FnXTMg8UnfeGsMaGg24o3NY21VRFRDRdgxuLGmXuYLeZmin", { "aura": "5Cyx94iyji8namhRxvs4mAbURtPsvwjWCb68ZihNzfRysGLZ", @@ -201,6 +202,7 @@ jq '.genesis.runtimeGenesis.config.session.initialValidators = [ } ], [ + "5FJMH4MeZgd4fpiiAVLnr4uRop2EDFgzAFcvLmcduQ2cofCi", "5FJMH4MeZgd4fpiiAVLnr4uRop2EDFgzAFcvLmcduQ2cofCi", { "aura": "5E4op92Z2Di1GoVS9KqnoGVKQXG2R9x1vdh3RW892YLFsLrc", diff --git a/toolkit/committee-selection/pallet/src/session_manager.rs b/toolkit/committee-selection/pallet/src/session_manager.rs index c608e20be..c9d448505 100644 --- a/toolkit/committee-selection/pallet/src/session_manager.rs +++ b/toolkit/committee-selection/pallet/src/session_manager.rs @@ -98,6 +98,47 @@ impl } } +impl pallet_session::SessionManager + for ValidatorManagementSessionManager +{ + fn new_session_genesis(_new_index: SessionIndex) -> Option> { + Some( + crate::Pallet::::current_committee_storage() + .committee + .into_iter() + .map(|member| member.authority_id().into()) + .collect::>(), + ) + } + + // Instead of Some((*).expect) we could just use (*). However, we rather panic in presence of + // important programming errors. + fn new_session(new_index: SessionIndex) -> Option> { + info!("New session {new_index}"); + pallet_session::pallet::CurrentIndex::::put(new_index); + Some( + crate::Pallet::::rotate_committee_to_next_epoch() + .expect( + "Session should never end without current epoch validators defined. \ + Check ShouldEndSession implementation or if it is used before starting new session", + ) + .into_iter() + .map(|member| member.authority_id().into()) + .collect(), + ) + } + + fn end_session(end_index: SessionIndex) { + info!("End session {end_index}"); + } + + // Session is expected to be at least 1 block behind sidechain epoch. + fn start_session(start_index: SessionIndex) { + let epoch_number = T::current_epoch_number(); + info!("Start session {start_index}, epoch {epoch_number}"); + } +} + /// This implementation tries to end each session in the first block of each sidechain epoch in which /// the committee for the epoch is defined. impl pallet_partner_chains_session::ShouldEndSession> @@ -114,6 +155,22 @@ where } } +/// This implementation tries to end each session in the first block of each sidechain epoch in which +/// the committee for the epoch is defined. +impl pallet_session::ShouldEndSession> + for ValidatorManagementSessionManager +where + T: crate::Config, + ScEpochNumber: Clone + PartialOrd, +{ + fn should_end_session(_n: BlockNumberFor) -> bool { + let current_epoch_number = T::current_epoch_number(); + + current_epoch_number > crate::Pallet::::current_committee_storage().epoch + && crate::Pallet::::next_committee().is_some() + } +} + #[cfg(test)] mod tests { use crate::mock::mock_pallet::CurrentEpoch; diff --git a/toolkit/session_keys_registration/Cargo.toml b/toolkit/session_keys_registration/Cargo.toml new file mode 100644 index 000000000..970718745 --- /dev/null +++ b/toolkit/session_keys_registration/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "pallet-session-keys-registration" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true +version.workspace = true +license = "Apache-2.0" +description = "Pallet for registering session keys for the partner chains" + +[lints] +workspace = true + +[dependencies] +frame-support = { workspace = true, default-features = false } +frame-system = { workspace = true, default-features = false } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true, default-features = false, features = [ + "derive", +] } +sp-runtime = { workspace = true, default-features = false } +pallet-session = { workspace = true } + +[dev-dependencies] +pallet-staking = { workspace = true } +sp-core = { workspace = true } +sp-io = { workspace = true } +sp-staking = { workspace = true } +sp-tracing = { workspace = true } + +[features] +default = ["std"] +std = [ + "frame-support/std", + "frame-system/std", + "parity-scale-codec/std", + "scale-info/std", + "sp-runtime/std", + "pallet-session/std", + "pallet-staking/std", +] diff --git a/toolkit/session_keys_registration/src/lib.rs b/toolkit/session_keys_registration/src/lib.rs new file mode 100644 index 000000000..f0945fb74 --- /dev/null +++ b/toolkit/session_keys_registration/src/lib.rs @@ -0,0 +1,47 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::{dispatch::DispatchResultWithPostInfo, pallet_prelude::*}; + use scale_info::prelude::boxed::Box; + use sp_runtime::Vec; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + pallet_session::Config { + /// The caller origin, overarching type of all pallets origins. + type PalletsOrigin: Parameter + + Into<::RuntimeOrigin> + + IsType<<::RuntimeOrigin as frame_support::traits::OriginTrait>::PalletsOrigin>; + } + + impl Pallet { + /// Invokes the `pallet_session::Call::set_keys` function to set the session keys. + /// + /// Allows the caller to set the session keys for the next session for particular user. + /// + /// ## Complexity + /// - `O(1)`. Actual cost depends on the number of length of `T::Keys::key_ids()` which is + /// fixed. + pub fn set_keys( + as_origin: Box, + keys: ::Keys, + proof: Vec, + ) -> DispatchResultWithPostInfo { + let call = pallet_session::Call::::set_keys { keys, proof }; + + use frame_support::traits::UnfilteredDispatchable; + call.dispatch_bypass_filter((*as_origin).into()) + } + } +} diff --git a/toolkit/session_keys_registration/src/mock.rs b/toolkit/session_keys_registration/src/mock.rs new file mode 100644 index 000000000..a7d02bb66 --- /dev/null +++ b/toolkit/session_keys_registration/src/mock.rs @@ -0,0 +1,100 @@ +use crate as pallet_session_keys_registration; + +use frame_support::derive_impl; +use frame_support::traits::{OnFinalize, OnInitialize}; +use sp_core::parameter_types; +use sp_runtime::key_types::DUMMY; +use sp_runtime::testing::UintAuthorityId; +use sp_runtime::{BuildStorage, KeyTypeId}; +use sp_staking::SessionIndex; + +type Block = frame_system::mocking::MockBlock; + +sp_runtime::impl_opaque_keys! { + pub struct SessionKeys { + pub foo: UintAuthorityId, + } +} + +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Session: pallet_session, + SessionKeysRegistration: pallet_session_keys_registration, + } +); + +type AccountId = u64; + +pub struct TestSessionHandler; +impl pallet_session::SessionHandler for TestSessionHandler { + const KEY_TYPE_IDS: &'static [KeyTypeId] = &[DUMMY]; + + fn on_genesis_session(_validators: &[(AccountId, Ks)]) {} + + fn on_new_session( + _: bool, + _: &[(AccountId, Ks)], + _: &[(AccountId, Ks)], + ) { + } + + fn on_disabled(_: u32) {} +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type Block = Block; +} + +parameter_types! { + pub const Period: u64 = 1; + pub const Offset: u64 = 0; +} + +impl pallet_session::Config for Test { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = u64; + type ValidatorIdOf = sp_runtime::traits::ConvertInto; + type ShouldEndSession = pallet_session::PeriodicSessions; + type NextSessionRotation = pallet_session::PeriodicSessions; + type SessionManager = (); + type SessionHandler = TestSessionHandler; + type Keys = SessionKeys; + type DisablingStrategy = (); + type WeightInfo = (); +} + +impl pallet_session_keys_registration::Config for Test { + type PalletsOrigin = OriginCaller; +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + sp_tracing::try_init_simple(); + let t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + sp_io::TestExternalities::new(t) +} + +pub fn start_session(session_index: SessionIndex) { + for i in Session::current_index()..session_index { + System::on_finalize(System::block_number()); + Session::on_finalize(System::block_number()); + + let parent_hash = if System::block_number() > 1 { + let hdr = System::finalize(); + hdr.hash() + } else { + System::parent_hash() + }; + + System::reset_events(); + System::initialize(&(i as u64 + 1), &parent_hash, &Default::default()); + System::set_block_number((i + 1).into()); + + System::on_initialize(System::block_number()); + Session::on_initialize(System::block_number()); + } + + assert_eq!(Session::current_index(), session_index); +} diff --git a/toolkit/session_keys_registration/src/tests.rs b/toolkit/session_keys_registration/src/tests.rs new file mode 100644 index 000000000..75fceac0c --- /dev/null +++ b/toolkit/session_keys_registration/src/tests.rs @@ -0,0 +1,35 @@ +use frame_support::assert_ok; +use sp_runtime::testing::UintAuthorityId; + +use crate::mock::{ + OriginCaller, Session, SessionKeys, SessionKeysRegistration, System, new_test_ext, + start_session, +}; + +#[test] +fn register_session_keys_for_provided_authorities() { + new_test_ext().execute_with(|| { + start_session(1); + + { + let account_id: u64 = 1; + System::inc_providers(&account_id); + + // By default, the session keys are not set for the account. + assert_eq!(Session::load_keys(&account_id), None); + + let as_origin = + Box::new(OriginCaller::system(frame_system::RawOrigin::Signed(account_id))); + let keys = SessionKeys { foo: UintAuthorityId::from(42) }; + let proof = Default::default(); + + assert_ok!(SessionKeysRegistration::set_keys(as_origin, keys, proof)); + + // After setting the keys, they should be stored in the session. + assert_eq!( + Session::load_keys(&account_id), + Some(SessionKeys { foo: UintAuthorityId(42) }) + ); + } + }); +}