Skip to content
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

R4R: Update slashing spec for slashing-by-period #2001

Merged
merged 27 commits into from
Aug 24, 2018

Conversation

cwgoes
Copy link
Contributor

@cwgoes cwgoes commented Aug 13, 2018

Ref #1256
Closes #1896

To complete before merge:

  • Include ASCII timeline diagrams

Standard checklist:

  • Linked to github-issue with discussion and accepted design OR link to spec that describes this work.
  • Updated all relevant documentation (docs/)
  • Updated all relevant code comments
  • Wrote tests
  • Added entries in PENDING.md that include links to the relevant issue or PR that most accurately describes the change.
  • Updated cmd/gaia and examples/

For Admin Use:

  • Added appropriate labels to PR (ex. wip, ready-for-review, docs)
  • Reviewers Assigned
  • Squashed all commits, uses message "Merge pull request #XYZ: [title]" (coding standards)

@cwgoes cwgoes requested a review from zramsay as a code owner August 13, 2018 12:51
@cwgoes cwgoes added the wip label Aug 13, 2018
@codecov
Copy link

codecov bot commented Aug 13, 2018

Codecov Report

Merging #2001 into develop will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##           develop   #2001   +/-   ##
=======================================
  Coverage     62.2%   62.2%           
=======================================
  Files          115     115           
  Lines         6874    6874           
=======================================
  Hits          4276    4276           
  Misses        2314    2314           
  Partials       284     284

@cwgoes cwgoes changed the title WIP: Update slashing spec for slashing-by-period WIP: Update slashing spec for slashing-by-period and NextValSet Aug 13, 2018
@cwgoes cwgoes changed the title WIP: Update slashing spec for slashing-by-period and NextValSet PR4R: Update slashing spec for slashing-by-period and NextValSet Aug 13, 2018
@cwgoes
Copy link
Contributor Author

cwgoes commented Aug 13, 2018

The slashing-by-period part of this PR is ready for review. Working on the NextValSet updates.

"PR4R" = "partially ready for review"

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates @cwgoes -- I left a question and a tiny remark.


- SlashingPeriod: ` 0x03 | ValTendermintAddr | StartHeight -> amino(slashingPeriod) `

This allows us to look up slashing period by validator address, the only lookup necessary,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slight rewording, This allows us to look up a slashing period by the validator's address ...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated


### Slashing Period

A slashing period is a start and end time associated with a particular validator,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's really a start and end block, right?

Copy link
Contributor Author

@cwgoes cwgoes Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks, updated

penalty for the worst offense.

This period starts when a validator is first bonded and ends when a validator is slashed & jailed
for double-signing (but does not end if they are slashed & jailed for just missing blocks).
Copy link
Contributor

@alexanderbez alexanderbez Aug 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the last part is pretty important and long -- it doesn't seem to belong in parentheses. Thoughts? In other words, I think it'll read easier with just a comma :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below comment.


This period starts when a validator is first bonded and ends when a validator is slashed & jailed
for double-signing (but does not end if they are slashed & jailed for just missing blocks).
When the validator voluntarily unjails themselves (and possibly changes signing keys), they reset the period.
Copy link
Contributor

@alexanderbez alexanderbez Aug 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you help clarify for me one case? What if a validator misses enough blocks to be slashed and jailed -- the slashing period doesn't end. The validator can then, after some time, unjail themselves, correct? If so, is the period reset even though it never ended (they never double signed)? Does that mean they never get penalized for liveliness cost?

I'm sure I'm missing something here, sorry.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump @cwgoes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup! you are right, this is unclear - addressing

Copy link
Contributor Author

@cwgoes cwgoes Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I don't think we need this, we should just end the period when they're unbonded for any reason.

If you think we do need it, please comment further...


Upon successful bonding of a validator (a given validator changing from "unbonded" state to "bonded" state,
which may happen on delegation, on unjailing, etc), we create a new `SlashingPeriod` structure for the
now-bonded validator, wich `StartHeight` of the current block, `EndHeight` of `0` (sentinel value for not-yet-ended),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wich -> with?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed

SignedBlocksCounter int64
StartHeight int64 // Height at which the validator became able to sign blocks
IndexOffset int64 // Offset into the signed block bit array
JailedUntil int64 // Block height until which the validator is jailed,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't JailedUntilHeight make a better name? I usually assume things like Until/After/Before are times

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, now JailedUntilHeight

@cwgoes
Copy link
Contributor Author

cwgoes commented Aug 14, 2018

Implementation of NextValSet depends on whether or not we change the SDK state machine to track the validator set differently. Likely it's just a simple offset of 1.

I think point 2.i in #1896 (comment) is a serious exploit and we need to prevent it, working on that now - unless we're OK with limiting ourselves to revoking-while-slashing.


### Slashing Period

A slashing period is a start and end block height associated with a particular validator,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@alexanderbez
Copy link
Contributor

@cwgoes

I think point 2.i in #1896 (comment) is a serious exploit and we need to prevent it, working on that now - unless we're OK with limiting ourselves to revoking-while-slashing.

Can you elaborate on why?

@cwgoes
Copy link
Contributor Author

cwgoes commented Aug 20, 2018

Can you elaborate on why?

Because otherwise a validator could start with a very small bond and intentionally slash themselves but remain within the slashing period, meaning that they aren't at stake in the future. I'll add a line to the spec about this.

Also see #1896 (comment).

@cwgoes cwgoes changed the title PR4R: Update slashing spec for slashing-by-period and NextValSet PR4R: Update slashing spec for slashing-by-period Aug 20, 2018
@cwgoes
Copy link
Contributor Author

cwgoes commented Aug 20, 2018

Going to leave NextValSet out of this PR as that's blocked on some documentation Tendermint-side.

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cwgoes thanks for the updates -- very straightforward to follow and the ASCII diagrams help. I left a few questions and suggestions 👍

@@ -0,0 +1,174 @@
## Transaction & State Machine Interaction Overview
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be an h1 heading and and all subsequent headers increased but not a big deal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure; updated & also updated in state.md.


*Multiple infractions*

<---------------------------->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the slashing period ends when the validator is jailed & unbonded (Vu), wouldn't that mean the slashing period should extend to Vu?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those two events are simultaneous, not quite sure how to express that best in ASCII, maybe I'll try stacking them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think stacking them might help -- either way, not a big deal because the spec describes this well enough.

ValidatorAddr sdk.AccAddress
}

handleMsgUnjail(tx TxUnjail)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a mixed bag of pseudo-code and Go -- I think we should just stick to one. I guess in this case, can we just add braces?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, thanks - I'd rather it be pseudocode, updated to be less Go-like, let me know if it's better now.


For example, with MaxFractionSlashedPerPeriod = `0.5`, if a validator is initially slashed at `0.4` near the start of a period when they have 100 steak bonded,
then later slashed at `0.4` when they have `1000` steak bonded, the total amount slashed is just `40 + 100 = 140` (since the latter slash is capped at `0.1`) -
whereas if they had `1000` steak bonded initially, the total amount slashed would have been `500`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... if they had 1000 steak bonded initially ... and slashed at what fraction? 0.4? Wouldn't that be 400?

Copy link
Contributor Author

@cwgoes cwgoes Aug 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0.4 * 1000 = 400 for the first offense and 0.1 * 1000 = 100 for the second, total 500.

Clarified the sentence.

then later slashed at `0.4` when they have `1000` steak bonded, the total amount slashed is just `40 + 100 = 140` (since the latter slash is capped at `0.1`) -
whereas if they had `1000` steak bonded initially, the total amount slashed would have been `500`.

This means that any slashing events which utilize the slashing period (are capped-per-period) **must** *also* jail the validator when the infraction is discovered.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this essentially saying (at least at launch), that a validator can only be slashed, in a given slashing period, at most the cost of a double sign OR missing enough signatures (at which point they'd be jailed + unbonded)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the former, downtime is not capped by the slashing period (although being unbonded for downtime does reset the slashing period).

Clarified in begin-block.md.

@cwgoes
Copy link
Contributor Author

cwgoes commented Aug 20, 2018

@alexanderbez Addressed your comments I think.

@jaekwon
Copy link
Contributor

jaekwon commented Aug 20, 2018

I wonder if the ascii diagram might look different on different browsers due to font issues.

@alexanderbez
Copy link
Contributor

Good point @jaekwon. I think this could be solved by simply throwing them into code blocks.

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM 👍

@cwgoes
Copy link
Contributor Author

cwgoes commented Aug 20, 2018

I wonder if the ascii diagram might look different on different browsers due to font issues.

Maybe so; does it look offset in yours? I can try code blocks although I'm not sure if that would make them consistent either; maybe images are a better option.

@alexanderbez
Copy link
Contributor

No, look great in Chrome!

@cwgoes
Copy link
Contributor Author

cwgoes commented Aug 22, 2018

@jaekwon Any further comments or ready to merge?

Copy link
Contributor

@rigelrozanski rigelrozanski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool


The slashing module enables Cosmos SDK-based blockchains to disincentivize any attributable action
by a protocol-recognized actor with value at stake by "slashing" them: burning some amount of their
stake - and possibly also removing their ability to vote on future blocks for a period of time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be more clear to include these two items as numbered bullets - also use of "possibly" seems a bit out of place - I think slashing and jailing are independant penalties which are both optional to a penalty

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, changed to a list.


Tendermint blocks can include
[Evidence](https://github.com/tendermint/tendermint/blob/develop/docs/spec/blockchain/blockchain.md#evidence), which indicates that a validator
committed malicious behaviour. The relevant information is forwarded to the
committed malicious behavior. The relevant information is forwarded to the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

darn 'mericans

Copy link
Contributor Author

@cwgoes cwgoes Aug 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, I originally spelled it the British way, but the spellchecker wasn't a fan.

@@ -75,7 +76,9 @@ This ensures that offending validators are punished the same amount whether they
act as a single validator with X stake or as N validators with collectively X
stake.

## Automatic Unbonding
Double signature slashes are capped by the slashing period as described in [state-machine.md](state-machine.md).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean by slashes are capped by the slashing period - I thought that "cap" referred to the amount one could be slashed, not by the period in which discovered actions where slashable by. Maybe we could say Double signature slashes are time bound by or something like that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The amount slashed for all infractions committed in a single slashing period is capped. Clarified.

@@ -113,3 +116,5 @@ for val in block.Validators:

SigningInfo.Set(val.Address, signInfo)
```

Downtime slashes are *not* capped by the slashing period, although they do reset it (since the validator is unbonded).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again clarification on capped would be good

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarified.


### States

At any given time, there are any number of validator candidates registered in the state machine.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validator candidates -> bonded validators
also generally remove use of candidates throughout

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validator candidates aren't necessarily bonded, do you mean "validators / bonded validators"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got rid of "validator candidates" in this paragraph, which was the only location.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the term validators includes validators in all states - so if you want to say validators/bonded validators you might as well just say validators

Copy link
Contributor Author

@cwgoes cwgoes Aug 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly; I mean "validators" instead of "validator candidates", and "bonded validators", for the top n - which I did I think (lmk if I missed any).

## State Cleanup

Once no evidence for a given slashing period can possibly be valid (the end time plus the unbonding period is less than the current time),
old slashing periods should be cleaned up. This will be implemented post-launch.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section State Cleanup should probably be moved to a new file future-improvements.md to stay consistent

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

continue with slashing
```

##### Safety note
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this safety note section should probably be moved into the conceptual-overview.md doc I suggested in an earlier comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, done.

then later slashed at `0.4` when they have `1000` stake bonded, the total amount slashed is just `40 + 100 = 140` (since the latter slash is capped at `0.1`) -
whereas if they had `1000` stake bonded initially, the first offense would have been slashed for `400` stake and the total amount slashed would have been `400 + 100 = 500`.

This means that any slashing events which utilize the slashing period (are capped-per-period) **must** *also* jail the validator when the infraction is discovered.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

**must** *also* is funny formatting but okay

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't achieve the desired effect of extra-special-emphasis? Ah well, changed to just bold.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol


```go
type SlashingPeriod struct {
ValidatorAddr sdk.ValAddress // Tendermint address of the validator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this is the Tendermint Addr - I almost think the variable should be renamed to something a bit more explicit

Copy link
Contributor Author

@cwgoes cwgoes Aug 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like what? It's called ValidatorAddr and has type sdk.ValAddress, that seems pretty explicit, we call the operator address validator.Operator

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack.

## Slashing Period

A slashing period is a start and end block height associated with a particular validator,
within which only the "worst infraction counts": the total amount of slashing for
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "worst-infraction-counts" is a good principal to outline in the conceptual-overview.md doc

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then it could just be linked here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So linked.

@rigelrozanski
Copy link
Contributor

rigelrozanski commented Aug 23, 2018

Thanks cwgoes! highlighted comment responses:
#2001 (comment)
#2001 (comment)
#2001 (comment)

Copy link
Contributor

@rigelrozanski rigelrozanski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good stuff, merge now? additional comments from Jae can be in another PR?

Also see added discussion on "un" vs. "not"

#2001 (comment)

@cwgoes cwgoes merged commit c5d44bc into develop Aug 24, 2018
@cwgoes cwgoes deleted the cwgoes/slashing-period-spec branch August 24, 2018 00:09
@cwgoes cwgoes mentioned this pull request Sep 3, 2018
23 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants