Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cb10d13
EPM and staking pallets: Adds new crate for integration tests
gpestana Dec 14, 2022
3ec1541
Adds ExtBuilder and helpers with initial conditions assertions
gpestana Dec 16, 2022
b818b29
removes account helpers; adds staking, session, etc genesis
gpestana Jan 1, 2023
624c728
Adds kusama incident test case
gpestana Jan 2, 2023
73197ae
Prepare for slashing test
gpestana Jan 5, 2023
762b0c0
Adds solution submission
gpestana Jan 6, 2023
869b677
slash_through_offending_threshold
gpestana Jan 6, 2023
eeb0438
Renames e2e integration tests dir and crate
gpestana Jan 8, 2023
888fa74
consistently slash 10% of validator set
gpestana Jan 9, 2023
8e73538
finishes continous_slashes_below_offending_threshold test
gpestana Jan 9, 2023
632e209
Update frame/election-provider-multi-phase/test-staking-e2e/src/lib.rs
gpestana Mar 13, 2023
ffc9aae
Update frame/election-provider-multi-phase/test-staking-e2e/src/lib.rs
gpestana Mar 13, 2023
81b2275
Update frame/election-provider-multi-phase/test-staking-e2e/src/lib.rs
gpestana Mar 13, 2023
b3c6e98
Update frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
gpestana Mar 15, 2023
a1dcd6c
Update frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
gpestana Mar 15, 2023
79d8d4b
Update frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
gpestana Mar 15, 2023
ac52c0b
mock fixes
gpestana Mar 15, 2023
40ac80f
Additional checks to delayed solution eras and mock fixes
gpestana Mar 15, 2023
f1de0a9
nits and addresses review comments; splits ext_builder into one per p…
gpestana Mar 15, 2023
84dfba6
helper to set balances ext builder
gpestana Mar 15, 2023
3597015
Merge branch 'master' into gpestana/9057-EPM-integration-tests
gpestana Mar 15, 2023
9829cc1
bring up mock.rs to master
gpestana Mar 15, 2023
3eb15b6
integration test fixes and additions
gpestana Mar 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Prepare for slashing test
  • Loading branch information
gpestana committed Jan 5, 2023
commit 73197ae3c359b27701412a8f78de1e772d3a1e2a
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ fn enters_emergency_phase_after_forcing_before_elect() {

roll_to_epm_off();
assert!(ElectionProviderMultiPhase::current_phase().is_off());
log_current_time();

assert_eq!(pallet_staking::ForceEra::<Runtime>::get(), pallet_staking::Forcing::NotForcing);
// slashes until staking gets into `Forcing::ForceNew`.
Expand All @@ -83,6 +84,7 @@ fn enters_emergency_phase_after_forcing_before_elect() {

advance_session();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we should plan the slashes to happen EXACTLY at the block where if we do roll_to(current_block + 1), a new session would happen automatically.

Right now, you are kinda simulating that 🙈

Not sure how accurate you want to be. Perhaps I am too strict here.

But, the nice thing is:

Assume the block at which the slashes happen is n, and the block at which the next session+election happens in x. If the difference between n and x is too short, then we fail. But if we have like 5 block between the two, this would not happen.

As a side note, in order to make these tests more accurate, you can inspire from here to also have automatic submission of OCWs: https://github.com/paritytech/substrate/blob/kiz-multi-block-election/frame/election-provider-multi-block/src/mock/mod.rs#L580

This could help tests be more accurate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah cool! Yes, I just finished my own flavour of fn roll_with_ocw, I should have looked a bit more into the existing code. But yes, I agree. The next commit should have a more accurate flow without simulating emergency etc

assert!(ElectionProviderMultiPhase::current_phase().is_emergency());
log_current_time();

// try to advance 2 eras.
advance_n_sessions(<SessionsPerEra as Get<u32>>::get().into());
Expand All @@ -109,13 +111,50 @@ fn enters_emergency_phase_after_forcing_before_elect() {
// EPM can now roll to signed phase to proceed with elections. The validator set is the
// expected (ie. set through `set_emergency_election_result`).
roll_to_epm_signed();
log_current_time();
assert!(ElectionProviderMultiPhase::current_phase().is_signed());
assert_eq!(Session::validators(), vec![21, 31, 41]);
});
}

#[test]
/// Continously slash validators in the validator set while in emergency phase.
fn continuous_slashes_in_emergency() {
// TODO(gpestana)
/// Continously slash 10% of the active validators per era, even during the emergency phase.
fn continous_slashes() {
ExtBuilder::default()
.initialize_first_session(true)
.validator_count(10)
.build_and_execute(|| {
assert_eq!(Session::validators().len(), 10);

roll_to_epm_off();
assert!(ElectionProviderMultiPhase::current_phase().is_off());

println!(
"slashing 11, set: {:?} - {:?}",
Session::validators(),
ElectionProviderMultiPhase::current_phase()
);
add_slash(&11);
advance_n_sessions(<SessionsPerEra as Get<u32>>::get().into());
assert_eq!(
pallet_staking::ForceEra::<Runtime>::get(),
pallet_staking::Forcing::NotForcing
);

println!(
"slashing 12, set: {:?} - {:?}",
Session::validators(),
ElectionProviderMultiPhase::current_phase()
);
add_slash(&12);
advance_n_sessions(<SessionsPerEra as Get<u32>>::get().into());
assert_eq!(
pallet_staking::ForceEra::<Runtime>::get(),
pallet_staking::Forcing::NotForcing
);
});
}

#[test]
/// Continously slash 10% of the active validators per era while in emergency phase.
fn continuous_slashes_in_emergency() {}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#![allow(dead_code)] // TODO(gpestana): remove when ready
#![allow(dead_code)]

use frame_support::{
parameter_types, traits,
traits::{GenesisBuild, Hooks},
weights::constants,
};
use frame_system::EnsureRoot;
use sp_core::{ConstU32, Get, H256};
Expand Down Expand Up @@ -74,7 +75,7 @@ pub(crate) type Moment = u64;

impl frame_system::Config for Runtime {
type BaseCallFilter = traits::Everything;
type BlockWeights = ();
type BlockWeights = BlockWeights;
type BlockLength = ();
type DbWeight = ();
type RuntimeOrigin = RuntimeOrigin;
Expand All @@ -99,8 +100,14 @@ impl frame_system::Config for Runtime {
type MaxConsumers = traits::ConstU32<16>;
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
parameter_types! {
pub static ExistentialDeposit: Balance = 1;
pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights
::with_sensible_defaults(
Weight::from_parts(2u64 * constants::WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
NORMAL_DISPATCH_RATIO,
);
}

impl pallet_balances::Config for Runtime {
Expand Down Expand Up @@ -165,14 +172,16 @@ frame_election_provider_support::generate_solution_type!(

parameter_types! {
pub static SignedPhase: BlockNumber = 10;
pub static UnsignedPhase: BlockNumber = 1;
pub static UnsignedPhase: BlockNumber = 5;
pub static MaxElectingVoters: VoterIndex = 1000;
pub static MaxElectableTargets: TargetIndex = 1000;
pub static MaxActiveValidators: u32 = 1000;
pub static Balancing: Option<BalancingConfig> = Some( BalancingConfig { iterations: 0, tolerance: 0 } );
pub static BetterSignedThreshold: Perbill = Perbill::zero();
pub static BetterUnsignedThreshold: Perbill = Perbill::zero();
pub static OffchainRepeat: u32 = 5;
pub static MinerMaxLength: u32 = 256;
pub static MinerMaxWeight: Weight = BlockWeights::get().max_block;
pub static TransactionPriority: transaction_validity::TransactionPriority = 1;
pub static MaxWinners: u32 = 100;
pub static MaxVotesPerVoter: u32 = 16;
Expand Down Expand Up @@ -216,10 +225,10 @@ impl MinerConfig for Runtime {
type AccountId = AccountId;
type Solution = MockNposSolution;
type MaxVotesPerVoter = MaxNominations;
type MaxLength = ();
type MaxWeight = ();
type MaxLength = MinerMaxLength;
type MaxWeight = MinerMaxWeight;

fn solution_weight(_voters: u32, _targets: u32, _active_voters: u32, _degree: u32) -> Weight {
fn solution_weight(_v: u32, _t: u32, _a: u32, _d: u32) -> Weight {
Weight::zero()
}
}
Expand All @@ -232,7 +241,7 @@ parameter_types! {
pub const BondingDuration: sp_staking::EraIndex = 28;
pub const SlashDeferDuration: sp_staking::EraIndex = 7; // 1/4 the bonding duration.
pub const MaxNominatorRewardedPerValidator: u32 = 256;
pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(10);
pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(40);
pub HistoryDepth: u32 = 84;
}

Expand Down Expand Up @@ -346,7 +355,6 @@ impl sp_runtime::BoundToRuntimeAppPublic for OtherSessionHandler {
}

pub struct ExtBuilder {
nominate: bool,
validator_count: u32,
minimum_validator_count: u32,
invulnerables: Vec<AccountId>,
Expand All @@ -363,7 +371,6 @@ pub struct ExtBuilder {
impl Default for ExtBuilder {
fn default() -> Self {
Self {
nominate: true,
validator_count: 2,
minimum_validator_count: 0,
balance_factor: 1,
Expand Down Expand Up @@ -399,22 +406,24 @@ impl ExtBuilder {
(30, self.balance_factor),
(40, self.balance_factor),
(50, self.balance_factor),
// stashes
(11, self.balance_factor * 1000),
(21, self.balance_factor * 2000),
(31, self.balance_factor * 2000),
(41, self.balance_factor * 2000),
(51, self.balance_factor * 2000),
// optional nominator
(100, self.balance_factor * 2000),
(101, self.balance_factor * 2000),
// aux accounts
(60, self.balance_factor),
(61, self.balance_factor * 2000),
(70, self.balance_factor),
(71, self.balance_factor * 2000),
(80, self.balance_factor),
(81, self.balance_factor * 2000),
(90, self.balance_factor),
(100, self.balance_factor),
(200, self.balance_factor),
// stashes
(11, self.balance_factor * 1000),
(21, self.balance_factor * 2000),
(31, self.balance_factor * 3000),
(41, self.balance_factor * 4000),
(51, self.balance_factor * 5000),
(61, self.balance_factor * 6000),
(71, self.balance_factor * 7000),
(81, self.balance_factor * 8000),
(91, self.balance_factor * 9000),
(101, self.balance_factor * 10000),
(201, self.balance_factor * 20000),
// This allows us to have a total_payout different from 0.
(999, 1_000_000_000_000),
],
Expand All @@ -428,20 +437,18 @@ impl ExtBuilder {
// these two will be elected in the default test where we elect 2.
(11, 10, self.balance_factor * 1000, StakerStatus::<AccountId>::Validator),
(21, 20, self.balance_factor * 1000, StakerStatus::<AccountId>::Validator),
// a loser validator
// loser validatos if validator_count() is default.
(31, 30, self.balance_factor * 500, StakerStatus::<AccountId>::Validator),
(41, 40, self.balance_factor * 500, StakerStatus::<AccountId>::Validator),
(51, 50, self.balance_factor * 500, StakerStatus::<AccountId>::Validator),
(61, 60, self.balance_factor * 500, StakerStatus::<AccountId>::Validator),
(71, 70, self.balance_factor * 500, StakerStatus::<AccountId>::Validator),
(81, 80, self.balance_factor * 500, StakerStatus::<AccountId>::Validator),
(91, 90, self.balance_factor * 500, StakerStatus::<AccountId>::Validator),
(101, 100, self.balance_factor * 500, StakerStatus::<AccountId>::Validator),
// an idle validator
(41, 40, self.balance_factor * 1000, StakerStatus::<AccountId>::Idle),
(201, 200, self.balance_factor * 1000, StakerStatus::<AccountId>::Idle),
];
// optionally add a nominator
if self.nominate {
stakers.push((
101,
100,
self.balance_factor * 500,
StakerStatus::<AccountId>::Nominator(vec![11, 21]),
))
}
// replace any of the status if needed.
self.status.into_iter().for_each(|(stash, status)| {
let (_, _, _, ref mut prev_status) = stakers
Expand Down Expand Up @@ -519,6 +526,10 @@ impl ExtBuilder {
<UnsignedPhase>::set(unsigned);
self
}
pub fn validator_count(mut self, n: u32) -> Self {
self.validator_count = n;
self
}
pub fn build_and_execute(self, test: impl FnOnce() -> ()) {
self.build().execute_with(test)
Copy link
Contributor

@kianenigma kianenigma Dec 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<AllPallets as TryState>::try_state()

}
Expand Down