Merge PR #5020: /spec/staking/ add copy on Slashing and Delegator Shares
This commit is contained in:
parent
9eb5375fda
commit
e660adc6e5
|
@ -24,6 +24,21 @@ type Params struct {
|
|||
|
||||
## Validator
|
||||
|
||||
Validators can have one of three statuses
|
||||
|
||||
- `Unbonded`: The validator is not in the active set. They cannot sign blocks and do not earn
|
||||
rewards. They can receive delegations.
|
||||
- `Bonded`": Once the validator receives sufficient bonded tokens they automtically join the
|
||||
active set during [`EndBlock`](./04_end_block.md#validator-set-changes) and their status is updated to `Bonded`.
|
||||
They are signing blocks and receiving rewards. They can receive further delegations.
|
||||
They can be slashed for misbehavior. Delegators to this validator who unbond their delegation
|
||||
must wait the duration of the UnbondingTime, a chain-specific param. during which time
|
||||
they are still slashable for offences of the source validator if those offences were committed
|
||||
during the period of time that the tokens were bonded.
|
||||
- `Unbonding`: When a validator leaves the active set, either by choice or due to slashing or
|
||||
tombstoning, an unbonding of all their delegations begins. All delegations must then wait the UnbondingTime
|
||||
before moving receiving their tokens to their accounts from the `BondedPool`.
|
||||
|
||||
Validators objects should be primarily stored and accessed by the
|
||||
`OperatorAddr`, an SDK validator address for the operator of the validator. Two
|
||||
additional indices are maintained per validator object in order to fulfill
|
||||
|
@ -113,6 +128,25 @@ type Delegation struct {
|
|||
}
|
||||
```
|
||||
|
||||
### Delegator Shares
|
||||
|
||||
When one Delegates tokens to a Validator they are issued a number of delegator shares based on a
|
||||
dynamic exchange rate, calculated as follows from the total number of tokens delegated to the
|
||||
validator and the number of shares issued so far:
|
||||
|
||||
`Shares per Token = validator.TotalShares() / validator.Tokens()`
|
||||
|
||||
Only the number of shares received is stored on the DelegationEntry. When a delegator then
|
||||
Undelegates, the token amount they receive is calculated from the number of shares they currently
|
||||
hold and the inverse exchange rate:
|
||||
|
||||
`Tokens per Share = validator.Tokens() / validatorShares()`
|
||||
|
||||
These `Shares` are simply an accounting mechanism. They are not a fungible asset. The reason for
|
||||
this mechanism is to simplify the accounting around slashing. Rather than iteratively slashing the
|
||||
tokens of every delegation entry, instead the Validators total bonded tokens can be slashed,
|
||||
effectively reducing the value of each issued delegator share.
|
||||
|
||||
## UnbondingDelegation
|
||||
|
||||
Shares in a `Delegation` can be unbonded, but they must for some time exist as
|
||||
|
@ -167,9 +201,9 @@ delegator. The second map is used for slashing based on the `ValidatorSrcAddr`,
|
|||
while the third map is for slashing based on the `ValidatorDstAddr`.
|
||||
|
||||
A redelegation object is created every time a redelegation occurs. To prevent
|
||||
"redelegation hopping" redelegations may not occure under the situation that:
|
||||
"redelegation hopping" redelegations may not occur under the situation that:
|
||||
|
||||
- the (re)delegator already has another unmature redelegation in progress
|
||||
- the (re)delegator already has another immature redelegation in progress
|
||||
with a destination to a validator (let's call it `Validator X`)
|
||||
- and, the (re)delegator is attempting to create a _new_ redelegation
|
||||
where the source validator for this new redelegation is `Validator-X`.
|
||||
|
|
|
@ -7,12 +7,13 @@ This document describes the state transition operations pertaining to:
|
|||
3. [Slashing](./02_state_transitions.md#slashing)
|
||||
|
||||
## Validators
|
||||
State transitions in validators are performed on every [`EndBlock`](./04_end_block.md#validator-set-changes)
|
||||
in order to check for changes in the active `ValidatorSet`.
|
||||
|
||||
State transitions in validators are performed on every [`EndBlock`](./04_end_block.md#validator-set-changes) in order to check for changes in the active `ValidatorSet`.
|
||||
### Unbonded to Bonded
|
||||
|
||||
### Non-Bonded to Bonded
|
||||
|
||||
When a validator is bonded from any other state the following operations occur:
|
||||
The following transition occurs when a validator's ranking in the `ValidatorPowerIndex` surpasses
|
||||
that of the `LastValidator`.
|
||||
|
||||
- set `validator.Status` to `Bonded`
|
||||
- send the `validator.Tokens` from the `NotBondedTokens` to the `BondedPool` `ModuleAccount`
|
||||
|
@ -59,7 +60,7 @@ When a delegation occurs both the validator and the delegation objects are affec
|
|||
- remove tokens from the sending account
|
||||
- add shares the delegation object or add them to a created validator object
|
||||
- add new delegator shares and update the `Validator` object
|
||||
- transfer the `delegation.Amount` from the delegator's account to the `BondedPool` or the `NotBondedPool` `ModuleAccount` depending if the `validator.Status` is `Bonded` or not
|
||||
- transfer the `delegation.Amount` from the delegator's account to the `BondedPool` or the `NotBondedPool` `ModuleAccount` depending if the `validator.Status` is `Bonded` or not
|
||||
- delete the existing record from `ValidatorByPowerIndex`
|
||||
- add an new updated record to the `ValidatorByPowerIndex`
|
||||
|
||||
|
@ -76,7 +77,7 @@ Delegation may be called.
|
|||
- if the delegation is the operator of the validator and no more shares exist then trigger a jail validator
|
||||
- update the validator with removed the delegator shares and associated coins
|
||||
- if the validator state is `Bonded`, transfer the `Coins` worth of the unbonded
|
||||
shares from the `BondedPool` to the `NotBondedPool` `ModuleAccount`
|
||||
shares from the `BondedPool` to the `NotBondedPool` `ModuleAccount`
|
||||
- remove the validator if it is unbonded and there are no more delegation shares.
|
||||
|
||||
### Complete Unbonding
|
||||
|
@ -93,8 +94,10 @@ Redelegations affect the delegation, source and destination validators.
|
|||
|
||||
- perform an `unbond` delegation from the source validator to retrieve the tokens worth of the unbonded shares
|
||||
- using the unbonded tokens, `Delegate` them to the destination validator
|
||||
- if the `sourceValidator.Status` is `Bonded`, and the `destinationValidator` is not, transfer the newly delegated tokens from the `BondedPool` to the `NotBondedPool` `ModuleAccount`
|
||||
- otherwise, if the `sourceValidator.Status` is not `Bonded`, and the `destinationValidator` is `Bonded`, transfer the newly delegated tokens from the `NotBondedPool` to the `BondedPool` `ModuleAccount`
|
||||
- if the `sourceValidator.Status` is `Bonded`, and the `destinationValidator` is not,
|
||||
transfer the newly delegated tokens from the `BondedPool` to the `NotBondedPool` `ModuleAccount`
|
||||
- otherwise, if the `sourceValidator.Status` is not `Bonded`, and the `destinationValidator`
|
||||
is `Bonded`, transfer the newly delegated tokens from the `NotBondedPool` to the `BondedPool` `ModuleAccount`
|
||||
- record the token amount in an new entry in the relevant `Redelegation`
|
||||
|
||||
### Complete Redelegation
|
||||
|
@ -107,6 +110,27 @@ When a redelegations complete the following occurs:
|
|||
|
||||
### Slash Validator
|
||||
|
||||
When a Validator is slashed, the following occurs:
|
||||
|
||||
- The total `slashAmount` is calculated as the `slashFactor` (a chain parameter) * `TokensFromConsensusPower`,
|
||||
the total number of tokens bonded to the validator at the time of the infraction.
|
||||
- Every unbonding delegation and redelegation from the validator are slashed by the `slashFactor`
|
||||
percentage of the initialBalance.
|
||||
- Each amount slashed from redelegations and unbonding delegations is subtracted from the
|
||||
total slash amount.
|
||||
- The `remaingSlashAmount` is then slashed from the validator's tokens in the `BondedPool` or
|
||||
`NonBondedPool` depending on the validator's status. This reduces the total supply of tokens.
|
||||
|
||||
### Slash Unbonding Delegation
|
||||
|
||||
When a validator is slashed, so are those unbonding delegations from the validator that began unbonding
|
||||
after the time of the infraction. Every entry in every unbonding delegation from the validator
|
||||
is slashed by `slashFactor`. The amount slashed is calculated from the `InitialBalance` of the
|
||||
delegation and is capped to prevent a resulting negative balance. Completed (or mature) unbondings are not slashed.
|
||||
|
||||
### Slash Redelegation
|
||||
|
||||
When a validator is slashed, so are all redelegations from the validator that began after the
|
||||
infraction. Redelegations are slashed by `slashFactor`.
|
||||
The amount slashed is calculated from the `InitialBalance` of the delegation and is capped to
|
||||
prevent a resulting negative balance. Mature redelegations are not slashed.
|
||||
|
|
Loading…
Reference in New Issue