Skip to content
tests.rs 69.9 KiB
Newer Older
		start_era(2);
		assert_eq!(Staking::current_era_start_session_index(), SessionsPerEra::get() * 2);

		let session = Session::current_index();
		ForceEra::put(Forcing::ForceNew);
		advance_session();
		assert_eq!(Staking::current_era(), 3);
		assert_eq!(Staking::current_era_start_session_index(), session + 1);

		start_era(4);
		assert_eq!(Staking::current_era_start_session_index(), session + SessionsPerEra::get() + 1);
	});
}

#[test]
fn offence_forces_new_era() {
	with_externalities(&mut ExtBuilder::default().build(), || {
		Staking::on_offence(
			&[OffenceDetails {
				offender: (
					11,
					Staking::stakers(&11),
				),
				reporters: vec![],
			}],
			&[Perbill::from_percent(5)],
		);

		assert_eq!(Staking::force_era(), Forcing::ForceNew);
	});
}

#[test]
fn slashing_performed_according_exposure() {
	// This test checks that slashing is performed according the exposure (or more precisely,
	// historical exposure), not the current balance.
	with_externalities(&mut ExtBuilder::default().build(), || {
		assert_eq!(Staking::stakers(&11).own, 1000);

		// Handle an offence with a historical exposure.
		Staking::on_offence(
			&[OffenceDetails {
				offender: (
					11,
					Exposure {
						total: 500,
						own: 500,
						others: vec![],
					},
				),
				reporters: vec![],
			}],
			&[Perbill::from_percent(50)],
		);

		// The stash account should be slashed for 250 (50% of 500).
		assert_eq!(Balances::free_balance(&11), 1000 - 250);
	});
}

#[test]
fn reporters_receive_their_slice() {
	// This test verifies that the reporters of the offence receive their slice from the slashed
	// amount.
	with_externalities(&mut ExtBuilder::default().build(), || {
		// The reporters' reward is calculated from the total exposure.
Kian Paimani's avatar
Kian Paimani committed
		#[cfg(feature = "equalize")]
		let initial_balance = 1250;
		#[cfg(not(feature = "equalize"))]
		let initial_balance = 1125;

		assert_eq!(Staking::stakers(&11).total, initial_balance);

		Staking::on_offence(
			&[OffenceDetails {
				offender: (
					11,
					Staking::stakers(&11),
				),
				reporters: vec![1, 2],
			}],
			&[Perbill::from_percent(50)],
		);

Kian Paimani's avatar
Kian Paimani committed
		// initial_balance x 50% (slash fraction) x 10% (rewards slice)
		let reward = initial_balance / 20 / 2;
		assert_eq!(Balances::free_balance(&1), 10 + reward);
		assert_eq!(Balances::free_balance(&2), 20 + reward);
	});
}

#[test]
fn invulnerables_are_not_slashed() {
	// For invulnerable validators no slashing is performed.
	with_externalities(
		&mut ExtBuilder::default().invulnerables(vec![11]).build(),
		|| {
Kian Paimani's avatar
Kian Paimani committed
			#[cfg(feature = "equalize")]
			let initial_balance = 1250;
			#[cfg(not(feature = "equalize"))]
			let initial_balance = 1375;

			assert_eq!(Balances::free_balance(&11), 1000);
			assert_eq!(Balances::free_balance(&21), 2000);
Kian Paimani's avatar
Kian Paimani committed
			assert_eq!(Staking::stakers(&21).total, initial_balance);

			Staking::on_offence(
				&[
					OffenceDetails {
						offender: (11, Staking::stakers(&11)),
						reporters: vec![],
					},
					OffenceDetails {
						offender: (21, Staking::stakers(&21)),
						reporters: vec![],
					},
				],
				&[Perbill::from_percent(50), Perbill::from_percent(20)],
			);

			// The validator 11 hasn't been slashed, but 21 has been.
			assert_eq!(Balances::free_balance(&11), 1000);
Kian Paimani's avatar
Kian Paimani committed
			// 2000 - (0.2 * initial_balance)
			assert_eq!(Balances::free_balance(&21), 2000 - (2 * initial_balance / 10));
		},
	);
}

#[test]
fn dont_slash_if_fraction_is_zero() {
	// Don't slash if the fraction is zero.
	with_externalities(&mut ExtBuilder::default().build(), || {
		assert_eq!(Balances::free_balance(&11), 1000);

		Staking::on_offence(
			&[OffenceDetails {
				offender: (
					11,
					Staking::stakers(&11),
				),
				reporters: vec![],
			}],
			&[Perbill::from_percent(0)],
		);

		// The validator hasn't been slashed. The new era is not forced.
		assert_eq!(Balances::free_balance(&11), 1000);
		assert_eq!(Staking::force_era(), Forcing::NotForcing);
	});
}