feat: punish confirmed light-client attacks at double-sign severity - #71
Open
giunatale wants to merge 1 commit into
Open
Conversation
HandleConsumerMisbehaviour was detection-only: it verified a light-client attack and logged the byzantine set but applied no punishment. It now slashes, jails, and tombstones the validators that signed both conflicting headers at the DoubleSign infraction severity, identical to vote-level double signing. The slash/jail/tombstone path is factored into a shared punishEquivocation primitive that HandleConsumerDoubleVoting also uses, so the two equivocation paths differ only in how the evidence is verified, not in how the equivocation is punished. When an attack is confirmed but no validator can be punished (an amnesia attack has no identifiable signers; other conflicts may leave only unbonded signers), the consumer is stopped and scheduled for removal via StopAndPrepareForConsumerRemoval instead of a silent no-op. The escalation only fires from the launched phase, so re-submitting the same evidence does not schedule removal twice.
giunatale
requested review from
clockworkgr,
julienrbrt and
tbruyelle
as code owners
July 30, 2026 16:07
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A confirmed light-client attack on a consumer was previously detection-only:
the byzantine validators were extracted, logged, and returned — no slashing,
jailing, or tombstoning. That left the cheapest way to attack a consumer chain
unpunished, while the equivalent offence via double-voting was tombstoned.
What
HandleConsumerMisbehaviournow punishes:consumer, headers at the same height within the trusting period, genuinely
conflicting, each valid against its trusted consensus state).
same primitive as consumer double-voting — slash, jail, and tombstone at the
double-sign infraction parameters. The punishment code is now factored and
shared (
punishEquivocation); the two evidence types differ only inverification. Already-tombstoned validators are a no-op, so repeated
submissions stay idempotent.
and schedules it for removal rather than no-opping on a proven-compromised
chain. This covers an amnesia attack, which has no attributable signer by
construction, and also the case where every extracted signer turns out to be
unpunishable (all unbonded). This is terminal: nothing moves a consumer out
of
STOPPED, so there is no veto or cancel path — deliberate, since the chainhas been proven byzantine. Escalation only applies to a LAUNCHED consumer; one
already stopping is left alone.
Testing
Unit: identifiable byzantine signers are slashed, jailed, and tombstoned at the
double-sign fraction; repeated submission is idempotent; an unidentifiable
attack stops the consumer and schedules removal; a non-launched consumer is not
escalated. Build, lint, and the module suite are green.