Skip to content

Commit 7f74b33

Browse files
rigelrozanskicwgoes
authored andcommitted
Merge PR #3357: Staking spec upgrades / some renaming
1 parent da0426a commit 7f74b33

File tree

17 files changed

+313
-122
lines changed

17 files changed

+313
-122
lines changed

PENDING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ IMPROVEMENTS
103103
* \#2509 Sanitize all usage of Dec.RoundInt64()
104104
* [\#556](https://github.com/cosmos/cosmos-sdk/issues/556) Increase `BaseApp`
105105
test coverage.
106+
* \#3357 develop state-transitions.md for staking spec, missing states added to `state.md`
106107
* [\#3552](https://github.com/cosmos/cosmos-sdk/pull/3552) Validate bit length when
107108
deserializing `Int` types.
108109

docs/spec/SPEC-SPEC.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function
1515

1616
- `overview.md` - describe module
1717
- `state.md` - specify and describe structures expected to marshalled into the store, and their keys
18-
- `state_transitions.md` - standard state transition operations triggered by by hooks, messages, etc.
18+
- `state_transitions.md` - standard state transition operations triggered by hooks, messages, etc.
1919
- `end_block.md` - specify any end-block operations
2020
- `begin_block.md` - specify any begin-block operations
2121
- `messages.md` - specify message structure and expected state machine behaviour

docs/spec/staking/TODO.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

docs/spec/staking/end_block.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ delegated to this validator). At this point the validator is said to be an
3838
unbonding validator, whereby it will mature to become an "unbonded validator"
3939
after the unbonding period has passed.
4040

41-
Each block the validator queue is to be checked for mature unbonding
42-
validators. For all unbonding validators that have finished their unbonding
43-
period, the validator.Status is switched from sdk.Unbonding to sdk.Unbonded.
44-
If at this switch they do not have any delegation left the validator object
45-
instead just deleted from state.
41+
Each block the validator queue is to be checked for mature unbonding validators
42+
(namely with a completion time <= current time). At this point any mature
43+
validators which do not have any delegations remaining are deleted from state.
44+
For all other mature unbonding validators that still have remaining
45+
delegations, the validator.Status is switched from sdk.Unbonding to
46+
sdk.Unbonded.
4647

4748
### Unbonding Delegations
4849

docs/spec/staking/overview.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,23 @@ native staking token of the chain.
2727
- Delegation
2828
- UnbondingDelegation
2929
- Redelegation
30-
2. **[Messages](messages.md)**
30+
- Queues
31+
2. **[State Transistions](state_transitions.md)**
32+
- Validator
33+
- Delegation
34+
- Slashing
35+
3. **[Messages](messages.md)**
3136
- MsgCreateValidator
3237
- MsgEditValidator
3338
- MsgDelegate
3439
- MsgBeginUnbonding
3540
- MsgBeginRedelegate
36-
3. **[End-Block](end_block.md)**
41+
4. **[End-Block](end_block.md)**
3742
- Validator Set Changes
3843
- Queues
3944
- Unbonding Validators
4045
- Unbonding Delegations
4146
- Redelegations
42-
4. **[Hooks](hooks.md)**
43-
5. **[Tags](tags.md)**
47+
5. **[Hooks](hooks.md)**
48+
6. **[Tags](tags.md)**
4449

docs/spec/staking/state.md

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ type Pool struct {
1717
}
1818
```
1919

20+
## LastTotalPower
21+
22+
LastTotalPower tracks the total amounts of bonded tokens recorded during the previous
23+
end block.
24+
25+
- LastTotalPower: `0x12 -> amino(sdk.Int)`
26+
2027
## Params
2128

2229
Params is a module-wide configuration structure that stores system parameters
@@ -37,27 +44,36 @@ type Params struct {
3744

3845
Validators objects should be primarily stored and accessed by the
3946
`OperatorAddr`, an SDK validator address for the operator of the validator. Two
40-
additional indexes are maintained in order to fulfill required lookups for
41-
slashing and validator-set updates.
47+
additional indices are maintained per validator object in order to fulfill
48+
required lookups for slashing and validator-set updates. A third special index
49+
(`LastValidatorPower`) is also maintained which however remains constant
50+
throughout each block, unlike the first two indices which mirror the validator
51+
records within a block.
4252

4353
- Validators: `0x21 | OperatorAddr -> amino(validator)`
4454
- ValidatorsByConsAddr: `0x22 | ConsAddr -> OperatorAddr`
4555
- ValidatorsByPower: `0x23 | BigEndian(Tokens) | OperatorAddr -> OperatorAddr`
56+
- LastValidatorsPower: `0x11 OperatorAddr -> amino(Tokens)
4657

4758
`Validators` is the primary index - it ensures that each operator can have only one
4859
associated validator, where the public key of that validator can change in the
4960
future. Delegators can refer to the immutable operator of the validator, without
5061
concern for the changing public key.
5162

52-
`ValidatorByConsAddr` is a secondary index that enables lookups for slashing.
63+
`ValidatorByConsAddr` is an additional index that enables lookups for slashing.
5364
When Tendermint reports evidence, it provides the validator address, so this
5465
map is needed to find the operator. Note that the `ConsAddr` corresponds to the
5566
address which can be derived from the validator's `ConsPubKey`.
5667

57-
`ValidatorsByPower` is a secondary index that provides a sorted list of
68+
`ValidatorsByPower` is an additional index that provides a sorted list o
5869
potential validators to quickly determine the current active set. Note
5970
that all validators where `Jailed` is true are not stored within this index.
6071

72+
`LastValidatorsPower` is a special index that provides a historical list of the
73+
last-block's bonded validators. This index remains constant during a block but
74+
is updated during the validator set update process which takes place in [end
75+
block](end_block.md).
76+
6177
Each validator's state is stored in a `Validator` struct:
6278

6379
```golang
@@ -190,3 +206,57 @@ type RedelegationEntry struct {
190206
SharesDst sdk.Dec // amount of destination-validator shares created by redelegation
191207
}
192208
```
209+
210+
## Queues
211+
212+
All queues objects are sorted by timestamp. The time used within any queue is
213+
first rounded to the nearest nanosecond then sorted. The sortable time format
214+
used is a slight modification of the RFC3339Nano and uses the the format string
215+
`"2006-01-02T15:04:05.000000000"`. Noteably This format:
216+
217+
- right pads all zeros
218+
- drops the time zone info (uses UTC)
219+
220+
In all cases, the stored timestamp represents the maturation time of the queue
221+
element.
222+
223+
### UnbondingDelegationQueue
224+
225+
For the purpose of tracking progress of unbonding delegations the unbonding
226+
delegations queue is kept.
227+
228+
- UnbondingDelegation: `0x41 | format(time) -> []DVPair`
229+
230+
```
231+
type DVPair struct {
232+
DelegatorAddr sdk.AccAddress
233+
ValidatorAddr sdk.ValAddress
234+
}
235+
```
236+
237+
### RedelegationQueue
238+
239+
For the purpose of tracking progress of redelegations the redelegation queue is
240+
kept.
241+
242+
- UnbondingDelegation: `0x42 | format(time) -> []DVVTriplet`
243+
244+
```
245+
type DVVTriplet struct {
246+
DelegatorAddr sdk.AccAddress
247+
ValidatorSrcAddr sdk.ValAddress
248+
ValidatorDstAddr sdk.ValAddress
249+
}
250+
```
251+
252+
### ValidatorQueue
253+
254+
For the purpose of tracking progress of unbonding validators the validator
255+
queue is kept.
256+
257+
- ValidatorQueueTime: `0x43 | format(time) -> []sdk.ValAddress`
258+
259+
The stored object as each key is an array of validator operator addresses from
260+
which the validator object can be accessed. Typically it is expected that only
261+
a single validator record will be associated with a given timestamp however it is possible
262+
that multiple validators exist in the queue at the same location.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# State Transitions
2+
3+
This document describes the state transition operations pertaining to:
4+
5+
- Validators
6+
- Delegations
7+
- Slashing
8+
9+
10+
## Validators
11+
12+
### Non-Bonded to Bonded
13+
14+
When a validator is bonded from any other state the following operations occur:
15+
- set `validator.Status` to `Bonded`
16+
- update the `Pool` object with tokens moved from `NotBondedTokens` to `BondedTokens`
17+
- delete record the existing record from `ValidatorByPowerIndex`
18+
- add an new updated record to the `ValidatorByPowerIndex`
19+
- update the `Validator` object for this validator
20+
- if it exists, delete any `ValidatorQueue` record for this validator
21+
22+
### Bonded to Unbonding
23+
When a validator begins the unbonding process the following operations occur:
24+
- update the `Pool` object with tokens moved from `BondedTokens` to `NotBondedTokens`
25+
- set `validator.Status` to `Unbonding`
26+
- delete record the existing record from `ValidatorByPowerIndex`
27+
- add an new updated record to the `ValidatorByPowerIndex`
28+
- update the `Validator` object for this validator
29+
- insert a new record into the `ValidatorQueue` for this validator
30+
31+
### Unbonding to Unbonded
32+
A validator moves from unbonding to unbonded when the `ValidatorQueue` object
33+
moves from bonded to unbonded
34+
- update the `Validator` object for this validator
35+
- set `validator.Status` to `Unbonded`
36+
37+
### Jail/Unjail
38+
when a validator is jailed it is effectively removed from the Tendermint set.
39+
this process may be also be reversed. the following operations occur:
40+
- set `Validator.Jailed` and update object
41+
- if jailed delete record from `ValidatorByPowerIndex`
42+
- if unjailed add record to `ValidatorByPowerIndex`
43+
44+
45+
## Delegations
46+
47+
### Delegate
48+
When a delegation occurs both the validator and the delegtion objects are affected
49+
- determine the delegators shares based on tokens delegated and the validator's exchange rate
50+
- remove tokens from the sending account
51+
- add shares the delegation object or add them to a created validator object
52+
- add new delegator shares and update the `Validator` object
53+
- update the `Pool` object appropriately if tokens have moved into a bonded validator
54+
- delete record the existing record from `ValidatorByPowerIndex`
55+
- add an new updated record to the `ValidatorByPowerIndex`
56+
57+
#### Unbond Delegation
58+
As a part of the Undelegate and Complete Unbonding state transitions Unbond
59+
Delegation may be called.
60+
- subtract the unbonded shares from delegator
61+
- update the delegation or remove the delegation if there are no more shares
62+
- if the delegation is the operator of the validator and no more shares exist
63+
then trigger a jail validator
64+
- update the validator with removed the delegator shares and associated coins, update
65+
the pool for any shifts between bonded and non-bonded tokens.
66+
- remove the validator if it is unbonded and there are no more delegation shares.
67+
68+
### Undelegate
69+
When an delegation occurs both the validator and the delegtion objects are affected
70+
- perform an unbond delegation
71+
- if the validator is unbonding or bonded add the tokens to an
72+
`UnbondingDelegation` Entry
73+
- if the validator is unbonded send the tokens directly to the withdraw
74+
account
75+
76+
### Complete Unbonding
77+
For undelegations which do not complete immediately, the following operations
78+
occur when the unbonding delegation queue element matures:
79+
- remove the entry from the `UnbondingDelegation` object
80+
- withdraw the tokens to the delegator withdraw address
81+
82+
### Begin Redelegation
83+
Redelegations affect the delegation, source and destination validators.
84+
- perform an unbond delegation from the source validator
85+
- using the generated tokens perform a Delegate to the destination
86+
validator
87+
- record the token amount in an new entry in the relevant `Redelegation`
88+
89+
### Complete Redelegation
90+
When a redelegations complete the following occurs:
91+
- remove the entry from the `Redelegation` object
92+
93+
94+
TODO TODO TOFU TODO
95+
## Slashing
96+
97+
### Slash Validator
98+
99+
### Slash Unbonding Delegation
100+
101+
### Slash Redelegation

x/distribution/types/keepers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ type StakingKeeper interface {
1111
ValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) sdk.Validator
1212
TotalPower(ctx sdk.Context) sdk.Int
1313
GetLastTotalPower(ctx sdk.Context) sdk.Int
14-
GetLastValidatorPower(ctx sdk.Context, valAddr sdk.ValAddress) sdk.Int
14+
GetLastValidatorPower(ctx sdk.Context, valAddr sdk.ValAddress) int64
1515
}
1616

1717
// expected coin keeper
File renamed without changes.

x/staking/keeper/delegation.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,7 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.In
457457
// Get or create the delegation object
458458
delegation, found := k.GetDelegation(ctx, delAddr, validator.OperatorAddr)
459459
if !found {
460-
delegation = types.Delegation{
461-
DelegatorAddr: delAddr,
462-
ValidatorAddr: validator.OperatorAddr,
463-
Shares: sdk.ZeroDec(),
464-
}
460+
delegation = types.NewDelegation(delAddr, validator.OperatorAddr, sdk.ZeroDec())
465461
}
466462

467463
// call the appropriate hook if present
@@ -535,7 +531,7 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA
535531
k.AfterDelegationModified(ctx, delegation.DelegatorAddr, delegation.ValidatorAddr)
536532
}
537533

538-
// remove the coins from the validator
534+
// remove the shares and coins from the validator
539535
validator, amount = k.RemoveValidatorTokensAndShares(ctx, validator, shares)
540536

541537
if validator.DelegatorShares.IsZero() && validator.Status == sdk.Unbonded {

0 commit comments

Comments
 (0)