cosmos-sdk/docs/spec/auth/vesting.md

100 lines
4.0 KiB
Markdown
Raw Normal View History

2018-07-27 18:35:21 -07:00
## Vesting
### Intro and Requirements
This paper specifies changes to the auth and bank modules to implement vested accounts for the Cosmos Hub.
The requirements for this vested account is that it should be capable of being initialized during genesis with
2018-07-30 13:25:44 -07:00
a starting balance X coins and a vesting blocktime T. The owner of this account should be able to delegate to validators and vote,
2018-07-29 19:35:23 -07:00
however they cannot send their coins to other accounts until the account has fully vested. Thus, the bank module's `MsgSend` handler
2018-07-30 13:25:44 -07:00
should error if a vested account is trying to send an amount before time T.
2018-07-27 18:35:21 -07:00
### Implementation
##### Changes to x/auth Module
2018-07-29 19:35:23 -07:00
The `Account` interface will specify both the Account type and any parameters it needs.
2018-07-27 18:35:21 -07:00
```go
// Account is a standard account using a sequence number for replay protection
// and a pubkey for authentication.
type Account interface {
Type() string // returns the type of the account
GetAddress() sdk.AccAddress
SetAddress(sdk.AccAddress) error // errors if already set.
GetPubKey() crypto.PubKey // can return nil.
SetPubKey(crypto.PubKey) error
GetAccountNumber() int64
SetAccountNumber(int64) error
GetSequence() int64
SetSequence(int64) error
GetCoins() sdk.Coins
SetCoins(sdk.Coins) error
// Getter and setter methods for account params
2018-07-30 13:25:44 -07:00
// Parameters can be understood to be a map[string]interface{} with encoded keys and vals in store
2018-07-27 18:35:21 -07:00
// It is upto handler to use these appropriately
2018-07-30 13:25:44 -07:00
GetParams([]byte) []byte
SetParams([]byte, []byte) error
2018-07-27 18:35:21 -07:00
}
```
The `Type` method will allow handlers to determine what type of account is sending the message, and the
handler can then call `GetParams` to handle the specific account type using the parameters it expects to
exist in the parameter map.
The `VestedAccount` will be an implementation of `Account` interface that wraps `BaseAccount` with
2018-07-30 13:25:44 -07:00
`Type() => "vested` and params, `GetParams() => {"TimeLock": N (int64)}`.
2018-07-29 19:29:54 -07:00
`SetParams` will be disabled as we do not want to update params after vested account initialization.
2018-07-27 18:35:21 -07:00
2018-07-29 19:29:54 -07:00
`auth.AccountMapper` will be modified handle vested accounts as well. Specific changes
2018-07-27 18:35:21 -07:00
are omitted in this doc for succinctness.
##### Changes to bank MsgSend Handler
Since a vested account should be capable of doing everything but sending, the restriction should be
handled at the `bank.Keeper` level. Specifically in methods that are explicitly used for sending like
`sendCoins` and `inputOutputCoins`. These methods must check an account's `Type` method; if it is a vested
account (i.e. `acc.Type() == "vested"`):
2018-07-30 13:25:44 -07:00
1. Check if `ctx.BlockHeader().Time < acc.GetParams()["BlockLock"]`
2018-07-29 19:29:54 -07:00
2. If `true`, the account is still vesting, return sdk.Error. Else, allow transaction to be processed as normal.
2018-07-27 18:35:21 -07:00
### Initializing at Genesis
2018-07-29 19:29:54 -07:00
To initialize both vested accounts and base accounts, the `GenesisAccount` struct will be:
```go
type GenesisAccount struct {
2018-07-30 13:25:44 -07:00
Address sdk.AccAddress `json:"address"`
Coins sdk.Coins `json:"coins"`
Type string `json:"type"`
TimeLock int64 `json:"lock"`
2018-07-29 19:29:54 -07:00
}
```
During `InitChain`, the GenesisAccount's are decoded. If they have `Type == "vested`, a vested account with parameters =>
2018-07-30 13:25:44 -07:00
`{"TimeLock": N}` gets created and put in initial state. Otherwise if `Type == "base"` a base account is created
and the `TimeLock` attribute of corresponding `GenesisAccount` is ignored. `InitChain` will panic on any other account types.
2018-07-29 19:29:54 -07:00
2018-07-27 18:35:21 -07:00
### Pros and Cons
##### Pros
- Easily Extensible. If more account types need to get added in the future or if developers building on top of SDK
want to handle multiple custom account types, they simply have to implement the `Account` interface with unique `Type`
and their custom parameters.
- Handlers (and their associated keepers) get to determine what types of accounts they will handle and can use the parameters
in Account interface to handle different accounts appropriately.
##### Cons
- Changes to `Account` interface
- Slightly more complex code in `bank.Keeper` functions