#[cfg(test)]
pub mod ah;
#[cfg(test)]
pub mod rc;
#[cfg(test)]
pub mod shared;
#[cfg(test)]
mod tests {
use super::*;
use crate::rc::RootOffences;
use ah_client::OperatingMode;
use frame::testing_prelude::*;
use frame_support::traits::Get;
use pallet_election_provider_multi_block as multi_block;
use pallet_staking as staking_classic;
use pallet_staking_async::{ActiveEra, ActiveEraInfo, Forcing};
use pallet_staking_async_ah_client as ah_client;
use pallet_staking_async_rc_client as rc_client;
#[test]
fn rc_session_change_reported_to_ah() {
shared::put_ah_state(ah::ExtBuilder::default().build());
shared::put_rc_state(rc::ExtBuilder::default().build());
shared::in_ah(|| {
assert_eq!(frame_system::Pallet::<ah::Runtime>::block_number(), 1);
assert_eq!(pallet_staking_async::CurrentEra::<ah::Runtime>::get(), Some(0));
assert_eq!(
ActiveEra::<ah::Runtime>::get(),
Some(ActiveEraInfo { index: 0, start: Some(0) })
);
});
shared::in_rc(|| {
assert_eq!(ah_client::Mode::<rc::Runtime>::get(), OperatingMode::Active);
assert!(frame_system::Pallet::<rc::Runtime>::block_number() == 1);
rc::roll_until_matches(
|| pallet_session::CurrentIndex::<rc::Runtime>::get() == 1,
true,
);
assert_eq!(frame_system::Pallet::<rc::Runtime>::block_number(), rc::Period::get());
});
shared::in_rc(|| {
rc::roll_until_matches(
|| pallet_session::CurrentIndex::<rc::Runtime>::get() == 4,
true,
);
});
shared::in_ah(|| {
assert_eq!(frame_system::Pallet::<ah::Runtime>::block_number(), 120);
assert!(matches!(
multi_block::CurrentPhase::<ah::Runtime>::get(),
multi_block::Phase::Snapshot(_)
));
});
shared::in_rc(|| {
rc::roll_until_matches(
|| pallet_session::CurrentIndex::<rc::Runtime>::get() == 5,
true,
);
});
shared::in_ah(|| {
assert_eq!(pallet_staking_async::CurrentEra::<ah::Runtime>::get(), Some(1));
assert_eq!(
ActiveEra::<ah::Runtime>::get(),
Some(ActiveEraInfo { index: 0, start: Some(0) })
);
});
shared::in_rc(|| {
rc::roll_until_matches(
|| pallet_session::CurrentIndex::<rc::Runtime>::get() == 6,
true,
);
});
}
#[test]
fn ah_takes_over_staking_post_migration() {
shared::put_rc_state(
rc::ExtBuilder::default()
.pre_migration()
.session_keys(vec![1, 2, 3, 4, 5, 6, 7, 8])
.build(),
);
shared::put_ah_state(ah::ExtBuilder::default().build());
shared::in_rc(|| {
assert!(staking_classic::ActiveEra::<rc::Runtime>::get().is_none());
rc::roll_until_matches(
|| {
staking_classic::ActiveEra::<rc::Runtime>::get().map(|a| a.index).unwrap_or(0) ==
1
},
true,
);
assert!(staking_classic::UnappliedSlashes::<rc::Runtime>::get(4).is_empty());
assert_ok!(RootOffences::create_offence(
rc::RuntimeOrigin::root(),
vec![(2, Perbill::from_percent(100))],
None,
None
));
assert_eq!(staking_classic::UnappliedSlashes::<rc::Runtime>::get(4).len(), 1);
});
shared::in_ah(|| {
assert_eq!(shared::CounterRCAHNewOffence::get(), 0);
assert_eq!(shared::CounterRCAHSessionReport::get(), 0);
assert_eq!(ah::mock::staking_events_since_last_call(), vec![]);
});
let mut pre_migration_block_number = 0;
shared::in_rc(|| {
rc::roll_next();
let pre_migration_era_points =
staking_classic::ErasRewardPoints::<rc::Runtime>::get(1).total;
ah_client::Pallet::<rc::Runtime>::on_migration_start();
assert_eq!(ah_client::Mode::<rc::Runtime>::get(), OperatingMode::Buffered);
let mut current_session = pallet_session::CurrentIndex::<rc::Runtime>::get();
pre_migration_block_number = frame_system::Pallet::<rc::Runtime>::block_number();
rc::roll_until_matches(
|| {
pallet_session::CurrentIndex::<rc::Runtime>::get() ==
current_session + ah::SessionsPerEra::get() + 1
},
true,
);
current_session = pallet_session::CurrentIndex::<rc::Runtime>::get();
let migration_start_block_number = frame_system::Pallet::<rc::Runtime>::block_number();
assert_eq!(staking_classic::ActiveEra::<rc::Runtime>::get().unwrap().index, 1);
assert_eq!(staking_classic::CurrentEra::<rc::Runtime>::get().unwrap(), 1);
assert_eq!(
staking_classic::ErasRewardPoints::<rc::Runtime>::get(1).total,
pre_migration_era_points
);
assert_eq!(
ah_client::ValidatorPoints::<rc::Runtime>::iter().count(),
1,
"only 11 has authored blocks in rc"
);
assert_eq!(
ah_client::ValidatorPoints::<rc::Runtime>::get(&11),
(migration_start_block_number - pre_migration_block_number) as u32 *
<<rc::Runtime as ah_client::Config>::PointsPerBlock as Get<u32>>::get()
);
assert_ok!(RootOffences::create_offence(
rc::RuntimeOrigin::root(),
vec![(5, Perbill::from_percent(100))],
None,
None,
));
assert_eq!(staking_classic::UnappliedSlashes::<rc::Runtime>::get(4).len(), 1);
assert_eq!(ah_client::BufferedOffences::<rc::Runtime>::get().len(), 1);
assert_eq!(
ah_client::BufferedOffences::<rc::Runtime>::get()[0],
(
current_session,
vec![rc_client::Offence {
offender: 5,
reporters: vec![],
slash_fraction: Perbill::from_percent(100),
}],
)
);
});
shared::in_ah(|| {
assert_eq!(shared::CounterRCAHNewOffence::get(), 0);
assert_eq!(shared::CounterRCAHSessionReport::get(), 0);
assert_eq!(ah::mock::staking_events_since_last_call(), vec![]);
});
shared::migrate_state();
shared::in_rc(|| {
ah_client::Pallet::<rc::Runtime>::on_migration_end();
assert_eq!(ah_client::Mode::<rc::Runtime>::get(), OperatingMode::Active);
assert_eq!(shared::CounterRCAHNewOffence::get(), 1);
});
let mut post_migration_era_reward_points = 0;
shared::in_ah(|| {
post_migration_era_reward_points =
pallet_staking_async::ErasRewardPoints::<ah::Runtime>::get(1).total;
assert_eq!(pallet_staking_async::ForceEra::<ah::Runtime>::get(), Forcing::NotForcing);
assert_eq!(
pallet_staking_async::OffenceQueue::<ah::Runtime>::get(1, 5).unwrap(),
pallet_staking_async::slashing::OffenceRecord {
reporter: None,
reported_era: 1,
exposure_page: 0,
slash_fraction: Perbill::from_percent(100),
prior_slash_fraction: Perbill::from_percent(0),
}
);
ah::roll_next();
assert_eq!(
ah::mock::staking_events_since_last_call(),
vec![
pallet_staking_async::Event::OffenceReported {
offence_era: 1,
validator: 5,
fraction: Perbill::from_percent(100)
},
pallet_staking_async::Event::SlashComputed {
offence_era: 1,
slash_era: 3,
offender: 5,
page: 0
},
]
);
assert_eq!(pallet_staking_async::OffenceQueue::<ah::Runtime>::get(1, 5), None);
assert!(pallet_staking_async::UnappliedSlashes::<ah::Runtime>::get(
3,
(5, Perbill::from_percent(100), 0)
)
.is_some());
});
shared::in_ah(|| {
ah::roll_next();
assert_eq!(pallet_staking_async::CurrentEra::<ah::Runtime>::get(), Some(1));
assert_eq!(pallet_staking_async::ActiveEra::<ah::Runtime>::get().unwrap().index, 1);
assert_eq!(shared::CounterRCAHSessionReport::get(), 0);
});
let mut post_migration_session_block_number = 0;
shared::in_rc(|| {
assert_eq!(pallet_session::CurrentIndex::<rc::Runtime>::get(), 12);
rc::roll_until_matches(
|| pallet_session::CurrentIndex::<rc::Runtime>::get() == 13,
true,
);
post_migration_session_block_number =
frame_system::Pallet::<rc::Runtime>::block_number();
assert_eq!(ah_client::ValidatorPoints::<rc::Runtime>::iter().count(), 0,);
});
assert_eq!(shared::CounterRCAHSessionReport::get(), 1);
shared::in_ah(|| {
assert_eq!(pallet_staking_async::ActiveEra::<ah::Runtime>::get().unwrap().index, 1);
assert_eq!(pallet_staking_async::CurrentEra::<ah::Runtime>::get(), Some(1 + 1));
assert_eq!(
ah::rc_client_events_since_last_call(),
vec![
rc_client::Event::OffenceReceived { slash_session: 12, offences_count: 1 },
rc_client::Event::SessionReportReceived {
end_index: 12,
activation_timestamp: None,
validator_points_counts: 1,
leftover: false
}
]
);
assert_eq!(
ah::mock::staking_events_since_last_call(),
vec![pallet_staking_async::Event::SessionRotated {
starting_session: 13,
active_era: 1,
planned_era: 2
}]
);
assert_eq!(
pallet_staking_async::ErasRewardPoints::<ah::Runtime>::get(1).total,
((post_migration_session_block_number - pre_migration_block_number) * 20) as u32 +
post_migration_era_reward_points );
ah::roll_until_matches(|| shared::CounterAHRCValidatorSet::get() == 1, true);
assert_eq!(
ah::staking_events_since_last_call(),
vec![
pallet_staking_async::Event::PagedElectionProceeded { page: 2, result: Ok(4) },
pallet_staking_async::Event::PagedElectionProceeded { page: 1, result: Ok(0) },
pallet_staking_async::Event::PagedElectionProceeded { page: 0, result: Ok(0) }
]
);
});
shared::in_rc(|| {
assert_eq!(
rc::ah_client_events_since_last_call(),
vec![ah_client::Event::ValidatorSetReceived {
id: 2,
new_validator_set_count: 4,
prune_up_to: None,
leftover: false
}]
);
let (planned_era, next_validator_set) =
ah_client::ValidatorSet::<rc::Runtime>::get().unwrap();
assert_eq!(planned_era, 2);
assert!(next_validator_set.len() >= rc::MinimumValidatorSetSize::get() as usize);
});
shared::in_ah(|| {
assert_eq!(pallet_staking_async::ActiveEra::<ah::Runtime>::get().unwrap().index, 1);
ah::roll_until_matches(|| shared::CounterRCAHSessionReport::get() == 2, true);
assert_eq!(pallet_staking_async::ActiveEra::<ah::Runtime>::get().unwrap().index, 1);
ah::roll_until_matches(|| shared::CounterRCAHSessionReport::get() == 3, true);
assert_eq!(pallet_staking_async::ActiveEra::<ah::Runtime>::get().unwrap().index, 2);
});
}
#[test]
fn election_result_on_ah_reported_to_rc() {
}
#[test]
fn rc_continues_with_same_validators_if_ah_is_late() {
}
#[test]
fn authoring_points_reported_to_ah_per_session() {}
#[test]
fn rc_is_late_to_report_session_change() {}
#[test]
fn pruning_is_at_least_bonding_duration() {}
#[test]
fn ah_eras_are_delayed() {
}
#[test]
fn ah_know_good_era_duration() {
}
#[test]
fn election_provider_fails_to_start() {
}
#[test]
fn overlapping_election() {
}
#[test]
fn session_report_burst() {
}
}