PlantUML diagrams (#8712)
* Overview of keepers in object capability model (OCM) * Updates to the spec, making clarifications * Create a sequence diagram of a (fresh) delegation * Misc notes, not yet decided where to put them * Description of the shares abstraction in validators * Model all keeper dependencies and move the UML file to docs * Move and rename delegation sequence diagram * Move shares description * Remove TODO * Diagram touch-ups * Add how consensus power is calculated * remove temp file * Diagram improvements * Describe slashing in more detail * Describe redelegation * Describe unbonding * Delegation updates * Delegation updates * Make a diagram describing overall transaction flow * Add delegation flows for the events of tokens being bonded/unbonding/etc. * Grammar fix * Diagram updates: distinguish alts, remove numbering. * Use groups instead of "func:" participants * Remove unused keepers from dependency diagram * Add title to unbonding diagram * Move keeper dependencies * small doc updates * remove numbers on sequence diagram * !!!WIP EndBlock * Explain "Last"-prefix in storage * Remove `panic` step (they are supposed to never happen) * EndBlock sequence diagram (with TODOs) * Add TODO * More visible TODOs * Remove numbering * Complete EndBlock * Remove numbering * Remove TODOs and update title * add title back * remove endblock seq-diagram * Make power index update conditional on not being jailed * update title * Move files to /docs * Install PlantUML and compile images to png and txt * Use transaction flow in documentation * Use staking UML in staking docs * Clarify uml with inline doc * Add keeper deps diagram to docs * Only produce SVG images Co-authored-by: hjort <> Co-authored-by: Marko <marbar3778@yahoo.com>
This commit is contained in:
parent
ed7bca8984
commit
c41baa9bc8
@ -13,7 +13,7 @@
|
||||
FROM golang:alpine AS build-env
|
||||
|
||||
# Install minimum necessary dependencies,
|
||||
ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3
|
||||
ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3 plantuml
|
||||
RUN apk add --no-cache $PACKAGES
|
||||
|
||||
# Set working directory for the build
|
||||
|
||||
@ -54,6 +54,10 @@ This method takes care of marshaling the `res` parameter to protobuf and attachi
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/base/abci/v1beta1/abci.proto#L81-L95
|
||||
|
||||
This diagram shows a typical structure of an `Msg` Service, and how the message propagates through the module.
|
||||
|
||||

|
||||
|
||||
## Legacy Amino `Msg`s
|
||||
|
||||
### `handler` type
|
||||
|
||||
@ -70,6 +70,10 @@ gaia app.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.41.4/simapp/app.go#L249-L273
|
||||
|
||||
The following diagram shows the current dependencies between keepers.
|
||||
|
||||

|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn about the [`runTx` middleware](./runtx_middleware.md) {hide}
|
||||
|
||||
@ -9,4 +9,6 @@ for D in ../x/*; do
|
||||
fi
|
||||
done
|
||||
|
||||
cat ../x/README.md | sed 's/\.\/x/\/modules/g' | sed 's/spec\/README.md//g' | sed 's/\.\.\/docs\/building-modules\/README\.md/\/building-modules\/intro\.html/g' > ./modules/README.md
|
||||
cat ../x/README.md | sed 's/\.\/x/\/modules/g' | sed 's/spec\/README.md//g' | sed 's/\.\.\/docs\/building-modules\/README\.md/\/building-modules\/intro\.html/g' > ./modules/README.md
|
||||
|
||||
plantuml -tsvg uml/*.puml
|
||||
|
||||
50
docs/uml/begin_redelegation_sequence.puml
Normal file
50
docs/uml/begin_redelegation_sequence.puml
Normal file
@ -0,0 +1,50 @@
|
||||
@startuml
|
||||
'https://plantuml.com/sequence-diagram
|
||||
|
||||
title: Redelegation
|
||||
|
||||
msgServer -> keeper : BeginRedelegation(delAddr, valSrcAddr, valDstAddr, sharesAmount)
|
||||
participant "keeper (staking)" as keeper
|
||||
keeper -> keeper : get number of sharew
|
||||
note left: If the delegator has more shares than the total shares in the validator\n(due to rounding errors), then just withdraw the max number of shares.
|
||||
keeper -> keeper : check the redelegation uses correct denom
|
||||
|
||||
alt valSrcAddr == valDstAddr
|
||||
keeper --> msgServer : error
|
||||
end
|
||||
alt transitive redelegation
|
||||
keeper --> msgServer : error
|
||||
end
|
||||
alt already has max redelegations
|
||||
keeper --> msgServer : error
|
||||
note left : this is the number of redelegations for a specific (del, valSrc, valDst) triple\ndefault : 7
|
||||
end
|
||||
|
||||
|
||||
keeper -> keeper : Unbond(del, valSrc) returns returnAmount
|
||||
...
|
||||
note left : See unbonding diagram
|
||||
|
||||
alt returnAmount is zero
|
||||
keeper -> msgServer : error
|
||||
end
|
||||
|
||||
keeper -> keeper : Delegate(del, returnAmount, status := valSrc.status, valDst, subtractAccount := false)
|
||||
note left : See delegation diagram
|
||||
...
|
||||
|
||||
alt validator is unbonded
|
||||
keeper -> msgServer : current time
|
||||
end
|
||||
|
||||
alt unbonding not complete, or just started
|
||||
database store
|
||||
keeper -> store : create redelegation object
|
||||
keeper -> store : insert redelegation in queue, to be processed at the appropriate time
|
||||
end
|
||||
|
||||
msgServer <-- keeper : completion time of the redelegation
|
||||
msgServer -> msgServer : emit event: delegator, valSrc, valSrc,\nsharesAmount, completionTime
|
||||
|
||||
@enduml
|
||||
|
||||
93
docs/uml/delegation_sequence.puml
Normal file
93
docs/uml/delegation_sequence.puml
Normal file
@ -0,0 +1,93 @@
|
||||
@startuml
|
||||
'https://plantuml.com/sequence-diagram
|
||||
|
||||
title: Delegating (currently undelegated funds delegator)
|
||||
|
||||
participant "msgServer (staking)"
|
||||
participant "keeper (staking)" as keeper
|
||||
participant validator
|
||||
participant keeper.bankKeeper
|
||||
participant vestingAccount
|
||||
participant ctx.EventManager
|
||||
|
||||
database store
|
||||
|
||||
"msgServer (staking)" -> keeper : Delegate(Context, DelegatorAddress, Amount, Validator, tokenSrc := Unbonded)
|
||||
|
||||
alt exchange rate is invalid (tokens in validator is 0)
|
||||
keeper --> "msgServer (staking)" : error
|
||||
end
|
||||
|
||||
alt perform a new delegation
|
||||
keeper -> keeper : delegation := create delegation object
|
||||
keeper -> keeper : BeforeDelegationCreated hook
|
||||
note left: Calls IncrementValidatorPeriod (Used to calculate distribution) in keeper/validator.go
|
||||
else delegation exists, more tokens being added
|
||||
keeper -> keeper : BeforeDelegationModified hook
|
||||
note left: withdraw current delegation rewards (and increment period)
|
||||
end
|
||||
|
||||
alt delegating from an account (subtractTokens == true)
|
||||
keeper -> keeper.bankKeeper : DelegateCoinsFromAccountToModule
|
||||
group DelegateCoinsFromAccountToModule function
|
||||
keeper.bankKeeper -> keeper.bankKeeper : DelegateCoinsFromAccountToModule
|
||||
keeper.bankKeeper -> keeper.bankKeeper : DelegateCoins
|
||||
group DelegateCoins function
|
||||
keeper.bankKeeper --> keeper.bankKeeper : Check the delegator has enough balances of all tokens delegated
|
||||
keeper.bankKeeper --> keeper.bankKeeper : Track delegation (register that it exists to keep track of it)
|
||||
alt validator is currently bonded
|
||||
keeper.bankKeeper --> store : Transfer tokens from delegator to BondedTokensPool.
|
||||
else validator is currently unbonded or unbonding
|
||||
keeper.bankKeeper --> store : Transfer tokens from delegator to NotBondedTokensPool.
|
||||
end
|
||||
group trackDelegation function
|
||||
keeper.bankKeeper -> keeper.bankKeeper : trackDelegation
|
||||
alt delegator is a vesting account
|
||||
keeper.bankKeeper -> vestingAccount : keep track of this delegation
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
keeper <-- keeper.bankKeeper : nil (success)
|
||||
else moving tokens between pools (subtractTokens == false)
|
||||
alt delegator tokens are not bonded but validator is bonded
|
||||
keeper -> keeper.bankKeeper : SendCoinsFromModuleToModule(notBondedPool, bondedPool, coins)
|
||||
else delegator tokens are bonded but validator is not bonded
|
||||
keeper -> keeper.bankKeeper : SendCoinsFromModuleToModule(bondedPool, notBondedPool, coins)
|
||||
end
|
||||
group SendCoins function
|
||||
keeper.bankKeeper -> keeper.bankKeeper : SendCoins
|
||||
keeper.bankKeeper -> ctx.EventManager : Emit TransferEvent(to, from, amount)
|
||||
alt amount of spendable (balance - locked) coins too low
|
||||
keeper <-- keeper.bankKeeper : error
|
||||
end
|
||||
keeper.bankKeeper -> store : subtract balance from sender
|
||||
keeper.bankKeeper -> store : add balance to recipient
|
||||
end
|
||||
end
|
||||
|
||||
keeper -> validator : AddTokensFromDel
|
||||
validator -> validator : calculate number of shares to issue
|
||||
note left: If there are no shares (validator being created) then 1 token = 1 share.\nIf there are already shares, then\nadded shares = (added tokens amount) * (current validator shares) / (current validator tokens)
|
||||
|
||||
validator -> validator : add delegated tokens to validator
|
||||
keeper <-- validator : validator, addedShares
|
||||
keeper -> store : update validator state
|
||||
keeper -> keeper: calculate new validator's power
|
||||
note left : Number of tokens divided by PowerReduction (default: 1,000,000,000,000,000,000 = 10^18)
|
||||
alt validator is not jailed
|
||||
keeper -> store : update validator's power in power index
|
||||
note left : the power index has entries shaped as 35 || power || address.\nThis makes the validators sorted by power, high to low.
|
||||
end
|
||||
|
||||
keeper -> keeper : AfterDelegationModified hook
|
||||
note left: Calls initializeDelegation\nStore the previous period\nCalculate the number of tokens from shares\n(shares the delegator has) * (tokens in delegation object)/(total tokens delegated to the validator)\nStore delegation starting info.
|
||||
"msgServer (staking)" <-- keeper : newShares (ignored by Delegate function)
|
||||
|
||||
|
||||
"msgServer (staking)" -> "msgServer (staking)" : Emit event: Delegation(ValidatorAddress)
|
||||
"msgServer (staking)" -> "msgServer (staking)" : Emit event: Message(DelegatorAddress)
|
||||
"msgServer (staking)" -> "msgServer (staking)" : telemetry(Amount, Denom)
|
||||
|
||||
@enduml
|
||||
|
||||
36
docs/uml/keeper_dependencies.puml
Normal file
36
docs/uml/keeper_dependencies.puml
Normal file
@ -0,0 +1,36 @@
|
||||
@startuml
|
||||
'https://plantuml.com/class-diagram
|
||||
|
||||
title: The dependencies between Keepers (Feb 2021)
|
||||
|
||||
abstract class Staking
|
||||
abstract class Distribution
|
||||
abstract class Slashing
|
||||
abstract class Evidence
|
||||
abstract class Bank
|
||||
abstract class "Auth/Account" as Auth
|
||||
abstract class Gov
|
||||
abstract class Mint
|
||||
|
||||
Staking <|-- Mint
|
||||
Bank <|-- Mint
|
||||
|
||||
Staking <|-- Gov
|
||||
Bank <|-- Gov
|
||||
Auth <|-- Gov
|
||||
|
||||
Auth <|-- Bank
|
||||
|
||||
Bank <|-- Distribution
|
||||
Auth <|-- Distribution
|
||||
Staking <|-- Distribution
|
||||
|
||||
Staking <|-- Evidence
|
||||
Slashing <|-- Evidence
|
||||
|
||||
Staking <|-- Slashing
|
||||
|
||||
Auth <|-- Staking
|
||||
Bank <|-- Staking
|
||||
|
||||
@enduml
|
||||
22
docs/uml/transaction_flow.puml
Normal file
22
docs/uml/transaction_flow.puml
Normal file
@ -0,0 +1,22 @@
|
||||
What happens after a transaction is unmarshalled and is processed by the SDK?
|
||||
|
||||
@startuml
|
||||
'https://plantuml.com/sequence-diagram
|
||||
|
||||
actor User
|
||||
User -> baseApp : Transaction Type<Tx>
|
||||
baseApp -> router : Route(ctx, msgRoute)
|
||||
router --> baseApp : handler
|
||||
baseApp -> handler: Msg<Tx>(Context, Msg(...))
|
||||
handler -> msgServer : <Tx>(Context, Msg)
|
||||
alt addresses invalid, denominations wrong, etc.
|
||||
msgServer --> handler : error
|
||||
end
|
||||
msgServer -> keeper : perform action, update context
|
||||
keeper --> msgServer : results, error code
|
||||
msgServer -> Context.EventManager : Emit relevant events
|
||||
msgServer -> msgServer : maybe wrap results in more structure
|
||||
msgServer --> handler : result, error code
|
||||
baseApp <-- handler : results, error code
|
||||
|
||||
@enduml
|
||||
51
docs/uml/unbond_sequence.puml
Normal file
51
docs/uml/unbond_sequence.puml
Normal file
@ -0,0 +1,51 @@
|
||||
@startuml
|
||||
'https://plantuml.com/sequence-diagram
|
||||
|
||||
title: Undelegate
|
||||
|
||||
msgServer -> keeper : Undelegate(delAddr, valAddr, tokenAmount)
|
||||
|
||||
keeper -> keeper : calculate number of shares the tokenAmount represents
|
||||
|
||||
alt wrong denom
|
||||
msgServer <-- keeper : error
|
||||
end
|
||||
|
||||
group Unbond(delAddr, valAddr, shares)
|
||||
keeper -> keeper: BeforeDelegationSharesModified hook
|
||||
alt no such delegation
|
||||
keeper --> msgServer : error
|
||||
end
|
||||
alt not enough shares
|
||||
keeper --> msgServer : error
|
||||
end
|
||||
alt delegator is the operator of the validator\nand validator is not already jailed\nand unbonding would put self-delegation under min threshold
|
||||
keeper -> keeper : jail the validator, but proceed with unbonding
|
||||
note left : Default min delegation threshold : 1 share
|
||||
end
|
||||
|
||||
database store
|
||||
|
||||
alt complete unbonding, all shares removed
|
||||
keeper -> store : remove delegation object
|
||||
else there are still shares delegated (not a complete undbonding)
|
||||
keeper -> store : update delegation object
|
||||
keeper -> keeper : AfterDelegationModified hook
|
||||
end
|
||||
|
||||
keeper -> store : update validator power index
|
||||
keeper -> store : update validator information (including token amount)
|
||||
|
||||
alt validator status is "unbonded" and it has no more tokens
|
||||
keeper -> store : delete the validator
|
||||
note right : otherwise, do this in EndBlock once validator is unbonded
|
||||
end
|
||||
end
|
||||
|
||||
alt validator is bonded
|
||||
keeper -> bankKeeper : send tokens from bonded pool to not bonded pool
|
||||
end
|
||||
|
||||
msgServer -> msgServer : emit event : EventTypeUnbond(delAddr, valAddr, tokenAmount, completion time)
|
||||
|
||||
@enduml
|
||||
@ -80,6 +80,8 @@ tracked in validator object in the `Validators` index.
|
||||
It is possible to delegate to a jailed validator, the only difference being it
|
||||
will not be added to the power index until it is unjailed.
|
||||
|
||||

|
||||
|
||||
## Msg/Undelegate
|
||||
|
||||
The `Msg/Undelegate` service message allows delegators to undelegate their tokens from
|
||||
@ -112,6 +114,8 @@ When this service message is processed the following actions occur:
|
||||
- if there are no more `Shares` in the delegation, then the delegation object is removed from the store
|
||||
- under this situation if the delegation is the validator's self-delegation then also jail the validator.
|
||||
|
||||

|
||||
|
||||
## Msg/BeginRedelegate
|
||||
|
||||
The redelegation command allows delegators to instantly switch validators. Once
|
||||
@ -146,3 +150,5 @@ When this service message is processed the following actions occur:
|
||||
- Delegate the token worth to the destination validator, possibly moving tokens back to the bonded state.
|
||||
- if there are no more `Shares` in the source delegation, then the source delegation object is removed from the store
|
||||
- under this situation if the delegation is the validator's self-delegation then also jail the validator.
|
||||
|
||||

|
||||
|
||||
Loading…
Reference in New Issue
Block a user