Merge branch 'develop' into cwgoes/slashing-period-spec

This commit is contained in:
Christopher Goes
2018-08-22 18:29:38 +02:00
165 changed files with 5246 additions and 18419 deletions
+1 -1
View File
@@ -6,6 +6,6 @@
- [ ] 4. Summarize breaking API changes section under “Breaking Changes” section to the `CHANGELOG.md` to bring attention to any breaking API changes that affect RPC consumers.
- [ ] 5. Tag the commit `{{ .Release.Name }}-rcN`
- [ ] 6. Kick off 1 day of automated fuzz testing
- [ ] 7. Release Lead assigns 2 people to perform buddy testing script
- [ ] 7. Release Lead assigns 2 people to perform [buddy testing script](/docs/RELEASE_TEST_SCRIPT.md) and update the relevant documentation
- [ ] 8. If errors are found in either #6 or #7 go back to #2 (*NOTE*: be sure to increment the `rcN`)
- [ ] 9. After #6 and #7 have successfully completed then merge the release PR and push the final release tag
+17
View File
@@ -0,0 +1,17 @@
This document should contain plain english instructions for testing functionality on `gaiad`. This “Script” is supposed to be run by 2 people who will each spin up a `gaiad` node and run the series of prompts below.
- [Create a network of 2 nodes](getting-started/create-testnet.md)
- [Generate an account](sdk/clients.md)
- [Send funds from one account to the other](sdk/clients.md)
- [Create a validator](validators/validator-setup.md)
- [Edit a validator](validators/validator-setup.md)
- [Delegate to validator](sdk/clients.md)
- [Unbond from a validator](sdk/clients.md)
- [View validators and verify output](validators/validator-setup.md)
- [Query network status](getting-started/full-node.md)
- [Create a proposal](validators/validator-setup.md)
- [Query a proposal](validators/validator-setup.md)
- [Vote on a proposal](validators/validator-setup.md)
- [Query status of a proposal](validators/validator-setup.md)
- [Query the votes on a proposal](validators/validator-setup.md)
- [Export state and reload](getting-started/create-testnet.md)
+1 -1
View File
@@ -2,7 +2,7 @@ swagger: '2.0'
info:
version: '1.1.0'
title: Gaia-Lite (former LCD) to interface with Cosmos BaseServer via REST
description: Specification for Gaia-lite provided by `gaiacli advanced rest-server`
description: Specification for Gaia-lite provided by `gaiacli rest-server`
tags:
- name: keys
+1 -1
View File
@@ -1,6 +1,6 @@
# REST
See `gaiacli advanced rest-server --help` for more.
See `gaiacli rest-server --help` for more.
Also see the
[work in progress API specification](https://github.com/cosmos/cosmos-sdk/pull/1314)
+27
View File
@@ -0,0 +1,27 @@
## Create your Own Testnet
To create your own testnet, first each validator will need to install gaiad and run gen-tx
```bash
gaiad init gen-tx --name <account_name>
```
This populations `$HOME/.gaiad/gen-tx/` with a json file.
Now these json files need to be aggregated together via Github, a Google form, pastebin or other methods.
Place all files on one computer in `$HOME/.gaiad/gen-tx/`
```bash
gaiad init --gen-txs -o --chain=<chain-name>
```
This will generate a `genesis.json` in `$HOME/.gaiad/config/genesis.json` distribute this file to all validators on your testnet.
### Export state
To export state and reload (useful for testing purposes):
```
gaiad export > genesis.json; cp genesis.json ~/.gaiad/config/genesis.json; gaiad start
```
+193
View File
@@ -0,0 +1,193 @@
# ICS 030: Cosmos Signed Messages
>TODO: Replace with valid ICS number and possibly move to new location.
* [Changelog](#changelog)
* [Abstract](#abstract)
* [Preliminary](#preliminary)
* [Specification](#specification)
* [Future Adaptations](#future-adaptations)
* [API](#api)
* [References](#references)
## Status
Proposed.
## Changelog
## Abstract
Having the ability to sign messages off-chain has proven to be a fundamental aspect
of nearly any blockchain. The notion of signing messages off-chain has many
added benefits such as saving on computational costs and reducing transaction
throughput and overhead. Within the context of the Cosmos, some of the major
applications of signing such data includes, but is not limited to, providing a
cryptographic secure and verifiable means of proving validator identity and
possibly associating it with some other framework or organization. In addition,
having the ability to sign Cosmos messages with a Ledger or similar HSM device.
A standardized protocol for hashing, signing, and verifying messages that can be
implemented by the Cosmos SDK and other third-party organizations is needed. Such a
standardized protocol subscribes to the following:
* Contains a specification of human-readable and machine-verifiable typed structured data
* Contains a framework for deterministic and injective encoding of structured data
* Utilizes cryptographic secure hashing and signing algorithms
* A framework for supporting extensions and domain separation
* Is invulnerable to chosen ciphertext attacks
* Has protection against potentially signing transactions a user did not intend to
This specification is only concerned with the rationale and the standardized
implementation of Cosmos signed messages. It does **not** concern itself with the
concept of replay attacks as that will be left up to the higher-level application
implementation. If you view signed messages in the means of authorizing some
action or data, then such an application would have to either treat this as
idempotent or have mechanisms in place to reject known signed messages.
## Preliminary
The Cosmos message signing protocol will be parameterized with a cryptographic
secure hashing algorithm `SHA-256` and a signing algorithm `S` that contains
the operations `sign` and `verify` which provide a digital signature over a set
of bytes and verification of a signature respectively.
Note, our goal here is not to provide context and reasoning about why necessarily
these algorithms were chosen apart from the fact they are the defacto algorithms
used in Tendermint and the Cosmos SDK and that they satisfy our needs for such
cryptographic algorithms such as having resistance to collision and second
pre-image attacks, as well as being [deterministic](https://en.wikipedia.org/wiki/Hash_function#Determinism) and [uniform](https://en.wikipedia.org/wiki/Hash_function#Uniformity).
## Specification
Tendermint has a well established protocol for signing messages using a canonical
JSON representation as defined [here](https://github.com/tendermint/tendermint/blob/master/types/canonical_json.go).
An example of such a canonical JSON structure is Tendermint's vote structure:
```golang
type CanonicalJSONVote struct {
ChainID string `json:"@chain_id"`
Type string `json:"@type"`
BlockID CanonicalJSONBlockID `json:"block_id"`
Height int64 `json:"height"`
Round int `json:"round"`
Timestamp string `json:"timestamp"`
VoteType byte `json:"type"`
}
```
With such canonical JSON structures, the specification requires that they include
meta fields: `@chain_id` and `@type`. These meta fields are reserved and must be
included. They are both of type `string`. In addition, fields must be ordered
in lexicographically ascending order.
For the purposes of signing Cosmos messages, the `@chain_id` field must correspond
to the Cosmos chain identifier. The user-agent should **refuse** signing if the
`@chain_id` field does not match the currently active chain! The `@type` field
must equal the constant `"message"`. The `@type` field corresponds to the type of
structure the user will be signing in an application. For now, a user is only
allowed to sign bytes of valid ASCII text ([see here](https://github.com/tendermint/tendermint/blob/master/libs/common/string.go#L61-L74)).
However, this will change and evolve to support additional application-specific
structures that are human-readable and machine-verifiable ([see Future Adaptations](#futureadaptations)).
Thus, we can have a canonical JSON structure for signing Cosmos messages using
the [JSON schema](http://json-schema.org/) specification as such:
```json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$id": "cosmos/signing/typeData/schema",
"title": "The Cosmos signed message typed data schema.",
"type": "object",
"properties": {
"@chain_id": {
"type": "string",
"description": "The corresponding Cosmos chain identifier.",
"minLength": 1
},
"@type": {
"type": "string",
"description": "The message type. It must be 'message'.",
"enum": [
"message"
]
},
"text": {
"type": "string",
"description": "The valid ASCII text to sign.",
"pattern": "^[\\x20-\\x7E]+$",
"minLength": 1
}
},
"required": [
"@chain_id",
"@type",
"text"
]
}
```
e.g.
```json
{
"@chain_id": "1",
"@type": "message",
"text": "Hello, you can identify me as XYZ on keybase."
}
```
## Future Adaptations
As applications can vary greatly in domain, it will be vital to support both
domain separation and human-readable and machine-verifiable structures.
Domain separation will allow for application developers to prevent collisions of
otherwise identical structures. It should be designed to be unique per application
use and should directly be used in the signature encoding itself.
Human-readable and machine-verifiable structures will allow end users to sign
more complex structures, apart from just string messages, and still be able to
know exactly what they are signing (opposed to signing a bunch of arbitrary bytes).
Thus, in the future, the Cosmos signing message specification will be expected
to expand upon it's canonical JSON structure to include such functionality.
## API
Application developers and designers should formalize a standard set of APIs that
adhere to the following specification:
-----
### **cosmosSignBytes**
Params:
* `data`: the Cosmos signed message canonical JSON structure
* `address`: the Bech32 Cosmos account address to sign data with
Returns:
* `signature`: the Cosmos signature derived using signing algorithm `S`
-----
### Examples
Using the `secp256k1` as the DSA, `S`:
```javascript
data = {
"@chain_id": "1",
"@type": "message",
"text": "I hereby claim I am ABC on Keybase!"
}
cosmosSignBytes(data, "cosmosaccaddr1pvsch6cddahhrn5e8ekw0us50dpnugwnlfngt3")
> "0x7fc4a495473045022100dec81a9820df0102381cdbf7e8b0f1e2cb64c58e0ecda1324543742e0388e41a02200df37905a6505c1b56a404e23b7473d2c0bc5bcda96771d2dda59df6ed2b98f8"
```
## References
+581 -443
View File
File diff suppressed because it is too large Load Diff
+249 -29
View File
@@ -12,27 +12,25 @@
`gaiacli` is the command line interface to manage accounts and transactions on Cosmos testnets. Here is a list of useful `gaiacli` commands, including usage examples.
### Key Types
### Keys
#### Key Types
There are three types of key representations that are used:
- `cosmosaccaddr`
- Derived from account keys generated by `gaiacli keys add`
- Used to receive funds
- e.g. `cosmosaccaddr15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc`
- `cosmosaccpub`
- Derived from account keys generated by `gaiacli keys add`
- e.g. `cosmosaccpub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm`
- `cosmosvalpub`
- Generated when the node is created with `gaiad init`.
- Get this value with `gaiad tendermint show-validator`
- e.g. `cosmosvalpub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c`
### Generate Keys
#### Generate Keys
You'll need an account private and public key pair \(a.k.a. `sk, pk` respectively\) to be able to receive funds, send txs, bond tx, etc.
@@ -66,10 +64,14 @@ gaiad tendermint show-validator
We strongly recommend _NOT_ using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds.
:::
### Get Tokens
### Account
#### Get Tokens
The best way to get tokens is from the [Cosmos Testnet Faucet](https://faucetcosmos.network). If the faucet is not working for you, try asking [#cosmos-validators](https://riot.im/app/#/room/#cosmos-validators:matrix.org). The faucet needs the `cosmosaccaddr` from the account you wish to use for staking.
#### Query Account balance
After receiving tokens to your address, you can view your account's balance by typing:
```bash
@@ -79,7 +81,6 @@ gaiacli account <account_cosmosaccaddr>
::: warning Note
When you query an account balance with zero tokens, you will get this error: `No account with address <account_cosmosaccaddr> was found in the state.` This can also happen if you fund the account before your node has fully synced with the chain. These are both normal.
We're working on improving our error messages!
:::
### Send Tokens
@@ -87,7 +88,7 @@ We're working on improving our error messages!
```bash
gaiacli send \
--amount=10faucetToken \
--chain-id=gaia-7005 \
--chain-id=<chain_id> \
--name=<key_name> \
--to=<destination_cosmosaccaddr>
```
@@ -109,20 +110,40 @@ You can also check your balance at a given block by using the `--block` flag:
gaiacli account <account_cosmosaccaddr> --block=<block_height>
```
### Delegate
### Staking
#### Set up a Validator
Please refer to the [Validator Setup](https://cosmos.network/docs/validators/validator-setup.html) section for a more complete guide on how to set up a validator-candidate.
#### Delegate to a Validator
On the upcoming mainnet, you can delegate `atom` to a validator. These [delegators](/resources/delegators-faq) can receive part of the validator's fee revenue. Read more about the [Cosmos Token Model](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf).
### Bond Tokens
##### Query Validators
On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator:
You can query the list of all validators of a specific chain:
```bash
gaiacli stake validators
```
If you want to get the information of a single validator you can check it with:
```bash
gaiacli stake validator <account_cosmosaccaddr>
```
#### Bond Tokens
On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator (*i.e.* delegate):
```bash
gaiacli stake delegate \
--amount=10steak \
--address-validator=$(gaiad tendermint show-validator) \
--validator=$(gaiad tendermint show-validator) \
--name=<key_name> \
--chain-id=gaia-7005
--chain-id=<chain_id>
```
While tokens are bonded, they are pooled with all the other bonded tokens in the network. Validators and delegators obtain a percentage of shares that equal their stake in this pool.
@@ -131,33 +152,232 @@ While tokens are bonded, they are pooled with all the other bonded tokens in the
Don't use more `steak` thank you have! You can always get more by using the [Faucet](https://faucetcosmos.network/)!
:::
### Unbond Tokens
##### Query Delegations
If for any reason the validator misbehaves, or you want to unbond a certain amount of tokens, use this following command. You can unbond a specific amount of`shares`\(eg:`12.1`\) or all of them \(`MAX`\).
Once submitted a delegation to a validator, you can see it's information by using the following command:
```bash
gaiacli stake delegation \
--address-delegator=<account_cosmosaccaddr> \
--address-validator=$(gaiad tendermint show-validator)
```
Or if you want to check all your current delegations with disctinct validators:
```bash
gaiacli stake delegations <account_cosmosaccaddr>
```
You can also get previous delegation(s) status by adding the `--height` flag.
#### Unbond Tokens
If for any reason the validator misbehaves, or you just want to unbond a certain amount of tokens, use this following command. You can unbond a specific `shares-amount` (eg:`12.1`\) or a `shares-percent` (eg:`25`) with the corresponding flags.
```bash
gaiacli stake unbond begin \
--address-validator=$(gaiad tendermint show-validator) \
--shares=MAX \
--name=<key_name> \
--chain-id=gaia-7005
--shares-percent=100 \
--from=<key_name> \
--chain-id=<chain_id>
```
Later you must use the `gaiacli stake unbond complete` command to finish
unbonding at which point you can can check your balance and your stake
delegation to see that the unbonding went through successfully.
Later you must complete the unbonding process by using the `gaiacli stake unbond complete` command:
```bash
gaiacli account <account_cosmosaccaddr>
gaiacli stake delegation \
--address-delegator=<account_cosmosaccaddr> \
gaiacli stake unbond complete \
--address-validator=$(gaiad tendermint show-validator) \
--chain-id=gaia-7005
--from=<key_name> \
--chain-id=<chain_id>
```
## Light Client Daemon
##### Query Unbonding-Delegations
Once you begin an unbonding-delegation, you can see it's information by using the following command:
```bash
gaiacli stake unbonding-delegation \
--address-delegator=<account_cosmosaccaddr> \
--address-validator=$(gaiad tendermint show-validator) \
```
Or if you want to check all your current unbonding-delegations with disctinct validators:
```bash
gaiacli stake unbonding-delegations <account_cosmosaccaddr>
```
You can also get previous unbonding-delegation(s) status by adding the `--height` flag.
#### Redelegate Tokens
A redelegation is a type delegation that allows you to bond illiquid tokens from one validator to another:
```bash
gaiacli stake redelegate begin \
--address-validator-source=$(gaiad tendermint show-validator) \
--address-validator-dest=<account_cosmosaccaddr> \
--shares-percent=50 \
--from=<key_name> \
--chain-id=<chain_id>
```
Here you can also redelegate a specific `shares-amount` or a `shares-percent` with the corresponding flags.
Later you must complete the redelegation process by using the `gaiacli stake redelegate complete` command:
```bash
gaiacli stake unbond complete \
--address-validator=$(gaiad tendermint show-validator) \
--from=<key_name> \
--chain-id=<chain_id>
```
##### Query Redelegations
Once you begin an redelegation, you can see it's information by using the following command:
```bash
gaiacli stake redelegation \
--address-delegator=<account_cosmosaccaddr> \
--address-validator-source=$(gaiad tendermint show-validator) \
--address-validator-dest=<account_cosmosaccaddr> \
```
Or if you want to check all your current unbonding-delegations with disctinct validators:
```bash
gaiacli stake redelegations <account_cosmosaccaddr>
```
You can also get previous redelegation(s) status by adding the `--height` flag.
### Governance
Governance is the process from which users in the Cosmos Hub can come to consensus on software upgrades, parameters of the mainnet or on custom text proposals. This is done through voting on proposals, which will be submitted by `Atom` holders on the mainnet.
Some considerations about the voting process:
- Voting is done by bonded `Atom` holders on a 1 bonded `Atom` 1 vote basis
- Delegators inherit the vote of their validator if they don't vote
- **Validators MUST vote on every proposal**. If a validator does not vote on a proposal, they will be **partially slashed**
- Votes are tallied at the end of the voting period (2 weeks on mainnet). Each address can vote multiple times to update its `Option` value (paying the transaction fee each time), only the last casted vote will count as valid
- Voters can choose between options `Yes`, `No`, `NoWithVeto` and `Abstain`
At the end of the voting period, a proposal is accepted if `(YesVotes/(YesVotes+NoVotes+NoWithVetoVotes))>1/2` and `(NoWithVetoVotes/(YesVotes+NoVotes+NoWithVetoVotes))<1/3`. It is rejected otherwise
For more information about the governance process and how it works, please check out the Governance module [specification](https://github.com/cosmos/cosmos-sdk/tree/develop/docs/spec/governance).
#### Create a Governance proposal
In order to create a governance proposal, you must submit an initial deposit along with the proposal details:
- `title`: Title of the proposal
- `description`: Description of the proposal
- `type`: Type of proposal. Must be of value _Text_ (types _SoftwareUpgrade_ and _ParameterChange_ not supported yet).
```bash
gaiacli gov submit-proposal \
--title=<title> \
--description=<description> \
--type=<Text/ParameterChange/SoftwareUpgrade> \
--proposer=<account_cosmosaccaddr> \
--deposit=<40steak> \
--from=<name> \
--chain-id=<chain_id>
```
##### Query proposals
Once created, you can now query information of the proposal:
```bash
gaiacli gov query-proposal \
--proposal-id=<proposal_id>
```
Or query all available proposals:
```bash
gaiacli gov query-proposals
```
You can also query proposals filtered by `voter` or `depositer` by using the corresponding flags.
#### Increase deposit
In order for a proposal to be broadcasted to the network, the amount deposited must be above a `minDeposit` value (default: `10 steak`). If the proposal you previously created didn't meet this requirement, you can still increase the total amount deposited to activate it. Once the minimum deposit is reached, the proposal enters voting period:
```bash
gaiacli gov deposit \
--proposal-id=<proposal_id> \
--depositer=<account_cosmosaccaddr> \
--deposit=<200steak> \
--from=<name> \
--chain-id=<chain_id>
```
> _NOTE_: Proposals that don't meet this requirement will be deleted after `MaxDepositPeriod` is reached.
#### Vote on a proposal
After a proposal's deposit reaches the `MinDeposit` value, the voting period opens. Bonded `Atom` holders can then cast vote on it:
```bash
gaiacli gov vote \
--proposal-id=<proposal_id> \
--voter=<account_cosmosaccaddr> \
--option=<Yes/No/NoWithVeto/Abstain> \
--from=<name> \
--chain-id=<chain_id>
```
##### Query vote
Check the vote with the option you just submitted:
```bash
gaiacli gov query-vote \
--proposal-id=<proposal_id> \
--voter=<account_cosmosaccaddr>
```
#### Query Parameters
You can get the current parameters that define high level settings for staking:
```
gaiacli stake parameters
```
With the above command you will get the values for:
- Maximum and minumum Inflation rate
- Maximum annual change in inflation rate,
- Goal of bonded tokens (%)
- Unbonding time
- Maximum numbers of validators
- Coin denomination for staking
All this values can be updated though a `governance` process by submitting a parameter change `proposal`.
#### Query Pool
A staking `Pool` defines the dynamic parameters of the current state. You can query them with the following command:
```
gaiacli stake pool
```
With the `pool` command you will get the values for:
- Loose and bonded tokens
- Token supply
- Current anual inflation and the block in which the last inflation was processed
- Last recorded bonded shares
## Gaia-Lite
::: tip Note
🚧 We are actively working on documentation for the LCD.
🚧 We are actively working on documentation for Gaia-lite.
:::
+1 -1
View File
@@ -469,7 +469,7 @@ Tendermint consensus engine. It would be initialized by a Genesis file, and it
would be driven by blocks of transactions committed by the underlying Tendermint
consensus. We'll talk more about ABCI and how this all works a bit later, but
feel free to check the
[specification](https://github.com/tendermint/tendermint/blob/master/docs/abci-spec.md).
[specification](https://github.com/tendermint/tendermint/blob/master/docs/app-dev/abci-spec.md).
We'll also see how to connect our app to a complete suite of components
for running and using a live blockchain application.
+1 -1
View File
@@ -16,7 +16,7 @@ here we will introduce the other ABCI requests sent by Tendermint, and
how we can use them to build more advanced applications. For a more complete
depiction of the ABCI and how its used, see
[the
specification](https://github.com/tendermint/tendermint/blob/master/docs/abci-spec.md)
specification](https://github.com/tendermint/tendermint/blob/master/docs/app-dev/abci-spec.md)
## InitChain
+1 -1
View File
@@ -6,7 +6,7 @@
The Cosmos SDK has all the necessary pre-built modules to add functionality on top of a `BaseApp`, which is the template to build a blockchain dApp in Cosmos. In this context, a `module` is a fundamental unit in the Cosmos SDK.
Each module is an extension of the `BaseApp`'s functionalities that defines transactions, handles application state and manages the state transition logic. Each module also contains handlers for messages and transactions, as well as REST and CLI for secure user interactions.
Each module is an extension of the `BaseApp`'s functionalities that defines transactions, handles application state and manages the state transition logic. Each module also contains handlers for messages and transactions, queriers for handling query requests, as well as REST and CLI for secure user interactions.
Some of the most important modules in the SDK are:
@@ -6,6 +6,23 @@ Uuse the CLI to create a new proposal:
simplegovcli propose --title="Voting Period update" --description="Should we change the proposal voting period to 3 weeks?" --deposit=300Atoms
```
Or, via a json file:
```bash
simplegovcli propose --proposal="path/to/proposal.json"
```
Where proposal.json contains:
```json
{
"title": "Voting Period Update",
"description": "Should we change the proposal voting period to 3 weeks?",
"type": "Text",
"deposit": "300Atoms"
}
```
Get the details of your newly created proposal:
```bash
+159
View File
@@ -0,0 +1,159 @@
## Vesting
### Intro and Requirements
This paper specifies vesting account implementation for the Cosmos Hub.
The requirements for this vesting account is that it should be initialized during genesis with
a starting balance X coins and a vesting endtime T. The owner of this account should be able to delegate to validators
and vote with locked coins, however they cannot send locked coins to other accounts until those coins have been unlocked.
The vesting account should also be able to spend any coins it receives from other users.
Thus, the bank module's `MsgSend` handler should error if a vesting account is trying to send an amount that exceeds their
unlocked coin amount.
### Implementation
##### Vesting Account implementation
NOTE: `Now = ctx.BlockHeader().Time`
```go
type VestingAccount interface {
Account
AssertIsVestingAccount() // existence implies that account is vesting.
// Calculates amount of coins that can be sent to other accounts given the current time
SendableCoins(sdk.Context) sdk.Coins
}
// Implements Vesting Account
// Continuously vests by unlocking coins linearly with respect to time
type ContinuousVestingAccount struct {
BaseAccount
OriginalVestingCoins sdk.Coins // Coins in account on Initialization
ReceivedCoins sdk.Coins // Coins received from other accounts
SentCoins sdk.Coins // Coins sent to other accounts
// StartTime and EndTime used to calculate how much of OriginalCoins is unlocked at any given point
StartTime time.Time
EndTime time.Time
}
// Uses time in context to calculate total unlocked coins
SendableCoins(vacc ContinuousVestingAccount, ctx sdk.Context) sdk.Coins:
// Coins unlocked by vesting schedule
unlockedCoins := ReceivedCoins - SentCoins + OriginalVestingCoins * (Now - StartTime) / (EndTime - StartTime)
// Must still check for currentCoins constraint since some unlocked coins may have been delegated.
currentCoins := vacc.BaseAccount.GetCoins()
// min will return sdk.Coins with each denom having the minimum amount from unlockedCoins and currentCoins
return min(unlockedCoins, currentCoins)
```
The `VestingAccount` interface is used to assert that an account is a vesting account like so:
```go
vacc, ok := acc.(VestingAccount); ok
```
as well as to calculate the SendableCoins at any given moment.
The `ContinuousVestingAccount` struct implements the Vesting account interface. It uses `OriginalVestingCoins`, `ReceivedCoins`,
`SentCoins`, `StartTime`, and `EndTime` to calculate how many coins are sendable at any given point.
Since the vesting restrictions need to be implemented on a per-module basis, the `ContinuousVestingAccount` implements
the `Account` interface exactly like `BaseAccount`. Thus, `ContinuousVestingAccount.GetCoins()` will return the total of
both locked coins and unlocked coins currently in the account. Delegated coins are deducted from `Account.GetCoins()`, but do not count against unlocked coins because they are still at stake and will be reinstated (partially if slashed) after waiting the full unbonding period.
##### Changes to Keepers/Handler
Since a vesting account should be capable of doing everything but sending with its locked coins, 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 that an account is a vesting account using the check described above.
```go
if acc is VestingAccount and Now < vestingAccount.EndTime:
// Check if amount is less than currently allowed sendable coins
if msg.Amount > vestingAccount.SendableCoins(ctx) then fail
else:
vestingAccount.SentCoins += msg.Amount
else:
// Account has fully vested, treat like regular account
if msg.Amount > account.GetCoins() then fail
// All checks passed, send the coins
SendCoins(inputs, outputs)
```
Coins that are sent to a vesting account after initialization by users sending them coins should be spendable
immediately after receiving them. Thus, handlers (like staking or bank) that send coins that a vesting account did not
originally own should increment `ReceivedCoins` by the amount sent.
Unlocked coins that are sent to other accounts will increment the vesting account's `SentCoins` attribute.
CONTRACT: Handlers SHOULD NOT update `ReceivedCoins` if they were originally sent from the vesting account. For example, if a vesting account unbonds from a validator, their tokens should be added back to account but staking handlers SHOULD NOT update `ReceivedCoins`.
However when a user sends coins to vesting account, then `ReceivedCoins` SHOULD be incremented.
### Initializing at Genesis
To initialize both vesting accounts and base accounts, the `GenesisAccount` struct will include an EndTime. Accounts meant to be
BaseAccounts will have `EndTime = 0`. The `initChainer` method will parse the GenesisAccount into BaseAccounts and VestingAccounts
as appropriate.
```go
type GenesisAccount struct {
Address sdk.AccAddress `json:"address"`
GenesisCoins sdk.Coins `json:"coins"`
EndTime int64 `json:"lock"`
}
initChainer:
for gacc in GenesisAccounts:
baseAccount := BaseAccount{
Address: gacc.Address,
Coins: gacc.GenesisCoins,
}
if gacc.EndTime != 0:
vestingAccount := ContinuouslyVestingAccount{
BaseAccount: baseAccount,
OriginalVestingCoins: gacc.GenesisCoins,
StartTime: RequestInitChain.Time,
EndTime: gacc.EndTime,
}
AddAccountToState(vestingAccount)
else:
AddAccountToState(baseAccount)
```
### Formulas
`OriginalVestingCoins`: Amount of coins in account at Genesis
`CurrentCoins`: Coins currently in the baseaccount (both locked and unlocked: `vestingAccount.GetCoins`)
`ReceivedCoins`: Coins received from other accounts (always unlocked)
`LockedCoins`: Coins that are currently locked
`Delegated`: Coins that have been delegated (no longer in account; may be locked or unlocked)
`Sent`: Coins sent to other accounts (MUST be unlocked)
Maximum amount of coins vesting schedule allows to be sent:
`ReceivedCoins - SentCoins + OriginalVestingCoins * (Now - StartTime) / (EndTime - StartTime)`
`ReceivedCoins - SentCoins + OriginalVestingCoins - LockedCoins`
Coins currently in Account:
`CurrentCoins = OriginalVestingCoins + ReceivedCoins - Delegated - Sent`
`CurrentCoins = vestingAccount.GetCoins()`
**Maximum amount of coins spendable right now:**
`min( ReceivedCoins - SentCoins + OriginalVestingCoins - LockedCoins, CurrentCoins )`
+9 -9
View File
@@ -25,9 +25,9 @@ type VotingProcedure struct {
```go
type TallyingProcedure struct {
Threshold rational.Rational // Minimum propotion of Yes votes for proposal to pass. Initial value: 0.5
Veto rational.Rational // Minimum proportion of Veto votes to Total votes ratio for proposal to be vetoed. Initial value: 1/3
GovernancePenalty sdk.Rat // Penalty if validator does not vote
Threshold sdk.Dec // Minimum propotion of Yes votes for proposal to pass. Initial value: 0.5
Veto sdk.Dec // Minimum proportion of Veto votes to Total votes ratio for proposal to be vetoed. Initial value: 1/3
GovernancePenalty sdk.Dec // Penalty if validator does not vote
GracePeriod int64 // If validator entered validator set in this period of blocks before vote ended, governance penalty does not apply
}
```
@@ -81,7 +81,7 @@ This type is used in a temp map when tallying
```go
type ValidatorGovInfo struct {
Minus sdk.Rat
Minus sdk.Dec
Vote Vote
}
```
@@ -103,17 +103,17 @@ type Proposal struct {
VotingStartBlock int64 // Height of the block where MinDeposit was reached. -1 if MinDeposit is not reached
CurrentStatus ProposalStatus // Current status of the proposal
YesVotes sdk.Rat
NoVotes sdk.Rat
NoWithVetoVotes sdk.Rat
AbstainVotes sdk.Rat
YesVotes sdk.Dec
NoVotes sdk.Dec
NoWithVetoVotes sdk.Dec
AbstainVotes sdk.Dec
}
```
We also mention a method to update the tally for a given proposal:
```go
func (proposal Proposal) updateTally(vote byte, amount sdk.Rat)
func (proposal Proposal) updateTally(vote byte, amount sdk.Dec)
```
### Stores
+1 -1
View File
@@ -7,7 +7,7 @@
The current annual inflation rate.
```golang
type Inflation sdk.Rat
type Inflation sdk.Dec
```
### InflationLastTime
-1
View File
@@ -16,4 +16,3 @@ EndBlock() ValidatorSetChanges
ClearTendermintUpdates()
return vsc
```
+15 -15
View File
@@ -13,7 +13,7 @@ type Pool struct {
LooseTokens int64 // tokens not associated with any bonded validator
BondedTokens int64 // reserve of bonded tokens
InflationLastTime int64 // block which the last inflation was processed // TODO make time
Inflation sdk.Rat // current annual inflation rate
Inflation sdk.Dec // current annual inflation rate
DateLastCommissionReset int64 // unix timestamp for last commission accounting reset (daily)
}
@@ -28,10 +28,10 @@ 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.Dec // maximum annual change in inflation rate
InflationMax sdk.Dec // maximum inflation rate
InflationMin sdk.Dec // minimum inflation rate
GoalBonded sdk.Dec // Goal of percent bonded atoms
MaxValidators uint16 // maximum number of validators
BondDenom string // bondable coin denomination
@@ -74,9 +74,9 @@ type Validator struct {
Revoked bool // has the validator been revoked?
Status sdk.BondStatus // validator status (bonded/unbonding/unbonded)
Tokens sdk.Rat // delegated tokens (incl. self-delegation)
DelegatorShares sdk.Rat // total shares issued to a validator's delegators
SlashRatio sdk.Rat // increases each time the validator is slashed
Tokens sdk.Dec // delegated tokens (incl. self-delegation)
DelegatorShares sdk.Dec // total shares issued to a validator's delegators
SlashRatio sdk.Dec // increases each time the validator is slashed
Description Description // description terms for the validator
@@ -88,10 +88,10 @@ type Validator struct {
}
type CommissionInfo struct {
Rate sdk.Rat // the commission rate of fees charged to any delegators
Max sdk.Rat // maximum commission rate which this validator can ever charge
ChangeRate sdk.Rat // maximum daily increase of the validator commission
ChangeToday sdk.Rat // commission rate change today, reset each day (UTC time)
Rate sdk.Dec // the commission rate of fees charged to any delegators
Max sdk.Dec // maximum commission rate which this validator can ever charge
ChangeRate sdk.Dec // maximum daily increase of the validator commission
ChangeToday sdk.Dec // commission rate change today, reset each day (UTC time)
LastChange int64 // unix timestamp of last commission change
}
@@ -117,7 +117,7 @@ the transaction is the owner of the bond.
```golang
type Delegation struct {
Shares sdk.Rat // delegation shares recieved
Shares sdk.Dec // delegation shares recieved
Height int64 // last height bond updated
}
```
@@ -178,8 +178,8 @@ the original redelegation has been completed.
```golang
type Redelegation struct {
SourceShares sdk.Rat // amount of source shares redelegating
DestinationShares sdk.Rat // amount of destination shares created at redelegation
SourceShares sdk.Dec // amount of source shares redelegating
DestinationShares sdk.Dec // amount of destination shares created at redelegation
CompleteTime int64 // unix time to complete redelegation
}
```
+56 -56
View File
@@ -1,7 +1,7 @@
## Transaction Overview
In this section we describe the processing of the transactions and the
corresponding updates to the state. Transactions:
corresponding updates to the state. Transactions:
- TxCreateValidator
- TxEditValidator
- TxDelegation
@@ -18,8 +18,8 @@ Other notes:
- `sender` denotes the address of the sender of the transaction
- `getXxx`, `setXxx`, and `removeXxx` functions are used to retrieve and
modify objects from the store
- `sdk.Rat` refers to a rational numeric type specified by the SDK.
- `sdk.Dec` refers to a decimal type specified by the SDK.
### TxCreateValidator
- triggers: `distribution.CreateValidatorDistribution`
@@ -28,74 +28,74 @@ A validator is created using the `TxCreateValidator` transaction.
```golang
type TxCreateValidator struct {
OwnerAddr sdk.Address
Operator sdk.Address
ConsensusPubKey crypto.PubKey
GovernancePubKey crypto.PubKey
SelfDelegation coin.Coin
SelfDelegation coin.Coin
Description Description
Commission sdk.Rat
CommissionMax sdk.Rat
CommissionMaxChange sdk.Rat
Commission sdk.Dec
CommissionMax sdk.Dec
CommissionMaxChange sdk.Dec
}
createValidator(tx TxCreateValidator):
validator = getValidator(tx.OwnerAddr)
validator = getValidator(tx.Operator)
if validator != nil return // only one validator per address
validator = NewValidator(OwnerAddr, ConsensusPubKey, GovernancePubKey, Description)
validator = NewValidator(operatorAddr, ConsensusPubKey, GovernancePubKey, Description)
init validator poolShares, delegatorShares set to 0
init validator commision fields from tx
validator.PoolShares = 0
setValidator(validator)
txDelegate = TxDelegate(tx.OwnerAddr, tx.OwnerAddr, tx.SelfDelegation)
txDelegate = TxDelegate(tx.Operator, tx.Operator, tx.SelfDelegation)
delegate(txDelegate, validator) // see delegate function in [TxDelegate](TxDelegate)
return
```
```
### TxEditValidator
If either the `Description` (excluding `DateBonded` which is constant),
`Commission`, or the `GovernancePubKey` need to be updated, the
`TxEditCandidacy` transaction should be sent from the owner account:
`TxEditCandidacy` transaction should be sent from the operator account:
```golang
type TxEditCandidacy struct {
GovernancePubKey crypto.PubKey
Commission sdk.Rat
Commission sdk.Dec
Description Description
}
editCandidacy(tx TxEditCandidacy):
validator = getValidator(tx.ValidatorAddr)
if tx.Commission > CommissionMax || tx.Commission < 0 then fail
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
if tx.Description != nil validator.Description = tx.Description
setValidator(store, validator)
return
```
### TxDelegate
- triggers: `distribution.CreateOrModDelegationDistribution`
Within this transaction the delegator provides coins, and in return receives
some amount of their validator's delegator-shares that are assigned to
`Delegation.Shares`.
`Delegation.Shares`.
```golang
type TxDelegate struct {
DelegatorAddr sdk.Address
ValidatorAddr sdk.Address
Amount sdk.Coin
DelegatorAddr sdk.Address
ValidatorAddr sdk.Address
Amount sdk.Coin
}
delegate(tx TxDelegate):
@@ -104,14 +104,14 @@ delegate(tx TxDelegate):
delegation = getDelegatorBond(DelegatorAddr, ValidatorAddr)
if delegation == nil then delegation = NewDelegation(DelegatorAddr, ValidatorAddr)
validator, pool, issuedDelegatorShares = validator.addTokensFromDel(tx.Amount, pool)
delegation.Shares += issuedDelegatorShares
setDelegation(delegation)
updateValidator(validator)
setPool(pool)
return
return
```
### TxStartUnbonding
@@ -120,28 +120,28 @@ Delegator unbonding is defined with the following transaction:
```golang
type TxStartUnbonding struct {
DelegatorAddr sdk.Address
ValidatorAddr sdk.Address
Shares string
DelegatorAddr sdk.Address
ValidatorAddr sdk.Address
Shares string
}
startUnbonding(tx TxStartUnbonding):
startUnbonding(tx TxStartUnbonding):
delegation, found = getDelegatorBond(store, sender, tx.PubKey)
if !found == nil return
if !found == nil return
if bond.Shares < tx.Shares
return ErrNotEnoughBondShares
validator, found = GetValidator(tx.ValidatorAddr)
if !found {
return err
return err
bond.Shares -= tx.Shares
revokeCandidacy = false
if bond.Shares.IsZero() {
if bond.DelegatorAddr == validator.Owner && validator.Revoked == false
if bond.DelegatorAddr == validator.Operator && validator.Revoked == false
revokeCandidacy = true
removeDelegation( bond)
@@ -162,7 +162,7 @@ startUnbonding(tx TxStartUnbonding):
validator = updateValidator(validator)
if validator.DelegatorShares == 0 {
removeValidator(validator.Owner)
removeValidator(validator.Operator)
return
```
@@ -185,7 +185,7 @@ redelegationComplete(tx TxRedelegate):
returnTokens = ExpectedTokens * tx.startSlashRatio/validator.SlashRatio
AddCoins(unbonding.DelegatorAddr, returnTokens)
removeUnbondingDelegation(unbonding)
return
return
```
### TxRedelegation
@@ -199,27 +199,27 @@ type TxRedelegate struct {
DelegatorAddr Address
ValidatorFrom Validator
ValidatorTo Validator
Shares sdk.Rat
Shares sdk.Dec
CompletedTime int64
}
redelegate(tx TxRedelegate):
pool = getPool()
delegation = getDelegatorBond(tx.DelegatorAddr, tx.ValidatorFrom.Owner)
delegation = getDelegatorBond(tx.DelegatorAddr, tx.ValidatorFrom.Operator)
if delegation == nil
return
if delegation.Shares < tx.Shares
return
return
if delegation.Shares < tx.Shares
return
delegation.shares -= Tx.Shares
validator, pool, createdCoins = validator.RemoveShares(pool, tx.Shares)
setPool(pool)
redelegation = newRedelegation(tx.DelegatorAddr, tx.validatorFrom,
redelegation = newRedelegation(tx.DelegatorAddr, tx.validatorFrom,
tx.validatorTo, tx.Shares, createdCoins, tx.CompletedTime)
setRedelegation(redelegation)
return
return
```
### TxCompleteRedelegation
@@ -239,7 +239,7 @@ redelegationComplete(tx TxRedelegate):
redelegation = getRedelegation(tx.DelegatorAddr, tx.validatorFrom, tx.validatorTo)
if redelegation.CompleteTime >= CurrentBlockTime && redelegation.CompleteHeight >= CurrentBlockHeight
removeRedelegation(redelegation)
return
return
```
### Update Validators
@@ -273,11 +273,11 @@ updateBondedValidators(newValidator Validator) (updatedVal Validator)
// use the validator provided because it has not yet been updated
// in the main validator store
ownerAddr = iterator.Value()
if bytes.Equal(ownerAddr, newValidator.Owner) {
operatorAddr = iterator.Value()
if bytes.Equal(operatorAddr, newValidator.Operator) {
validator = newValidator
else
validator = getValidator(ownerAddr)
validator = getValidator(operatorAddr)
// if not previously a validator (and unrevoked),
// kick the cliff validator / bond this new validator
@@ -285,7 +285,7 @@ updateBondedValidators(newValidator Validator) (updatedVal Validator)
kickCliffValidator = true
validator = bondValidator(ctx, store, validator)
if bytes.Equal(ownerAddr, newValidator.Owner) {
if bytes.Equal(operatorAddr, newValidator.Operator) {
updatedVal = validator
bondedValidatorsCount++
@@ -316,7 +316,7 @@ unbondValidator(ctx Context, store KVStore, validator Validator)
}
// perform all the store operations for when a validator status becomes bonded
bondValidator(ctx Context, store KVStore, validator Validator) Validator
bondValidator(ctx Context, store KVStore, validator Validator) Validator
pool = GetPool(ctx)
// set the status
+30 -12
View File
@@ -1,10 +1,10 @@
# Validator Setup
::: warning Current Testnet
The current testnet is `gaia-7005`.
The current testnet is `gaia-8000`.
:::
Before setting up your validator node, make sure you've already gone through the [Full Node Setup](/getting-started/full-node.md) guide.
Before setting up your validator node, make sure you've already gone through the [Full Node Setup](/docs/getting-started/full-node.md) guide.
## Running a Validator Node
@@ -34,7 +34,7 @@ gaiacli stake create-validator \
--pubkey=$(gaiad tendermint show-validator) \
--address-validator=<account_cosmosaccaddr>
--moniker="choose a moniker" \
--chain-id=gaia-7005 \
--chain-id=<chain_id> \
--name=<key_name>
```
@@ -46,12 +46,12 @@ The `--identity` can be used as to verify identity with systems like Keybase or
```bash
gaiacli stake edit-validator
--address-validator=<account_cosmosaccaddr>
--validator=<account_cosmosaccaddr>
--moniker="choose a moniker" \
--website="https://cosmos.network" \
--identity=6A0D65E29A4CBC8E
--details="To infinity and beyond!"
--chain-id=gaia-7005 \
--chain-id=<chain_id> \
--name=<key_name>
```
@@ -60,9 +60,28 @@ gaiacli stake edit-validator
View the validator's information with this command:
```bash
gaiacli stake validator \
--address-validator=<account_cosmosaccaddr> \
--chain-id=gaia-7005
gaiacli stake validator <account_cosmosaccaddr>
```
### Track Validator Signing Information
In order to keep track of a validator's signatures in the past you can do so by using the `signing-info` command:
```bash
gaiacli stake signing-information <validator-pubkey>\
--chain-id=<chain_id>
```
### Unrevoke Validator
When a validator is `Revoked` for downtime, you must submit an `Unrevoke` transaction in order to be able to get block proposer rewards again (depends on the zone fee distribution).
```bash
gaiacli stake unrevoke \
--from=<key_name> \
--chain-id=<chain_id>
--validator=<account_cosmosaccaddr> \
--chain-id=gaia-6002
```
### Confirm Your Validator is Running
@@ -70,12 +89,11 @@ gaiacli stake validator \
Your validator is active if the following command returns anything:
```bash
gaiacli advanced tendermint validator-set | grep "$(gaiad tendermint show-validator)"
gaiacli tendermint validator-set | grep "$(gaiad tendermint show-validator)"
```
You should also be able to see your validator on the [Explorer](https://explorecosmos.network/validators). You are looking for the `bech32` encoded `address` in the `~/.gaiad/config/priv_validator.json` file.
::: warning Note
To be in the validator set, you need to have more total voting power than the 100th validator.
:::
@@ -84,7 +102,7 @@ To be in the validator set, you need to have more total voting power than the 10
### Problem #1: My validator has `voting_power: 0`
Your validator has become auto-unbonded. In `gaia-7005`, we unbond validators if they do not vote on `50` of the last `100` blocks. Since blocks are proposed every ~2 seconds, a validator unresponsive for ~100 seconds will become unbonded. This usually happens when your `gaiad` process crashes.
Your validator has become auto-unbonded. In `gaia-8000`, we unbond validators if they do not vote on `50` of the last `100` blocks. Since blocks are proposed every ~2 seconds, a validator unresponsive for ~100 seconds will become unbonded. This usually happens when your `gaiad` process crashes.
Here's how you can return the voting power back to your validator. First, if `gaiad` is not running, start it up again:
@@ -95,7 +113,7 @@ gaiad start
Wait for your full node to catch up to the latest block. Next, run the following command. Note that `<cosmosaccaddr>` is the address of your validator account, and `<name>` is the name of the validator account. You can find this info by running `gaiacli keys list`.
```bash
gaiacli stake unrevoke <cosmosaccaddr> --chain-id=gaia-7005 --name=<name>
gaiacli stake unrevoke <cosmosaccaddr> --chain-id=<chain_id> --name=<name>
```
::: danger Warning