From de5686509c61370ce097857dd1d68f1fb55a215b Mon Sep 17 00:00:00 2001 From: Gavin Wood <gavin@parity.io> Date: Wed, 27 Nov 2019 18:57:03 +0000 Subject: [PATCH] Validators don't get slashed for offlineness until 10% at once (#4232) * Validators don't get slashed for offlineness until 10% at once * Update frame/im-online/src/tests.rs Co-Authored-By: Marcio Diaz <marcio.diaz@gmail.com> * Update frame/im-online/src/tests.rs Co-Authored-By: Marcio Diaz <marcio.diaz@gmail.com> * Apply suggestions from code review Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- substrate/frame/im-online/src/lib.rs | 12 +++++++++--- substrate/frame/im-online/src/tests.rs | 11 ++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/substrate/frame/im-online/src/lib.rs b/substrate/frame/im-online/src/lib.rs index 01ebde206e4..8f3361186ff 100644 --- a/substrate/frame/im-online/src/lib.rs +++ b/substrate/frame/im-online/src/lib.rs @@ -653,8 +653,14 @@ impl<Offender: Clone> Offence<Offender> for UnresponsivenessOffence<Offender> { } fn slash_fraction(offenders: u32, validator_set_count: u32) -> Perbill { - // the formula is min((3 * (k - 1)) / n, 1) * 0.05 - let x = Perbill::from_rational_approximation(3 * (offenders - 1), validator_set_count); - x.saturating_mul(Perbill::from_percent(5)) + // the formula is min((3 * (k - (n / 10 + 1))) / n, 1) * 0.07 + // basically, 10% can be offline with no slash, but after that, it linearly climbs up to 7% + // when 13/30 are offline (around 5% when 1/3 are offline). + if let Some(threshold) = offenders.checked_sub(validator_set_count / 10 + 1) { + let x = Perbill::from_rational_approximation(3 * threshold, validator_set_count); + x.saturating_mul(Perbill::from_percent(7)) + } else { + Perbill::default() + } } } diff --git a/substrate/frame/im-online/src/tests.rs b/substrate/frame/im-online/src/tests.rs index edfdc34bc00..788956ba6e0 100644 --- a/substrate/frame/im-online/src/tests.rs +++ b/substrate/frame/im-online/src/tests.rs @@ -38,14 +38,19 @@ fn test_unresponsiveness_slash_fraction() { ); assert_eq!( - UnresponsivenessOffence::<()>::slash_fraction(3, 50), - Perbill::from_parts(6000000), // 0.6% + UnresponsivenessOffence::<()>::slash_fraction(5, 50), + Perbill::zero(), // 0% + ); + + assert_eq!( + UnresponsivenessOffence::<()>::slash_fraction(7, 50), + Perbill::from_parts(4200000), // 0.42% ); // One third offline should be punished around 5%. assert_eq!( UnresponsivenessOffence::<()>::slash_fraction(17, 50), - Perbill::from_parts(48000000), // 4.8% + Perbill::from_parts(46200000), // 4.62% ); } -- GitLab