Skip to content

Slashing Condition Engine Griefing via Minimal-Evidence Flood on Single Validator #25

Description

@JamesEjembi

Problem Statement / Feature Objective

The slashing condition engine processes evidence from the mempool on a first-come-first-served basis without rate-limiting by validator index. An attacker can submit thousands of minimal-evidence packages (duplicate attestations with trivial slot offsets) for the same victim validator, each triggering a full slashing evaluation including signature verification and state mutation. This exhausts the epoch processing gas budget and blocks legitimate slashing evidence from being processed.

Technical Invariants & Bounds

  • Mempool capacity: 1024 evidence entries (ring buffer).
  • Processing budget: 500ms per epoch boundary for slashing.
  • Each evidence verification: ~2ms (signature check + state read).
  • Max evidence per validator per epoch: unbounded (no rate limit).
  • Griefing cost: attacker can submit 500 evidence entries in ~1 block.
  • Legitimate evidence for the same validator is delayed by at least 1 epoch.

Codebase Navigation Guide

  • src/slashing/condition-engine.rs - process_slashing_evidence() and mempool drain.
  • src/slashing/mempool.rs - SlashingMempool with push_evidence() and drain_all().
  • src/slashing/evidence-verifier.rs - verify_and_apply() with signature verification.
  • tests/slashing/griefing_resistance_test.rs - DoS resistance tests.

Implementation Blueprint

  1. In src/slashing/mempool.rs, add a rate limiter: a HashMap<ValidatorIndex, u8> tracking evidence count per validator per epoch.
  2. Set MAX_EVIDENCE_PER_VALIDATOR_PER_EPOCH = 1 (one slashing is sufficient; additional evidence is redundant).
  3. On push_evidence(), if the validator has already reached the limit, return an OverflowError and drop the evidence without processing.
  4. At epoch boundary, reset the rate-limit map.
  5. Add a test that submits 100 evidence entries for the same validator and asserts only the first is processed and the remaining 99 are rejected.

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions