github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/staking/spec/01_state.md (about) 1 <!-- 2 order: 1 3 --> 4 5 # State 6 7 ## LastTotalPower 8 9 LastTotalPower tracks the total amounts of bonded tokens recorded during the previous end block. 10 11 - LastTotalPower: `0x12 -> amino(sdk.Int)` 12 13 ## Params 14 15 Params is a module-wide configuration structure that stores system parameters 16 and defines overall functioning of the staking module. 17 18 - Params: `Paramsspace("staking") -> amino(params)` 19 20 ```go 21 type Params struct { 22 UnbondingTime time.Duration // time duration of unbonding 23 MaxValidators uint16 // maximum number of validators 24 MaxEntries uint16 // max entries for either unbonding delegation or redelegation (per pair/trio) 25 BondDenom string // bondable coin denomination 26 } 27 ``` 28 29 ## Validator 30 31 Validators can have one of three statuses 32 33 - `Unbonded`: The validator is not in the active set. They cannot sign blocks and do not earn 34 rewards. They can receive delegations. 35 - `Bonded`": Once the validator receives sufficient bonded tokens they automtically join the 36 active set during [`EndBlock`](./05_end_block.md#validator-set-changes) and their status is updated to `Bonded`. 37 They are signing blocks and receiving rewards. They can receive further delegations. 38 They can be slashed for misbehavior. Delegators to this validator who unbond their delegation 39 must wait the duration of the UnbondingTime, a chain-specific param. during which time 40 they are still slashable for offences of the source validator if those offences were committed 41 during the period of time that the tokens were bonded. 42 - `Unbonding`: When a validator leaves the active set, either by choice or due to slashing or 43 tombstoning, an unbonding of all their delegations begins. All delegations must then wait the UnbondingTime 44 before moving receiving their tokens to their accounts from the `BondedPool`. 45 46 Validators objects should be primarily stored and accessed by the 47 `OperatorAddr`, an SDK validator address for the operator of the validator. Two 48 additional indices are maintained per validator object in order to fulfill 49 required lookups for slashing and validator-set updates. A third special index 50 (`LastValidatorPower`) is also maintained which however remains constant 51 throughout each block, unlike the first two indices which mirror the validator 52 records within a block. 53 54 - Validators: `0x21 | OperatorAddr -> amino(validator)` 55 - ValidatorsByConsAddr: `0x22 | ConsAddr -> OperatorAddr` 56 - ValidatorsByPower: `0x23 | BigEndian(ConsensusPower) | OperatorAddr -> OperatorAddr` 57 - LastValidatorsPower: `0x11 OperatorAddr -> amino(ConsensusPower)` 58 59 `Validators` is the primary index - it ensures that each operator can have only one 60 associated validator, where the public key of that validator can change in the 61 future. Delegators can refer to the immutable operator of the validator, without 62 concern for the changing public key. 63 64 `ValidatorByConsAddr` is an additional index that enables lookups for slashing. 65 When Tendermint reports evidence, it provides the validator address, so this 66 map is needed to find the operator. Note that the `ConsAddr` corresponds to the 67 address which can be derived from the validator's `ConsPubKey`. 68 69 `ValidatorsByPower` is an additional index that provides a sorted list o 70 potential validators to quickly determine the current active set. Here 71 ConsensusPower is validator.Tokens/10^6. Note that all validators where 72 `Jailed` is true are not stored within this index. 73 74 `LastValidatorsPower` is a special index that provides a historical list of the 75 last-block's bonded validators. This index remains constant during a block but 76 is updated during the validator set update process which takes place in [`EndBlock`](./05_end_block.md). 77 78 Each validator's state is stored in a `Validator` struct: 79 80 ```go 81 type Validator struct { 82 OperatorAddress sdk.ValAddress // address of the validator's operator; bech encoded in JSON 83 ConsPubKey crypto.PubKey // the consensus public key of the validator; bech encoded in JSON 84 Jailed bool // has the validator been jailed from bonded status? 85 Status sdk.BondStatus // validator status (bonded/unbonding/unbonded) 86 Tokens sdk.Int // delegated tokens (incl. self-delegation) 87 DelegatorShares sdk.Dec // total shares issued to a validator's delegators 88 Description Description // description terms for the validator 89 UnbondingHeight int64 // if unbonding, height at which this validator has begun unbonding 90 UnbondingCompletionTime time.Time // if unbonding, min time for the validator to complete unbonding 91 Commission Commission // commission parameters 92 MinSelfDelegation sdk.Int // validator's self declared minimum self delegation 93 } 94 95 type Commission struct { 96 CommissionRates 97 UpdateTime time.Time // the last time the commission rate was changed 98 } 99 100 CommissionRates struct { 101 Rate sdk.Dec // the commission rate charged to delegators, as a fraction 102 MaxRate sdk.Dec // maximum commission rate which validator can ever charge, as a fraction 103 MaxChangeRate sdk.Dec // maximum daily increase of the validator commission, as a fraction 104 } 105 106 type Description struct { 107 Moniker string // name 108 Identity string // optional identity signature (ex. UPort or Keybase) 109 Website string // optional website link 110 SecurityContact string // optional email for security contact 111 Details string // optional details 112 } 113 ``` 114 115 ## Delegation 116 117 Delegations are identified by combining `DelegatorAddr` (the address of the delegator) 118 with the `ValidatorAddr` Delegators are indexed in the store as follows: 119 120 - Delegation: `0x31 | DelegatorAddr | ValidatorAddr -> amino(delegation)` 121 122 Stake holders may delegate coins to validators; under this circumstance their 123 funds are held in a `Delegation` data structure. It is owned by one 124 delegator, and is associated with the shares for one validator. The sender of 125 the transaction is the owner of the bond. 126 127 ```go 128 type Delegation struct { 129 DelegatorAddr sdk.AccAddress 130 ValidatorAddr sdk.ValAddress 131 Shares sdk.Dec // delegation shares received 132 } 133 ``` 134 135 ### Delegator Shares 136 137 When one Delegates tokens to a Validator they are issued a number of delegator shares based on a 138 dynamic exchange rate, calculated as follows from the total number of tokens delegated to the 139 validator and the number of shares issued so far: 140 141 `Shares per Token = validator.TotalShares() / validator.Tokens()` 142 143 Only the number of shares received is stored on the DelegationEntry. When a delegator then 144 Undelegates, the token amount they receive is calculated from the number of shares they currently 145 hold and the inverse exchange rate: 146 147 `Tokens per Share = validator.Tokens() / validatorShares()` 148 149 These `Shares` are simply an accounting mechanism. They are not a fungible asset. The reason for 150 this mechanism is to simplify the accounting around slashing. Rather than iteratively slashing the 151 tokens of every delegation entry, instead the Validators total bonded tokens can be slashed, 152 effectively reducing the value of each issued delegator share. 153 154 ## UnbondingDelegation 155 156 Shares in a `Delegation` can be unbonded, but they must for some time exist as 157 an `UnbondingDelegation`, where shares can be reduced if Byzantine behavior is 158 detected. 159 160 `UnbondingDelegation` are indexed in the store as: 161 162 - UnbondingDelegation: `0x32 | DelegatorAddr | ValidatorAddr -> 163 amino(unbondingDelegation)` 164 - UnbondingDelegationsFromValidator: `0x33 | ValidatorAddr | DelegatorAddr -> 165 nil` 166 167 The first map here is used in queries, to lookup all unbonding delegations for 168 a given delegator, while the second map is used in slashing, to lookup all 169 unbonding delegations associated with a given validator that need to be 170 slashed. 171 172 A UnbondingDelegation object is created every time an unbonding is initiated. 173 174 ```go 175 type UnbondingDelegation struct { 176 DelegatorAddr sdk.AccAddress // delegator 177 ValidatorAddr sdk.ValAddress // validator unbonding from operator addr 178 Entries []UnbondingDelegationEntry // unbonding delegation entries 179 } 180 181 type UnbondingDelegationEntry struct { 182 CreationHeight int64 // height which the unbonding took place 183 CompletionTime time.Time // unix time for unbonding completion 184 InitialBalance sdk.Coin // atoms initially scheduled to receive at completion 185 Balance sdk.Coin // atoms to receive at completion 186 } 187 ``` 188 189 ## Redelegation 190 191 The bonded tokens worth of a `Delegation` may be instantly redelegated from a 192 source validator to a different validator (destination validator). However when 193 this occurs they must be tracked in a `Redelegation` object, whereby their 194 shares can be slashed if their tokens have contributed to a Byzantine fault 195 committed by the source validator. 196 197 `Redelegation` are indexed in the store as: 198 199 - Redelegations: `0x34 | DelegatorAddr | ValidatorSrcAddr | ValidatorDstAddr -> amino(redelegation)` 200 - RedelegationsBySrc: `0x35 | ValidatorSrcAddr | ValidatorDstAddr | DelegatorAddr -> nil` 201 - RedelegationsByDst: `0x36 | ValidatorDstAddr | ValidatorSrcAddr | DelegatorAddr -> nil` 202 203 The first map here is used for queries, to lookup all redelegations for a given 204 delegator. The second map is used for slashing based on the `ValidatorSrcAddr`, 205 while the third map is for slashing based on the `ValidatorDstAddr`. 206 207 A redelegation object is created every time a redelegation occurs. To prevent 208 "redelegation hopping" redelegations may not occur under the situation that: 209 210 - the (re)delegator already has another immature redelegation in progress 211 with a destination to a validator (let's call it `Validator X`) 212 - and, the (re)delegator is attempting to create a _new_ redelegation 213 where the source validator for this new redelegation is `Validator-X`. 214 215 ```go 216 type Redelegation struct { 217 DelegatorAddr sdk.AccAddress // delegator 218 ValidatorSrcAddr sdk.ValAddress // validator redelegation source operator addr 219 ValidatorDstAddr sdk.ValAddress // validator redelegation destination operator addr 220 Entries []RedelegationEntry // redelegation entries 221 } 222 223 type RedelegationEntry struct { 224 CreationHeight int64 // height which the redelegation took place 225 CompletionTime time.Time // unix time for redelegation completion 226 InitialBalance sdk.Coin // initial balance when redelegation started 227 Balance sdk.Coin // current balance (current value held in destination validator) 228 SharesDst sdk.Dec // amount of destination-validator shares created by redelegation 229 } 230 ``` 231 232 ## Queues 233 234 All queues objects are sorted by timestamp. The time used within any queue is 235 first rounded to the nearest nanosecond then sorted. The sortable time format 236 used is a slight modification of the RFC3339Nano and uses the the format string 237 `"2006-01-02T15:04:05.000000000"`. Notably this format: 238 239 - right pads all zeros 240 - drops the time zone info (uses UTC) 241 242 In all cases, the stored timestamp represents the maturation time of the queue 243 element. 244 245 ### UnbondingDelegationQueue 246 247 For the purpose of tracking progress of unbonding delegations the unbonding 248 delegations queue is kept. 249 250 - UnbondingDelegation: `0x41 | format(time) -> []DVPair` 251 252 ```go 253 type DVPair struct { 254 DelegatorAddr sdk.AccAddress 255 ValidatorAddr sdk.ValAddress 256 } 257 ``` 258 259 ### RedelegationQueue 260 261 For the purpose of tracking progress of redelegations the redelegation queue is 262 kept. 263 264 - UnbondingDelegation: `0x42 | format(time) -> []DVVTriplet` 265 266 ```go 267 type DVVTriplet struct { 268 DelegatorAddr sdk.AccAddress 269 ValidatorSrcAddr sdk.ValAddress 270 ValidatorDstAddr sdk.ValAddress 271 } 272 ``` 273 274 ### ValidatorQueue 275 276 For the purpose of tracking progress of unbonding validators the validator 277 queue is kept. 278 279 - ValidatorQueueTime: `0x43 | format(time) -> []sdk.ValAddress` 280 281 The stored object as each key is an array of validator operator addresses from 282 which the validator object can be accessed. Typically it is expected that only 283 a single validator record will be associated with a given timestamp however it is possible 284 that multiple validators exist in the queue at the same location. 285 286 ## HistoricalInfo 287 288 HistoricalInfo objects are stored and pruned at each block such that the staking keeper persists 289 the `n` most recent historical info defined by staking module parameter: `HistoricalEntries`. 290 291 ```go 292 type HistoricalInfo struct { 293 Header abci.Header 294 ValSet []types.Validator 295 } 296 ``` 297 298 At each BeginBlock, the staking keeper will persist the current Header and the Validators that committed 299 the current block in a `HistoricalInfo` object. The Validators are sorted on their address to ensure that 300 they are in a determisnistic order. 301 The oldest HistoricalEntries will be pruned to ensure that there only exist the parameter-defined number of 302 historical entries.