diff --git a/testnet/README.md b/testnet/README.md new file mode 100644 index 00000000..f7a1bda6 --- /dev/null +++ b/testnet/README.md @@ -0,0 +1,11 @@ +# Testnet + +## Setup local laconic multi node testnet in local enviorment + +```shell +$ bash multinode_testnet.sh + +or +# this is create localnet with docker containers +$ make localnet-start +``` diff --git a/testnet/full_node.md b/testnet/full_node.md new file mode 100644 index 00000000..ea6670a5 --- /dev/null +++ b/testnet/full_node.md @@ -0,0 +1,209 @@ +# Instructions to Run Full Node + +## Hardware + +#### Supported + +- **Operating System (OS):** Ubuntu 20.04 +- **CPU:** 1 core +- **RAM:** 2GB +- **Storage:** 25GB SSD + +#### Recommended + +- **Operating System (OS):** Ubuntu 20.04 +- **CPU:** 2 core +- **RAM:** 4GB +- **Storage:** 50GB SSD + +# A) Setup + +## 1) Install Golang (go) + +1.1) Remove any existing installation of `go` + +``` +sudo rm -rf /usr/local/go +``` + +1.2) Install latest/required Go version (installing `go1.17.2`) + +``` +curl https://golang.org/dl/go1.17.2.linux-amd64.tar.gz +sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.17.2.linux-amd64.tar.gz +``` + +1.3) Update env variables to include `go` + +``` +cat <<'EOF' >>$HOME/.profile +export GOROOT=/usr/local/go +export GOPATH=$HOME/go +export GO111MODULE=on +export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin +EOF + +source $HOME/.profile +``` + +1.4) Check the version of go installed + +``` +go version +``` + +### 2) Install required software packages + +``` +sudo apt-get install git curl build-essential make jq -y +``` + +### 3) Install `laconicd` + +``` +git clone https://github.com/cerc-io/laconicd.git +cd laconicd +git fetch --all +git checkout main +make install +``` + +### 4) Verify your installation + +``` +laconicd version --long +``` + +On running the above command, you should see a similar response like this. Make sure that the _version_ and _commit +hash_ are accurate + +``` +name: laconicd +server_name: laconicd +``` + +### 5) Initialize Node + +**Not required if you have already initialized before** + +``` +laconicd init --chain-id laconic_81337-2 +``` + +On running the above command, node will be initialized with default configuration. (config files will be saved in node's +default home directory (~/.laconicd/config) + +NOTE: Backup node and validator keys . You will need to use these keys at a later point in time. + +--- + +# B) Starting Node + +## 1) Download Final Genesis + +Use `curl` to download the genesis file +**Replace your **genesis** file with published genesis file** + +```shell +# Will be updated +curl {GENESIS_LINK} | jq .result.genesis > ~/.laconicd/config/genesis.json +``` + +Verify sha256 hash of genesis file with the below command + +``` +jq -S -c -M '' ~/.laconicd/config/genesis.json | shasum -a 256 +``` + +genesis sha256 hash should be + +``` +{WILL BE UPDATED} +``` + +## 2) Update Peers & Seeds in config.toml + +``` + + +{peers={WILL BE UPDATED}} +sed -i.bak -e "s/^persistent_peers *=.*/persistent_peers = \"$peers\"/" ~/.laconicd/config/config.toml +``` + +## 3) Start the Full Node + +#### 3.1) Start node as `systemctl` service + +3.1.1) Create the service file + +``` +sudo tee /etc/systemd/system/laconicd.service > /dev/null <>$HOME/.profile +export GOROOT=/usr/local/go +export GOPATH=$HOME/go +export GO111MODULE=on +export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin +EOF + +source $HOME/.profile +``` + +Check the version of go installed + +```sh +go version + +# Should return something like: go version go1.17.2 linux/amd64 +``` + +--- + +## Install `laconic` + +```sh +git clone https://github.com/cerc-io/laconicd.git +cd laconicd + +# Checkout main branch +git fetch --all +git checkout main + +# Build and install laconic +make install +``` + +Verify your installation + +```sh +laconicd version --long +``` + +On running the above command, you should see a similar response like this. Make sure that the _version_ and _commit +hash_ are accurate + +```sh +name: laconic +server_name: laconicd +``` + +--- + +## Initialize Validator Node + +**Not required if you have already initialized before** + +```sh +# Initialize the validator node +laconicd init --chain-id laconic_81337-4 +``` + +Running the above commands will initialize the validator node with default configuration. The config files will be saved in the default location (`~/.laconicd/config`). + +**NOTE:** Backup your node and validator keys. You will need to use these keys at a later point in time. + +--- + +## Overwrite Validator Initialization from previous testnet + +**Required for `laconic_81337-4`** + +First we have to reset the previous genesis state (only because the `laconic_81337-3` testnet failed) whereafter we can initialize the validator node for `laconic_81337-4` + +```sh +# Stop your node (in case it was still running) +systemctl stop laconicd + +# Keep a backup of your old validator directory +cp -a ~/.laconicd ~/backup-laconic_81337-2 + +# Reset the state of your validator +laconicd tendermint unsafe-reset-all --home $HOME/.laconicd + +# Remove your previous genesis transactions +rm $HOME/.laconicd/config/gentx/gentx*.json + +# Overwrite your genesis state with the new chain-id +laconicd init --overwrite --chain-id laconic_81337-4 +``` + +Running the above commands will re-initialize the validator node with default configuration. The config files will be saved in the default location (`~/.laconicd/config`). + +**NOTE:** Backup your node and validator keys. You will need to use these keys at a later point in time. + +--- + +## Create Account keys + +If you have participated in a previous testnet and have a mnemonic phrase, use below command to recover your account: + +```sh +laconicd keys add --recover +``` + +To create a new account use: + +```sh +laconicd keys add +``` + +**NOTE:** Save the `mnemonic` and related account details (public key). You will need to use the mnemonic and / or private key to recover accounts at a later point in time. + +--- + +## Add Genesis Account + +**NOTE:** Don't add more than 12,900 CHK , if you add more than that, your gentx will be ignored. + +```sh +laconicd add-genesis-account 12900000000000000000000achk --keyring-backend os +``` + +Create Your `gentx` transaction file + +```sh +laconicd gentx 12900000000000000000000achk \ + --pubkey=$(laconicd tendermint show-validator) \ + --chain-id="laconic_81337-4" \ + --moniker="" \ + --website="" \ + --details="" \ + --identity="" \ + --commission-rate="0.10" \ + --commission-max-rate="0.20" \ + --commission-max-change-rate="0.01" \ + --min-self-delegation="1" +``` + +**NOTE:** + +- `` and `chain-id` are required. other flags are optional +- Don't change the amount value while creating your gentx +- Genesis transaction file will be saved in `~/.laconicd/config/gentx` folder + +--- + +## Submit Your gentx + +Submit your `gentx` file to the [https://github.com/cerc-io/laconic-testnet]() repository in the following format: +`-gentx.json` + +**NOTE:** (Do NOT use spaces in the file name) + +To submit the gentx file, follow the below process: + +- Fork the [https://github.com/cerc-io/laconic-testnet]() repository +- Upload your gentx file in the `laconic_81337-4/config/gentxs` folder +- Submit Pull Request to [https://github.com/cerc-io/laconic-testnet]() with name `ADD gentx` + +The genesis file will be published in the `laconic_81337-4/config/` folder within the [https://github.com/cerc-io/laconic-testnet]() repository. + +# CONTINUE WITH BELOW STEPS ONLY AFTER GENESIS FILE HAS BEEN PUBLISHED + +## Adjust validator node configuration + +```sh +# Set seed & peers variable +seeds="" +peers="" + +# Update seeds, persistent_peers and prometheus parameters in config.toml +sed -i.bak -e "s/^seeds *=.*/seeds = \"$seeds\"/; s/^persistent_peers *=.*/persistent_peers = \"$peers\"/; s/^prometheus *=.*/prometheus = true/" $HOME/.laconicd/config/config.toml + +# Create systemd validator service +sudo tee /etc/systemd/system/laconicd.service > /dev/null </dev/null +} + +if command_exists go; then + echo "Golang is already installed" +else + echo "Installing golang dependencies" + wget https://golang.org/dl/go1.17.2.linux-amd64.tar.gz + rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.2.linux-amd64.tar.gz + + echo "Updating the profile" + export GOPATH=$HOME/go + export GOROOT=/usr/local/go + export GOBIN=$GOPATH/bin + export PATH=$PATH:/usr/local/go/bin:$GOBIN + + echo "" >>~/.profile + echo 'export GOPATH=$HOME/go' >>~/.profile + echo 'export GOROOT=/usr/local/go' >>~/.profile + echo 'export GOBIN=$GOPATH/bin' >>~/.profile + echo 'export PATH=$PATH:/usr/local/go/bin:$GOBIN' >>~/.profile + + source ~/.profile + mkdir -p "$GOBIN" + mkdir -p $GOPATH/src/github.com + go version +fi + +# chain env variables +export DAEMON_HOME=~/.testlaconic +export CHAINID=laconic_9000-1 +export DENOM=achk +export GH_URL=https://github.com/cerc-io/laconicd.git +export CHAIN_VERSION=main +export DAEMON=laconicd + +display_usage() { + printf "** Please check the exported values:: **\n Daemon : $DAEMON\n Denom : $DENOM\n ChainID : $CHAINID\n DaemonHome : $DAEMON_HOME\n \n Github URL : $GH_URL\n Chain Version : $CHAIN_VERSION\n" + exit 1 +} + +if [ -z $DAEMON ] || [ -z $DENOM ] || [ -z $CHAINID ] || [ -z $DAEMON_HOME ] || [ -z $GH_URL ] || [ -z $CHAIN_VERSION ]; then + display_usage +fi + +echo "--------- Install $DAEMON ---------" +git clone -b $CHAIN_VERSION --single-branch $GH_URL && cd $(basename $_ .git) +git fetch && git checkout $CHAIN_VERSION +make install + +cd $HOME + +# check version +$DAEMON version --long + +#echo "----------Create test keys-----------" + +export DAEMON_HOME_1=$DAEMON_HOME-1 +export DAEMON_HOME_2=$DAEMON_HOME-2 +export DAEMON_HOME_3=$DAEMON_HOME-3 +export DAEMON_HOME_4=$DAEMON_HOME-4 + +printf "DAEMON_HOME_1=$DAEMON_HOME_1\nDAEMON_HOME_2=$DAEMON_HOME_2\nDAEMON_HOME_3=$DAEMON_HOME_3\nDAEMON_HOME_4=$DAEMON_HOME_4\n" + +rm -rf $DAEMON_HOME* + +echo "-----Create daemon home directories if not exist------" + +mkdir -p "$DAEMON_HOME_1" +mkdir -p "$DAEMON_HOME_2" +mkdir -p "$DAEMON_HOME_3" +mkdir -p "$DAEMON_HOME_4" + +echo "--------Start initializing the chain ($CHAINID)---------" + +$DAEMON init --chain-id $CHAINID $DAEMON_HOME_1 --home $DAEMON_HOME_1 --keyring-backend test +$DAEMON init --chain-id $CHAINID $DAEMON_HOME_2 --home $DAEMON_HOME_2 --keyring-backend test +$DAEMON init --chain-id $CHAINID $DAEMON_HOME_3 --home $DAEMON_HOME_3 --keyring-backend test +$DAEMON init --chain-id $CHAINID $DAEMON_HOME_4 --home $DAEMON_HOME_4 --keyring-backend test + +echo "---------Creating four keys-------------" + +$DAEMON keys add validator1 --home $DAEMON_HOME_1 --keyring-backend test +$DAEMON keys add validator2 --home $DAEMON_HOME_2 --keyring-backend test +$DAEMON keys add validator3 --home $DAEMON_HOME_3 --keyring-backend test +$DAEMON keys add validator4 --home $DAEMON_HOME_4 --keyring-backend test + +echo "----------Genesis creation---------" + +$DAEMON --home $DAEMON_HOME_1 add-genesis-account validator1 1000000000000$DENOM --keyring-backend test +$DAEMON --home $DAEMON_HOME_2 add-genesis-account validator2 1000000000000$DENOM --keyring-backend test +$DAEMON --home $DAEMON_HOME_3 add-genesis-account validator3 1000000000000$DENOM --keyring-backend test +$DAEMON --home $DAEMON_HOME_4 add-genesis-account validator4 1000000000000$DENOM --keyring-backend test +$DAEMON --home $DAEMON_HOME_1 add-genesis-account $($DAEMON keys show validator2 -a --home $DAEMON_HOME_2 --keyring-backend test) 1000000000000$DENOM +$DAEMON --home $DAEMON_HOME_1 add-genesis-account $($DAEMON keys show validator3 -a --home $DAEMON_HOME_3 --keyring-backend test) 1000000000000$DENOM +$DAEMON --home $DAEMON_HOME_1 add-genesis-account $($DAEMON keys show validator4 -a --home $DAEMON_HOME_4 --keyring-backend test) 1000000000000$DENOM + +echo "--------Gentx--------" + +$DAEMON gentx validator1 90000000000$DENOM --chain-id $CHAINID --keyring-backend test --home $DAEMON_HOME_1 +$DAEMON gentx validator2 90000000000$DENOM --chain-id $CHAINID --keyring-backend test --home $DAEMON_HOME_2 +$DAEMON gentx validator3 90000000000$DENOM --chain-id $CHAINID --keyring-backend test --home $DAEMON_HOME_3 +$DAEMON gentx validator4 90000000000$DENOM --chain-id $CHAINID --keyring-backend test --home $DAEMON_HOME_4 + +echo "---------Copy all the genesis to $DAEMON_HOME_1----------" + +cp $DAEMON_HOME_2/config/gentx/*.json $DAEMON_HOME_1/config/gentx/ +cp $DAEMON_HOME_3/config/gentx/*.json $DAEMON_HOME_1/config/gentx/ +cp $DAEMON_HOME_4/config/gentx/*.json $DAEMON_HOME_1/config/gentx/ + +echo "----------collect-gentxs------------" + +$DAEMON collect-gentxs --home $DAEMON_HOME_1 + +echo "---------Updating $DAEMON_HOME_1 genesis.json ------------" + +sed -i "s/172800000000000/600000000000/g" $DAEMON_HOME_1/config/genesis.json +sed -i "s/172800s/600s/g" $DAEMON_HOME_1/config/genesis.json +sed -i "s/stake/$DENOM/g" $DAEMON_HOME_1/config/genesis.json + +echo "---------Distribute genesis.json of $DAEMON_HOME_1 to remaining nodes-------" + +cp $DAEMON_HOME_1/config/genesis.json $DAEMON_HOME_2/config/ +cp $DAEMON_HOME_1/config/genesis.json $DAEMON_HOME_3/config/ +cp $DAEMON_HOME_1/config/genesis.json $DAEMON_HOME_4/config/ + +echo "---------Getting public IP address-----------" + +IP="127.0.0.1" +echo "Public IP address: ${IP}" + +echo "----------Update node-id of $DAEMON_HOME_1 in remaining nodes---------" +nodeID=$("${DAEMON}" tendermint show-node-id --home $DAEMON_HOME_1) +echo $nodeID +PERSISTENT_PEERS="$nodeID@$IP:16656" +echo "PERSISTENT_PEERS : $PERSISTENT_PEERS" + +echo "----------Updating $DAEMON_HOME_1 chain config-----------" + +sed -i 's#tcp://127.0.0.1:26657#tcp://0.0.0.0:16657#g' $DAEMON_HOME_1/config/config.toml +sed -i 's#tcp://0.0.0.0:26656#tcp://0.0.0.0:16656#g' $DAEMON_HOME_1/config/config.toml +sed -i '/persistent_peers =/c\persistent_peers = "'""'"' $DAEMON_HOME_1/config/config.toml +sed -i '/max_num_inbound_peers =/c\max_num_inbound_peers = 140' $DAEMON_HOME_1/config/config.toml +sed -i '/max_num_outbound_peers =/c\max_num_outbound_peers = 110' $DAEMON_HOME_1/config/config.toml +sed -i '/pprof_laddr =/c\# pprof_laddr = "localhost:6060"' $DAEMON_HOME_1/config/config.toml +sed -i '/allow_duplicate_ip =/c\allow_duplicate_ip = true' $DAEMON_HOME_1/config/config.toml + +sed -i 's#0.0.0.0:9090#0.0.0.0:1090#g' $DAEMON_HOME_1/config/app.toml +sed -i 's#0.0.0.0:9091#0.0.0.0:1091#g' $DAEMON_HOME_1/config/app.toml + +sed -i 's#0.0.0.0:8545#0.0.0.0:1545#g' $DAEMON_HOME_1/config/app.toml +sed -i 's#0.0.0.0:8546#0.0.0.0:1546#g' $DAEMON_HOME_1/config/app.toml + +echo "----------Updating $DAEMON_HOME_2 chain config-----------" + +sed -i 's#tcp://127.0.0.1:26657#tcp://0.0.0.0:26657#g' $DAEMON_HOME_2/config/config.toml +sed -i 's#tcp://0.0.0.0:26656#tcp://0.0.0.0:26656#g' $DAEMON_HOME_2/config/config.toml +sed -i '/persistent_peers =/c\persistent_peers = "'"$PERSISTENT_PEERS"'"' $DAEMON_HOME_2/config/config.toml +sed -i '/max_num_inbound_peers =/c\max_num_inbound_peers = 140' $DAEMON_HOME_2/config/config.toml +sed -i '/max_num_outbound_peers =/c\max_num_outbound_peers = 110' $DAEMON_HOME_2/config/config.toml +sed -i '/pprof_laddr =/c\# pprof_laddr = "localhost:6060"' $DAEMON_HOME_2/config/config.toml +sed -i '/allow_duplicate_ip =/c\allow_duplicate_ip = true' $DAEMON_HOME_2/config/config.toml + +sed -i 's#0.0.0.0:9090#0.0.0.0:2090#g' $DAEMON_HOME_2/config/app.toml +sed -i 's#0.0.0.0:9091#0.0.0.0:2091#g' $DAEMON_HOME_2/config/app.toml + +sed -i 's#0.0.0.0:8545#0.0.0.0:2545#g' $DAEMON_HOME_2/config/app.toml +sed -i 's#0.0.0.0:8546#0.0.0.0:2546#g' $DAEMON_HOME_2/config/app.toml + +echo "----------Updating $DAEMON_HOME_3 chain config------------" + +sed -i 's#tcp://127.0.0.1:26657#tcp://0.0.0.0:36657#g' $DAEMON_HOME_3/config/config.toml +sed -i 's#tcp://0.0.0.0:26656#tcp://0.0.0.0:36656#g' $DAEMON_HOME_3/config/config.toml +sed -i '/persistent_peers =/c\persistent_peers = "'"$PERSISTENT_PEERS"'"' $DAEMON_HOME_3/config/config.toml +sed -i '/max_num_inbound_peers =/c\max_num_inbound_peers = 140' $DAEMON_HOME_3/config/config.toml +sed -i '/max_num_outbound_peers =/c\max_num_outbound_peers = 110' $DAEMON_HOME_3/config/config.toml +sed -i '/pprof_laddr =/c\# pprof_laddr = "localhost:6060"' $DAEMON_HOME_3/config/config.toml +sed -i '/allow_duplicate_ip =/c\allow_duplicate_ip = true' $DAEMON_HOME_3/config/config.toml + +sed -i 's#0.0.0.0:9090#0.0.0.0:3090#g' $DAEMON_HOME_3/config/app.toml +sed -i 's#0.0.0.0:9091#0.0.0.0:3091#g' $DAEMON_HOME_3/config/app.toml + +sed -i 's#0.0.0.0:8545#0.0.0.0:3545#g' $DAEMON_HOME_3/config/app.toml +sed -i 's#0.0.0.0:8546#0.0.0.0:3546#g' $DAEMON_HOME_3/config/app.toml + +echo "----------Updating $DAEMON_HOME_4 chain config------------" + +sed -i 's#tcp://127.0.0.1:26657#tcp://0.0.0.0:46657#g' $DAEMON_HOME_4/config/config.toml +sed -i 's#tcp://0.0.0.0:26656#tcp://0.0.0.0:46656#g' $DAEMON_HOME_4/config/config.toml +sed -i '/persistent_peers =/c\persistent_peers = "'"$PERSISTENT_PEERS"'"' $DAEMON_HOME_4/config/config.toml +sed -i '/max_num_inbound_peers =/c\max_num_inbound_peers = 140' $DAEMON_HOME_4/config/config.toml +sed -i '/max_num_outbound_peers =/c\max_num_outbound_peers = 110' $DAEMON_HOME_4/config/config.toml +sed -i '/pprof_laddr =/c\# pprof_laddr = "localhost:6060"' $DAEMON_HOME_4/config/config.toml +sed -i '/allow_duplicate_ip =/c\allow_duplicate_ip = true' $DAEMON_HOME_4/config/config.toml + +sed -i 's#0.0.0.0:9090#0.0.0.0:4090#g' $DAEMON_HOME_4/config/app.toml +sed -i 's#0.0.0.0:9091#0.0.0.0:4091#g' $DAEMON_HOME_4/config/app.toml + +sed -i 's#0.0.0.0:8545#0.0.0.0:4545#g' $DAEMON_HOME_4/config/app.toml +sed -i 's#0.0.0.0:8546#0.0.0.0:4546#g' $DAEMON_HOME_4/config/app.toml + +echo "starting the chains" + +nohup $(which $DAEMON) start --gql-playground --gql-server --home $DAEMON_HOME_1 >$DAEMON_HOME_1.log & +sleep 5s +echo "Checking $DAEMON_HOME_1 chain status" +$DAEMON status --node tcp://localhost:16657 + +nohup $(which $DAEMON) start --gql-playground --gql-server --home $DAEMON_HOME_2 >$DAEMON_HOME_2.log & +sleep 5s +echo "Checking $DAEMON_HOME_2 chain status" +$DAEMON status --node tcp://localhost:26657 + +nohup $(which $DAEMON) start --gql-playground --gql-server --home $DAEMON_HOME_3 >$DAEMON_HOME_3.log & +sleep 5s +echo "Checking $DAEMON_HOME_3 chain status" +$DAEMON status --node tcp://localhost:36657 + +nohup $(which $DAEMON) start --gql-playground --gql-server --home $DAEMON_HOME_4 >$DAEMON_HOME_4.log & +sleep 5s +echo "Checking $DAEMON_HOME_4 chain status" +$DAEMON status --node tcp://localhost:46657 \ No newline at end of file diff --git a/testnet/validator_node.md b/testnet/validator_node.md new file mode 100644 index 00000000..c7c92695 --- /dev/null +++ b/testnet/validator_node.md @@ -0,0 +1,55 @@ +### Create Validator Post Genesis + +1. Run Full Node +2. Create Account and Get test tokens +3. Create Validator + +### 1.Run Full Node + +- Check "[Run Full Node](full_node.md)" section to Run a Full Node + +### 2. Create Account & Get test tokens + +``` +laconicd keys add --keyring-backend test +``` + +NOTE: Save `mnemonic` and related account details (public key). You will need to use the need mnemonic/private key to +recover accounts at a later point in time. + +##### Get Test tokens from faucet + +- Faucet website link will be updated +- 1 CHK = 1 \* 10e^18 achk + +### 3.Create Validator + +- ##### Check full node sync status + + `laconicd status 2>&1 | jq -r ".SyncInfo"` + + `catching_up: false` means node is completely synced + +- ##### Create validator + +`Note:` Only execute below transaction after complete sync of your full node + +Please replace `key_name` with your key name, amount with staking amount, validator description and `moniker` also + +``` +laconicd tx staking create-validator \ + --amount="AMOUNT" \ + --pubkey=$(laconicd tendermint show-validator) \ + --moniker="my-moniker" \ + --website="https://myweb.site" \ + --details="description of your validator" \ + --chain-id="laconic_81337-2" \ + --commission-rate="0.10" \ + --commission-max-rate="0.20" \ + --commission-max-change-rate="0.01" \ + --min-self-delegation="1" \ + --gas="auto" \ + --gas-adjustment="1.2" \ + --gas-prices="0.025achk" \ + --from= +```