Merge remote-tracking branch 'origin/develop' into rigel/fee-distribution

This commit is contained in:
rigelrozanski
2018-09-25 17:45:48 -04:00
51 changed files with 1182 additions and 438 deletions
+2 -2
View File
@@ -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"
]
},
{
+3
View File
@@ -0,0 +1,3 @@
export default ({ router }) => {
router.addRoutes([{ path: "/testnet/", redirect: "/" }])
}
+4
View File
@@ -0,0 +1,4 @@
$accentColor = #304DE9
$textColor = #15192C
$borderColor = #eaecef
$codeBgColor = #282c34
+29 -4
View File
@@ -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
+111
View File
@@ -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.
-27
View File
@@ -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
```
+209
View File
@@ -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
```
+18 -2
View File
@@ -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
+25
View File
@@ -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.
-2
View File
@@ -1,2 +0,0 @@
- SDK related specifications (ie. how multistore, signatures, etc. work).
- Basecoin (SendTx)
+9 -14
View File
@@ -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))
+6 -5
View File
@@ -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)
+70 -49
View File
@@ -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
+17 -2
View File
@@ -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: