Eth2.0-specs: Slashing penalty overflows

Created on 10 Jul 2019  路  10Comments  路  Source: ethereum/eth2.0-specs

I think it'd be a good idea to make comments on the places which uint64 overflow can happen and big int should be used. Since the default primitive is uint64, expression like:

penalty = validator.effective_balance * min(sum(state.slashings) * 3, total_balance) // total_balance

results in a differently because validator.effective_balance * min(sum(state.slashings) * 3, total_balance) overflows uint64

presentation

All 10 comments

big int should be used

One of the design goals is that big int should never be used. As such, I'm labelling this is a bug.

penalty = validator.effective_balance * min(sum(state.slashings) * 3, total_balance) // total_balance

In the worst case validator.effective_balance * min(sum(state.slashings) * 3, total_balance) can indeed overflow.

expression like

Do you have other examples?

This was actually discovered from the yaml test. I think for python, it just converts to long instead of overflow

Do you have other examples

Not right now, I'll go through the spec today to see if I can spot more offenders

Here's a non-substantive fix which makes use of the fact that validator.effective_balance is a small multiple of GWEI_PER_ETH.

penalty = (validator.effective_balance // GWEI_PER_ETH) * min(sum(state.slashings) * 3, total_balance) // total_balance * GWEI_PER_ETH

This works because (validator.effective_balance // GWEI_PER_ETH) * min(sum(state.slashings) * 3, total_balance) is at most 32 * total_balance, itself at most 32 * 2**22 * 2**5 * 10**9, itself less than 2**62 馃帀

If we want to be even more conservative we could use the same trick on min(sum(state.slashings) * 3, total_balance) which is guaranteed to also be a multiple of GWEI_PER_ETH.

@JustinDrake This is substantive because validator.effective_balance is not guaranteed to be a multiple of GWEI_PER_ETH

validator.effective_balance is not guaranteed to be a multiple of GWEI_PER_ETH

How?

hm, you're right. The tests failed due to this change due to a mismatch in previous calculations and current. digging in

If we want to be even more conservative we could use the same trick on min(sum(state.slashings) * 3, total_balance) which is guaranteed to also be a multiple of GWEI_PER_ETH

We can't actually do this due to a sum(state.slashings) * 3 // EFFECTIVE_BALANCE_INCREMENT zeroing out in many cases. That was the issue I found when performing the calculations that led me to my incorrect prior assumption.

Also note that the divisor should be EFFECTIVE_BALANCE_INCREMENT rather than GWEI_PER_ETH

penalty = (validator.effective_balance // GWEI_PER_ETH) * min(sum(state.slashings) * 3, total_balance) // total_balance * GWEI_PER_ETH

Seems reasonable to me.

Fixed in #1286.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JustinDrake picture JustinDrake  路  24Comments

JustinDrake picture JustinDrake  路  12Comments

protolambda picture protolambda  路  18Comments

JustinDrake picture JustinDrake  路  33Comments

paulhauner picture paulhauner  路  15Comments