Merge PR #4599: Supply module spec
* supply spec * update spec * update other modules * update distr * update spec according to latest refactors * Apply suggestions from code review Co-Authored-By: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> * updated spec * Apply suggestions from code review Co-Authored-By: Marko <marbar3778@yahoo.com> * final updates * Apply suggestions from code review Co-Authored-By: Alessio Treglia <quadrispro@ubuntu.com> * word wrap in supply concepts * edits to concepts
This commit is contained in:
committed by
frog power 4000
co-authored by
Alexander Bezobchuk
Marko
Alessio Treglia
parent
ce0c0946b6
commit
5d5f0149a4
@@ -1,37 +1,19 @@
|
||||
# State
|
||||
|
||||
## Pool
|
||||
|
||||
The pool tracks the total amounts of tokens (each staking denom is tracked
|
||||
separately) and their state (bonded or loose).
|
||||
|
||||
Note: `NotBondedTokens` _includes_ both tokens in an `unbonding` state as well
|
||||
as fully `unbonded` state.
|
||||
|
||||
- Pool: `0x01 -> amino(pool)`
|
||||
|
||||
```golang
|
||||
type Pool struct {
|
||||
NotBondedTokens sdk.Int // tokens not associated with any bonded validator
|
||||
BondedTokens sdk.Int // reserve of bonded tokens
|
||||
}
|
||||
```
|
||||
|
||||
## LastTotalPower
|
||||
|
||||
LastTotalPower tracks the total amounts of bonded tokens recorded during the previous
|
||||
end block.
|
||||
LastTotalPower tracks the total amounts of bonded tokens recorded during the previous end block.
|
||||
|
||||
- LastTotalPower: `0x12 -> amino(sdk.Int)`
|
||||
- LastTotalPower: `0x12 -> amino(sdk.Int)`
|
||||
|
||||
## Params
|
||||
|
||||
Params is a module-wide configuration structure that stores system parameters
|
||||
and defines overall functioning of the staking module.
|
||||
|
||||
- Params: `Paramsspace("staking") -> amino(params)`
|
||||
- Params: `Paramsspace("staking") -> amino(params)`
|
||||
|
||||
```golang
|
||||
```go
|
||||
type Params struct {
|
||||
UnbondingTime time.Duration // time duration of unbonding
|
||||
MaxValidators uint16 // maximum number of validators
|
||||
@@ -48,12 +30,12 @@ additional indices are maintained per validator object in order to fulfill
|
||||
required lookups for slashing and validator-set updates. A third special index
|
||||
(`LastValidatorPower`) is also maintained which however remains constant
|
||||
throughout each block, unlike the first two indices which mirror the validator
|
||||
records within a block.
|
||||
records within a block.
|
||||
|
||||
- Validators: `0x21 | OperatorAddr -> amino(validator)`
|
||||
- ValidatorsByConsAddr: `0x22 | ConsAddr -> OperatorAddr`
|
||||
- ValidatorsByPower: `0x23 | BigEndian(ConsensusPower) | OperatorAddr -> OperatorAddr`
|
||||
- LastValidatorsPower: `0x11 OperatorAddr -> amino(ConsensusPower)
|
||||
- LastValidatorsPower: `0x11 OperatorAddr -> amino(ConsensusPower)`
|
||||
|
||||
`Validators` is the primary index - it ensures that each operator can have only one
|
||||
associated validator, where the public key of that validator can change in the
|
||||
@@ -63,7 +45,7 @@ concern for the changing public key.
|
||||
`ValidatorByConsAddr` is an additional index that enables lookups for slashing.
|
||||
When Tendermint reports evidence, it provides the validator address, so this
|
||||
map is needed to find the operator. Note that the `ConsAddr` corresponds to the
|
||||
address which can be derived from the validator's `ConsPubKey`.
|
||||
address which can be derived from the validator's `ConsPubKey`.
|
||||
|
||||
`ValidatorsByPower` is an additional index that provides a sorted list o
|
||||
potential validators to quickly determine the current active set. Here
|
||||
@@ -72,12 +54,11 @@ ConsensusPower is validator.Tokens/10^6. Note that all validators where
|
||||
|
||||
`LastValidatorsPower` is a special index that provides a historical list of the
|
||||
last-block's bonded validators. This index remains constant during a block but
|
||||
is updated during the validator set update process which takes place in [end
|
||||
block](end_block.md).
|
||||
is updated during the validator set update process which takes place in [`EndBlock`](./04_end_block.md).
|
||||
|
||||
Each validator's state is stored in a `Validator` struct:
|
||||
|
||||
```golang
|
||||
```go
|
||||
type Validator struct {
|
||||
OperatorAddress sdk.ValAddress // address of the validator's operator; bech encoded in JSON
|
||||
ConsPubKey crypto.PubKey // the consensus public key of the validator; bech encoded in JSON
|
||||
@@ -116,17 +97,17 @@ type Description struct {
|
||||
Delegations are identified by combining `DelegatorAddr` (the address of the delegator)
|
||||
with the `ValidatorAddr` Delegators are indexed in the store as follows:
|
||||
|
||||
- Delegation: ` 0x31 | DelegatorAddr | ValidatorAddr -> amino(delegation)`
|
||||
- Delegation: `0x31 | DelegatorAddr | ValidatorAddr -> amino(delegation)`
|
||||
|
||||
Stake holders may delegate coins to validators; under this circumstance their
|
||||
funds are held in a `Delegation` data structure. It is owned by one
|
||||
delegator, and is associated with the shares for one validator. The sender of
|
||||
the transaction is the owner of the bond.
|
||||
|
||||
```golang
|
||||
```go
|
||||
type Delegation struct {
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorAddr sdk.ValAddress
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorAddr sdk.ValAddress
|
||||
Shares sdk.Dec // delegation shares received
|
||||
}
|
||||
```
|
||||
@@ -139,9 +120,9 @@ detected.
|
||||
|
||||
`UnbondingDelegation` are indexed in the store as:
|
||||
|
||||
- UnbondingDelegation: ` 0x32 | DelegatorAddr | ValidatorAddr ->
|
||||
- UnbondingDelegation: `0x32 | DelegatorAddr | ValidatorAddr ->
|
||||
amino(unbondingDelegation)`
|
||||
- UnbondingDelegationsFromValidator: ` 0x33 | ValidatorAddr | DelegatorAddr ->
|
||||
- UnbondingDelegationsFromValidator: `0x33 | ValidatorAddr | DelegatorAddr ->
|
||||
nil`
|
||||
|
||||
The first map here is used in queries, to lookup all unbonding delegations for
|
||||
@@ -151,7 +132,7 @@ slashed.
|
||||
|
||||
A UnbondingDelegation object is created every time an unbonding is initiated.
|
||||
|
||||
```golang
|
||||
```go
|
||||
type UnbondingDelegation struct {
|
||||
DelegatorAddr sdk.AccAddress // delegator
|
||||
ValidatorAddr sdk.ValAddress // validator unbonding from operator addr
|
||||
@@ -172,13 +153,13 @@ The bonded tokens worth of a `Delegation` may be instantly redelegated from a
|
||||
source validator to a different validator (destination validator). However when
|
||||
this occurs they must be tracked in a `Redelegation` object, whereby their
|
||||
shares can be slashed if their tokens have contributed to a Byzantine fault
|
||||
committed by the source validator.
|
||||
committed by the source validator.
|
||||
|
||||
`Redelegation` are indexed in the store as:
|
||||
|
||||
- Redelegations: `0x34 | DelegatorAddr | ValidatorSrcAddr | ValidatorDstAddr -> amino(redelegation)`
|
||||
- RedelegationsBySrc: `0x35 | ValidatorSrcAddr | ValidatorDstAddr | DelegatorAddr -> nil`
|
||||
- RedelegationsByDst: `0x36 | ValidatorDstAddr | ValidatorSrcAddr | DelegatorAddr -> nil`
|
||||
- Redelegations: `0x34 | DelegatorAddr | ValidatorSrcAddr | ValidatorDstAddr -> amino(redelegation)`
|
||||
- RedelegationsBySrc: `0x35 | ValidatorSrcAddr | ValidatorDstAddr | DelegatorAddr -> nil`
|
||||
- RedelegationsByDst: `0x36 | ValidatorDstAddr | ValidatorSrcAddr | DelegatorAddr -> nil`
|
||||
|
||||
The first map here is used for queries, to lookup all redelegations for a given
|
||||
delegator. The second map is used for slashing based on the `ValidatorSrcAddr`,
|
||||
@@ -186,12 +167,13 @@ 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:
|
||||
- the (re)delegator already has another unmature 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`.
|
||||
|
||||
```golang
|
||||
- the (re)delegator already has another unmature 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`.
|
||||
|
||||
```go
|
||||
type Redelegation struct {
|
||||
DelegatorAddr sdk.AccAddress // delegator
|
||||
ValidatorSrcAddr sdk.ValAddress // validator redelegation source operator addr
|
||||
@@ -213,47 +195,47 @@ type RedelegationEntry struct {
|
||||
All queues objects are sorted by timestamp. The time used within any queue is
|
||||
first rounded to the nearest nanosecond then sorted. The sortable time format
|
||||
used is a slight modification of the RFC3339Nano and uses the the format string
|
||||
`"2006-01-02T15:04:05.000000000"`. Notably this format:
|
||||
`"2006-01-02T15:04:05.000000000"`. Notably this format:
|
||||
|
||||
- right pads all zeros
|
||||
- drops the time zone info (uses UTC)
|
||||
- right pads all zeros
|
||||
- drops the time zone info (uses UTC)
|
||||
|
||||
In all cases, the stored timestamp represents the maturation time of the queue
|
||||
element.
|
||||
element.
|
||||
|
||||
### UnbondingDelegationQueue
|
||||
|
||||
For the purpose of tracking progress of unbonding delegations the unbonding
|
||||
delegations queue is kept.
|
||||
delegations queue is kept.
|
||||
|
||||
- UnbondingDelegation: `0x41 | format(time) -> []DVPair`
|
||||
|
||||
```
|
||||
```go
|
||||
type DVPair struct {
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorAddr sdk.ValAddress
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorAddr sdk.ValAddress
|
||||
}
|
||||
```
|
||||
|
||||
### RedelegationQueue
|
||||
|
||||
For the purpose of tracking progress of redelegations the redelegation queue is
|
||||
kept.
|
||||
kept.
|
||||
|
||||
- UnbondingDelegation: `0x42 | format(time) -> []DVVTriplet`
|
||||
|
||||
```
|
||||
```go
|
||||
type DVVTriplet struct {
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorSrcAddr sdk.ValAddress
|
||||
ValidatorDstAddr sdk.ValAddress
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorSrcAddr sdk.ValAddress
|
||||
ValidatorDstAddr sdk.ValAddress
|
||||
}
|
||||
```
|
||||
|
||||
### ValidatorQueue
|
||||
|
||||
For the purpose of tracking progress of unbonding validators the validator
|
||||
queue is kept.
|
||||
queue is kept.
|
||||
|
||||
- ValidatorQueueTime: `0x43 | format(time) -> []sdk.ValAddress`
|
||||
|
||||
|
||||
@@ -2,96 +2,107 @@
|
||||
|
||||
This document describes the state transition operations pertaining to:
|
||||
|
||||
- Validators
|
||||
- Delegations
|
||||
- Slashing
|
||||
|
||||
1. [Validators](./02_state_transitions.md#validators)
|
||||
2. [Delegations](./02_state_transitions.md#delegations)
|
||||
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`.
|
||||
|
||||
### Non-Bonded to Bonded
|
||||
|
||||
When a validator is bonded from any other state the following operations occur:
|
||||
- set `validator.Status` to `Bonded`
|
||||
- update the `Pool` object with tokens moved from `NotBondedTokens` to `BondedTokens`
|
||||
- delete record the existing record from `ValidatorByPowerIndex`
|
||||
- add an new updated record to the `ValidatorByPowerIndex`
|
||||
- update the `Validator` object for this validator
|
||||
- if it exists, delete any `ValidatorQueue` record for this validator
|
||||
|
||||
- set `validator.Status` to `Bonded`
|
||||
- send the `validator.Tokens` from the `NotBondedTokens` to the `BondedPool` `ModuleAccount`
|
||||
- delete the existing record from `ValidatorByPowerIndex`
|
||||
- add a new updated record to the `ValidatorByPowerIndex`
|
||||
- update the `Validator` object for this validator
|
||||
- if it exists, delete any `ValidatorQueue` record for this validator
|
||||
|
||||
### Bonded to Unbonding
|
||||
When a validator begins the unbonding process the following operations occur:
|
||||
- update the `Pool` object with tokens moved from `BondedTokens` to `NotBondedTokens`
|
||||
- set `validator.Status` to `Unbonding`
|
||||
- delete record the existing record from `ValidatorByPowerIndex`
|
||||
- add an new updated record to the `ValidatorByPowerIndex`
|
||||
- update the `Validator` object for this validator
|
||||
- insert a new record into the `ValidatorQueue` for this validator
|
||||
|
||||
When a validator begins the unbonding process the following operations occur:
|
||||
|
||||
- send the `validator.Tokens` from the `BondedPool` to the `NotBondedTokens` `ModuleAccount`
|
||||
- set `validator.Status` to `Unbonding`
|
||||
- delete the existing record from `ValidatorByPowerIndex`
|
||||
- add a new updated record to the `ValidatorByPowerIndex`
|
||||
- update the `Validator` object for this validator
|
||||
- insert a new record into the `ValidatorQueue` for this validator
|
||||
|
||||
### Unbonding to Unbonded
|
||||
|
||||
A validator moves from unbonding to unbonded when the `ValidatorQueue` object
|
||||
moves from bonded to unbonded
|
||||
- update the `Validator` object for this validator
|
||||
- set `validator.Status` to `Unbonded`
|
||||
|
||||
### Jail/Unjail
|
||||
- update the `Validator` object for this validator
|
||||
- set `validator.Status` to `Unbonded`
|
||||
|
||||
### Jail/Unjail
|
||||
|
||||
when a validator is jailed it is effectively removed from the Tendermint set.
|
||||
this process may be also be reversed. the following operations occur:
|
||||
- set `Validator.Jailed` and update object
|
||||
- if jailed delete record from `ValidatorByPowerIndex`
|
||||
- if unjailed add record to `ValidatorByPowerIndex`
|
||||
|
||||
- set `Validator.Jailed` and update object
|
||||
- if jailed delete record from `ValidatorByPowerIndex`
|
||||
- if unjailed add record to `ValidatorByPowerIndex`
|
||||
|
||||
## Delegations
|
||||
|
||||
### Delegate
|
||||
When a delegation occurs both the validator and the delegtion objects are affected
|
||||
- determine the delegators shares based on tokens delegated and the validator's exchange rate
|
||||
- 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
|
||||
- update the `Pool` object appropriately if tokens have moved into a bonded validator
|
||||
- delete record the existing record from `ValidatorByPowerIndex`
|
||||
- add an new updated record to the `ValidatorByPowerIndex`
|
||||
|
||||
#### Unbond Delegation
|
||||
When a delegation occurs both the validator and the delegation objects are affected
|
||||
|
||||
- determine the delegators shares based on tokens delegated and the validator's exchange rate
|
||||
- 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
|
||||
- delete the existing record from `ValidatorByPowerIndex`
|
||||
- add an new updated record to the `ValidatorByPowerIndex`
|
||||
|
||||
### Begin Unbonding
|
||||
|
||||
As a part of the Undelegate and Complete Unbonding state transitions Unbond
|
||||
Delegation may be called.
|
||||
- subtract the unbonded shares from delegator
|
||||
- update the delegation or remove the delegation if there are no more shares
|
||||
- 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, update
|
||||
the pool for any shifts between bonded and non-bonded tokens.
|
||||
- remove the validator if it is unbonded and there are no more delegation shares.
|
||||
Delegation may be called.
|
||||
|
||||
### Undelegate
|
||||
When an delegation occurs both the validator and the delegtion objects are affected
|
||||
- perform an unbond delegation
|
||||
- if the validator is unbonding or bonded add the tokens to an
|
||||
`UnbondingDelegation` Entry
|
||||
- if the validator is unbonded send the tokens directly to the withdraw
|
||||
account
|
||||
- subtract the unbonded shares from delegator
|
||||
- if the validator is `Unbonding` or `Bonded` add the tokens to an `UnbondingDelegation` Entry
|
||||
- if the validator is `Unbonded` send the tokens directly to the withdraw
|
||||
account
|
||||
- update the delegation or remove the delegation if there are no more shares
|
||||
- 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`
|
||||
- remove the validator if it is unbonded and there are no more delegation shares.
|
||||
|
||||
### Complete Unbonding
|
||||
|
||||
For undelegations which do not complete immediately, the following operations
|
||||
occur when the unbonding delegation queue element matures:
|
||||
- remove the entry from the `UnbondingDelegation` object
|
||||
- withdraw the tokens to the delegator withdraw address
|
||||
|
||||
- remove the entry from the `UnbondingDelegation` object
|
||||
- transfer the tokens from the `NotBondedPool` `ModuleAccount` to the delegator `Account`
|
||||
|
||||
### Begin Redelegation
|
||||
Redelegations affect the delegation, source and destination validators.
|
||||
- perform an unbond delegation from the source validator
|
||||
- using the generated tokens perform a Delegate to the destination
|
||||
validator
|
||||
- record the token amount in an new entry in the relevant `Redelegation`
|
||||
|
||||
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`
|
||||
- record the token amount in an new entry in the relevant `Redelegation`
|
||||
|
||||
### Complete Redelegation
|
||||
|
||||
When a redelegations complete the following occurs:
|
||||
- remove the entry from the `Redelegation` object
|
||||
|
||||
- remove the entry from the `Redelegation` object
|
||||
|
||||
TODO TODO TOFU TODO
|
||||
## Slashing
|
||||
|
||||
### Slash Validator
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# Messages
|
||||
|
||||
In this section we describe the processing of the staking messages and the
|
||||
corresponding updates to the state. All created/modified state objects
|
||||
specified by each message are defined within [state.md](state.md).
|
||||
In this section we describe the processing of the staking messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state.md) section.
|
||||
|
||||
## MsgCreateValidator
|
||||
|
||||
A validator is created using the `MsgCreateValidator` message.
|
||||
A validator is created using the `MsgCreateValidator` message.
|
||||
|
||||
```golang
|
||||
```go
|
||||
type MsgCreateValidator struct {
|
||||
Description Description
|
||||
Commission Commission
|
||||
@@ -20,30 +18,28 @@ type MsgCreateValidator struct {
|
||||
}
|
||||
```
|
||||
|
||||
This message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- another validator with this operator address is already registered
|
||||
- another validator with this pubkey is already registered
|
||||
- the initial self-delegation tokens are of a denom not specified as the bonding denom
|
||||
- the commission parameters are faulty, namely:
|
||||
- `MaxRate` is either > 1 or < 0
|
||||
- the initial `Rate` is either negative or > `MaxRate`
|
||||
- the initial `MaxChangeRate` is either negative or > `MaxRate`
|
||||
- the description fields are too large
|
||||
|
||||
- another validator with this operator address is already registered
|
||||
- another validator with this pubkey is already registered
|
||||
- the initial self-delegation tokens are of a denom not specified as the
|
||||
bonding denom
|
||||
- the commission parameters are faulty, namely:
|
||||
- `MaxRate` is either > 1 or < 0
|
||||
- the initial `Rate` is either negative or > `MaxRate`
|
||||
- the initial `MaxChangeRate` is either negative or > `MaxRate`
|
||||
- the description fields are too large
|
||||
|
||||
This message creates and stores the `Validator` object at appropriate indexes.
|
||||
Additionally a self-delegation is made with the initial tokens delegation
|
||||
tokens `Delegation`. The validator always starts as unbonded but may be bonded
|
||||
in the first end-block.
|
||||
|
||||
in the first end-block.
|
||||
|
||||
## MsgEditValidator
|
||||
|
||||
The `Description`, `CommissionRate` of a validator can be updated using the
|
||||
`MsgEditCandidacy`.
|
||||
|
||||
```golang
|
||||
```go
|
||||
type MsgEditCandidacy struct {
|
||||
Description Description
|
||||
ValidatorAddr sdk.ValAddress
|
||||
@@ -51,77 +47,70 @@ type MsgEditCandidacy struct {
|
||||
}
|
||||
```
|
||||
|
||||
This message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- the initial `CommissionRate` is either negative or > `MaxRate`
|
||||
- the `CommissionRate` has already been updated within the previous 24 hours
|
||||
- the `CommissionRate` is > `MaxChangeRate`
|
||||
- the description fields are too large
|
||||
- the initial `CommissionRate` is either negative or > `MaxRate`
|
||||
- the `CommissionRate` has already been updated within the previous 24 hours
|
||||
- the `CommissionRate` is > `MaxChangeRate`
|
||||
- the description fields are too large
|
||||
|
||||
This message stores the updated `Validator` object.
|
||||
This message stores the updated `Validator` object.
|
||||
|
||||
## MsgDelegate
|
||||
|
||||
Within this message the delegator provides coins, and in return receives
|
||||
some amount of their validator's (newly created) delegator-shares that are
|
||||
assigned to `Delegation.Shares`.
|
||||
assigned to `Delegation.Shares`.
|
||||
|
||||
```golang
|
||||
```go
|
||||
type MsgDelegate struct {
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorAddr sdk.ValAddress
|
||||
Delegation sdk.Coin
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorAddr sdk.ValAddress
|
||||
Amount sdk.Coin
|
||||
}
|
||||
```
|
||||
|
||||
This message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- the validator is does not exist
|
||||
- the validator is jailed
|
||||
- the validator is does not exist
|
||||
- the validator is jailed
|
||||
- the `Amount` `Coin` has a denomination different than one defined by `params.BondDenom`
|
||||
|
||||
If an existing `Delegation` object for provided addresses does not already
|
||||
exist than it is created as part of this message otherwise the existing
|
||||
`Delegation` is updated to include the newly received shares.
|
||||
`Delegation` is updated to include the newly received shares.
|
||||
|
||||
## MsgBeginUnbonding
|
||||
|
||||
The begin unbonding message allows delegators to undelegate their tokens from
|
||||
validator.
|
||||
validator.
|
||||
|
||||
```golang
|
||||
```go
|
||||
type MsgBeginUnbonding struct {
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorAddr sdk.ValAddress
|
||||
SharesAmount sdk.Dec
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorAddr sdk.ValAddress
|
||||
Amount sdk.Coin
|
||||
}
|
||||
```
|
||||
|
||||
This message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- the delegation doesn't exist
|
||||
- the validator doesn't exist
|
||||
- the delegation has less shares than `SharesAmount`
|
||||
- existing `UnbondingDelegation` has maximum entries as defined by
|
||||
params.MaxEntries
|
||||
- the delegation doesn't exist
|
||||
- the validator doesn't exist
|
||||
- the delegation has less shares than the ones worth of `Amount`
|
||||
- existing `UnbondingDelegation` has maximum entries as defined by `params.MaxEntries`
|
||||
- the `Amount` has a denomination different than one defined by `params.BondDenom`
|
||||
|
||||
When this message is processed the following actions occur:
|
||||
- validator's `DelegatorShares` and the delegation's `Shares` are both reduced
|
||||
by the message `SharesAmount`
|
||||
- calculate the token worth of the shares remove that amount tokens held
|
||||
within the validator
|
||||
- with those removed tokens, if the validator is:
|
||||
- bonded - add them to an entry in `UnbondingDelegation` (create
|
||||
`UnbondingDelegation` if it doesn't exist) with a completion time a full
|
||||
unbonding period from the current time. Update pool shares to reduce
|
||||
BondedTokens and increase NotBondedTokens by token worth of the shares.
|
||||
- unbonding - add them to an entry in `UnbondingDelegation` (create
|
||||
`UnbondingDelegation` if it doesn't exist) with the same completion time
|
||||
as the validator (`UnbondingMinTime`).
|
||||
- unbonded - then send the coins the message `DelegatorAddr`
|
||||
- if there are no more `Shares` in the delegation, then the delegation object
|
||||
is removed from the store
|
||||
- under this situation if the delegation is the validator's self-delegation
|
||||
then also jail the validator.
|
||||
|
||||
- validator's `DelegatorShares` and the delegation's `Shares` are both reduced by the message `SharesAmount`
|
||||
- calculate the token worth of the shares remove that amount tokens held within the validator
|
||||
- with those removed tokens, if the validator is:
|
||||
- `Bonded` - add them to an entry in `UnbondingDelegation` (create `UnbondingDelegation` if it doesn't exist) with a completion time a full unbonding period from the current time. Update pool shares to reduce BondedTokens and increase NotBondedTokens by token worth of the shares.
|
||||
- `Unbonding` - add them to an entry in `UnbondingDelegation` (create `UnbondingDelegation` if it doesn't exist) with the same completion time as the validator (`UnbondingMinTime`).
|
||||
- `Unbonded` - then send the coins the message `DelegatorAddr`
|
||||
- if there are no more `Shares` in the delegation, then the delegation object is removed from the store
|
||||
- under this situation if the delegation is the validator's self-delegation then also jail the validator.
|
||||
|
||||
## MsgBeginRedelegate
|
||||
|
||||
@@ -129,43 +118,32 @@ The redelegation command allows delegators to instantly switch validators. Once
|
||||
the unbonding period has passed, the redelegation is automatically completed in
|
||||
the EndBlocker.
|
||||
|
||||
```golang
|
||||
```go
|
||||
type MsgBeginRedelegate struct {
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorSrcAddr sdk.ValAddress
|
||||
ValidatorDstAddr sdk.ValAddress
|
||||
SharesAmount sdk.Dec
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorSrcAddr sdk.ValAddress
|
||||
ValidatorDstAddr sdk.ValAddress
|
||||
Amount sdk.Coin
|
||||
}
|
||||
```
|
||||
|
||||
This message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- the delegation doesn't exist
|
||||
- the source or destination validators don't exist
|
||||
- the delegation has less shares than `SharesAmount`
|
||||
- the source validator has a receiving redelegation which
|
||||
is not matured (aka. the redelegation may be transitive)
|
||||
- existing `Redelegation` has maximum entries as defined by
|
||||
params.MaxEntries
|
||||
- the delegation doesn't exist
|
||||
- the source or destination validators don't exist
|
||||
- the delegation has less shares than the ones worth of `Amount`
|
||||
- the source validator has a receiving redelegation which is not matured (aka. the redelegation may be transitive)
|
||||
- existing `Redelegation` has maximum entries as defined by `params.MaxEntries`
|
||||
- the `Amount` `Coin` has a denomination different than one defined by `params.BondDenom`
|
||||
|
||||
When this message is processed the following actions occur:
|
||||
- the source validator's `DelegatorShares` and the delegations `Shares` are
|
||||
both reduced by the message `SharesAmount`
|
||||
- calculate the token worth of the shares remove that amount tokens held
|
||||
within the source validator.
|
||||
- if the source validator is:
|
||||
- bonded - add an entry to the `Redelegation` (create
|
||||
`Redelegation` if it doesn't exist) with a completion time a full
|
||||
unbonding period from the current time. Update pool shares to reduce
|
||||
BondedTokens and increase NotBondedTokens by token worth of the shares
|
||||
(this may be effectively reversed in the next step however).
|
||||
- unbonding - add an entry to the `Redelegation` (create `Redelegation` if
|
||||
it doesn't exist) with the same completion time as the validator
|
||||
(`UnbondingMinTime`).
|
||||
- unbonded - no action required in this step
|
||||
- Delegate the token worth to the destination validator, possibly moving
|
||||
tokens back to the bonded state.
|
||||
- if there are no more `Shares` in the source delegation, then the source
|
||||
delegation object is removed from the store
|
||||
- under this situation if the delegation is the validator's self-delegation
|
||||
then also jail the validator.
|
||||
|
||||
- the source validator's `DelegatorShares` and the delegations `Shares` are both reduced by the message `SharesAmount`
|
||||
- calculate the token worth of the shares remove that amount tokens held within the source validator.
|
||||
- if the source validator is:
|
||||
- `Bonded` - add an entry to the `Redelegation` (create `Redelegation` if it doesn't exist) with a completion time a full unbonding period from the current time. Update pool shares to reduce BondedTokens and increase NotBondedTokens by token worth of the shares (this may be effectively reversed in the next step however).
|
||||
- `Unbonding` - add an entry to the `Redelegation` (create `Redelegation` if it doesn't exist) with the same completion time as the validator (`UnbondingMinTime`).
|
||||
- `Unbonded` - no action required in this step
|
||||
- Delegate the token worth to the destination validator, possibly moving tokens back to the bonded state.
|
||||
- if there are no more `Shares` in the source delegation, then the source delegation object is removed from the store
|
||||
- under this situation if the delegation is the validator's self-delegation then also jail the validator.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# End-Block
|
||||
# End-Block
|
||||
|
||||
Each abci end block call, the operations to update queues and validator set
|
||||
changes are specified to execute.
|
||||
changes are specified to execute.
|
||||
|
||||
## Validator Set Changes
|
||||
|
||||
@@ -11,23 +11,25 @@ validators are also returned back to Tendermint for inclusion in the Tendermint
|
||||
validator set which is responsible for validating Tendermint messages at the
|
||||
consensus layer. Operations are as following:
|
||||
|
||||
- the new validator set is taken as the top `params.MaxValidators` number of
|
||||
validators retrieved from the ValidatorsByPower index
|
||||
- the previous validator set is compared with the new validator set
|
||||
- missing validators begin unbonding
|
||||
- new validator are instantly bonded
|
||||
- the new validator set is taken as the top `params.MaxValidators` number of
|
||||
validators retrieved from the ValidatorsByPower index
|
||||
- the previous validator set is compared with the new validator set:
|
||||
- missing validators begin unbonding and their `Tokens` are transferred from the
|
||||
`BondedPool` to the `NotBondedPool` `ModuleAccount`
|
||||
- new validators are instantly bonded and their `Tokens` are transferred from the
|
||||
`NotBondedPool` to the `BondedPool` `ModuleAccount`
|
||||
|
||||
In all cases, any validators leaving or entering the bonded validator set or
|
||||
changing balances and staying within the bonded validator set incur an update
|
||||
message which is passed back to Tendermint.
|
||||
|
||||
## Queues
|
||||
## Queues
|
||||
|
||||
Within staking, certain state-transitions are not instantaneous but take place
|
||||
over a duration of time (typically the unbonding period). When these
|
||||
transitions are mature certain operations must take place in order to complete
|
||||
the state operation. This is achieved through the use of queues which are
|
||||
checked/processed at the end of each block.
|
||||
checked/processed at the end of each block.
|
||||
|
||||
### Unbonding Validators
|
||||
|
||||
@@ -36,7 +38,7 @@ being jailed, or not having sufficient bonded tokens) it begins the unbonding
|
||||
process along with all its delegations begin unbonding (while still being
|
||||
delegated to this validator). At this point the validator is said to be an
|
||||
unbonding validator, whereby it will mature to become an "unbonded validator"
|
||||
after the unbonding period has passed.
|
||||
after the unbonding period has passed.
|
||||
|
||||
Each block the validator queue is to be checked for mature unbonding validators
|
||||
(namely with a completion time <= current time). At this point any mature
|
||||
@@ -48,16 +50,18 @@ delegations, the `validator.Status` is switched from `sdk.Unbonding` to
|
||||
### Unbonding Delegations
|
||||
|
||||
Complete the unbonding of all mature `UnbondingDelegations.Entries` within the
|
||||
`UnbondingDelegations` queue with the following procedure:
|
||||
- transfer the balance coins to the delegator's wallet address
|
||||
- remove the mature entry from `UnbondingDelegation.Entries`
|
||||
- remove the `UnbondingDelegation` object from the store if there are no
|
||||
remaining entries.
|
||||
`UnbondingDelegations` queue with the following procedure:
|
||||
|
||||
- transfer the balance coins to the delegator's wallet address
|
||||
- remove the mature entry from `UnbondingDelegation.Entries`
|
||||
- remove the `UnbondingDelegation` object from the store if there are no
|
||||
remaining entries.
|
||||
|
||||
### Redelegations
|
||||
|
||||
Complete the unbonding of all mature `Redelegation.Entries` within the
|
||||
`Redelegations` queue with the following procedure:
|
||||
- remove the mature entry from `Redelegation.Entries`
|
||||
- remove the `Redelegation` object from the store if there are no
|
||||
remaining entries.
|
||||
`Redelegations` queue with the following procedure:
|
||||
|
||||
- remove the mature entry from `Redelegation.Entries`
|
||||
- remove the `Redelegation` object from the store if there are no
|
||||
remaining entries.
|
||||
|
||||
Reference in New Issue
Block a user