Background
slashing.rs currently treats every inactivity or fault detection as an immediate, permanent penalty, with two related gaps called out directly in the code:
/// # TODO
/// - Add a grace period counter so a validator gets one warning before
/// being slashed (reduces false positives from transient network issues).
pub fn check_inactivity(env: &Env, validator: Address) -> Result<bool, BridgeError> { ... }
/// # TODO
/// - Consider a time-based reputation recovery mechanism so validators can
/// rehabilitate after a period of honest behaviour.
fn calculate_new_reputation(current: u32, reason: &SlashingReason) -> u32 { ... }
Today, check_inactivity slashes on the very first detected inactivity window with no tolerance for transient network issues (a validator briefly unreachable due to a network blip is penalized the same as one that's actually gone offline), and calculate_new_reputation only ever subtracts via saturating_sub — reputation can never recover, so a validator who was slashed once for a minor issue (e.g. Inactivity, -5) stays permanently closer to the MIN_ACTIVE_REPUTATION = 40 removal threshold even after months of honest behavior.
Implementation Plan
- Add a grace-period counter (e.g., stored alongside
ValidatorInfo) so a validator gets one recorded warning on first inactivity detection and is only slashed if inactivity persists past a second check.
- Add a time-based reputation recovery mechanism: reputation gradually increases toward a cap during sustained honest activity (e.g., a small recovery increment per elapsed period since the last slash, capped at the original baseline).
- Add tests: a single transient inactivity event does not trigger a slash (only a warning), a persistent inactivity event does slash, and reputation recovers over time after a slash given continued honest activity.
Acceptance Criteria
- A validator's first inactivity detection results in a warning, not an immediate slash
- Reputation recovers over time following honest behavior after a slash, bounded by a sensible cap
- Tests cover the grace-period and recovery paths
Background
slashing.rscurrently treats every inactivity or fault detection as an immediate, permanent penalty, with two related gaps called out directly in the code:Today,
check_inactivityslashes on the very first detected inactivity window with no tolerance for transient network issues (a validator briefly unreachable due to a network blip is penalized the same as one that's actually gone offline), andcalculate_new_reputationonly ever subtracts viasaturating_sub— reputation can never recover, so a validator who was slashed once for a minor issue (e.g.Inactivity, -5) stays permanently closer to theMIN_ACTIVE_REPUTATION = 40removal threshold even after months of honest behavior.Implementation Plan
ValidatorInfo) so a validator gets one recorded warning on first inactivity detection and is only slashed if inactivity persists past a second check.Acceptance Criteria