feat: initialize Kurdistan SDK - independent fork of Polkadot SDK
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// This file is part of Pezkuwi.
|
||||
|
||||
// Pezkuwi is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Pezkuwi is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Pezkuwi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! A module that is responsible for migration of storage.
|
||||
|
||||
use frame_support::traits::StorageVersion;
|
||||
|
||||
/// The in-code storage version.
|
||||
pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
|
||||
@@ -0,0 +1,211 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// This file is part of Pezkuwi.
|
||||
|
||||
// Pezkuwi is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Pezkuwi is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Pezkuwi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
configuration::HostConfiguration,
|
||||
initializer::SessionChangeNotification,
|
||||
mock::{
|
||||
new_test_ext, Configuration, MockGenesisConfig, ParasShared, RuntimeOrigin, SessionInfo,
|
||||
System, Test,
|
||||
},
|
||||
util::take_active_subset,
|
||||
};
|
||||
use pezkuwi_primitives::{BlockNumber, SchedulerParams, ValidatorId, ValidatorIndex};
|
||||
use sp_keyring::Sr25519Keyring;
|
||||
|
||||
fn run_to_block(
|
||||
to: BlockNumber,
|
||||
new_session: impl Fn(BlockNumber) -> Option<SessionChangeNotification<BlockNumber>>,
|
||||
) {
|
||||
while System::block_number() < to {
|
||||
let b = System::block_number();
|
||||
|
||||
SessionInfo::initializer_finalize();
|
||||
ParasShared::initializer_finalize();
|
||||
Configuration::initializer_finalize();
|
||||
|
||||
if let Some(notification) = new_session(b + 1) {
|
||||
Configuration::initializer_on_new_session(¬ification.session_index);
|
||||
ParasShared::initializer_on_new_session(
|
||||
notification.session_index,
|
||||
notification.random_seed,
|
||||
¬ification.new_config,
|
||||
notification.validators.clone(),
|
||||
);
|
||||
SessionInfo::initializer_on_new_session(¬ification);
|
||||
}
|
||||
|
||||
System::on_finalize(b);
|
||||
|
||||
System::on_initialize(b + 1);
|
||||
System::set_block_number(b + 1);
|
||||
|
||||
Configuration::initializer_initialize(b + 1);
|
||||
ParasShared::initializer_initialize(b + 1);
|
||||
SessionInfo::initializer_initialize(b + 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn default_config() -> HostConfiguration<BlockNumber> {
|
||||
HostConfiguration {
|
||||
dispute_period: 2,
|
||||
needed_approvals: 3,
|
||||
scheduler_params: SchedulerParams { num_cores: 1, ..Default::default() },
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn genesis_config() -> MockGenesisConfig {
|
||||
MockGenesisConfig {
|
||||
configuration: configuration::GenesisConfig { config: default_config() },
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn session_changes(n: BlockNumber) -> Option<SessionChangeNotification<BlockNumber>> {
|
||||
if n % 10 == 0 {
|
||||
Some(SessionChangeNotification { session_index: n / 10, ..Default::default() })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn new_session_every_block(n: BlockNumber) -> Option<SessionChangeNotification<BlockNumber>> {
|
||||
Some(SessionChangeNotification { session_index: n, ..Default::default() })
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_pruning_is_based_on_dispute_period() {
|
||||
new_test_ext(genesis_config()).execute_with(|| {
|
||||
// Dispute period starts at 2
|
||||
let config = configuration::ActiveConfig::<Test>::get();
|
||||
assert_eq!(config.dispute_period, 2);
|
||||
|
||||
// Move to session 10
|
||||
run_to_block(100, session_changes);
|
||||
// Earliest stored session is 10 - 2 = 8
|
||||
assert_eq!(EarliestStoredSession::<Test>::get(), 8);
|
||||
// Pruning works as expected
|
||||
assert!(Sessions::<Test>::get(7).is_none());
|
||||
assert!(Sessions::<Test>::get(8).is_some());
|
||||
assert!(Sessions::<Test>::get(9).is_some());
|
||||
|
||||
// changing `dispute_period` works
|
||||
let dispute_period = 5;
|
||||
Configuration::set_dispute_period(RuntimeOrigin::root(), dispute_period).unwrap();
|
||||
|
||||
// Dispute period does not automatically change
|
||||
let config = configuration::ActiveConfig::<Test>::get();
|
||||
assert_eq!(config.dispute_period, 2);
|
||||
// Two sessions later it will though
|
||||
run_to_block(120, session_changes);
|
||||
let config = configuration::ActiveConfig::<Test>::get();
|
||||
assert_eq!(config.dispute_period, 5);
|
||||
|
||||
run_to_block(200, session_changes);
|
||||
assert_eq!(EarliestStoredSession::<Test>::get(), 20 - dispute_period);
|
||||
|
||||
// Increase dispute period even more
|
||||
let new_dispute_period = 16;
|
||||
Configuration::set_dispute_period(RuntimeOrigin::root(), new_dispute_period).unwrap();
|
||||
|
||||
run_to_block(210, session_changes);
|
||||
assert_eq!(EarliestStoredSession::<Test>::get(), 21 - dispute_period);
|
||||
|
||||
// Two sessions later it kicks in
|
||||
run_to_block(220, session_changes);
|
||||
let config = configuration::ActiveConfig::<Test>::get();
|
||||
assert_eq!(config.dispute_period, 16);
|
||||
// Earliest session stays the same
|
||||
assert_eq!(EarliestStoredSession::<Test>::get(), 21 - dispute_period);
|
||||
|
||||
// We still don't have enough stored sessions to start pruning
|
||||
run_to_block(300, session_changes);
|
||||
assert_eq!(EarliestStoredSession::<Test>::get(), 21 - dispute_period);
|
||||
|
||||
// now we do
|
||||
run_to_block(420, session_changes);
|
||||
assert_eq!(EarliestStoredSession::<Test>::get(), 42 - new_dispute_period);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_info_is_based_on_config() {
|
||||
new_test_ext(genesis_config()).execute_with(|| {
|
||||
run_to_block(1, new_session_every_block);
|
||||
let session = Sessions::<Test>::get(&1).unwrap();
|
||||
assert_eq!(session.needed_approvals, 3);
|
||||
|
||||
// change some param
|
||||
Configuration::set_needed_approvals(RuntimeOrigin::root(), 42).unwrap();
|
||||
// 2 sessions later
|
||||
run_to_block(3, new_session_every_block);
|
||||
let session = Sessions::<Test>::get(&3).unwrap();
|
||||
assert_eq!(session.needed_approvals, 42);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_info_active_subsets() {
|
||||
let unscrambled = vec![
|
||||
Sr25519Keyring::Alice,
|
||||
Sr25519Keyring::Bob,
|
||||
Sr25519Keyring::Charlie,
|
||||
Sr25519Keyring::Dave,
|
||||
Sr25519Keyring::Eve,
|
||||
];
|
||||
|
||||
let active_set = vec![ValidatorIndex(4), ValidatorIndex(0), ValidatorIndex(2)];
|
||||
|
||||
let unscrambled_validators: Vec<ValidatorId> =
|
||||
unscrambled.iter().map(|v| v.public().into()).collect();
|
||||
let unscrambled_discovery: Vec<AuthorityDiscoveryId> =
|
||||
unscrambled.iter().map(|v| v.public().into()).collect();
|
||||
let unscrambled_assignment: Vec<AssignmentId> =
|
||||
unscrambled.iter().map(|v| v.public().into()).collect();
|
||||
|
||||
let validators = take_active_subset(&active_set, &unscrambled_validators);
|
||||
|
||||
new_test_ext(genesis_config()).execute_with(|| {
|
||||
ParasShared::set_active_validators_with_indices(active_set.clone(), validators.clone());
|
||||
|
||||
assert_eq!(shared::ActiveValidatorIndices::<Test>::get(), active_set);
|
||||
|
||||
AssignmentKeysUnsafe::<Test>::set(unscrambled_assignment.clone());
|
||||
crate::mock::set_discovery_authorities(unscrambled_discovery.clone());
|
||||
assert_eq!(<Test>::authorities(), unscrambled_discovery);
|
||||
|
||||
// invoke directly, because `run_to_block` will invoke `Shared` and clobber our
|
||||
// values.
|
||||
SessionInfo::initializer_on_new_session(&SessionChangeNotification {
|
||||
session_index: 1,
|
||||
validators: validators.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
let session = Sessions::<Test>::get(&1).unwrap();
|
||||
|
||||
assert_eq!(session.validators.to_vec(), validators);
|
||||
assert_eq!(
|
||||
session.discovery_keys,
|
||||
take_active_subset_and_inactive(&active_set, &unscrambled_discovery),
|
||||
);
|
||||
assert_eq!(
|
||||
session.assignment_keys,
|
||||
take_active_subset(&active_set, &unscrambled_assignment),
|
||||
);
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user