-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slashing: differentiating between stake bonded at the time of infraction and since the time of infraction #1440
Comments
Is this basically referring to "don't slash a delegator who just joined you and didn't contribute voting power to your nasty nasty move in a previous block" - right now it doesn't really matter if you just joined a validator or not - if you join and then that validator get's slashed your going to get the short end of the stick and (arguably maybe unfairly) get slashed Yeah I mean it's arguable whether it's unfair behaviour or not - it's the same kind of problem of the other issue - if we allow for this kind of slashing to persist it would be considered slashing-by-association - which I don't think is the worst thing in the world Maybe even we just want to keep this to keep the code base simpler and have less avenues for being spammed (spamvenues 😄) but yeah basically if we kept an additional queue of delegations for the first unbonding period for which you have bonded to somebody then we could parse this information out and prevent this instance of slashing-by-association |
Yes, that's the behaviour at the moment. I don't know how likely it is to arise in practice, but it's a bit concerning because it can set up perverse incentives. It's not just that stake which delegated since an infraction also gets slashed - it's (maybe more concerningly) that stake which contributed to the infraction is slashed less if other stake delegates before the infraction is discovered. For example, let's say users A and B are delegating 10 stake to validators 1 and 2 (who have no other delegators in this simple example). Validators 1 and 2 both commit equally slashable infractions (slash fraction 1/2) at time α, which are not discovered until time β. In between α and β, A convinces C to also delegate 10 stake to validator 1, while B does nothing. At time β, both infractions are discovered, and validators 1 and 2 are each slashed by 5 stake (half of 10). Now, share and validator distributions are as follows: Validator 1 has 15 stake (10 delegated from A + 10 delegated from C - 5 slashed) A and C each own 50% shares in validator 1, while B owns 100% shares in validator 2 - giving A an equivalent 7.5 stake and B an equivalent 5 stake. A and B committed equal severity offenses at the same time, but since A managed to convince C to delegate to A's validator before the offense was discovered, A has halved his punishment. More generally, this means that if I am delegating to a validator and I believe it likely (for whatever reason) that my validator has committed an infraction, it's in my immediate best interest not to unbond (for if I did my stake would be slashable at the usual infraction rate), but rather to convince other delegators to delegate to my validator, so that I will be slashed less, effectively, at which point the infraction is discovered and published to the chain. |
Another interesting attack: I start up a "fake" validator, with a small self-bond. I immediately commit an infraction or many infractions with high severity (several double-signs, for example) but do not publish them to the chain. I then spend the next unbonding period (or possibly much longer depending on the resolution of #1378) convincing delegators to delegate to me (maybe a particular delegator whose stake I want to burn). Once I have convinced this stake to delegate to me, I publish the infraction evidence and burn all delegated stake (an amount which may be arbitrarily more than my self-bond, the only stake which actually contributed to the infraction). |
I definitely agree with you're points @cwgoes, and think this should be addressed. I don't think this should be solved via an additional store / putting more things into a current store. I think instead that we should ensure that all full nodes contain all blocks within the last unbonding period handily accessible. Then when its been determined that there should be a slash, they query the store at the block which the double sign was on, and slash accordingly (time of infraction). I think this method makes it more clear as to what is going on. (Though has the downside of having to load one of the state trees, shouldn't be too bad though if we assume validators are running on ssd's) |
We don't need to keep a full state archive for the unbonding period, just an archive of the staking store. |
yeah if we were to leave this form of slashing in here we'd want to increase the amount of slashing to make sure that the original tokens contributing to the bad behaviour had an equal amount slashed independent of the discovery date. -> aka we just slash more than usual the later it's discovered -> however this now has new funky cryptoeconomic implications :( so yeah sounds like a good idea to do create "fair" slashing - aka don't screw the new delegators. Let's do this 👍 |
NOTE - slashing with different proportions of the current stake breaks a design constraint the distribution spec. This needs to be addressed (I think it probably is possible) if we update to this unproportional slashing as proposed |
Tabled to post-launch by slashing design meeting. |
I don't think we need to do this post-launch either, but lets have another discussion if needed? Delegators are responsible for ensuring that validators didn't commit a prior infraction, but I think that's minor compared to their existing responsibility of ensuring future security... and leaving as is appears to keep the logic simpler. |
we could compile a list of delegator responsibilities - that's the only action item I can think of for this. Let's close? |
I'm still not convinced that our implementation is ideal, but I agree that this ranks pretty low on the list of potential PoS problems. Closing in favor of #1678. |
The semantics of slashing should be that voting power which contributed to an infraction is punished proportionally to the infraction's severity, and that voting power which did not contribute is not punished. This means we need to be able to reconstruct the changes in contributing stake to a validator up to an unbonding period in the past.
Redelegations and unbonding delegations give us sufficient information to identify and punish delegators who have since redelegated or unbonded, but we do not presently differentiate between stake which was delegated at the time of the infraction and still delegated at the time of discovery and stake which was delegated between the time of infraction and the time of discovery. The latter stake did not contribute to the infraction and per these desired semantics should not be slashable.
We could differentiate between these two categories of stake, with our current store model, by simply iterating over the delegations to a validator which is slashed, finding all the stake delegated since the infraction, and subtracting that stake from the validator's "slashable stake" (and adjusting the delegator's percentage of the validator's shares) - however, this is
O(n)
in the total number of delegations to the validator. Other possible approaches include keeping a time-sorted index of delegations, adding a secondary data structure for this purpose which can be deleted after an unbonding period, or just making the stake delegated since the infraction slashable anyways.The text was updated successfully, but these errors were encountered: