-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
Changes from 17 commits
4f8c9e4
84e9b21
98a278d
ff01cbb
53fa4a2
a8af4a4
07a7db7
2445718
8b7d6e0
52475b1
32263ff
a2463d0
21be609
79e3c05
94dc512
e3cb1e1
b8d6465
da92b1b
d0c87ff
c9e5745
f188955
41df6db
73e1965
bb9c265
4cc2054
4475a8c
63a85aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Slashing module specification | ||
|
||
## Abstract | ||
|
||
This section specifies the slashing module of the Cosmos SDK, which implements functionality | ||
first outlined in the [Cosmos Whitepaper](https://cosmos.network/about/whitepaper) in June 2016. | ||
|
||
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. | ||
|
||
This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosystem. | ||
|
||
## Contents | ||
|
||
1. **[State](state.md)** | ||
1. [SigningInfo](state.md#signing-info) | ||
1. [SlashingPeriod](state.md#slashing-period) | ||
1. **[State Machine](state-machine.md)** | ||
1. [Transactions](state-machine.md#transactions) | ||
1. Unjail | ||
1. [Interactions](state-machine.md#interactions) | ||
1. Validator Bonded | ||
1. Validator Unbonding | ||
1. Validator Slashed | ||
1. [State Cleanup](state-machine.md#state-cleanup) | ||
1. **[Begin Block](begin-block.md)** | ||
1. [Evidence handling](begin-block.md#evidence-handling) | ||
1. [Uptime tracking](begin-block.md#uptime-tracking) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,13 @@ | ||
# End-Block | ||
# Begin-Block | ||
|
||
## Slashing | ||
## Evidence handling | ||
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. darn 'mericans There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
application as [ABCI | ||
Evidence](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto#L259), so the validator an be accordingly punished. | ||
Evidence](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto#L259) in `abci.RequestBeginBlock` | ||
so that the validator an be accordingly punished. | ||
|
||
For some `evidence` to be valid, it must satisfy: | ||
|
||
|
@@ -75,7 +76,7 @@ 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 | ||
## Uptime tracking | ||
|
||
At the beginning of each block, we update the signing info for each validator and check if they should be automatically unbonded: | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
## Transaction & State Machine Interaction Overview | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably be an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure; updated & also updated in |
||
|
||
### Conceptual overview | ||
|
||
#### States | ||
|
||
At any given time, there are any number of validator candidates registered in the state machine. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validator candidates aren't necessarily bonded, do you mean "validators / bonded validators"? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the term There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
Each block, the top `n` candidates who are not jailed become *bonded*, meaning that they may propose and vote on blocks. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. clarify what There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 , clarified |
||
Validators who are *bonded* are *at stake*, meaning that part or all of their stake is at risk if they commit a protocol fault. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe something that all their stake and ALL of their delegators stake There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added. |
||
|
||
#### Slashing period | ||
|
||
In order to mitigate the impact of initially likely categories of non-malicious protocol faults, the Cosmos Hub implements for each validator | ||
a *slashing period*, in which the amount by which a validator can be slashed is capped at the punishment for the worst violation. For example, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The slashing period doesn't have a particular length, it's determined by when the validator bonds or unbonds. Clarified that difference. |
||
if you misconfigure your HSM and double-sign a bunch of old blocks, you'll only be punished for the first double-sign (and then immediately jailed, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this a realistic example? (fine if so) I just don't want to scare people into thinking if they slip up somehow in configuration they get messed - we should make hsm configuration pretty robust There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is a realistic example, that's why the slashing period exists. Agreed that we want to develop secure HSM software though! |
||
so that you have a chance to reconfigure your setup). This will still be quite expensive and desirable to avoid, but slashing periods somewhat blunt | ||
the economic impact of unintentional misconfiguration. | ||
|
||
A new slashing period starts whenever a validator is bonded and ends whenever the validator is unbonded (which will happen if the validator is jailed). | ||
The amount of tokens slashed relative to validator power for infractions committed within the slashing period, whenever they are discovered, is capped | ||
at the punishment for the worst infraction (which for the Cosmos Hub at launch will be double-signing a block). | ||
|
||
##### ASCII timelines | ||
|
||
*Code* | ||
|
||
*[* : timeline start | ||
*]* : timeline end | ||
*<* : slashing period start | ||
*>* : slashing period end | ||
*C<sub>n</sub>* : infraction `n` committed | ||
*D<sub>n</sub>* : infraction `n` discovered | ||
*V<sub>b</sub>* : validator bonded | ||
*V<sub>u</sub>* : validator unbonded | ||
|
||
*Single infraction* | ||
|
||
<-----------------> | ||
[----------C<sub>1</sub>----D<sub>1</sub>,V<sub>u</sub>-----] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although I like how compact it is, I think that a numbered list would more clearly and understandably depict timelines... pretty confusing to have to look back and forth from the codes and timeline here, especially when rendered in text like here in the PR diff - I'd suggest we switch even if this becomes more verbose There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A numbered list doesn't really allow for parallel tracks; maybe a table? Leaving for now, but I agree that this could be cleaner. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh geez that's right - yeah we should upgrade to use a table then There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay - I reverse my opinion - I actually really like the markdown rendering - I think the ultimate solution is to just include graphics however There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, maybe a separate PR though? |
||
|
||
A single infraction is committed then later discovered, at which point the validator is unbonded and slashed at the full amount for the infraction. | ||
|
||
*Multiple infractions* | ||
|
||
<----------------------------> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought the slashing period ends when the validator is jailed & unbonded ( There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
[----------C<sub>1</sub>--C<sub>2</sub>---C<sub>3</sub>---D<sub>1</sub>,D<sub>2</sub>,D<sub>3</sub>V<sub>u</sub>-----] | ||
|
||
Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction. | ||
|
||
*Multiple infractions after rebonding* | ||
|
||
|
||
<----------------------------> <--------------> | ||
[----------C<sub>1</sub>--C<sub>2</sub>---C<sub>3</sub>---D<sub>1</sub>,D<sub>2</sub>,D<sub>3</sub>V<sub>u</sub>---V<sub>b</sub>---C<sub>4</sub>----D<sub>4</sub>,V<sub>u</sub>--] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hellish There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, I like the rendered output, but if there's a better way to do this in Markdown I'm all ears There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed the ASCII diagrams a bit but I'm not sure if they'll render exactly the same on different browsers, feel free to update if they still look off. |
||
|
||
Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction. | ||
The validator then unjails themself and rebonds, then commits a fourth infraction - which is discovered and punished at the full amount, since a new slashing period started | ||
when they unjailed and rebonded. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that protocol actions can be added directly into the bulleted list I've suggested above -> this means that each of these scenarios can JUST be the bulleted list, all explanations should happen within the list There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think a list is sufficient, see the above comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, agreed |
||
|
||
### Transactions | ||
|
||
In this section we describe the processing of transactions for the `slashing` module. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unnecessary intro, transactions should be its own file ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure; moved the intro to |
||
|
||
#### TxUnjail | ||
|
||
If a validator was automatically unbonded due to downtime and wishes to come back online & | ||
possibly rejoin the bonded set, it must send `TxUnjail`: | ||
|
||
```golang | ||
type TxUnjail struct { | ||
ValidatorAddr sdk.AccAddress | ||
} | ||
|
||
handleMsgUnjail(tx TxUnjail) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
|
||
validator := getValidator(tx.ValidatorAddr) | ||
if validator == nil | ||
fail with "No validator found" | ||
|
||
if !validator.Jailed | ||
fail with "Validator not jailed, cannot unjail" | ||
|
||
info := getValidatorSigningInfo(operator) | ||
if BlockHeader.Time.Before(info.JailedUntil) | ||
fail with "Validator still jailed, cannot unjail until period has expired" | ||
|
||
// Update the start height so the validator won't be immediately unbonded again | ||
info.StartHeight = BlockHeight | ||
setValidatorSigningInfo(info) | ||
|
||
validator.Jailed = false | ||
setValidator(validator) | ||
|
||
return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the return statement is implied here and thus can be removed (and all the other pseudo functions which do not have early returns in this file) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, this I did to maintain consistency with the other specs, e.g. https://github.com/cosmos/cosmos-sdk/blob/develop/docs/spec/staking/transactions.md |
||
``` | ||
|
||
If the validator has enough stake to be in the top hundred, they will be automatically rebonded, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. top There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated. |
||
and all delegators still delegated to the validator will be rebonded and begin to again collect | ||
provisions and rewards. | ||
|
||
### Interactions | ||
|
||
In this section we describe the "hooks" - slashing module code that runs when other events happen. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think Interactions or "hooks" should maybe be separated into a new file - in distribution I use "triggers" - not sure if that's the most ideal - but we should def stay consistent between the two specs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Within piggy bank, I also included "triggered-by" section for each "trigger" could be good to outline these here as well for each hook There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I think I'm using the standard terminology here, e.g. https://en.wikipedia.org/wiki/Hooking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh interesting - I'll update piggy bank to use a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
#### Validator Bonded | ||
|
||
Upon successful bonding of a validator (a given validator changing from "unbonded" state to "bonded" state, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is that we have two terms: "unbonded" == "not bonded", and "unbonded == sdk.Unbonded state", because we call the state itself unbonded it's unclear what to refer to the former by. I like your wording better anyways but maybe we should consider renaming the state. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I disagree with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but "unbonded" is also an English word, e.g. https://www.dictionary.com/browse/unbonded or https://www.collinsdictionary.com/dictionary/english/unbonded, which means "not bonded" (is the antonym of "bonded") - and I presume this etymology is the same root as for Cosmos; e.g. https://en.wikipedia.org/wiki/Bonded_warehouse (perhaps)? What do you think we should call the state of "not bonded", if not "unbonded"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I don't use "unbonded" this way in the spec anymore though) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. okay - yeah confusing. We should probably just completely avoid the language unbonded and only refer to things AS bonded/unbonding/unbonded - and define this strictly as meaning one of the 3 states of tokens. However I will draw the subtle generalized distinction (as I understand it) between the prefix "un-" and the the adverb "not". The word "not" is rooted in the idea of exclusion "exclude a person or part of a group", whereas "un-" when used as "subtle" lol |
||
which may happen on delegation, on unjailing, etc), we create a new `SlashingPeriod` structure for the | ||
now-bonded validator, which `StartHeight` of the current block, `EndHeight` of `0` (sentinel value for not-yet-ended), | ||
and `SlashedSoFar` of `0`: | ||
|
||
```golang | ||
onValidatorBonded(address sdk.ValAddress) | ||
|
||
slashingPeriod := SlashingPeriod{ | ||
ValidatorAddr : address, | ||
StartHeight : CurrentHeight, | ||
EndHeight : 0, | ||
SlashedSoFar : 0, | ||
} | ||
setSlashingPeriod(slashingPeriod) | ||
|
||
return | ||
``` | ||
|
||
#### Validator Unbonded | ||
|
||
When a validator is unbonded, we update the in-progress `SlashingPeriod` with the current block as the `EndHeight`: | ||
|
||
```golang | ||
onValidatorUnbonded(address sdk.ValAddress) | ||
|
||
slashingPeriod = getSlashingPeriod(address, CurrentHeight) | ||
slashingPeriod.EndHeight = CurrentHeight | ||
setSlashingPeriod(slashingPeriod) | ||
|
||
return | ||
``` | ||
|
||
#### Validator Slashed | ||
|
||
When a validator is slashed, we look up the appropriate `SlashingPeriod` based on the validator | ||
address and the time of infraction, cap the fraction slashed as `max(SlashFraction, SlashedSoFar)` | ||
(which may be `0`), and update the `SlashingPeriod` with the increased `SlashedSoFar`: | ||
|
||
```golang | ||
beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat, infractionHeight int64) | ||
|
||
slashingPeriod = getSlashingPeriod(address, infractionHeight) | ||
totalToSlash = max(slashingPeriod.SlashedSoFar, fraction) | ||
slashingPeriod.SlashedSoFar = totalToSlash | ||
setSlashingPeriod(slashingPeriod) | ||
|
||
remainderToSlash = slashingPeriod.SlashedSoFar - totalToSlash | ||
fraction = remainderToSlash | ||
|
||
continue with slashing | ||
``` | ||
|
||
##### Safety note | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this safety note section should probably be moved into the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, done. |
||
|
||
Slashing is capped fractionally per period, but the amount of total bonded stake associated with any given validator can change (by an unbounded amount) over that period. | ||
|
||
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`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Clarified the sentence. |
||
|
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol |
||
Otherwise it would be possible for a validator to slash themselves intentionally at a low bond, then increase their bond but no longer be at stake since they would have already hit the `SlashedSoFar` cap. | ||
|
||
### 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,10 +36,11 @@ The information stored for tracking validator liveness is as follows: | |
|
||
```go | ||
type ValidatorSigningInfo struct { | ||
StartHeight int64 | ||
IndexOffset int64 | ||
JailedUntil int64 | ||
SignedBlocksCounter int64 | ||
StartHeight int64 // Height at which the validator became able to sign blocks | ||
IndexOffset int64 // Offset into the signed block bit array | ||
JailedUntilHeight int64 // Block height until which the validator is jailed, | ||
// or sentinel value of 0 for not jailed | ||
SignedBlocksCounter int64 // Running counter of signed blocks | ||
} | ||
|
||
``` | ||
|
@@ -49,3 +50,31 @@ Where: | |
* `IndexOffset` is incremented each time the candidate was a bonded validator in a block (and may have signed a precommit or not). | ||
* `JailedUntil` is set whenever the candidate is revoked due to downtime | ||
* `SignedBlocksCounter` is a counter kept to avoid unnecessary array reads. `SignedBlocksBitArray.Sum() == SignedBlocksCounter` always. | ||
|
||
### Slashing Period | ||
|
||
A slashing period is a start and end block height associated with a particular validator, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
within which only the "worst infraction counts": the total amount of slashing for | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "worst-infraction-counts" is a good principal to outline in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. then it could just be linked here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So linked. |
||
infractions committed within the period (and discovered whenever) is capped at the | ||
penalty for the worst offense. | ||
|
||
This period starts when a validator is first bonded and ends when a validator is slashed & jailed | ||
for any reason. When the validator rejoins the validator set (perhaps through unjailing themselves, | ||
and perhaps also changing signing keys), they enter into a new period. | ||
|
||
Slashing periods are indexed in the store as follows: | ||
|
||
- SlashingPeriod: ` 0x03 | ValTendermintAddr | StartHeight -> amino(slashingPeriod) ` | ||
|
||
This allows us to look up slashing period by a validator's address, the only lookup necessary, | ||
and iterate over start height to efficiently retrieve the most recent slashing period(s) | ||
or those beginning after a given height. | ||
|
||
```go | ||
type SlashingPeriod struct { | ||
ValidatorAddr sdk.ValAddress // Tendermint address of the validator | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like what? It's called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ack. |
||
StartHeight int64 // Block height at which slashing period begin | ||
EndHeight int64 // Block height at which slashing period ended | ||
SlashedSoFar sdk.Rat // Fraction slashed so far, cumulative | ||
} | ||
``` |
This file was deleted.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.