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

@ -67,6 +67,7 @@ type Validator struct {
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
@ -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
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
}