Merge remote-tracking branch 'origin/develop' into rigel/fee-distribution
This commit is contained in:
@@ -24,8 +24,8 @@ module.exports = {
|
||||
children: [
|
||||
"/getting-started/voyager",
|
||||
"/getting-started/installation",
|
||||
"/getting-started/full-node",
|
||||
"/getting-started/create-testnet"
|
||||
"/getting-started/join-testnet",
|
||||
"/getting-started/networks"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -0,0 +1,3 @@
|
||||
export default ({ router }) => {
|
||||
router.addRoutes([{ path: "/testnet/", redirect: "/" }])
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
$accentColor = #304DE9
|
||||
$textColor = #15192C
|
||||
$borderColor = #eaecef
|
||||
$codeBgColor = #282c34
|
||||
+29
-4
@@ -24,7 +24,7 @@ on the website.
|
||||
|
||||
## Config.js
|
||||
|
||||
The [config.js](./config.js) generates the sidebar and Table of Contents
|
||||
The [config.js](./.vuepress/config.js) generates the sidebar and Table of Contents
|
||||
on the website docs. Note the use of relative links and the omission of
|
||||
file extensions. Additional features are available to improve the look
|
||||
of the sidebar.
|
||||
@@ -59,9 +59,34 @@ to send users to the GitHub.
|
||||
|
||||
## Building Locally
|
||||
|
||||
Not currently possible but coming soon! Doing so requires
|
||||
assets held in the (private) website repo, installing
|
||||
[VuePress](https://vuepress.vuejs.org/), and modifying the `config.js`.
|
||||
To build and serve the documentation locally, run:
|
||||
|
||||
```
|
||||
npm install -g vuepress
|
||||
```
|
||||
|
||||
then change the following line in the `config.js`:
|
||||
|
||||
```
|
||||
base: "/docs/",
|
||||
```
|
||||
|
||||
to:
|
||||
|
||||
```
|
||||
base: "/",
|
||||
```
|
||||
|
||||
Finally, go up one directory to the root of the repo and run:
|
||||
|
||||
```
|
||||
# from root of repo
|
||||
vuepress build docs
|
||||
cd dist/docs
|
||||
python -m SimpleHTTPServer 8080
|
||||
```
|
||||
|
||||
then navigate to localhost:8080 in your browser.
|
||||
|
||||
## Consistency
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
# Integrate a Cosmos-SDK based blockchain as a Service Provider
|
||||
|
||||
We define 'service providers' as entities providing services for end-users that involve some form of interaction with a Cosmos-SDK based blockchain (this includes the Cosmos Hub). More specifically, this document will be focused around interactions with tokens.
|
||||
|
||||
This section does not concern wallet builders that want to provide [Light-Client](https://github.com/cosmos/cosmos-sdk/tree/develop/docs/light) functionalities. Service providers are expected to act as trusted point of contact to the blockchain for their end-users.
|
||||
|
||||
## High-level description of the architecture
|
||||
|
||||
There are three main pieces to consider:
|
||||
|
||||
- Full-nodes: To interact with the blockchain.
|
||||
- Rest Server: This acts as a relayer for HTTP calls.
|
||||
- Rest API: Define available endpoints for the Rest Server.
|
||||
|
||||
## Running a Full-Node
|
||||
|
||||
### Installation and configuration
|
||||
|
||||
We will describe the steps to run and interract with a full-node for the Cosmos Hub. For other SDK-based blockchain, the process should be similar.
|
||||
|
||||
First, you need to [install the software](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/getting-started/installation.md).
|
||||
|
||||
Then, you can start [running a full-node](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/getting-started/full-node.md).
|
||||
|
||||
### Command-Line interface
|
||||
|
||||
Next you will find a few useful CLI commands to interact with the Full-Node.
|
||||
|
||||
#### Creating a key-pair
|
||||
|
||||
To generate a new key (default ed25519 elliptic curve):
|
||||
|
||||
```bash
|
||||
gaiacli keys add <your_key_name>
|
||||
```
|
||||
|
||||
You will be asked to create a passwords (at least 8 characters) for this key-pair. The command returns 4 informations:
|
||||
|
||||
- `NAME`: Name of your key
|
||||
- `ADDRESS`: Your address. Used to receive funds.
|
||||
- `PUBKEY`: Your public key. Useful for validators.
|
||||
- `Seed phrase`: 12-words phrase. **Save this seed phrase somewhere safe**. It is used to recover your private key in case you forget the password.
|
||||
|
||||
You can see all your available keys by typing:
|
||||
|
||||
```bash
|
||||
gaiacli keys list
|
||||
```
|
||||
|
||||
#### Checking your balance
|
||||
|
||||
After receiving tokens to your address, you can view your account's balance by typing:
|
||||
|
||||
```bash
|
||||
gaiacli account <YOUR_ADDRESS>
|
||||
```
|
||||
|
||||
*Note: When you query an account balance with zero tokens, you will get this error: No account with address <YOUR_ADDRESS> was found in the state. This is expected! We're working on improving our error messages.*
|
||||
|
||||
#### Sending coins via the CLI
|
||||
|
||||
Here is the command to send coins via the CLI:
|
||||
|
||||
```bash
|
||||
gaiacli send --amount=10faucetToken --chain-id=<name_of_testnet_chain> --name=<key_name> --to=<destination_address>
|
||||
```
|
||||
|
||||
Flags:
|
||||
- `--amount`: This flag accepts the format `<value|coinName>`.
|
||||
- `--chain-id`: This flag allows you to specify the id of the chain. There will be different ids for different testnet chains and main chain.
|
||||
- `--name`: Name of the key of the sending account.
|
||||
- `--to`: Address of the recipient.
|
||||
|
||||
#### Help
|
||||
|
||||
If you need to do something else, the best command you can run is:
|
||||
|
||||
```bash
|
||||
gaiacli
|
||||
```
|
||||
|
||||
It will display all the available commands. For each command, you can use the `--help` flag to get further information.
|
||||
|
||||
## Setting up the Rest Server
|
||||
|
||||
The Rest Server acts as an intermediary between the front-end and the full-node. You don't need to run the Rest Server on the same machine as the full-node. If you intend to run the Rest Server on another machine, you need to go through the [Installation and configuration](#installation-and-configuration) again on this machine.
|
||||
|
||||
To start the Rest server:
|
||||
|
||||
```bash
|
||||
gaiacli advanced rest-server --trust-node=false --node=<full_node_address:full_node_port>
|
||||
```
|
||||
|
||||
Flags:
|
||||
- `--trust-node`: A boolean. If `true`, light-client verification is enabled. If `false`, it is disabled. For service providers, this should be set to `false`.
|
||||
- `--node`: This is where you indicate the address and the port of your full-node. The format is <full_node_address:full_node_port>. If the full-node is on the same machine, the address should be "tcp://localhost".
|
||||
- `--laddr`: This flag allows you to specify the address and port for the Rest Server. You will mostly use this flag only to specify the port, in which case just input "localhost" for the address. The format is <rest_server_address:port>.
|
||||
|
||||
### Listening for incoming transaction
|
||||
|
||||
The recommended way to listen for incoming transaction is to periodically query the blockchain through the following endpoint of the LCD:
|
||||
|
||||
[`/bank/balance/{account}`](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/light/api.md#bankbalanceaccount---get)
|
||||
|
||||
## Rest API
|
||||
|
||||
The Rest API documents all the available endpoints that you can use to interract with your full node. It can be found [here](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/light/api.md).
|
||||
|
||||
The API is divided into ICS standards for each category of endpoints. For example, the [ICS20](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/light/api.md#ics20---tokenapi) describes the API to interact with tokens.
|
||||
|
||||
To give more flexibility to implementers, we have separated the different steps that are involved in the process of sending transactions. You will be able to generate unsigned transactions (example with [coin transfer](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/light/api.md#post-banktransfers)), [sign](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/light/api.md#post-authtxsign) and [broadcast](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/light/api.md#post-authtxbroadcast) them with different API endpoints. This allows service providers to use their own signing mechanism for instance.
|
||||
@@ -1,27 +0,0 @@
|
||||
## 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 --with-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
|
||||
```
|
||||
@@ -0,0 +1,209 @@
|
||||
# Networks
|
||||
|
||||
There are a variety of ways to setup either local or remote networks with automation, detailed below.
|
||||
All the required files are found in the [networks directory](https://github.com/cosmos/cosmos-sdk/tree/develop/networks) and additionally the `local` or `remote` sub-directories.
|
||||
|
||||
## Local Testnet
|
||||
|
||||
From the [networks/local directory](https://github.com/cosmos/cosmos-sdk/tree/develop/networks/local):
|
||||
|
||||
### Requirements
|
||||
|
||||
- [Install gaia](https://cosmos.network/docs/getting-started/installation.html)
|
||||
- [Install docker](https://docs.docker.com/engine/installation/)
|
||||
- [Install docker-compose](https://docs.docker.com/compose/install/)
|
||||
|
||||
### Build
|
||||
|
||||
Build the `gaiad` binary and the `tendermint/gaiadnode` docker image.
|
||||
|
||||
Note the binary will be mounted into the container so it can be updated without
|
||||
rebuilding the image.
|
||||
|
||||
```
|
||||
cd $GOPATH/src/github.com/cosmos/cosmos-sdk
|
||||
|
||||
# Build the linux binary in ./build
|
||||
make build-linux
|
||||
|
||||
# Build tendermint/gaiadnode image
|
||||
make build-docker-gaiadnode
|
||||
```
|
||||
|
||||
### Run a testnet
|
||||
|
||||
To start a 4 node testnet run:
|
||||
|
||||
```
|
||||
make localnet-start
|
||||
```
|
||||
|
||||
This command creates a 4-node network using the gaiadnode image.
|
||||
The ports for each node are found in this table:
|
||||
|
||||
| Node ID | P2P Port | RPC Port |
|
||||
| --------|-------|------|
|
||||
| `gaianode0` | `26656` | `26657` |
|
||||
| `gaianode1` | `26659` | `26660` |
|
||||
| `gaianode2` | `26661` | `26662` |
|
||||
| `gaianode3` | `26663` | `26664` |
|
||||
|
||||
To update the binary, just rebuild it and restart the nodes:
|
||||
|
||||
```
|
||||
make build-linux localnet-stop localnet-start
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
The `make localnet-start` creates files for a 4-node testnet in `./build` by calling the `gaiad testnet` command.
|
||||
This outputs a handful of files in the `./build` directory:
|
||||
|
||||
```tree -L 2 build/
|
||||
build/
|
||||
├── gaiacli
|
||||
├── gaiad
|
||||
├── gentxs
|
||||
│ ├── node0.json
|
||||
│ ├── node1.json
|
||||
│ ├── node2.json
|
||||
│ └── node3.json
|
||||
├── node0
|
||||
│ ├── gaiacli
|
||||
│ │ ├── key_seed.json
|
||||
│ │ └── keys
|
||||
│ └── gaiad
|
||||
│ ├── ${LOG:-gaiad.log}
|
||||
│ ├── config
|
||||
│ └── data
|
||||
├── node1
|
||||
│ ├── gaiacli
|
||||
│ │ └── key_seed.json
|
||||
│ └── gaiad
|
||||
│ ├── ${LOG:-gaiad.log}
|
||||
│ ├── config
|
||||
│ └── data
|
||||
├── node2
|
||||
│ ├── gaiacli
|
||||
│ │ └── key_seed.json
|
||||
│ └── gaiad
|
||||
│ ├── ${LOG:-gaiad.log}
|
||||
│ ├── config
|
||||
│ └── data
|
||||
└── node3
|
||||
├── gaiacli
|
||||
│ └── key_seed.json
|
||||
└── gaiad
|
||||
├── ${LOG:-gaiad.log}
|
||||
├── config
|
||||
└── data
|
||||
```
|
||||
|
||||
Each `./build/nodeN` directory is mounted to the `/gaiad` directory in each container.
|
||||
|
||||
### Logging
|
||||
|
||||
Logs are saved under each `./build/nodeN/gaiad/gaia.log`. Watch them stream in with, for example:
|
||||
|
||||
```
|
||||
tail -f build/node0/gaiad/gaia.log
|
||||
```
|
||||
|
||||
### Special binaries
|
||||
|
||||
If you have multiple binaries with different names, you can specify which one to run with the BINARY environment variable. The path of the binary is relative to the attached volume. For example:
|
||||
|
||||
```
|
||||
# Run with custom binary
|
||||
BINARY=gaiafoo make localnet-start
|
||||
```
|
||||
|
||||
## Remote Testnet
|
||||
|
||||
The following should be run from the [networks directory](https://github.com/cosmos/cosmos-sdk/tree/develop/networks).
|
||||
|
||||
### Terraform & Ansible
|
||||
|
||||
Automated deployments are done using [Terraform](https://www.terraform.io/) to create servers on AWS then
|
||||
[Ansible](http://www.ansible.com/) to create and manage testnets on those servers.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Install [Terraform](https://www.terraform.io/downloads.html) and [Ansible](http://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) on a Linux machine.
|
||||
- Create an [AWS API token](https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html) with EC2 create capability.
|
||||
- Create SSH keys
|
||||
|
||||
```
|
||||
export AWS_ACCESS_KEY_ID="2345234jk2lh4234"
|
||||
export AWS_SECRET_ACCESS_KEY="234jhkg234h52kh4g5khg34"
|
||||
export TESTNET_NAME="remotenet"
|
||||
export CLUSTER_NAME= "remotenetvalidators"
|
||||
export SSH_PRIVATE_FILE="$HOME/.ssh/id_rsa"
|
||||
export SSH_PUBLIC_FILE="$HOME/.ssh/id_rsa.pub"
|
||||
```
|
||||
|
||||
These will be used by both `terraform` and `ansible`.
|
||||
|
||||
### Create a remote network
|
||||
|
||||
```
|
||||
SERVERS=1 REGION_LIMIT=1 make validators-start
|
||||
```
|
||||
|
||||
The testnet name is what's going to be used in --chain-id, while the cluster name is the administrative tag in AWS for the servers. The code will create SERVERS amount of servers in each availability zone up to the number of REGION_LIMITs, starting at us-east-2. (us-east-1 is excluded.) The below BaSH script does the same, but sometimes it's more comfortable for input.
|
||||
|
||||
```
|
||||
./new-testnet.sh "$TESTNET_NAME" "$CLUSTER_NAME" 1 1
|
||||
```
|
||||
|
||||
### Quickly see the /status endpoint
|
||||
|
||||
```
|
||||
make validators-status
|
||||
```
|
||||
|
||||
### Delete servers
|
||||
|
||||
```
|
||||
make validators-stop
|
||||
```
|
||||
|
||||
### Logging
|
||||
|
||||
You can ship logs to Logz.io, an Elastic stack (Elastic search, Logstash and Kibana) service provider. You can set up your nodes to log there automatically. Create an account and get your API key from the notes on [this page](https://app.logz.io/#/dashboard/data-sources/Filebeat), then:
|
||||
|
||||
```
|
||||
yum install systemd-devel || echo "This will only work on RHEL-based systems."
|
||||
apt-get install libsystemd-dev || echo "This will only work on Debian-based systems."
|
||||
|
||||
go get github.com/mheese/journalbeat
|
||||
ansible-playbook -i inventory/digital_ocean.py -l remotenet logzio.yml -e LOGZIO_TOKEN=ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
|
||||
You can install the DataDog agent with:
|
||||
|
||||
```
|
||||
make datadog-install
|
||||
```
|
||||
|
||||
### Single-node testnet
|
||||
|
||||
To create a single node testnet:
|
||||
|
||||
```
|
||||
cd $GOPATH/src/github.com/cosmos/cosmos-sdk
|
||||
|
||||
# Clear the build folder
|
||||
rm -rf ./build
|
||||
|
||||
# Build binary
|
||||
make build-linux
|
||||
|
||||
# Create configuration
|
||||
docker run -v `pwd`/build:/gaiad tendermint/gaiadnode testnet -o . --v 1
|
||||
|
||||
# Run the node
|
||||
docker run -v `pwd`/build:/gaiad tendermint/gaiadnode
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
# Getting Started
|
||||
|
||||
To start a rest server, we need to specify the following parameters:
|
||||
To start a REST server, we need to specify the following parameters:
|
||||
| Parameter | Type | Default | Required | Description |
|
||||
| ----------- | --------- | ----------------------- | -------- | ---------------------------------------------------- |
|
||||
| chain-id | string | null | true | chain id of the full node to connect |
|
||||
@@ -12,9 +12,25 @@ To start a rest server, we need to specify the following parameters:
|
||||
Sample command:
|
||||
|
||||
```bash
|
||||
gaiacli light-client --chain-id=test --laddr=tcp://localhost:1317 --node tcp://localhost:46657 --trust-node=false
|
||||
gaiacli rest-server --chain-id=test \
|
||||
--laddr=tcp://localhost:1317 \
|
||||
--node tcp://localhost:46657 \
|
||||
--trust-node=false
|
||||
```
|
||||
|
||||
The server listens on HTTPS by default. You can set the SSL certificate to be used by the server with these additional flags:
|
||||
|
||||
```bash
|
||||
gaiacli rest-server --chain-id=test \
|
||||
--laddr=tcp://localhost:1317 \
|
||||
--node tcp://localhost:46657 \
|
||||
--trust-node=false \
|
||||
--certfile=mycert.pem --keyfile=mykey.key
|
||||
```
|
||||
|
||||
If no certificate/keyfile pair is supplied, a self-signed certificate will be generated and its fingerprint printed out.
|
||||
Append `--insecure` to the command line if you want to disable the secure layer and listen on an insecure HTTP port.
|
||||
|
||||
## Gaia Light Use Cases
|
||||
|
||||
LCD could be very helpful for related service providers. For a wallet service provider, LCD could
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
WORK IN PROGRESS
|
||||
See PR comments here https://github.com/cosmos/cosmos-sdk/pull/2072
|
||||
|
||||
# Keeper
|
||||
|
||||
## Denom Metadata
|
||||
|
||||
The BankKeeper contains a store that stores the metadata of different token denoms. Denoms are referred to by their name, same as the `denom` field in sdk.Coin. The different attributes of a denom are stored in the denom metadata store under the key `[denom name]:[attribute name]`. The default attributes in the store are explained below. However, this can be extended by the developer or through SoftwareUpgrade proposals.
|
||||
|
||||
### Decimals `int8`
|
||||
|
||||
- `Base Unit` = The common standard for the default "standard" size of a token. Examples: 1 Bitcoin or 1 Ether.
|
||||
- `Smallest Unit` = The smallest possible denomination of a token. A fraction of the base unit. Examples: 1 satoshi or 1 wei.
|
||||
|
||||
All amounts throughout the SDK are denominated in the smallest unit of a token, so that all amounts can be expressed as integers. However, UIs typically want to display token values in the base unit, so the Decimals metadata field standardizes the number of digits that come after the decimal place in the base unit.
|
||||
|
||||
`1 [Base Unit] = 10^(N) [Smallest Unit]`
|
||||
|
||||
### TotalSupply `sdk.Integer`
|
||||
|
||||
The TotalSupply of a denom is the total amount of a token that exists (known to the chain) across all accounts and modules. It is denominated in the `smallest unit` of a denom. It can be changed by the Keeper functions `MintCoins` and `BurnCoins`. `AddCoins` and `SubtractCoins` are used when adding or subtracting coins for an account, but not removing them from total supply (for example, when moving the coins to the control of the staking module).
|
||||
|
||||
### Aliases `[]string`
|
||||
|
||||
Aliases is an array of strings that are "alternative names" for a token. As an example, while the Ether's denom name might be `ether`, a possible alias could be `ETH`. This field can be useful for UIs and clients. It is intended that this field can be modified by a governance mechanism.
|
||||
@@ -1,2 +0,0 @@
|
||||
- SDK related specifications (ie. how multistore, signatures, etc. work).
|
||||
- Basecoin (SendTx)
|
||||
@@ -13,13 +13,13 @@ has to be created and the previous one rendered inactive.
|
||||
```go
|
||||
type DepositProcedure struct {
|
||||
MinDeposit sdk.Coins // Minimum deposit for a proposal to enter voting period.
|
||||
MaxDepositPeriod int64 // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 months
|
||||
MaxDepositPeriod time.Time // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 months
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
type VotingProcedure struct {
|
||||
VotingPeriod int64 // Length of the voting period. Initial value: 2 weeks
|
||||
VotingPeriod time.Time // Length of the voting period. Initial value: 2 weeks
|
||||
}
|
||||
```
|
||||
|
||||
@@ -28,7 +28,6 @@ type TallyingProcedure struct {
|
||||
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
|
||||
}
|
||||
```
|
||||
|
||||
@@ -97,10 +96,10 @@ type Proposal struct {
|
||||
Type ProposalType // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
|
||||
TotalDeposit sdk.Coins // Current deposit on this proposal. Initial value is set at InitialDeposit
|
||||
Deposits []Deposit // List of deposits on the proposal
|
||||
SubmitBlock int64 // Height of the block where TxGovSubmitProposal was included
|
||||
SubmitTime time.Time // Time of the block where TxGovSubmitProposal was included
|
||||
Submitter sdk.Address // Address of the submitter
|
||||
|
||||
VotingStartBlock int64 // Height of the block where MinDeposit was reached. -1 if MinDeposit is not reached
|
||||
VotingStartTime time.Time // Time of the block where MinDeposit was reached. time.Time{} if MinDeposit is not reached
|
||||
CurrentStatus ProposalStatus // Current status of the proposal
|
||||
|
||||
YesVotes sdk.Dec
|
||||
@@ -137,7 +136,7 @@ For pseudocode purposes, here are the two function we will use to read or write
|
||||
* `ProposalProcessingQueue`: A queue `queue[proposalID]` containing all the
|
||||
`ProposalIDs` of proposals that reached `MinDeposit`. Each round, the oldest
|
||||
element of `ProposalProcessingQueue` is checked during `BeginBlock` to see if
|
||||
`CurrentBlock == VotingStartBlock + activeProcedure.VotingPeriod`. If it is,
|
||||
`CurrentTime == VotingStartTime + activeProcedure.VotingPeriod`. If it is,
|
||||
then the application tallies the votes, compute the votes of each validator and checks if every validator in the valdiator set have voted
|
||||
and, if not, applies `GovernancePenalty`. If the proposal is accepted, deposits are refunded.
|
||||
After that proposal is ejected from `ProposalProcessingQueue` and the next element of the queue is evaluated.
|
||||
@@ -159,7 +158,7 @@ And the pseudocode for the `ProposalProcessingQueue`:
|
||||
proposal = load(Governance, <proposalID|'proposal'>) // proposal is a const key
|
||||
votingProcedure = load(GlobalParams, 'VotingProcedure')
|
||||
|
||||
if (CurrentBlock == proposal.VotingStartBlock + votingProcedure.VotingPeriod && proposal.CurrentStatus == ProposalStatusActive)
|
||||
if (CurrentTime == proposal.VotingStartTime + votingProcedure.VotingPeriod && proposal.CurrentStatus == ProposalStatusActive)
|
||||
|
||||
// End of voting period, tally
|
||||
|
||||
@@ -192,14 +191,10 @@ And the pseudocode for the `ProposalProcessingQueue`:
|
||||
|
||||
tallyingProcedure = load(GlobalParams, 'TallyingProcedure')
|
||||
|
||||
// Slash validators that did not vote, or update tally if they voted
|
||||
// Update tally if validator voted they voted
|
||||
for each validator in validators
|
||||
if (validator.bondHeight < CurrentBlock - tallyingProcedure.GracePeriod)
|
||||
// only slash if validator entered validator set before grace period
|
||||
if (!tmpValMap(validator).HasVoted)
|
||||
slash validator by tallyingProcedure.GovernancePenalty
|
||||
else
|
||||
proposal.updateTally(tmpValMap(validator).Vote, (validator.TotalShares - tmpValMap(validator).Minus))
|
||||
if tmpValMap(validator).HasVoted
|
||||
proposal.updateTally(tmpValMap(validator).Vote, (validator.TotalShares - tmpValMap(validator).Minus))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -43,12 +43,13 @@ type Params struct {
|
||||
Validators are identified according to the `OperatorAddr`, an SDK validator
|
||||
address for the operator of the validator.
|
||||
|
||||
Validators also have a `ConsPubKey`, the public key of the validator.
|
||||
|
||||
Validators are indexed in the store using the following maps:
|
||||
Validators also have a `ConsPubKey`, the public key of the validator used in
|
||||
Tendermint consensus. The validator can be retrieved from it's `ConsPubKey`
|
||||
once it can be converted into the corresponding `ConsAddr`. Validators are
|
||||
indexed in the store using the following maps:
|
||||
|
||||
- Validators: `0x02 | OperatorAddr -> amino(validator)`
|
||||
- ValidatorsByPubKey: `0x03 | ConsPubKey -> OperatorAddr`
|
||||
- ValidatorsByConsAddr: `0x03 | ConsAddr -> OperatorAddr`
|
||||
- ValidatorsByPower: `0x05 | power | blockHeight | blockTx -> OperatorAddr`
|
||||
|
||||
`Validators` is the primary index - it ensures that each operator can have only one
|
||||
@@ -69,7 +70,7 @@ validator.
|
||||
|
||||
```golang
|
||||
type Validator struct {
|
||||
ConsensusPubKey crypto.PubKey // Tendermint consensus pubkey of validator
|
||||
ConsPubKey crypto.PubKey // Tendermint consensus pubkey of validator
|
||||
Jailed bool // has the validator been jailed?
|
||||
|
||||
Status sdk.BondStatus // validator status (bonded/unbonding/unbonded)
|
||||
|
||||
@@ -1,86 +1,107 @@
|
||||
## Transaction Overview
|
||||
# Transaction Overview
|
||||
|
||||
In this section we describe the processing of the transactions and the
|
||||
corresponding updates to the state. Transactions:
|
||||
- TxCreateValidator
|
||||
- TxEditValidator
|
||||
- TxDelegation
|
||||
- TxStartUnbonding
|
||||
- TxCompleteUnbonding
|
||||
- TxRedelegate
|
||||
- TxCompleteRedelegation
|
||||
|
||||
* TxCreateValidator
|
||||
* TxEditValidator
|
||||
* TxDelegation
|
||||
* TxStartUnbonding
|
||||
* TxCompleteUnbonding
|
||||
* TxRedelegate
|
||||
* TxCompleteRedelegation
|
||||
|
||||
Other important state changes:
|
||||
- Update Validators
|
||||
|
||||
* Update Validators
|
||||
|
||||
Other notes:
|
||||
- `tx` denotes a reference to the transaction being processed
|
||||
- `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.Dec` refers to a decimal type specified by the SDK.
|
||||
|
||||
### TxCreateValidator
|
||||
* `tx` denotes a reference to the transaction being processed
|
||||
* `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.Dec` refers to a decimal type specified by the SDK.
|
||||
|
||||
- triggers: `distribution.CreateValidatorDistribution`
|
||||
## TxCreateValidator
|
||||
|
||||
* triggers: `distribution.CreateValidatorDistribution`
|
||||
|
||||
A validator is created using the `TxCreateValidator` transaction.
|
||||
|
||||
```golang
|
||||
type TxCreateValidator struct {
|
||||
Operator sdk.Address
|
||||
ConsensusPubKey crypto.PubKey
|
||||
GovernancePubKey crypto.PubKey
|
||||
SelfDelegation coin.Coin
|
||||
Description Description
|
||||
Commission Commission
|
||||
|
||||
Description Description
|
||||
Commission sdk.Dec
|
||||
CommissionMax sdk.Dec
|
||||
CommissionMaxChange sdk.Dec
|
||||
DelegatorAddr sdk.AccAddress
|
||||
ValidatorAddr sdk.ValAddress
|
||||
PubKey crypto.PubKey
|
||||
Delegation sdk.Coin
|
||||
}
|
||||
|
||||
|
||||
createValidator(tx TxCreateValidator):
|
||||
validator = getValidator(tx.Operator)
|
||||
if validator != nil return // only one validator per address
|
||||
ok := validatorExists(tx.ValidatorAddr)
|
||||
if ok return err // only one validator per address
|
||||
|
||||
validator = NewValidator(operatorAddr, ConsensusPubKey, GovernancePubKey, Description)
|
||||
init validator poolShares, delegatorShares set to 0
|
||||
init validator commision fields from tx
|
||||
validator.PoolShares = 0
|
||||
ok := validatorByPubKeyExists(tx.PubKey)
|
||||
if ok return err // only one validator per public key
|
||||
|
||||
err := validateDenom(tx.Delegation.Denom)
|
||||
if err != nil return err // denomination must be valid
|
||||
|
||||
validator := NewValidator(tx.ValidatorAddr, tx.PubKey, tx.Description)
|
||||
|
||||
err := setInitialCommission(validator, tx.Commission, blockTime)
|
||||
if err != nil return err // must be able to set initial commission correctly
|
||||
|
||||
// set the validator and public key
|
||||
setValidator(validator)
|
||||
setValidatorByPubKeyIndex(validator)
|
||||
|
||||
txDelegate = TxDelegate(tx.Operator, tx.Operator, tx.SelfDelegation)
|
||||
delegate(txDelegate, validator) // see delegate function in [TxDelegate](TxDelegate)
|
||||
return
|
||||
// delegate coins from tx.DelegatorAddr to the validator
|
||||
err := delegate(tx.DelegatorAddr, tx.Delegation, validator)
|
||||
if err != nil return err // must be able to set delegation correctly
|
||||
|
||||
tags := createTags(tx)
|
||||
return tags
|
||||
```
|
||||
|
||||
### TxEditValidator
|
||||
## 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 operator account:
|
||||
If either the `Description`, `Commission`, or the `ValidatorAddr` need to be
|
||||
updated, the `TxEditCandidacy` transaction should be sent from the operator
|
||||
account:
|
||||
|
||||
```golang
|
||||
type TxEditCandidacy struct {
|
||||
GovernancePubKey crypto.PubKey
|
||||
Commission sdk.Dec
|
||||
Description Description
|
||||
Description Description
|
||||
ValidatorAddr sdk.ValAddress
|
||||
CommissionRate sdk.Dec
|
||||
}
|
||||
|
||||
editCandidacy(tx TxEditCandidacy):
|
||||
validator = getValidator(tx.ValidatorAddr)
|
||||
validator, ok := getValidator(tx.ValidatorAddr)
|
||||
if !ok return err // validator must exist
|
||||
|
||||
if tx.Commission > CommissionMax || tx.Commission < 0 then fail
|
||||
if rateChange(tx.Commission) > CommissionMaxChange then fail
|
||||
validator.Commission = tx.Commission
|
||||
// Attempt to update the validator's description. The description provided
|
||||
// must be valid.
|
||||
description, err := updateDescription(validator, tx.Description)
|
||||
if err != nil return err
|
||||
|
||||
if tx.GovernancePubKey != nil validator.GovernancePubKey = tx.GovernancePubKey
|
||||
if tx.Description != nil validator.Description = tx.Description
|
||||
// a validator is not required to update it's commission rate
|
||||
if tx.CommissionRate != nil {
|
||||
// Attempt to update a validator's commission rate. The rate provided
|
||||
// must be valid. It's rate can only be updated once a day.
|
||||
err := updateValidatorCommission(validator, tx.CommissionRate)
|
||||
if err != nil return err
|
||||
}
|
||||
|
||||
setValidator(store, validator)
|
||||
return
|
||||
// set the validator and public key
|
||||
setValidator(validator)
|
||||
|
||||
tags := createTags(tx)
|
||||
return tags
|
||||
```
|
||||
|
||||
### TxDelegate
|
||||
|
||||
@@ -35,9 +35,16 @@ gaiacli stake create-validator \
|
||||
--address-validator=<account_cosmosval>
|
||||
--moniker="choose a moniker" \
|
||||
--chain-id=<chain_id> \
|
||||
--name=<key_name>
|
||||
--name=<key_name> \
|
||||
--commission-rate="0.10" \
|
||||
--commission-max-rate="0.20" \
|
||||
--commission-max-change-rate="0.01"
|
||||
```
|
||||
|
||||
__Note__: When specifying commission parameters, the `commission-max-change-rate`
|
||||
is used to measure % _point_ change over the `commission-rate`. E.g. 1% to 2% is
|
||||
a 100% rate increase, but only 1 percentage point.
|
||||
|
||||
### Edit Validator Description
|
||||
|
||||
You can edit your validator's public description. This info is to identify your validator, and will be relied on by delegators to decide which validators to stake to. Make sure to provide input for every flag below, otherwise the field will default to empty (`--moniker` defaults to the machine name).
|
||||
@@ -52,9 +59,17 @@ gaiacli stake edit-validator
|
||||
--identity=6A0D65E29A4CBC8E
|
||||
--details="To infinity and beyond!"
|
||||
--chain-id=<chain_id> \
|
||||
--name=<key_name>
|
||||
--name=<key_name> \
|
||||
--commission-rate="0.10"
|
||||
```
|
||||
|
||||
__Note__: The `commission-rate` value must adhere to the following invariants:
|
||||
|
||||
- Must be between 0 and the validator's `commission-max-rate`
|
||||
- Must not exceed the validator's `commission-max-change-rate` which is maximum
|
||||
% point change rate **per day**. In other words, a validator can only change
|
||||
its commission once per day and within `commission-max-change-rate` bounds.
|
||||
|
||||
### View Validator Description
|
||||
|
||||
View the validator's information with this command:
|
||||
|
||||
Reference in New Issue
Block a user