cwgoes comments, improved pseudocode

This commit is contained in:
rigelrozanski 2018-06-13 21:58:36 -07:00
parent 14c1ff27f3
commit ab028a7805
5 changed files with 72 additions and 79 deletions

View File

@ -3,15 +3,5 @@
Here we cover many aspects of handling keys within the Cosmos SDK
framework.
## Pseudo Code
Generating an address for an ed25519 public key (in pseudo code):
```
const TypeDistinguisher = HexToBytes("1624de6220")
// prepend the TypeDistinguisher as Bytes
SerializedBytes = TypeDistinguisher ++ PubKey.asBytes()
Address = ripemd160(SerializedBytes)
```
// TODO add relevant key discussion
(related https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md#public-key-cryptography)

View File

@ -8,23 +8,24 @@ The Cosmos Hub is a Tendermint-based Delegated Proof of Stake (DPos) blockchain
system that serves as a backbone of the Cosmos ecosystem. It is operated and
secured by an open and globally decentralized set of validators. Tendermint is
a Byzantine fault-tolerant distributed protocol for consensus among distrusting
parties, in this case the group of validators which produce the blocks for
cosmos. To avoid the nothing-at-stake problem, a validator in Tendermint needs
to lock up coins in a bond deposit. Each bond's atoms are illiquid, they cannot
be transferred however they can be unbonded to become liquid, this process
takes the unbonding-period which will be 3 weeks by default at Cosmos-Hub
launch. Tendermint protocol messages are signed by the validator's private key,
and this is a basis for Tendermint strict accountability that allows punishing
misbehaving validators by slashing (burning) their bonded Atoms. On the other
hand, validators are rewarded for their service of securing blockchain network
by the inflationary provisions and transactions fees. This incentivizes correct
behavior of the validators and provides the economic security of the network.
parties, in this case the group of validators which produce the blocks for the
Cosmos Hub. To avoid the nothing-at-stake problem, a validator in Tendermint
needs to lock up coins in a bond deposit. Each bond's atoms are illiquid, they
cannot be transferred - in order to become liquid, they must be unbonded, a
process which will take 3 weeks by default at Cosmos Hub launch. Tendermint
protocol messages are signed by the validator's private key and are therefor
attributable. Validators acting outside protocol specifications can be made
accountable through punishing by slashing (burning) their bonded Atoms. On the
other hand, validators are rewarded for their service of securing blockchain
network by the inflationary provisions and transactions fees. This incentivizes
correct behavior of the validators and provides the economic security of the
network.
The native token of the Cosmos Hub is called the Atom; becoming a validator of the
Cosmos Hub requires holding Atoms. However, not all Atom holders are validators
of the Cosmos Hub. More precisely, there is a selection process that determines
the validator set as a subset of all validators (Atom holders that
wants to become a validator). The other option for Atom holder is to delegate
want to become a validator). The other option for Atom holders is to delegate
their atoms to validators, i.e., being a delegator. A delegator is an Atom
holder that has put its Atoms at stake by delegating it to a validator. By bonding
Atoms to secure the network (and taking a risk of being slashed in case of
@ -59,20 +60,22 @@ transaction fees.
bonded the shares must first remain in an inbetween unbonding state for the
duration of the unbonding period
* Redelegating Shares - Process of redelegating atoms from one validator to
another. This process is instantanious, the redelegated delegation is
slashible to the old validator for all blocks before the redelegation and to
the new validator for all new blocks.
another. This process is instantaneous, but the redelegated atoms are
retrospecively slashable if the old validator is found to misbehave for any
blocks before the redelegation. These atoms are simultaniously slashable
for any new blocks which the new validator misbehavess
* Validator - entity with atoms which is either actively validating the Tendermint
protocol (bonded validator) or vying to validate .
* Bonded Validator - a validator whose atoms are currently bonded and liable to
be slashed. These validators are to be able to sign protocol messages in the
Tendermint consensus protocol. There are limited number of bonded validators
at Cosmos Hub genesis there is a maximum of 100 bonded validators. Only Bonded
Validators receive atom provisions and fee rewards.
be slashed. These validators are to be able to sign protocol messages for
Tendermint consensus. At Cosmos Hub genesis there is a maximum of 100
bonded validator positions. Only Bonded Validators receive atom provisions
and fee rewards.
* Delegator - an Atom holder that has bonded Atoms to a validator
* Unbonding period - time required in the unbonding state when unbonding
shares. Time slashable to old validator after a redelegation. Time for which
validators can be slashed after an infraction
validators can be slashed after an infraction. To provide the requisite
cryptoeconomic security guarantees, all of these must be equal.
* Atom provisions - The process of increasing the Atom supply. Atoms are
periodically created on the Cosmos Hub and issued to bonded Atom holders.
The goal of inflation is to incentize most of the Atoms in existence to be
@ -90,7 +93,7 @@ At the core of the Staking module is the concept of a pool which denotes a
collection of Atoms contributed by different Atom holders. There are three
pools in the Staking module: the bonded, unbonding, and unbonded pool. Bonded
Atoms are part of the global bonded pool. If a validator or delegator wants to
unbond its Shares, these Shares are moved to the the unbonding pool for the
unbond its shares, these Shares are moved to the the unbonding pool for the
duration of the unbonding period. From here normally Atoms will be moved
directly into the delegators wallet, however under the situation thatn an
entire validator gets unbonded, the Atoms of the delegations will remain with
@ -169,17 +172,17 @@ delegators (we will explain this in section X).
#### Delegator shares
A validator is, depending on its status, contributing Atoms to either the bond,
A validator is, depending on its status, contributing Atoms to either the
unbonding or unbonded pool - the validator in turn holds some amount of pool
shares. Not all of a validators Atoms (and respective shares) are owned by the
validator, some may be owned by delegators to that validator. The mechanism for
distribution of Atoms (and shares) between a validator and its delegators is
based on a notion of delegator shares. More precisely, every validator is
issuing (local) delegator shares (`Validator.IssuedDelegatorShares`) that
represents some portion of global shares managed by the validator
(`Validator.GlobalStakeShares`). The principle behind managing delegator shares
is the same as described in [Section](#The pool and the share). We now
illustrate it with an example.
shares. Not all of a validator's Atoms (and respective shares) are necessarily
owned by the validator, some may be owned by delegators to that validator. The
mechanism for distribution of Atoms (and shares) between a validator and its
delegators is based on a notion of delegator shares. More precisely, every
validator is issuing (local) delegator shares
(`Validator.IssuedDelegatorShares`) that represents some portion of global
shares managed by the validator (`Validator.GlobalStakeShares`). The principle
behind managing delegator shares is the same as described in [Section](#The
pool and the share). We now illustrate it with an example.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXX TODO make way less verbose lets use bullet points to describe the example

View File

@ -10,7 +10,7 @@ NOTE: the specifications are not yet complete and very much a work in progress.
- [Governance](governance) - Governance related specifications including
proposals and voting.
- [IBC](ibc) - Specification of the Cosmos inter-blockchain communication (IBC) protocol.
- [Staking](staking) - Proof of Stake related specifications including bonding
- [Staking](staking) - Proof-of-stake related specifications including bonding
and delegation transactions, inflation, etc.
- [Slashing](slashing) - Specifications of validator punishment mechanisms
- [Provisioning](provisioning) - Fee distribution, and atom provision distribution specification

View File

@ -8,6 +8,8 @@ information about the total amounts of Atoms in all states, representative
validator shares for stake in the global pools, moving Atom inflation
information, etc.
- stored object:
```golang
type Pool struct {
LooseUnbondedTokens int64 // tokens not associated with any validator
@ -35,6 +37,8 @@ type PoolShares struct {
Params is global data structure that stores system parameters and defines
overall functioning of the stake module.
- stored object:
```golang
type Params struct {
InflationRateChange sdk.Rat // maximum annual change in inflation rate
@ -59,6 +63,8 @@ Related Store which holds Validator.ABCIValidator()
The `Validator` holds the current state and some historical actions of the
validator.
- stored object:
```golang
type Validator struct {
Owner sdk.Address // sender of BondTx - UnbondTx returns here
@ -98,6 +104,8 @@ 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.
- stored object:
```golang
type Delegation struct {
DelegatorAddr sdk.Address // delegation owner address
@ -114,6 +122,8 @@ A UnbondingDelegation object is created every time an unbonding is initiated.
The unbond must be completed with a second transaction provided by the
delegation owner after the unbonding period has passed.
- stored object:
```golang
type UnbondingDelegation struct {
DelegationKey sdk.Address // key of the delegation
@ -135,6 +145,8 @@ delegation owner after the unbonding period has passed. The destination
delegation of a redelegation may not itself undergo a new redelegation until
the original redelegation has been completed.
- stored object:
```golang
type Redelegation struct {
SourceDelegation sdk.Address // source delegation key

View File

@ -44,7 +44,7 @@ createValidator(tx TxCreateValidator):
if validator != nil return // only one validator per address
validator = NewValidator(OwnerAddr, ConsensusPubKey, GovernancePubKey, Description)
init validator poolShares, delegatorShares set to 0 //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
init validator poolShares, delegatorShares set to 0
init validator commision fields from tx
validator.PoolShares = 0
@ -71,8 +71,8 @@ type TxEditCandidacy struct {
editCandidacy(tx TxEditCandidacy):
validator = getValidator(tx.ValidatorAddr)
if tx.Commission > CommissionMax || tx.Commission < 0 return halt tx
if rateChange(tx.Commission) > CommissionMaxChange return halt tx
if tx.Commission > CommissionMax || tx.Commission < 0 then fail
if rateChange(tx.Commission) > CommissionMaxChange then fail
validator.Commission = tx.Commission
if tx.GovernancePubKey != nil validator.GovernancePubKey = tx.GovernancePubKey
@ -126,28 +126,16 @@ startUnbonding(tx TxStartUnbonding):
delegation, found = getDelegatorBond(store, sender, tx.PubKey)
if !found == nil return
if tx.Shares == "MAX" {
if !bond.Shares.GT(sdk.ZeroRat()) {
return ErrNotEnoughBondShares
else
var err sdk.Error
delShares, err = sdk.NewRatFromDecimal(tx.Shares)
if err != nil
return err
if bond.Shares.LT(delShares)
if bond.Shares < tx.Shares
return ErrNotEnoughBondShares
validator, found := GetValidator(tx.ValidatorAddr)
validator, found = GetValidator(tx.ValidatorAddr)
if !found {
return err
if tx.Shares == "MAX"
delShares = bond.Shares
bond.Shares -= tx.Shares
bond.Shares -= delShares
revokeCandidacy := false
revokeCandidacy = false
if bond.Shares.IsZero() {
if bond.DelegatorAddr == validator.Owner && validator.Revoked == false
@ -158,8 +146,8 @@ startUnbonding(tx TxStartUnbonding):
bond.Height = currentBlockHeight
setDelegation(bond)
pool := GetPool()
validator, pool, returnAmount := validator.removeDelShares(pool, delShares)
pool = GetPool()
validator, pool, returnAmount = validator.removeDelShares(pool, tx.Shares)
setPool( pool)
unbondingDelegation = NewUnbondingDelegation(sender, returnAmount, currentHeight/Time, startSlashRatio)
@ -261,13 +249,13 @@ Tendermint.
```golang
updateBondedValidators(newValidator Validator) (updatedVal Validator)
kickCliffValidator := false
oldCliffValidatorAddr := getCliffValidator(ctx)
kickCliffValidator = false
oldCliffValidatorAddr = getCliffValidator(ctx)
// add the actual validator power sorted store
maxValidators := GetParams(ctx).MaxValidators
iterator := ReverseSubspaceIterator(ValidatorsByPowerKey) // largest to smallest
bondedValidatorsCount := 0
maxValidators = GetParams(ctx).MaxValidators
iterator = ReverseSubspaceIterator(ValidatorsByPowerKey) // largest to smallest
bondedValidatorsCount = 0
var validator Validator
for {
if !iterator.Valid() || bondedValidatorsCount > int(maxValidators-1) {
@ -282,7 +270,7 @@ updateBondedValidators(newValidator Validator) (updatedVal Validator)
// use the validator provided because it has not yet been updated
// in the main validator store
ownerAddr := iterator.Value()
ownerAddr = iterator.Value()
if bytes.Equal(ownerAddr, newValidator.Owner) {
validator = newValidator
else
@ -290,7 +278,7 @@ updateBondedValidators(newValidator Validator) (updatedVal Validator)
// if not previously a validator (and unrevoked),
// kick the cliff validator / bond this new validator
if validator.Status() != sdk.Bonded && !validator.Revoked {
if validator.Status() != Bonded && !validator.Revoked {
kickCliffValidator = true
validator = bondValidator(ctx, store, validator)
@ -302,16 +290,16 @@ updateBondedValidators(newValidator Validator) (updatedVal Validator)
// perform the actual kicks
if oldCliffValidatorAddr != nil && kickCliffValidator {
validator := getValidator(store, oldCliffValidatorAddr)
validator = getValidator(store, oldCliffValidatorAddr)
unbondValidator(ctx, store, validator)
return
// perform all the store operations for when a validator status becomes unbonded
unbondValidator(ctx sdk.Context, store sdk.KVStore, validator Validator)
pool := GetPool(ctx)
unbondValidator(ctx Context, store KVStore, validator Validator)
pool = GetPool(ctx)
// set the status
validator, pool = validator.UpdateStatus(pool, sdk.Unbonded)
validator, pool = validator.UpdateStatus(pool, Unbonded)
setPool(ctx, pool)
// save the now unbonded validator record
@ -325,11 +313,11 @@ unbondValidator(ctx sdk.Context, store sdk.KVStore, validator Validator)
}
// perform all the store operations for when a validator status becomes bonded
bondValidator(ctx sdk.Context, store sdk.KVStore, validator Validator) Validator
pool := GetPool(ctx)
bondValidator(ctx Context, store KVStore, validator Validator) Validator
pool = GetPool(ctx)
// set the status
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
validator, pool = validator.UpdateStatus(pool, Bonded)
setPool(ctx, pool)
// save the now bonded validator record to the three referenced stores