diff --git a/.dockerignore b/.dockerignore index 3732311e0..015d5e1de 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,5 @@ .idea .vscode build -localnet \ No newline at end of file +localnet +.localnet diff --git a/.gitignore b/.gitignore index 7121639d5..45e742f66 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ settings.json .idea localnet +.localnet rest-server.out .DS_Store .vscode diff --git a/Makefile b/Makefile index 420dee230..851a09c32 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=DcLedger \ BUILD_FLAGS := -ldflags '$(ldflags)' OUTPUT_DIR ?= build -LOCALNET_DIR ?= localnet +LOCALNET_DIR ?= .localnet LICENSE_TYPE = "apache" COPYRIGHT_YEAR = "2020" @@ -57,7 +57,7 @@ localnet_init: /bin/bash ./genlocalnetconfig.sh localnet_start: - @if [ -d "localnet/observer0" ]; then\ + @if [ -d "${LOCALNET_DIR}/observer0" ]; then\ docker-compose --profile observers up -d;\ else\ docker-compose up -d;\ @@ -71,7 +71,7 @@ localnet_export: localnet_stop docker-compose run node1 dcld export --for-zero-height >genesis.export.node1.json docker-compose run node2 dcld export --for-zero-height >genesis.export.node2.json docker-compose run node3 dcld export --for-zero-height >genesis.export.node3.json - @if [ -d "localnet/observer0" ]; then\ + @if [ -d "${LOCALNET_DIR}/observer0" ]; then\ docker-compose run observer0 dcld export --for-zero-height >genesis.export.observer0.json;\ fi @@ -81,7 +81,7 @@ localnet_reset: localnet_stop docker-compose run node1 dcld unsafe-reset-all docker-compose run node2 dcld unsafe-reset-all docker-compose run node3 dcld unsafe-reset-all - @if [ -d "localnet/observer0" ]; then\ + @if [ -d "${LOCALNET_DIR}/observer0" ]; then\ docker-compose run observer0 dcld unsafe-reset-all;\ fi diff --git a/README-DEV.md b/README-DEV.md index 03fdd0a8f..67479a76e 100644 --- a/README-DEV.md +++ b/README-DEV.md @@ -67,7 +67,7 @@ This will start a local pool of 4 validator nodes in Docker. The nodes will expo If you need to start a new clean network then do the following steps prior to executing `make localnet_start`: - Remove `.dclcli` and `.dcld` directories from your user home directory (`~`) - - Remove `localnet` directory from the root directory of the cloned project + - Remove `.localnet` directory from the root directory of the cloned project - Initialize the new network data using `make localnet_init` ## Run CLI Start a local pool as described above, and then just execute diff --git a/deployment/ansible/client/config.yml b/deployment/ansible/client/config.yml index 52144a51c..368cb5b4a 100644 --- a/deployment/ansible/client/config.yml +++ b/deployment/ansible/client/config.yml @@ -21,7 +21,7 @@ state: absent - name: Copy config copy: - src: "./../../../localnet/client/" + src: "./../../../.localnet/client/" dest: "/home/ubuntu/.dclcli/" owner: "ubuntu" - group: "ubuntu" \ No newline at end of file + group: "ubuntu" diff --git a/deployment/ansible/nodes/config.yml b/deployment/ansible/nodes/config.yml index 81f21a0b7..1b8cfef5b 100644 --- a/deployment/ansible/nodes/config.yml +++ b/deployment/ansible/nodes/config.yml @@ -22,7 +22,7 @@ - name: Copy config when: inventory_hostname == 'node' ~ item copy: - src: "./../../localnet/node{{item}}/" + src: "./../../.localnet/node{{item}}/" dest: "/home/ubuntu/.dcld/" owner: "ubuntu" group: "ubuntu" diff --git a/deployment/scripts/run_dcl_node b/deployment/scripts/run_dcl_node new file mode 100755 index 000000000..9206989ef --- /dev/null +++ b/deployment/scripts/run_dcl_node @@ -0,0 +1,456 @@ +#!/bin/bash +# Copyright 2020 DSR Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eu +set -o pipefail + +export PATH="$PATH:/usr/bin" + +SCRIPT_PATH="$(readlink -f "$0")" +BASEDIR="$(dirname "$SCRIPT_PATH")" + +# TODO DOC dcld.service and other files in the current directory +# TODO errors to stderr +# TODO optionally fetch dcld, dclcli and dcld.service from GitHub release + +SERVICE_FILE="./dcld.service" +PERSISTENT_PEERS_FILE='./persistent_peers.txt' +GENESIS_IN_FILE="./genesis.json" +CONFIG_FILE="$HOME/.dcld/config/config.toml" +GENESIS_FILE="$HOME/.dcld/config/genesis.json" + +CLI_PORT=26657 + +PERSISTENT_PEERS= +PEER= +PEER_ID= +PEER_HOSTSPEC="localhost:$CLI_PORT" + + +# ================ FUNCTIONS ============================ +DEF_NODE_TYPE="validator" +DEF_CHAIN_ID="testnet" +DEF_NODE_USER="ubuntu" + +# NODE_TYPE="${1:-validator}" +# NODE_NAME="$2" +# KEY_NAME="${3:-${NODE_NAME}admin}" +# CHAIN_ID="${4:-testnet}" +# NODE_USER="${5:-ubuntu}" +# PEER="${5:-}" + +verbosity=0 +NODE_NAME= +KEY_NAME= +PEER= + +NODE_TYPE="$DEF_NODE_TYPE" +CHAIN_ID="$DEF_CHAIN_ID" +NODE_USER="$DEF_NODE_USER" + + +function usage { + echo "\ +Usage: $0 [options] node-name + +Initializes DCL node of a given type. + +Options: + -c, --chain-id chain id, default: '$DEF_CHAIN_ID' + -h, --help print this help and exit + -k, --key-name account key-name, default: 'admin' + -u, --user node service user, default: '$DEF_NODE_USER' + -t, --type node type, one of 'genesis', 'validator', 'observer', default: '$DEF_NODE_TYPE' +" +#-p, --peer peer hostspec as 'HOST:PORT', default: first entry of 'persistent_peers.txt' +# -v, --verbose be more verbose +} + + +function parse_args { + set -eu + + #getopt --test > /dev/null + #if [[ ${PIPESTATUS[0]} -ne 4 ]]; then + # >&2 echo 'Error: getopt is not functional.' + # exit 1 + #fi + + local _opts=hc:k:p:u:t:v + local _long_opts=help,chain-id:,key-name:,peer:,user:type:,verbose + + local _getopt_res + _getopt_res="$(getopt --name "$0" --options=$_opts --longoptions=$_long_opts -- "$@")" || exit 1 + #if [[ ${PIPESTATUS[0]} -ne 0 ]]; then + # exit 2 + #fi + + # TODO why eval here + eval set -- "$_getopt_res" + + while true; do + case "$1" in + -h|--help) + usage + exit 0 + ;; + -c|--chain-id) + CHAIN_ID="$2" + shift 2 + ;; + -k|--key-name) + KEY_NAME="$2" + shift 2 + ;; + -p|--peer) + PEER="$2" + shift 2 + ;; + -u|--user) + USER="$2" + shift 2 + ;; + -t|--type) + NODE_TYPE="$2" + shift 2 + ;; + -v|--verbose) + ((verbosity=verbosity+1)) + shift + ;; + --) + shift + break + ;; + ?) + >&2 echo "Runtime error" + exit 3 + ;; + *) + >&2 echo "Parser error" + exit 3 + esac + done + + if [[ $# -ne 1 ]]; then + echo "Wrong number of positional arguments" + usage + exit 1 + fi + + NODE_NAME="$1" + + if [[ -z "$KEY_NAME" ]]; then + KEY_NAME="${NODE_NAME}admin" + fi + + if [[ "$NODE_TYPE" == "genesis" ]]; then + PEER_ADDR="localhost" + else + if [[ ! -f "$PERSISTENT_PEERS_FILE" ]]; then + echo "Error. '$PERSISTENT_PEERS_FILE' file not found" + exit 1 + fi + + if [[ ! -f "$GENESIS_IN_FILE" ]]; then + echo "Error. '$GENESIS_IN_FILE' file not found" + exit 1 + fi + + PERSISTENT_PEERS="$(cat $PERSISTENT_PEERS_FILE | head -n1)" + + if [[ -z "$PEER" ]]; then + PEER="$(echo "$PERSISTENT_PEERS" | awk -F',' '{print $1}')" + fi + PEER_ID="$(echo "$PEER" | awk -F'@' '{print $1}')" + PEER_HOSTSPEC="$(echo "$PEER" | awk -F'@' '{print $2}')" + PEER_ADDR="$(echo "$PEER_HOSTSPEC" | awk -F':' '{print $1}')" + fi +} + +function config_cli { + set -eu + set -o pipefail + + local _chain_id="$1" + local _peer_host="${2:-}" + + dclcli config chain-id "$_chain_id" + dclcli config output json + dclcli config indent true + dclcli config trust-node false + if [[ -n "$_peer_host" ]]; then + dclcli config node tcp://"$_peer_host" + fi +} + + +function add_key { + set -eu + set -o pipefail + + local _key_name="$1" + local _output="${2:-${_key_name}.dclkey.json}" + + dclcli keys add "$_key_name" 2>&1 | tee "$_output" + echo -e "\tSaved key data in '$_output'" +} + + +function node_init { + set -eu + set -o pipefail + + local _name="$1" + local _chain_id="$2" + + rm -rf "$HOME/.dcld/config/gentx" + rm -f "$GENESIS_FILE" + + dcld init "$_name" --chain-id "$_chain_id" +} + + +function build_genesis { + set -eu + set -o pipefail + + local _key_name="$1" + local _acc_address="$2" + local _acc_pubkey="$3" + local _acc_roles="${4:-Trustee,NodeAdmin}" + + dcld add-genesis-account --address="$_acc_address" --pubkey="$_acc_pubkey" --roles="$_acc_roles" + dcld gentx --from "$_key_name" + dcld collect-gentxs + dcld validate-genesis +} + +function config_node { + set -eu + set -o pipefail + + local _node_user="$1" + local _dcld_service_p="${2:-./dcld.service}" + local _peers="${3:-}" + + local _debug="${DEBUG:-}" + + sed -i -r 's~^laddr = "tcp://127.0.0.1:~laddr = "tcp://0.0.0.0:~' "$CONFIG_FILE" + + # FIXME verify + if [[ -n "$_peers" ]]; then + sed -i -r "s~^persistent_peers = .*~persistent_peers = \"$_peers\"~" "$CONFIG_FILE" + fi + + if [[ -z "$_debug" ]]; then + # config the service + # Ubuntu only + grep -q -i -e 'ubuntu' /etc/*-release && { + if [[ ! -f "$_dcld_service_p" ]]; then + echo "Error. '$_dcld_service_p' file not found" + exit 1 + fi + + # TODO move ot a separate script + # Open '26656' (p2p) and '26657' (RPC) ports. + sudo ufw allow 26656/tcp + sudo ufw allow 26657/tcp + # set systemd dcld.service + sed -i -r "s~^User=ubuntu$~User=${NODE_USER}~" "$_dcld_service_p" + sudo cp -f "$_dcld_service_p" /etc/systemd/system/dcld.service + } || { echo "Warning: Not an Ubuntu system. Skipping systemd service configuration";} + fi +} + + +function run_node { + set -eu + set -o pipefail + + local _debug="${DEBUG:-}" + + if [[ -z "$_debug" ]]; then + # Ubuntu only + grep -q -i -e 'ubuntu' /etc/*-release && { + # Enable the service + sudo systemctl enable dcld + # Start node + sudo systemctl start dcld + } || { echo "Warning: Not an Ubuntu system. Skipping service start..."; return 0; } + + echo "Node has been stared as a service." + + echo -e "\tUse 'systemctl status dcld' to get the node service status." + echo "Use 'journalctl -u dcld.service -f' to see node logs." + else + dcld start & + echo "Node has been stared in the backgroud." + fi +} + + +function verify_node { + set -eu + set -o pipefail + + local _node_ip="${1:-0.0.0.0:26657}" + + echo "Checking a node's 'sync_info.latest_block_height' value is not increasing..." + + echo "sync_info.latest_block_height Try 1" + check1="$(dclcli status --node "$_node_ip" | grep latest_block_height)" + + echo "sync_info.latest_block_height Try 2" + # TODO it should depend on empty block creation setting value + sleep 6 + check2="$(dclcli status --node "$_node_ip" | grep latest_block_height)" + + if [[ "$check1" == "$check2" ]]; then + echo "Error: sync_info.latest_block_height value is not increasing..." + exit 1 + fi + + # TODO improve: makes sense only for initial genesis node + echo "Checking the node is participating in consensus..." + dclcli tendermint-validator-set | grep -q address + + # TODO check: catching_up is false + + echo "Passed" +} + + +function add_account { + set -eu + set -o pipefail + + local _acc_address="$1" + local _acc_pubkey="$2" + local _acc_roles="$3" + local _from="$4" + + dclcli tx auth propose-add-account --address="$_acc_address" --pubkey="$_acc_pubkey" \ + --roles="$_acc_roles" --from="$_from" + + echo "Account added" + echo "To approve run: dclcli tx auth approve-add-account --address= --from=" +} + + +function approve_account { + set -eu + set -o pipefail + + local _acc_address="$1" + local _from="$2" + + dclcli tx auth approve-add-account --address="$_acc_address" --from="$_from" + + echo "Account approved by $_from" +} + +# ======================================================= + +parse_args "$@" + +if [[ "$verbosity" -ge 2 ]]; then + set -x +fi + +if [[ "$verbosity" -ge 1 ]]; then + echo "" + #parsed_args="" + #parsed_args+="\t CHAIN_ID=$output_dir\n\toutput_type=$output_type" + #parsed_args+="\n\tin_docker=$in_docker\n\tinput_dir=$input_dir" + #parsed_args+="\n\tfpm_tool=$fpm_tool\n\tverbosity=$verbosity" + #parsed_args+="\n\trelease=$pkg_version" + + #echo -e "Parsed arguments:\n$parsed_args" +fi + +echo "Configuring CLI" + +# Note. we consider that cli would connect to local node (default setting) +config_cli "$CHAIN_ID" + +if [[ "$NODE_TYPE" != "observer" ]]; then + echo "Generating genesis account keys..." + add_key "$KEY_NAME" +fi + +ACC_ADDR="$(dclcli keys show "${KEY_NAME}" | grep address | awk -F'"' '{print $4}')" +ACC_PUBKEY="$(dclcli keys show "${KEY_NAME}" | grep pubkey | awk -F'"' '{print $4}')" + +echo "Initializing the node" +node_init "$NODE_NAME" "$CHAIN_ID" + + +if [[ "$NODE_TYPE" == "genesis" ]]; then + echo "Building genesis file" + build_genesis "$KEY_NAME" "$ACC_ADDR" "$ACC_PUBKEY" + # TODO copy to the current directory +else + echo "Locating the genesis file at $GENESIS_FILE" + cp -f "$GENESIS_IN_FILE" "$GENESIS_FILE" +fi + +echo "Configuring node" +config_node "$NODE_USER" "$SERVICE_FILE" "$PERSISTENT_PEERS" +echo -e "\tDone." +echo -e "\nOptionally, edit '$CONFIG_FILE' in order to set different setting (like listen address)" + +echo "Running the node" +run_node + +if [[ "$NODE_TYPE" == "validator" ]]; then + VAL_ADDR="$(dcld tendermint show-address)" + VAL_PUBKEY="$(dcld tendermint show-validator)" + + + echo "Done" + + echo -e "\n====================================\n" + + echo "Generated data:" + echo -e "\tAccount data:" + echo -e "\t\taddress: '$ACC_ADDR'" + echo -e "\t\tpublic key: '$ACC_PUBKEY'" + echo -e "\tValidator node data:" + echo -e "\t\taddress: '$VAL_ADDR'" + echo -e "\t\tpublic key: '$VAL_PUBKEY'" + + echo -e "\nNext steps:" + echo -e "\t1. Share generated account addres and pubkey to any 'Trustee' to create an account with 'NodeAdmin' role." + echo -e "\t(e.g. dclcli tx auth propose-add-account --address=$ACC_ADDR --pubkey=$ACC_PUBKEY --roles=NodeAdmin --from=)" + echo -e "\n\t2 Once the account is approved, please run the following command to make the node a validator:" + echo -e "\t\t'dclcli tx validator add-node --validator-address=$VAL_ADDR --validator-pubkey=$VAL_PUBKEY --name=$NODE_NAME --from=$KEY_NAME'" + + +fi + +echo "Done" + + +# useful commands +# - keys: +# dclcli keys show : to get address and oubkey for a ketname +# - node status: +# - systemctl status dcld: to get the node service status. +# - journalctl -u dcld.service -f: to see node logs. +# - dclcli status [--node `]: to get the current status. +# - dclcli tendermint-validator-set [height]: list of nodes participating in consensus +# - account status: +# - dclcli query auth account --address=
: to ensure that account is created and has assigned role diff --git a/deployment/scripts/verify_node b/deployment/scripts/verify_node new file mode 100755 index 000000000..6dcaf39d2 --- /dev/null +++ b/deployment/scripts/verify_node @@ -0,0 +1,44 @@ +#!/bin/bash +# Copyright 2020 DSR Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +DEBUG="${DEBUG:-}" + +NODE_IP="${1:-0.0.0.0:26657}" + +set -eu +set -o pipefail + +export PATH="$PATH:/usr/bin" + +echo "Checking the node 'sync_info.latest_block_height' value is not increasing..." + +echo "sync_info.latest_block_height Try 1" +check1="$(dclcli status --node "$NODE_IP" | grep latest_block_height)" + +echo "sync_info.latest_block_height Try 2" +# TODO it should depend on empty block creation setting value +sleep 6 +check2="$(dclcli status --node "$NODE_IP" | grep latest_block_height)" + +if [[ "$check1" == "$check2" ]]; then + echo "Error: sync_info.latest_block_height value is not increasing..." + exit 1 +fi + +# TODO improve +echo "Checking the node is participating in consensus..." +dclcli tendermint-validator-set | grep -q address + +echo "Passed" diff --git a/docker-compose.yml b/docker-compose.yml index 4de8984ef..ee430aa0b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,7 +23,7 @@ services: - "26656-26657:26656-26657" - "26650:26660" volumes: - - ./localnet/node0:/root/.dcld:Z + - ./.localnet/node0:/root/.dcld:Z networks: localnet: ipv4_address: 192.167.10.2 @@ -37,7 +37,7 @@ services: - "26658-26659:26656-26657" - "26651:26660" volumes: - - ./localnet/node1:/root/.dcld:Z + - ./.localnet/node1:/root/.dcld:Z networks: localnet: ipv4_address: 192.167.10.3 @@ -51,7 +51,7 @@ services: - "26660-26661:26656-26657" - "26652:26660" volumes: - - ./localnet/node2:/root/.dcld:Z + - ./.localnet/node2:/root/.dcld:Z networks: localnet: ipv4_address: 192.167.10.4 @@ -67,7 +67,7 @@ services: # uncomment following line if starting in debug mode # - "2345:2345" volumes: - - ./localnet/node3:/root/.dcld:Z + - ./.localnet/node3:/root/.dcld:Z networks: localnet: ipv4_address: 192.167.10.5 @@ -87,7 +87,7 @@ services: # uncomment following line if starting in debug mode # - "2345:2345" volumes: - - ./localnet/observer0:/root/.dcld:Z + - ./.localnet/observer0:/root/.dcld:Z networks: localnet: ipv4_address: 192.167.10.6 diff --git a/docs/localnet-setup.md b/docs/localnet-setup.md index b7e3ea025..9b90059b7 100644 --- a/docs/localnet-setup.md +++ b/docs/localnet-setup.md @@ -45,5 +45,5 @@ - Then you can start the network again with the existing data using `make localnet_start` - If you need to start a new clean network then do the following steps prior to executing `make localnet_start`: - Remove `.dclcli` and `.dcld` directories from your user home directory (`~`) - - Remove `localnet` directory from the root directory of the cloned project + - Remove `.localnet` directory from the root directory of the cloned project - Initialize the new network data using `make localnet_init` diff --git a/docs/running-node.md b/docs/running-node.md new file mode 100644 index 000000000..85350b64d --- /dev/null +++ b/docs/running-node.md @@ -0,0 +1,161 @@ +# Running a DCLedger Node + +This document describes in details how to configure different types of DCLedger nodes. + +## Components + +* Common release artifacts: + * Binary artifacts (part of the release): + * dcld: The binary used for running a node. + * dclcli: The binary that allows users to interact with the network of nodes. + * The service configuration file `dcld.service` + (either part of the release or [deployment](../deployment) folder). + * where to get: + * The latest release can be found at [DCL Releases](https://github.com/zigbee-alliance/distributed-compliance-ledger/releases). +* Additional generated data (for validators and observers): + * Genesis transactions file: `genesis.json` + * The list of alive peers: `persistent_peers.txt` with the following format: `@,@,...`. + * where to get: + * If you want to join an existing persistent network (such as Test Net), then look at the [Persistent Chains](../deployment/persistent_chains) + folder for a list of available networks. Each subfolder there represents a `` and contains the genesis and persistent_peers files. + +## Hardware requirements + +Minimal: + +* 1GB RAM +* 25GB of disk space +* 1.4 GHz CPU + +Recommended (for highload applications): + +* 2GB RAM +* 100GB SSD +* x64 2.0 GHz 2v CPU + +## Operating System + +Current delivery is compiled and tested under `Ubuntu 18.04.3 LTS` so we recommend using this distribution for now. In future, it will be possible to compile the application for a wide range of operating systems thanks to Go language. + +Notes: + +* the deployment commands below will try to setup and run `dcld` systemd service on Ubuntu +* that will require `sudo` for a user +* in case non-Ubuntu system these steps will be scipped so you would need to take care about + +## Deployment + +Pre-requisites: + +1. `dcld` and `dclcli` binaries are located in `/usr/bin` +2. (for systemd systems) `dcld.service` is available in the current directory +3. (for validator and observer) `genesis.json` and `persistent_peers.txt` are available in the current directory + +### Genesis Validator Node + +This part describes how to configure a genesis node - a starting point of any new network. + +The following steps automates a set of instructions that you can find in [Running Genesis Node](running-genesis-node.md) document. + +#### Choose the chain ID + +Every network (for example, test-net, main-net, etc.) must have a unique chain ID. + +#### Setup a node + +Run + +```bash +$ run_dcl_node -t genesis -c node0 +``` + +This command: + +* generates a new key entry for a node admin account +* generates `genesis.json` file with the following entries: + * a genenesis account for the key entry above with `Trustee` and `NodeAdmin` roles + * a genesis txn that makes the local node a validator +* configures and starts the node + +Outputs: + +* `*.dclkey.json` file in the current directory with node admint key data (address, public key, mnemonic) +* standard output: + * genesis file `$HOME/.dcld/config/genesis.json` + +**Note**. Once more validator nodes are added it's important to update: + +* `persistent_peers.txt` file by including the entries for every added initial node +* update the `persistent_peers` field in `$HOME/.dcld/config/config.toml` + +## Validator Node + +This part describes how to configure a validator node and add it to the existing network. + +The following steps automates a set of instructions that you can find in [Running Validator Node](running-validator-node.md) document + +#### Setup a node + +Run + +```bash +$ run_dcl_node -c +``` + +This command: + +* generates a new key entry for a node admin account + * by default `admin` key name is used + * can be configured using `-k/--key-name` option +* properly locates `genesis.json` +* configures and starts the node + +Outputs: + +* `*.dclkey.json` file in the current directory with node admint key data (address, public key, mnemonic) +* standard output: + * node admin key data: `address` and `pubkey` + * validator data: `address` and `pubkey` + +#### Ask for a ledger account + +Provide generated node admin key `address` and `pubkey` to any `Trustee`(s). So they may create +an account with `NodeAdmin` role. And **wait** until: + +* Account is created +* The node completed a catch-up: + * `dclcli status --node ` returns `false` for `catching_up` field + +#### Make the node a validator + +```bash +$ dclcli tx validator add-node \ + --validator-address= --validator-pubkey= \ + --name= --from= +``` + +If the transaction has been successfully written you would find `"success": true` in the output JSON. + +### Observer Node + +This part describes how to configure an observer node and add it to the existing network. + +The following command automates a set of instructions that you can find in [Running Observer Node](running-observer-node.md) document + +Run + +```bash +$ run_dcl_node -t observer -c +``` + +## Deployment Verification + +* Check the account: + * `dclcli query auth account --address=
` +* Check the node is running and participates in consensus: + * `dclcli status --node ` + * The value of `` matches to `[rpc] laddr` field in `$HOME/.dcld/config/config.toml` + * Make sure that `result.sync_info.latest_block_height` is increasing over the time (once in about 5 sec). +* Get the list of nodes participating in the consensus for the last block: + * `dclcli tendermint-validator-set`. + * You can pass the additional value to get the result for a specific height: `dclcli tendermint-validator-set 100`. diff --git a/genlocalnetconfig.sh b/genlocalnetconfig.sh index df12d223b..3be84a1c1 100755 --- a/genlocalnetconfig.sh +++ b/genlocalnetconfig.sh @@ -16,6 +16,7 @@ set -euo pipefail DCL_OBSERVERS="${DCL_OBSERVERS:-}" +LOCALNET_DIR=".localnet" SED_EXT= if [ "$(uname)" == "Darwin" ]; then @@ -26,11 +27,11 @@ fi rm -rf ~/.dclcli rm -rf ~/.dcld -rm -rf localnet -mkdir localnet localnet/client localnet/node0 localnet/node1 localnet/node2 localnet/node3 +rm -rf "$LOCALNET_DIR" +mkdir "$LOCALNET_DIR" "$LOCALNET_DIR"/{client,node0,node1,node2,node3} if [[ -n "$DCL_OBSERVERS" ]]; then - mkdir localnet/observer0 + mkdir "$LOCALNET_DIR/observer0" fi # client @@ -45,7 +46,7 @@ echo 'test1234' | dclcli keys add alice echo 'test1234' | dclcli keys add bob echo 'test1234' | dclcli keys add anna -cp -r ~/.dclcli/* localnet/client +cp -r ~/.dclcli/* "$LOCALNET_DIR/client" # node 0 @@ -70,7 +71,7 @@ dcld add-genesis-account --address=$anna_address --pubkey=$anna_pubkey --roles=" echo 'test1234' | dcld gentx --from jack -mv ~/.dcld/* localnet/node0 +mv ~/.dcld/* "$LOCALNET_DIR/node0" # node 1 @@ -83,7 +84,7 @@ dcld add-genesis-account --address=$anna_address --pubkey=$anna_pubkey --roles=" echo 'test1234' | dcld gentx --from alice -mv ~/.dcld/* localnet/node1 +mv ~/.dcld/* "$LOCALNET_DIR/node1" # node 2 @@ -96,7 +97,7 @@ dcld add-genesis-account --address=$anna_address --pubkey=$anna_pubkey --roles=" echo 'test1234' | dcld gentx --from bob -mv ~/.dcld/* localnet/node2 +mv ~/.dcld/* "$LOCALNET_DIR/node2" # node 3 @@ -109,10 +110,10 @@ dcld add-genesis-account --address=$anna_address --pubkey=$anna_pubkey --roles=" echo 'test1234' | dcld gentx --from anna -cp -r ~/.dcld/* localnet/node3 +cp -r ~/.dcld/* "$LOCALNET_DIR/node3" -if [[ -d "localnet/observer0" ]]; then +if [[ -d "$LOCALNET_DIR/observer0" ]]; then rm -rf ~/.dcld/* # observer0 @@ -123,16 +124,16 @@ if [[ -d "localnet/observer0" ]]; then dcld add-genesis-account --address=$bob_address --pubkey=$bob_pubkey --roles="Trustee,NodeAdmin" dcld add-genesis-account --address=$anna_address --pubkey=$anna_pubkey --roles="NodeAdmin" - cp -r ~/.dcld/* localnet/observer0 + cp -r ~/.dcld/* "$LOCALNET_DIR/observer0" fi # Collect all validator creation transactions mkdir -p ~/.dcld/config/gentx -cp localnet/node0/config/gentx/* ~/.dcld/config/gentx -cp localnet/node1/config/gentx/* ~/.dcld/config/gentx -cp localnet/node2/config/gentx/* ~/.dcld/config/gentx -cp localnet/node3/config/gentx/* ~/.dcld/config/gentx +cp "$LOCALNET_DIR"/node0/config/gentx/* ~/.dcld/config/gentx +cp "$LOCALNET_DIR"/node1/config/gentx/* ~/.dcld/config/gentx +cp "$LOCALNET_DIR"/node2/config/gentx/* ~/.dcld/config/gentx +cp "$LOCALNET_DIR"/node3/config/gentx/* ~/.dcld/config/gentx # Embed them into genesis @@ -141,35 +142,35 @@ dcld validate-genesis # Update genesis for all nodes -cp ~/.dcld/config/genesis.json localnet/node0/config/ -cp ~/.dcld/config/genesis.json localnet/node1/config/ -cp ~/.dcld/config/genesis.json localnet/node2/config/ -cp ~/.dcld/config/genesis.json localnet/node3/config/ +cp ~/.dcld/config/genesis.json "$LOCALNET_DIR/node0/config/" +cp ~/.dcld/config/genesis.json "$LOCALNET_DIR/node1/config/" +cp ~/.dcld/config/genesis.json "$LOCALNET_DIR/node2/config/" +cp ~/.dcld/config/genesis.json "$LOCALNET_DIR/node3/config/" -if [[ -d "localnet/observer0" ]]; then - cp ~/.dcld/config/genesis.json localnet/observer0/config/ +if [[ -d "$LOCALNET_DIR/observer0" ]]; then + cp ~/.dcld/config/genesis.json "$LOCALNET_DIR/observer0/config/" fi # Find out node ids -id0=$(ls localnet/node0/config/gentx | sed 's/gentx-\(.*\).json/\1/') -id1=$(ls localnet/node1/config/gentx | sed 's/gentx-\(.*\).json/\1/') -id2=$(ls localnet/node2/config/gentx | sed 's/gentx-\(.*\).json/\1/') -id3=$(ls localnet/node3/config/gentx | sed 's/gentx-\(.*\).json/\1/') +id0=$(ls "$LOCALNET_DIR/node0/config/gentx" | sed 's/gentx-\(.*\).json/\1/') +id1=$(ls "$LOCALNET_DIR/node1/config/gentx" | sed 's/gentx-\(.*\).json/\1/') +id2=$(ls "$LOCALNET_DIR/node2/config/gentx" | sed 's/gentx-\(.*\).json/\1/') +id3=$(ls "$LOCALNET_DIR/node3/config/gentx" | sed 's/gentx-\(.*\).json/\1/') # Update address book of the first node peers="$id0@192.167.10.2:26656,$id1@192.167.10.3:26656,$id2@192.167.10.4:26656,$id3@192.167.10.5:26656" # Update address book of the first node -sed -i $SED_EXT "s/persistent_peers = \"\"/persistent_peers = \"$peers\"/g" localnet/node0/config/config.toml -if [[ -d "localnet/observer0" ]]; then - sed -i $SED_EXT "s/persistent_peers = \"\"/persistent_peers = \"$peers\"/g" localnet/observer0/config/config.toml +sed -i $SED_EXT "s/persistent_peers = \"\"/persistent_peers = \"$peers\"/g" "$LOCALNET_DIR/node0/config/config.toml" +if [[ -d "$LOCALNET_DIR/observer0" ]]; then + sed -i $SED_EXT "s/persistent_peers = \"\"/persistent_peers = \"$peers\"/g" "$LOCALNET_DIR/observer0/config/config.toml" fi # Make RPC endpoint available externally for node_id in node0 node1 node2 node3 observer0; do - if [[ -d "localnet/${node_id}" ]]; then - sed -i $SED_EXT 's/laddr = "tcp:\/\/127.0.0.1:26657"/laddr = "tcp:\/\/0.0.0.0:26657"/g' "localnet/${node_id}/config/config.toml" - sed -i $SED_EXT 's/prometheus = false/prometheus = true/g' "localnet/${node_id}/config/config.toml" + if [[ -d "$LOCALNET_DIR/${node_id}" ]]; then + sed -i $SED_EXT 's/laddr = "tcp:\/\/127.0.0.1:26657"/laddr = "tcp:\/\/0.0.0.0:26657"/g' "$LOCALNET_DIR/${node_id}/config/config.toml" + sed -i $SED_EXT 's/prometheus = false/prometheus = true/g' "$LOCALNET_DIR/${node_id}/config/config.toml" fi done diff --git a/gentestaccounts.sh b/gentestaccounts.sh index a9ee003d9..3e15a4476 100755 --- a/gentestaccounts.sh +++ b/gentestaccounts.sh @@ -21,7 +21,9 @@ if [ "$(uname)" == "Darwin" ]; then SED_EXT="''" fi -rm -rf localnet/client/* +LOCALNET_DIR=".localnet" + +rm -rf "$LOCALNET_DIR"/client/* PASSWD=test1234 NUMUSERS="${1:-10}" @@ -40,9 +42,9 @@ done dcld validate-genesis -cp -r ~/.dclcli/* localnet/client +cp -r ~/.dclcli/* "$LOCALNET_DIR"/client for node_id in node0 node1 node2 node3 observer0; do - if [[ -d "localnet/${node_id}" ]]; then - cp -f ~/.dcld/config/genesis.json "localnet/${node_id}/config/" + if [[ -d "$LOCALNET_DIR/${node_id}" ]]; then + cp -f ~/.dcld/config/genesis.json "$LOCALNET_DIR/${node_id}/config/" fi done diff --git a/integration_tests/ci/run-all.sh b/integration_tests/ci/run-all.sh index 42ddb43cf..d3436caa5 100755 --- a/integration_tests/ci/run-all.sh +++ b/integration_tests/ci/run-all.sh @@ -15,6 +15,8 @@ DETAILED_OUTPUT=true +LOCALNET_DIR=".localnet" + LOG_PREFIX="[run all] " SED_EXT= if [ "$(uname)" == "Darwin" ]; then @@ -61,7 +63,7 @@ wait_for_height() { } patch_consensus_config() { - local NODE_CONFIGS=$(find localnet -type f -name "config.toml" -wholename "*node*") + local NODE_CONFIGS="$(find "$LOCALNET_DIR" -type f -name "config.toml" -wholename "*node*")" for NODE_CONFIG in ${NODE_CONFIGS}; do sed -i $SED_EXT 's/timeout_propose = "3s"/timeout_propose = "500ms"/g' "${NODE_CONFIG}" @@ -95,9 +97,9 @@ cleanup_pool() { rm -rf ~/.dclcli rm -rf ~/.dcld if [ "$(uname)" == "Darwin" ]; then - rm -rf localnet + rm -rf "$LOCALNET_DIR" else - sudo rm -rf localnet + sudo rm -rf "$LOCALNET_DIR" fi } diff --git a/integration_tests/cli/validator-demo.sh b/integration_tests/cli/validator-demo.sh index 2912f5c06..206ae8a17 100755 --- a/integration_tests/cli/validator-demo.sh +++ b/integration_tests/cli/validator-demo.sh @@ -16,6 +16,8 @@ set -euo pipefail source integration_tests/cli/common.sh +LOCALNET_DIR=".localnet" + random_string account container="validator-demo" node="node-demo" @@ -51,8 +53,8 @@ test_divider echo "$account Prepare Node configuration files" docker exec $container dcld init $node --chain-id $chain_id -docker cp ./localnet/node0/config/genesis.json $container:/root/.dcld/config -peers=$(cat localnet/node0/config/config.toml | grep -o -E "persistent_peers = \".*\"") +docker cp "$LOCALNET_DIR/node0/config/genesis.json" $container:/root/.dcld/config +peers="$(cat "$LOCALNET_DIR/node0/config/config.toml" | grep -o -E "persistent_peers = \".*\"")" docker exec $container sed -i "s/persistent_peers = \"\"/$peers/g" /root/.dcld/config/config.toml docker exec $container sed -i 's/laddr = "tcp:\/\/127.0.0.1:26657"/laddr = "tcp:\/\/0.0.0.0:26657"/g' /root/.dcld/config/config.toml @@ -136,4 +138,4 @@ check_response "$result" "\"pid\": $pid" check_response "$result" "\"productLabel\": \"$productName\"" echo "$result" -docker rm -f $container \ No newline at end of file +docker rm -f $container