From d51875b07eb8a3a32ad71714e3f46f2b953e7b45 Mon Sep 17 00:00:00 2001 From: Rikard Hjort <8545447+hjorthjort@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:42:41 +0100 Subject: [PATCH] Updates and clarifications to the staking specs (#8675) --- x/staking/spec/01_state.md | 2 +- x/staking/spec/02_state_transitions.md | 33 +++++++++++++++++++++++--- x/staking/spec/03_messages.md | 9 ++++++- x/staking/spec/08_params.md | 2 +- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/x/staking/spec/01_state.md b/x/staking/spec/01_state.md index 045bc5f35d..66c6c0c5d6 100644 --- a/x/staking/spec/01_state.md +++ b/x/staking/spec/01_state.md @@ -34,7 +34,7 @@ Validators can have one of three statuses 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`. + before moving 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 diff --git a/x/staking/spec/02_state_transitions.md b/x/staking/spec/02_state_transitions.md index 9e245719cc..4a69769b95 100644 --- a/x/staking/spec/02_state_transitions.md +++ b/x/staking/spec/02_state_transitions.md @@ -105,6 +105,9 @@ Redelegations affect the delegation, source and destination validators. 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` +From when a redelegation begins until it completes, the delegator is in a state of "pseudo-unbonding", and can still be +slashed for infractions that occured before the redelegation began. + ### Complete Redelegation When a redelegations complete the following occurs: @@ -119,13 +122,17 @@ 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. +- Every unbonding delegation and pseudo-unbonding redelegation such that the infraction occured before the unbonding or + redelegation began 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. +In the case of a slash due to any infraction that requires evidence to submitted (for example double-sign), the slash +occurs at the block where the evidence is included, not at the block where the infraction occured. +Put otherwise, validators are not slashed retroactively, only when they are caught. + ### Slash Unbonding Delegation When a validator is slashed, so are those unbonding delegations from the validator that began unbonding @@ -137,5 +144,25 @@ delegation and is capped to prevent a resulting negative balance. Completed (or When a validator is slashed, so are all redelegations from the validator that began after the infraction. Redelegations are slashed by `slashFactor`. +Redelegations that began before the infraction are not slashed. 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. +prevent a resulting negative balance. +Mature redelegations (that have completed pseudo-unbonding) are not slashed. + +## How Shares are calculated + +At any given point in time, each validator has a number of tokens, `T`, and has a number of shares issued, `S`. +Each delegator, `i`, holds a number of shares, `S_i`. +The number of tokens is the sum of all tokens delegated to the validator, plus the rewards, minus the slashes. + +The delegator is entitled to a portion of the underlying tokens proportional to their proportion of shares. +So delegator `i` is entitled to `T * S_i / S` of the validator's tokens. + +When a delegator delegates new tokens to the validator, they receive a number of shares proportional to their contribution. +So when delegator `j` delegates `T_j` tokens, they receive `S_j = S * T_j / T` shares. +The total number of tokens is now `T + T_j`, and the total number of shares is `S + S_j`. +`j`s proportion of the shares is the same as their proportion of the total tokens contributed: `(S + S_j) / S = (T + T_j) / T`. + +A special case is the initial delegation, when `T = 0` and `S = 0`, so `T_j / T` is undefined. +For the initial delegation, delegator `j` who delegates `T_j` tokens receive `S_j = T_j` shares. +So a validator that hasn't received any rewards and has not been slashed will have `T = S`. diff --git a/x/staking/spec/03_messages.md b/x/staking/spec/03_messages.md index 1155da93d9..d0f059ecf6 100644 --- a/x/staking/spec/03_messages.md +++ b/x/staking/spec/03_messages.md @@ -9,6 +9,7 @@ In this section we describe the processing of the staking messages and the corre ## Msg/CreateValidator A validator is created using the `Msg/CreateValidator` service message. +The validator must be created with an initial delegation from the operator. +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L16-L17 @@ -63,11 +64,17 @@ This service message is expected to fail if: - the validator is does not exist - the validator is jailed - the `Amount` `Coin` has a denomination different than one defined by `params.BondDenom` +- the exchange rate is invalid, meaning the validator has no tokens (due to slashing) but there are outstanding shares +- the amount delegated is less than the minimum allowed delegation If an existing `Delegation` object for provided addresses does not already -exist than it is created as part of this service message otherwise the existing +exist then it is created as part of this message otherwise the existing `Delegation` is updated to include the newly received shares. +The delegator receives newly minted shares at the current exchange rate. +The exchange rate is the number of existing shares in the validator divided by +the number of currently delegated tokens. + ## Msg/Undelegate The `Msg/Undelegate` service message allows delegators to undelegate their tokens from diff --git a/x/staking/spec/08_params.md b/x/staking/spec/08_params.md index 3d87879e18..8d78efa5c5 100644 --- a/x/staking/spec/08_params.md +++ b/x/staking/spec/08_params.md @@ -12,4 +12,4 @@ The staking module contains the following parameters: | MaxValidators | uint16 | 100 | | KeyMaxEntries | uint16 | 7 | | HistoricalEntries | uint16 | 3 | -| BondDenom | string | "uatom" | +| BondDenom | string | "stake" |