From ab028a780570caeedefd5786f10ece2513539519 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 13 Jun 2018 21:58:36 -0700 Subject: [PATCH] cwgoes comments, improved pseudocode --- docs/guides/sdk/key-management.md | 14 +------ docs/guides/staking/overview.md | 65 ++++++++++++++++--------------- docs/spec/README.md | 2 +- docs/spec/staking/state.md | 12 ++++++ docs/spec/staking/transactions.md | 58 +++++++++++---------------- 5 files changed, 72 insertions(+), 79 deletions(-) diff --git a/docs/guides/sdk/key-management.md b/docs/guides/sdk/key-management.md index a4c0f55012..1474989b93 100644 --- a/docs/guides/sdk/key-management.md +++ b/docs/guides/sdk/key-management.md @@ -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) diff --git a/docs/guides/staking/overview.md b/docs/guides/staking/overview.md index 570a0bfc59..79033fe1ea 100644 --- a/docs/guides/staking/overview.md +++ b/docs/guides/staking/overview.md @@ -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 diff --git a/docs/spec/README.md b/docs/spec/README.md index 7f773e6aa3..b115e0d45b 100644 --- a/docs/spec/README.md +++ b/docs/spec/README.md @@ -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 diff --git a/docs/spec/staking/state.md b/docs/spec/staking/state.md index 82a22dc652..1cfe4b26e6 100644 --- a/docs/spec/staking/state.md +++ b/docs/spec/staking/state.md @@ -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 diff --git a/docs/spec/staking/transactions.md b/docs/spec/staking/transactions.md index 11edbb98bc..91df029c9a 100644 --- a/docs/spec/staking/transactions.md +++ b/docs/spec/staking/transactions.md @@ -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