ethereum/casper

Partial Slashing

djrtwo opened this issue · 3 comments

Issue

Need to implement partial slashing to reduce the discouragement of validating for the occasional not-so-malicious incorrectly signed messages.

Proposed Implementation

The following is a rough outline and needs to be cleaned up

  • maintain a mapping epoch => total_slashed, keeping track of the total amount of validator deposits removed through slashing up until that point. When you initialize a new epoch, set total_slashed[now] = total_slashed[now - 1], so the total carries over.
  • let recently_slashed = total_slashed[now] - total_slashed[now - withdrawal_delay]
  • When a validator is slashed, add their entire deposit size to total_slashed[now]
  • When a validator gets slashed, forcibly log them out for dynasty n+1. Set a flag forcing them to be slashed when they withdraw. When they initiate the withdrawal, the following fraction of their deposit is slashed
fraction_to_slash = (total_slashed[withdraw_time] - total_slashed[withdraw_time - 2 * withdrawal_delay]) * 6 / total_deposits_at_logout

Additionally their deposit is calculated based on the deposit_scale_factor at time of withdrawal, so they have to suffer all inactivity penalties up until the block during which they withdraw

This slashing occurring at withdrawal ensures that if a coordinated attack occurs and a significant amount of validators are slashed, then the attackers all suffer equal magnitude slashing.

I have a few questions.

  • What is recently_slashed for?
  • How the numbers(2 and 6) are decided in (total_slashed[withdraw_time] - total_slashed[withdraw_time - 2 * withdrawal_delay]) * 6?

I think I need to read articles(if exist) about the reasoning behind slashing conditions and parameters including this, like sharding spec. Where can I find it?

What is recently_slashed for?

The intention is to slash validators by an amount proportional to the percentage of other validators that were slashed around the same time. recently_slashed is the numerator.

Aah, sorry, I think it's meant to be equal to total_slashed[withdraw_time] - total_slashed[withdraw_time - 2 * withdrawal_delay]

How the numbers(2 and 6) are decided in (total_slashed[withdraw_time] - total_slashed[withdraw_time - 2 * withdrawal_delay]) * 6?

The 2 basically means that if you commit a violation at time T, you're slashed based on the portion of validators that misbehaved between time [T - withdrawal_delay, T + withdrawal_delay]

The 6 makes the slashing 100% if 16.667% of validators are slashed. Originally the interval was [T - withdrawal_delay, T] which meant that if 1/3 were slashed due to the attack, the validators that are slashed first would lose less, making the attack 25% less costly; if the denominator was more forgiving (eg. 3) then the attackers would lose far less. Now that the interval wraps around in both directions, I actually would favor decreasing the 6 to a 3.

addressed in #115