spec complete unbonding, redelegation txs

This commit is contained in:
rigelrozanski 2018-05-29 16:03:13 -04:00
parent e39ba70c08
commit 25ae026958
3 changed files with 120 additions and 70 deletions

View File

@ -10,22 +10,22 @@ information, etc.
```golang
type Pool struct {
LooseUnbondedTokens int64 // tokens not associated with any validator
UnbondedTokens int64 // reserve of unbonded tokens held with validators
UnbondingTokens int64 // tokens moving from bonded to unbonded pool
BondedTokens int64 // reserve of bonded tokens
UnbondedShares sdk.Rat // sum of all shares distributed for the Unbonded Pool
UnbondingShares sdk.Rat // shares moving from Bonded to Unbonded Pool
BondedShares sdk.Rat // sum of all shares distributed for the Bonded Pool
InflationLastTime int64 // block which the last inflation was processed // TODO make time
Inflation sdk.Rat // current annual inflation rate
LooseUnbondedTokens int64 // tokens not associated with any validator
UnbondedTokens int64 // reserve of unbonded tokens held with validators
UnbondingTokens int64 // tokens moving from bonded to unbonded pool
BondedTokens int64 // reserve of bonded tokens
UnbondedShares sdk.Rat // sum of all shares distributed for the Unbonded Pool
UnbondingShares sdk.Rat // shares moving from Bonded to Unbonded Pool
BondedShares sdk.Rat // sum of all shares distributed for the Bonded Pool
InflationLastTime int64 // block which the last inflation was processed // TODO make time
Inflation sdk.Rat // current annual inflation rate
DateLastCommissionReset int64 // unix timestamp for last commission accounting reset (daily)
}
type PoolShares struct {
Status sdk.BondStatus // either: unbonded, unbonding, or bonded
Amount sdk.Rat // total shares of type ShareKind
Status sdk.BondStatus // either: unbonded, unbonding, or bonded
Amount sdk.Rat // total shares of type ShareKind
}
```
@ -37,13 +37,13 @@ overall functioning of the stake module.
```golang
type Params struct {
InflationRateChange sdk.Rat // maximum annual change in inflation rate
InflationMax sdk.Rat // maximum inflation rate
InflationMin sdk.Rat // minimum inflation rate
GoalBonded sdk.Rat // Goal of percent bonded atoms
InflationRateChange sdk.Rat // maximum annual change in inflation rate
InflationMax sdk.Rat // maximum inflation rate
InflationMin sdk.Rat // minimum inflation rate
GoalBonded sdk.Rat // Goal of percent bonded atoms
MaxValidators uint16 // maximum number of validators
BondDenom string // bondable coin denomination
MaxValidators uint16 // maximum number of validators
BondDenom string // bondable coin denomination
}
```
@ -65,27 +65,28 @@ type Validator struct {
ConsensusPubKey crypto.PubKey // Tendermint consensus pubkey of validator
Revoked bool // has the validator been revoked?
PoolShares PoolShares // total shares for tokens held in the pool
DelegatorShares sdk.Rat // total shares issued to a validator's delegators
PoolShares PoolShares // total shares for tokens held in the pool
DelegatorShares sdk.Rat // total shares issued to a validator's delegators
SlashRatio sdk.Rat // increases each time the validator is slashed
Description Description // description terms for the validator
BondHeight int64 // earliest height as a bonded validator
BondIntraTxCounter int16 // block-local tx index of validator change
ProposerRewardPool sdk.Coins // reward pool collected from being the proposer
Description Description // description terms for the validator
BondHeight int64 // earliest height as a bonded validator
BondIntraTxCounter int16 // block-local tx index of validator change
ProposerRewardPool sdk.Coins // reward pool collected from being the proposer
Commission sdk.Rat // the commission rate of fees charged to any delegators
CommissionMax sdk.Rat // maximum commission rate which this validator can ever charge
CommissionChangeRate sdk.Rat // maximum daily increase of the validator commission
CommissionChangeToday sdk.Rat // commission rate change today, reset each day (UTC time)
PrevPoolShares PoolShares // total shares of a global hold pools
PrevPoolShares PoolShares // total shares of a global hold pools
}
type Description struct {
Moniker string // name
Identity string // optional identity signature (ex. UPort or Keybase)
Website string // optional website link
Details string // optional details
Moniker string // name
Identity string // optional identity signature (ex. UPort or Keybase)
Website string // optional website link
Details string // optional details
}
```
@ -99,10 +100,10 @@ the transaction is the owner of the bond.
```golang
type Delegation struct {
DelegatorAddr sdk.Address // delegation owner address
ValidatorAddr sdk.Address // validator owner address
Shares sdk.Rat // delegation shares recieved
Height int64 // last height bond updated
DelegatorAddr sdk.Address // delegation owner address
ValidatorAddr sdk.Address // validator owner address
Shares sdk.Rat // delegation shares recieved
Height int64 // last height bond updated
}
```
@ -110,17 +111,16 @@ type Delegation struct {
- index: delegation address
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.
The unbond must be completed with a second transaction provided by the
delegation owner after the unbonding period has passed.
```golang
type UnbondingDelegation struct {
DelegationKey []byte // key of the delegation
InitTime int64 // unix time at unbonding initation
InitHeight int64 // block height at unbonding initation
ExpectedTokens sdk.Coins // the value in Atoms of the amount of shares which are unbonding
StartSlashRatio sdk.Rat // validator slash ratio at unbonding initiation
DelegationKey sdk.Address // key of the delegation
ExpectedTokens sdk.Coins // the value in Atoms of the amount of shares which are unbonding
StartSlashRatio sdk.Rat // validator slash ratio at unbonding initiation
CompleteTime int64 // unix time to complete redelegation
CompleteHeight int64 // block height to complete redelegation
}
```
@ -135,13 +135,14 @@ 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.
```golang
type Redelegation struct {
SourceDelegation []byte // source delegation key
DestinationDelegation []byte // destination delegation key
InitTime int64 // unix time at redelegation
InitHeight int64 // block height at redelegation
Shares sdk.Rat // amount of shares redelegating
SourceDelegation sdk.Address // source delegation key
DestinationDelegation sdk.Address // destination delegation key
SourceShares sdk.Rat // amount of source shares redelegating
DestinationShares sdk.Rat // amount of destination shares created at redelegation
SourceStartSlashRatio sdk.Rat // source validator slash ratio at unbonding initiation
CompleteTime int64 // unix time to complete redelegation
CompleteHeight int64 // block height to complete redelegation
}
```

View File

@ -6,8 +6,10 @@ corresponding updates to the state. Transactions:
- TxCreateValidator
- TxEditValidator
- TxDelegation
- TxRedelegation
- TxUnbond
- TxStartUnbonding
- TxCompleteUnbonding
- TxRedelegate
- TxCompleteRedelegation
Other important state changes:
- Update Validators
@ -109,43 +111,41 @@ delegate(tx TxDelegate):
return
```
### TxUnbond
### TxStartUnbonding
Delegator unbonding is defined with the following transaction:
```golang
type TxUnbond struct {
type TxStartUnbonding struct {
DelegatorAddr sdk.Address
ValidatorAddr sdk.Address
Shares string
}
unbond(tx TxUnbond):
startUnbonding(tx TxStartUnbonding):
delegation, found = getDelegatorBond(store, sender, tx.PubKey)
if !found == nil return
if msg.Shares == "MAX" {
if tx.Shares == "MAX" {
if !bond.Shares.GT(sdk.ZeroRat()) {
return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result()
return ErrNotEnoughBondShares
else
var err sdk.Error
delShares, err = sdk.NewRatFromDecimal(msg.Shares)
delShares, err = sdk.NewRatFromDecimal(tx.Shares)
if err != nil
return err
if bond.Shares.LT(delShares)
return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result()
return ErrNotEnoughBondShares
validator, found := k.GetValidator(ctx, msg.ValidatorAddr)
validator, found := GetValidator(tx.ValidatorAddr)
if !found {
return err
if msg.Shares == "MAX"
if tx.Shares == "MAX"
delShares = bond.Shares
bond.Shares -= delShares
unbondingDelegation = NewUnbondingDelegation(sender, delShares, currentHeight/Time, startSlashRatio)
setUnbondingDelegation(unbondingDelegation)
revokeCandidacy := false
if bond.Shares.IsZero() {
@ -153,30 +153,55 @@ unbond(tx TxUnbond):
if bond.DelegatorAddr == validator.Owner && validator.Revoked == false
revokeCandidacy = true
k.removeDelegation(ctx, bond)
removeDelegation( bond)
else
bond.Height = currentBlockHeight
setDelegation(bond)
pool := k.GetPool(ctx)
pool := GetPool()
validator, pool, returnAmount := validator.removeDelShares(pool, delShares)
k.setPool(ctx, pool)
AddCoins(ctx, bond.DelegatorAddr, returnAmount)
setPool( pool)
unbondingDelegation = NewUnbondingDelegation(sender, returnAmount, currentHeight/Time, startSlashRatio)
setUnbondingDelegation(unbondingDelegation)
if revokeCandidacy
validator.Revoked = true
validator = updateValidator(ctx, validator)
validator = updateValidator(validator)
if validator.DelegatorShares == 0 {
removeValidator(ctx, validator.Owner)
removeValidator(validator.Owner)
return
```
### TxCompleteUnbonding
Complete the unbonding and transfer the coins to the delegate. Perform any
slashing that occured during the unbonding period.
```golang
type TxUnbondingComplete struct {
DelegatorAddr sdk.Address
ValidatorAddr sdk.Address
}
redelegationComplete(tx TxRedelegate):
unbonding = getUnbondingDelegation(tx.DelegatorAddr, tx.Validator)
if unbonding.CompleteTime >= CurrentBlockTime && unbonding.CompleteHeight >= CurrentBlockHeight
validator = GetValidator(tx.ValidatorAddr)
returnTokens = ExpectedTokens * tx.startSlashRatio/validator.SlashRatio
AddCoins(unbonding.DelegatorAddr, returnTokens)
removeUnbondingDelegation(unbonding)
return
```
### TxRedelegation
The redelegation command allows delegators to instantly switch validators.
The redelegation command allows delegators to instantly switch validators. Once
the unbonding period has passed, the redelegation must be completed with
txRedelegationComplete.
```golang
type TxRedelegate struct {
@ -184,23 +209,48 @@ type TxRedelegate struct {
ValidatorFrom Validator
ValidatorTo Validator
Shares sdk.Rat
CompletedTime int64
}
redelegate(tx TxRedelegate):
pool = getPool()
delegation = getDelegatorBond(tx.DelegatorAddr, tx.ValidatorFrom.Owner)
if delegation == nil then return
if delegation == nil
return
if delegation.Shares < tx.Shares return
if delegation.Shares < tx.Shares
return
delegation.shares -= Tx.Shares
validator, pool, createdCoins = validator.RemoveShares(pool, tx.Shares)
setPool(pool)
redelegation = newRedelegation(validatorFrom, validatorTo, Shares, createdCoins)
redelegation = newRedelegation(tx.DelegatorAddr, tx.validatorFrom,
tx.validatorTo, tx.Shares, createdCoins, tx.CompletedTime)
setRedelegation(redelegation)
return
```
### TxCompleteRedelegation
Note that unlike TxCompleteUnbonding slashing of redelegating shares does not
take place during completion. Slashing on redelegated shares takes place
actively as a slashing occurs.
```golang
type TxRedelegationComplete struct {
DelegatorAddr Address
ValidatorFrom Validator
ValidatorTo Validator
}
redelegationComplete(tx TxRedelegate):
redelegation = getRedelegation(tx.DelegatorAddr, tx.validatorFrom, tx.validatorTo)
if redelegation.CompleteTime >= CurrentBlockTime && redelegation.CompleteHeight >= CurrentBlockHeight
removeRedelegation(redelegation)
return
```
### Update Validators
Within many transactions the validator set must be updated based on changes in

View File

@ -49,5 +49,4 @@ func (b Delegation) HumanReadableString() (string, error) {
resp += fmt.Sprintf("Height: %d", b.Height)
return resp, nil
}