-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Co-authored-by: Julien Robert <[email protected]>
- Loading branch information
1 parent
9f70225
commit 4af4c27
Showing
13 changed files
with
1,927 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# Setting up the keyring | ||
|
||
:::note Synopsis | ||
This document describes how to configure and use the keyring and its various backends for an [**application**](../../learn/beginner/00-app-anatomy.md). | ||
::: | ||
|
||
The keyring holds the private/public keypairs used to interact with a node. For instance, a validator key needs to be set up before running the blockchain node, so that blocks can be correctly signed. The private key can be stored in different locations, called "backends", such as a file or the operating system's own key storage. | ||
|
||
## Available backends for the keyring | ||
|
||
Starting with the v0.38.0 release, Cosmos SDK comes with a new keyring implementation | ||
that provides a set of commands to manage cryptographic keys in a secure fashion. The | ||
new keyring supports multiple storage backends, some of which may not be available on | ||
all operating systems. | ||
|
||
### The `os` backend | ||
|
||
The `os` backend relies on operating system-specific defaults to handle key storage | ||
securely. Typically, an operating system's credential sub-system handles password prompts, | ||
private keys storage, and user sessions according to the user's password policies. Here | ||
is a list of the most popular operating systems and their respective passwords manager: | ||
|
||
* macOS: [Keychain](https://support.apple.com/en-gb/guide/keychain-access/welcome/mac) | ||
* Windows: [Credentials Management API](https://docs.microsoft.com/en-us/windows/win32/secauthn/credentials-management) | ||
* GNU/Linux: | ||
* [libsecret](https://gitlab.gnome.org/GNOME/libsecret) | ||
* [kwallet](https://api.kde.org/frameworks/kwallet/html/index.html) | ||
|
||
GNU/Linux distributions that use GNOME as default desktop environment typically come with | ||
[Seahorse](https://wiki.gnome.org/Apps/Seahorse). Users of KDE based distributions are | ||
commonly provided with [KDE Wallet Manager](https://userbase.kde.org/KDE_Wallet_Manager). | ||
Whilst the former is in fact a `libsecret` convenient frontend, the latter is a `kwallet` | ||
client. | ||
|
||
`os` is the default option since operating system's default credentials managers are | ||
designed to meet users' most common needs and provide them with a comfortable | ||
experience without compromising on security. | ||
|
||
The recommended backends for headless environments are `file` and `pass`. | ||
|
||
### The `file` backend | ||
|
||
The `file` backend more closely resembles the keybase implementation used prior to | ||
v0.38.1. It stores the keyring encrypted within the app's configuration directory. This | ||
keyring will request a password each time it is accessed, which may occur multiple | ||
times in a single command resulting in repeated password prompts. If using bash scripts | ||
to execute commands using the `file` option you may want to utilize the following format | ||
for multiple prompts: | ||
|
||
```shell | ||
# assuming that KEYPASSWD is set in the environment | ||
$ gaiacli config keyring-backend file # use file backend | ||
$ (echo $KEYPASSWD; echo $KEYPASSWD) | gaiacli keys add me # multiple prompts | ||
$ echo $KEYPASSWD | gaiacli keys show me # single prompt | ||
``` | ||
|
||
:::tip | ||
The first time you add a key to an empty keyring, you will be prompted to type the password twice. | ||
::: | ||
|
||
### The `pass` backend | ||
|
||
The `pass` backend uses the [pass](https://www.passwordstore.org/) utility to manage on-disk | ||
encryption of keys' sensitive data and metadata. Keys are stored inside `gpg` encrypted files | ||
within app-specific directories. `pass` is available for the most popular UNIX | ||
operating systems as well as GNU/Linux distributions. Please refer to its manual page for | ||
information on how to download and install it. | ||
|
||
:::tip | ||
**pass** uses [GnuPG](https://gnupg.org/) for encryption. `gpg` automatically invokes the `gpg-agent` | ||
daemon upon execution, which handles the caching of GnuPG credentials. Please refer to `gpg-agent` | ||
man page for more information on how to configure cache parameters such as credentials TTL and | ||
passphrase expiration. | ||
::: | ||
|
||
The password store must be set up prior to first use: | ||
|
||
```shell | ||
pass init <GPG_KEY_ID> | ||
``` | ||
|
||
Replace `<GPG_KEY_ID>` with your GPG key ID. You can use your personal GPG key or an alternative | ||
one you may want to use specifically to encrypt the password store. | ||
|
||
### The `kwallet` backend | ||
|
||
The `kwallet` backend uses `KDE Wallet Manager`, which comes installed by default on the | ||
GNU/Linux distributions that ships KDE as default desktop environment. Please refer to | ||
[KWallet Handbook](https://docs.kde.org/stable5/en/kdeutils/kwallet5/index.html) for more | ||
information. | ||
|
||
### The `test` backend | ||
|
||
The `test` backend is a password-less variation of the `file` backend. Keys are stored | ||
unencrypted on disk. | ||
|
||
**Provided for testing purposes only. The `test` backend is not recommended for use in production environments**. | ||
|
||
### The `memory` backend | ||
|
||
The `memory` backend stores keys in memory. The keys are immediately deleted after the program has exited. | ||
|
||
**Provided for testing purposes only. The `memory` backend is not recommended for use in production environments**. | ||
|
||
### Setting backend using the env variable | ||
|
||
You can set the keyring-backend using env variable: `BINNAME_KEYRING_BACKEND`. For example, if your binary name is `gaia-v5` then set: `export GAIA_V5_KEYRING_BACKEND=pass` | ||
|
||
## Adding keys to the keyring | ||
|
||
:::warning | ||
Make sure you can build your own binary, and replace `simd` with the name of your binary in the snippets. | ||
::: | ||
|
||
Applications developed using the Cosmos SDK come with the `keys` subcommand. For the purpose of this tutorial, we're running the `simd` CLI, which is an application built using the Cosmos SDK for testing and educational purposes. For more information, see [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/main/simapp). | ||
|
||
You can use `simd keys` for help about the keys command and `simd keys [command] --help` for more information about a particular subcommand. | ||
|
||
To create a new key in the keyring, run the `add` subcommand with a `<key_name>` argument. For the purpose of this tutorial, we will solely use the `test` backend, and call our new key `my_validator`. This key will be used in the next section. | ||
|
||
```bash | ||
$ simd keys add my_validator --keyring-backend test | ||
|
||
# Put the generated address in a variable for later use. | ||
MY_VALIDATOR_ADDRESS=$(simd keys show my_validator -a --keyring-backend test) | ||
``` | ||
|
||
This command generates a new 24-word mnemonic phrase, persists it to the relevant backend, and outputs information about the keypair. If this keypair will be used to hold value-bearing tokens, be sure to write down the mnemonic phrase somewhere safe! | ||
|
||
By default, the keyring generates a `secp256k1` keypair. The keyring also supports `ed25519` keys, which may be created by passing the `--algo ed25519` flag. A keyring can of course hold both types of keys simultaneously, and the Cosmos SDK's `x/auth` module supports natively these two public key algorithms. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# Running a Node | ||
|
||
:::note Synopsis | ||
Now that the application is ready and the keyring populated, it's time to see how to run the blockchain node. In this section, the application we are running is called [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/main/simapp), and its corresponding CLI binary `simd`. | ||
::: | ||
|
||
:::note Pre-requisite Readings | ||
|
||
* [Anatomy of a Cosmos SDK Application](../../learn/beginner/00-app-anatomy.md) | ||
* [Setting up the keyring](./00-keyring.md) | ||
|
||
::: | ||
|
||
## Initialize the Chain | ||
|
||
:::warning | ||
Make sure you can build your own binary, and replace `simd` with the name of your binary in the snippets. | ||
::: | ||
|
||
Before actually running the node, we need to initialize the chain, and most importantly its genesis file. This is done with the `init` subcommand: | ||
|
||
```bash | ||
# The argument <moniker> is the custom username of your node, it should be human-readable. | ||
simd init <moniker> --chain-id my-test-chain | ||
``` | ||
|
||
The command above creates all the configuration files needed for your node to run, as well as a default genesis file, which defines the initial state of the network. | ||
|
||
:::tip | ||
All these configuration files are in `~/.simapp` by default, but you can overwrite the location of this folder by passing the `--home` flag to each commands, | ||
or set an `$APPD_HOME` environment variable (where `APPD` is the name of the binary). | ||
::: | ||
|
||
The `~/.simapp` folder has the following structure: | ||
|
||
```bash | ||
. # ~/.simapp | ||
|- data # Contains the databases used by the node. | ||
|- config/ | ||
|- app.toml # Application-related configuration file. | ||
|- config.toml # CometBFT-related configuration file. | ||
|- genesis.json # The genesis file. | ||
|- node_key.json # Private key to use for node authentication in the p2p protocol. | ||
|- priv_validator_key.json # Private key to use as a validator in the consensus protocol. | ||
``` | ||
|
||
## Updating Some Default Settings | ||
|
||
If you want to change any field values in configuration files (for ex: genesis.json) you can use `jq` ([installation](https://stedolan.github.io/jq/download/) & [docs](https://stedolan.github.io/jq/manual/#Assignment)) & `sed` commands to do that. Few examples are listed here. | ||
|
||
```bash | ||
# to change the chain-id | ||
jq '.chain_id = "testing"' genesis.json > temp.json && mv temp.json genesis.json | ||
|
||
# to enable the api server | ||
sed -i '/\[api\]/,+3 s/enable = false/enable = true/' app.toml | ||
|
||
# to change the voting_period | ||
jq '.app_state.gov.voting_params.voting_period = "600s"' genesis.json > temp.json && mv temp.json genesis.json | ||
|
||
# to change the inflation | ||
jq '.app_state.mint.minter.inflation = "0.300000000000000000"' genesis.json > temp.json && mv temp.json genesis.json | ||
``` | ||
|
||
### Client Interaction | ||
|
||
When instantiating a node, GRPC and REST are defaulted to localhost to avoid unknown exposure of your node to the public. It is recommended to not expose these endpoints without a proxy that can handle load balancing or authentication is setup between your node and the public. | ||
|
||
:::tip | ||
A commonly used tool for this is [nginx](https://nginx.org). | ||
::: | ||
|
||
|
||
## Adding Genesis Accounts | ||
|
||
Before starting the chain, you need to populate the state with at least one account. To do so, first [create a new account in the keyring](./00-keyring.md#adding-keys-to-the-keyring) named `my_validator` under the `test` keyring backend (feel free to choose another name and another backend). | ||
|
||
Now that you have created a local account, go ahead and grant it some `stake` tokens in your chain's genesis file. Doing so will also make sure your chain is aware of this account's existence: | ||
|
||
```bash | ||
simd genesis add-genesis-account $MY_VALIDATOR_ADDRESS 100000000000stake | ||
``` | ||
|
||
Recall that `$MY_VALIDATOR_ADDRESS` is a variable that holds the address of the `my_validator` key in the [keyring](./00-keyring.md#adding-keys-to-the-keyring). Also note that the tokens in the Cosmos SDK have the `{amount}{denom}` format: `amount` is an 18-digit-precision decimal number, and `denom` is the unique token identifier with its denomination key (e.g. `atom` or `uatom`). Here, we are granting `stake` tokens, as `stake` is the token identifier used for staking in [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/main/simapp). For your own chain with its own staking denom, that token identifier should be used instead. | ||
|
||
Now that your account has some tokens, you need to add a validator to your chain. Validators are special full-nodes that participate in the consensus process (implemented in the [underlying consensus engine](../../learn/intro/02-sdk-app-architecture.md#cometbft)) in order to add new blocks to the chain. Any account can declare its intention to become a validator operator, but only those with sufficient delegation get to enter the active set (for example, only the top 125 validator candidates with the most delegation get to be validators in the Cosmos Hub). For this guide, you will add your local node (created via the `init` command above) as a validator of your chain. Validators can be declared before a chain is first started via a special transaction included in the genesis file called a `gentx`: | ||
|
||
```bash | ||
# Create a gentx. | ||
simd genesis gentx my_validator 100000000stake --chain-id my-test-chain --keyring-backend test | ||
|
||
# Add the gentx to the genesis file. | ||
simd genesis collect-gentxs | ||
``` | ||
|
||
A `gentx` does three things: | ||
|
||
1. Registers the `validator` account you created as a validator operator account (i.e. the account that controls the validator). | ||
2. Self-delegates the provided `amount` of staking tokens. | ||
3. Link the operator account with a CometBFT node pubkey that will be used for signing blocks. If no `--pubkey` flag is provided, it defaults to the local node pubkey created via the `simd init` command above. | ||
|
||
For more information on `gentx`, use the following command: | ||
|
||
```bash | ||
simd genesis gentx --help | ||
``` | ||
|
||
## Configuring the Node Using `app.toml` and `config.toml` | ||
|
||
The Cosmos SDK automatically generates two configuration files inside `~/.simapp/config`: | ||
|
||
* `config.toml`: used to configure the CometBFT, learn more on [CometBFT's documentation](https://docs.cometbft.com/v0.37/core/configuration), | ||
* `app.toml`: generated by the Cosmos SDK, and used to configure your app, such as state pruning strategies, telemetry, gRPC and REST servers configuration, state sync... | ||
|
||
Both files are heavily commented, please refer to them directly to tweak your node. | ||
|
||
One example config to tweak is the `minimum-gas-prices` field inside `app.toml`, which defines the minimum gas prices the validator node is willing to accept for processing a transaction. Depending on the chain, it might be an empty string or not. If it's empty, make sure to edit the field with some value, for example `10token`, or else the node will halt on startup. For the purpose of this tutorial, let's set the minimum gas price to 0: | ||
|
||
```toml | ||
# The minimum gas prices a validator is willing to accept for processing a | ||
# transaction. A transaction's fees must meet the minimum of any denomination | ||
# specified in this config (e.g. 0.25token1;0.0001token2). | ||
minimum-gas-prices = "0stake" | ||
``` | ||
|
||
:::tip | ||
When running a node (not a validator!) and not wanting to run the application mempool, set the `max-txs` field to `-1`. | ||
|
||
```toml | ||
[mempool] | ||
# Setting max-txs to 0 will allow for a unbounded amount of transactions in the mempool. | ||
# Setting max_txs to negative 1 (-1) will disable transactions from being inserted into the mempool. | ||
# Setting max_txs to a positive number (> 0) will limit the number of transactions in the mempool, by the specified amount. | ||
# | ||
# Note, this configuration only applies to SDK built-in app-side mempool | ||
# implementations. | ||
max-txs = "-1" | ||
``` | ||
|
||
::: | ||
|
||
## Run a Localnet | ||
|
||
Now that everything is set up, you can finally start your node: | ||
|
||
```bash | ||
simd start | ||
``` | ||
|
||
You should see blocks come in. | ||
|
||
The previous command allow you to run a single node. This is enough for the next section on interacting with this node, but you may wish to run multiple nodes at the same time, and see how consensus happens between them. | ||
|
||
The naive way would be to run the same commands again in separate terminal windows. This is possible, however in the Cosmos SDK, we leverage the power of [Docker Compose](https://docs.docker.com/compose/) to run a localnet. If you need inspiration on how to set up your own localnet with Docker Compose, you can have a look at the Cosmos SDK's [`docker-compose.yml`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/docker-compose.yml). | ||
|
||
### Standalone App/CometBFT | ||
|
||
By default, the Cosmos SDK runs CometBFT in-process with the application | ||
If you want to run the application and CometBFT in separate processes, | ||
start the application with the `--with-comet=false` flag | ||
and set `rpc.laddr` in `config.toml` to the CometBFT node's RPC address. | ||
|
||
## Logging | ||
|
||
Logging provides a way to see what is going on with a node. By default the `info` level is set. This is a global level and all info logs will be outputted to the terminal. | ||
|
||
If you would like to filter specific logs to the terminal instead of all, then setting `<module>:<log_level>` is how this can work. | ||
Example: | ||
|
||
In `config.toml`: | ||
|
||
```toml | ||
log_level: "state:info,p2p:info,consensus:info,x/staking:info,x/ibc:info,*:error" | ||
``` | ||
|
||
Or directly in the command line: | ||
|
||
```bash | ||
<appd> start --log_level "state:info,p2p:info,consensus:info,x/staking:info,x/ibc:info,*:error" | ||
``` | ||
|
||
The above will show info logs for the state, p2p, consensus, staking, and ibc modules, and error logs for all other modules. | ||
When no log filtering is required, simply use one of the supported global log levels: `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `panic` or `disabled`. | ||
|
||
## State Sync | ||
|
||
State sync is the act in which a node syncs the latest or close to the latest state of a blockchain. This is useful for users who don't want to sync all the blocks in history. Read more in [CometBFT documentation](https://docs.cometbft.com/v0.37/core/state-sync). | ||
|
||
State sync works thanks to snapshots. Read how the SDK handles snapshots [here](https://github.com/cosmos/cosmos-sdk/blob/825245d/store/snapshots/README.md). | ||
|
||
### Local State Sync | ||
|
||
Local state sync work similar to normal state sync except that it works off a local snapshot of state instead of one provided via the p2p network. The steps to start local state sync are similar to normal state sync with a few different designs. | ||
|
||
1. As mentioned in https://docs.cometbft.com/v0.37/core/state-sync, one must set a height and hash in the config.toml along with a few rpc servers (the afromentioned link has instructions on how to do this). | ||
2. Run `<appd snapshot restore <height> <format>` to restore a local snapshot (note: first load it from a file with the *load* command). | ||
3. Bootsrapping Comet state in order to start the node after the snapshot has been ingested. This can be done with the bootstrap command `<app> comet bootstrap-state` | ||
|
||
### Snapshots Commands | ||
|
||
The Cosmos SDK provides commands for managing snapshots. | ||
These commands can be added in an app with the following snippet in `cmd/<app>/root.go`: | ||
|
||
```go | ||
import ( | ||
"github.com/cosmos/cosmos-sdk/client/snapshot" | ||
) | ||
|
||
func initRootCmd(/* ... */) { | ||
// ... | ||
rootCmd.AddCommand( | ||
snapshot.Cmd(appCreator), | ||
) | ||
} | ||
``` | ||
|
||
Then following commands are available at `<appd> snapshots [command]`: | ||
|
||
* **list**: list local snapshots | ||
* **load**: Load a snapshot archive file into snapshot store | ||
* **restore**: Restore app state from local snapshot | ||
* **export**: Export app state to snapshot store | ||
* **dump**: Dump the snapshot as portable archive format | ||
* **delete**: Delete a local snapshot |
Oops, something went wrong.