From 0c25f9daff9996356ef841f5b5703d6d6d89b278 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 13 May 2025 12:19:15 +0530 Subject: [PATCH 01/31] Add initial stack to create gentx --- .../compose/docker-compose-create-gentx.yml | 32 ++++++++++ .../config/laconicd/create-gentx.sh | 59 +++++++++++++++++++ .../container-build/cerc-laconicd/build.sh | 5 ++ .../stacks/create-gentx/README.md | 3 + 4 files changed, 99 insertions(+) create mode 100644 stack-orchestrator/compose/docker-compose-create-gentx.yml create mode 100755 stack-orchestrator/config/laconicd/create-gentx.sh create mode 100755 stack-orchestrator/container-build/cerc-laconicd/build.sh create mode 100644 stack-orchestrator/stacks/create-gentx/README.md diff --git a/stack-orchestrator/compose/docker-compose-create-gentx.yml b/stack-orchestrator/compose/docker-compose-create-gentx.yml new file mode 100644 index 0000000..5a1a22f --- /dev/null +++ b/stack-orchestrator/compose/docker-compose-create-gentx.yml @@ -0,0 +1,32 @@ +services: + laconicd: + restart: unless-stopped + image: cerc/laconicd:local + command: ["bash", "-c", "/opt/run-laconicd.sh"] + environment: + CERC_MONIKER: ${CERC_MONIKER:-TestnetNode} + CERC_CHAIN_ID: ${CERC_CHAIN_ID:-laconic_9000-1} + CERC_PEERS: ${CERC_PEERS} + MIN_GAS_PRICE: ${MIN_GAS_PRICE:-0.001} + CERC_LOGLEVEL: ${CERC_LOGLEVEL:-info} + volumes: + - laconicd-data:/root/.laconicd + - ../config/laconicd/run-laconicd.sh:/opt/run-laconicd.sh + ports: + - "6060" + - "26657" + - "26656" + - "9473" + - "9090" + - "1317" + healthcheck: + test: ["CMD", "nc", "-vz", "127.0.0.1", "26657"] + interval: 30s + timeout: 10s + retries: 10 + start_period: 10s + extra_hosts: + - "host.docker.internal:host-gateway" + +volumes: + laconicd-data: diff --git a/stack-orchestrator/config/laconicd/create-gentx.sh b/stack-orchestrator/config/laconicd/create-gentx.sh new file mode 100755 index 0000000..860d3a0 --- /dev/null +++ b/stack-orchestrator/config/laconicd/create-gentx.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then + set -x +fi + +set -e + +input_genesis_file=/root/.laconicd/tmp/genesis.json +if [ ! -f ${input_genesis_file} ]; then + echo "Genesis file not provided, exiting..." + exit 1 +fi + +if [ -z "$CERC_PEERS" ]; then + echo "Persistent peers not provided, exiting..." + exit 1 +fi + +echo "Env:" +echo "Moniker: $CERC_MONIKER" +echo "Chain Id: $CERC_CHAIN_ID" +echo "Persistent peers: $CERC_PEERS" +echo "Min gas price: $MIN_GAS_PRICE" +echo "Log level: $CERC_LOGLEVEL" + +NODE_HOME=/root/.laconicd + +# TODO: Add command to import key +# Set chain id in config +laconicd config set client chain-id $CERC_CHAIN_ID --home $NODE_HOME + +# Check if node data dir already exists +if [ -z "$(ls -A "$NODE_HOME/data")" ]; then + # Init node + echo "Initializing a new laconicd node with moniker $CERC_MONIKER and chain id $CERC_CHAIN_ID" + laconicd init $CERC_MONIKER --chain-id=$CERC_CHAIN_ID --home $NODE_HOME + + # TODO: Add command to create gentxs + # Use provided genesis config + cp $input_genesis_file $NODE_HOME/config/genesis.json +else + echo "Node data dir $NODE_HOME/data already exists, skipping initialization..." +fi + +# Enable cors +sed -i 's/cors_allowed_origins.*$/cors_allowed_origins = ["*"]/' $HOME/.laconicd/config/config.toml + +# Update config with persistent peers +sed -i "s/^persistent_peers *=.*/persistent_peers = \"$CERC_PEERS\"/g" $NODE_HOME/config/config.toml + +echo "Starting laconicd node..." +laconicd start \ + --api.enable \ + --minimum-gas-prices=${MIN_GAS_PRICE}alnt \ + --rpc.laddr="tcp://0.0.0.0:26657" \ + --gql-playground --gql-server \ + --log_level $CERC_LOGLEVEL \ + --home $NODE_HOME diff --git a/stack-orchestrator/container-build/cerc-laconicd/build.sh b/stack-orchestrator/container-build/cerc-laconicd/build.sh new file mode 100755 index 0000000..65bab74 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-laconicd/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +# Build cerc/laconicd +source ${CERC_CONTAINER_BASE_DIR}/build-base.sh +docker build -t cerc/laconicd:local ${build_command_args} ${CERC_REPO_BASE_DIR}/laconicd diff --git a/stack-orchestrator/stacks/create-gentx/README.md b/stack-orchestrator/stacks/create-gentx/README.md new file mode 100644 index 0000000..b88e13f --- /dev/null +++ b/stack-orchestrator/stacks/create-gentx/README.md @@ -0,0 +1,3 @@ +# create-gentx + +Instructions for creating gentxs for joining as a validator -- 2.45.2 From ad22b6350b7efdd5b4cf4374a87fd0db651c704b Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 13 May 2025 12:57:42 +0530 Subject: [PATCH 02/31] Update script to setup account and create gentx --- .../compose/docker-compose-create-gentx.yml | 17 ++--- .../config/laconicd/create-gentx.sh | 68 +++++++++---------- 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/stack-orchestrator/compose/docker-compose-create-gentx.yml b/stack-orchestrator/compose/docker-compose-create-gentx.yml index 5a1a22f..bf126aa 100644 --- a/stack-orchestrator/compose/docker-compose-create-gentx.yml +++ b/stack-orchestrator/compose/docker-compose-create-gentx.yml @@ -2,23 +2,16 @@ services: laconicd: restart: unless-stopped image: cerc/laconicd:local - command: ["bash", "-c", "/opt/run-laconicd.sh"] + command: ["bash", "-c", "/opt/create-gentx.sh"] environment: CERC_MONIKER: ${CERC_MONIKER:-TestnetNode} CERC_CHAIN_ID: ${CERC_CHAIN_ID:-laconic_9000-1} - CERC_PEERS: ${CERC_PEERS} - MIN_GAS_PRICE: ${MIN_GAS_PRICE:-0.001} - CERC_LOGLEVEL: ${CERC_LOGLEVEL:-info} + DENOM: ${DENOM} + KEY_NAME: ${KEY_NAME:-mykey} + PVT_KEY: ${PVT_KEY} volumes: - laconicd-data:/root/.laconicd - - ../config/laconicd/run-laconicd.sh:/opt/run-laconicd.sh - ports: - - "6060" - - "26657" - - "26656" - - "9473" - - "9090" - - "1317" + - ../config/laconicd/create-gentx.sh:/opt/create-gentx.sh healthcheck: test: ["CMD", "nc", "-vz", "127.0.0.1", "26657"] interval: 30s diff --git a/stack-orchestrator/config/laconicd/create-gentx.sh b/stack-orchestrator/config/laconicd/create-gentx.sh index 860d3a0..fe00dc1 100755 --- a/stack-orchestrator/config/laconicd/create-gentx.sh +++ b/stack-orchestrator/config/laconicd/create-gentx.sh @@ -4,56 +4,52 @@ if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then set -x fi +if [ -z "$DENOM" ]; then + echo "DENOM environment variable not set, exiting..." + exit 1 +fi + set -e -input_genesis_file=/root/.laconicd/tmp/genesis.json -if [ ! -f ${input_genesis_file} ]; then - echo "Genesis file not provided, exiting..." - exit 1 -fi - -if [ -z "$CERC_PEERS" ]; then - echo "Persistent peers not provided, exiting..." - exit 1 -fi - echo "Env:" echo "Moniker: $CERC_MONIKER" echo "Chain Id: $CERC_CHAIN_ID" -echo "Persistent peers: $CERC_PEERS" -echo "Min gas price: $MIN_GAS_PRICE" -echo "Log level: $CERC_LOGLEVEL" +echo "Denom: $DENOM" +echo "Key name: $KEY_NAME" +echo "PVT Key: $PVT_KEY" NODE_HOME=/root/.laconicd -# TODO: Add command to import key +KEYRING=test + # Set chain id in config laconicd config set client chain-id $CERC_CHAIN_ID --home $NODE_HOME -# Check if node data dir already exists -if [ -z "$(ls -A "$NODE_HOME/data")" ]; then - # Init node - echo "Initializing a new laconicd node with moniker $CERC_MONIKER and chain id $CERC_CHAIN_ID" - laconicd init $CERC_MONIKER --chain-id=$CERC_CHAIN_ID --home $NODE_HOME +export CERC_MONIKER=$(echo "$CERC_MONIKER" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') +export CERC_CHAIN_ID=$(echo "$CERC_CHAIN_ID" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') +export DENOM=$(echo "$DENOM" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') - # TODO: Add command to create gentxs - # Use provided genesis config - cp $input_genesis_file $NODE_HOME/config/genesis.json +# TODO: Update amounts +BALANCE=100000000000000000000000$DENOM +STAKE_AMOUNT=100000000000000000000$DENOM + +# Init node +echo "Initializing a new laconicd node with moniker $CERC_MONIKER and chain id $CERC_CHAIN_ID" +laconicd init $CERC_MONIKER --chain-id=$CERC_CHAIN_ID --home $NODE_HOME + +# Support both importing key and generating account +if [ -n "$PVT_KEY" ]; then + # If PVT_KEY is provided, import the key + laconicd keys import-hex "$KEY_NAME" "$PVT_KEY" else - echo "Node data dir $NODE_HOME/data already exists, skipping initialization..." + # If PVT_KEY is not provided, create a new key + laconicd keys add "$KEY_NAME" fi -# Enable cors -sed -i 's/cors_allowed_origins.*$/cors_allowed_origins = ["*"]/' $HOME/.laconicd/config/config.toml +laconicd genesis add-genesis-account $KEY_NAME $BALANCE --keyring-backend $KEYRING --home $NODE_HOME -# Update config with persistent peers -sed -i "s/^persistent_peers *=.*/persistent_peers = \"$CERC_PEERS\"/g" $NODE_HOME/config/config.toml +laconicd genesis gentx $KEY_NAME $STAKE_AMOUNT --keyring-backend $KEYRING --home $NODE_HOME -echo "Starting laconicd node..." -laconicd start \ - --api.enable \ - --minimum-gas-prices=${MIN_GAS_PRICE}alnt \ - --rpc.laddr="tcp://0.0.0.0:26657" \ - --gql-playground --gql-server \ - --log_level $CERC_LOGLEVEL \ - --home $NODE_HOME +echo "Genesis transaction created successfully..." +# Keep the script running indefinitely +tail -f /dev/null -- 2.45.2 From 44219c801c833799703f1962b1f3b2ab86b88785 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 13 May 2025 15:14:56 +0530 Subject: [PATCH 03/31] Add initial stack to run mainnet nodes --- .gitignore | 2 + README.md | 2 +- .../compose/docker-compose-create-gentx.yml | 25 ------- .../docker-compose-mainnet-laconicd.yml | 35 +++++++++ .../config/laconicd/create-gentx.sh | 55 -------------- .../config/laconicd/run-laconicd.sh | 71 +++++++++++++++++++ .../README.md | 0 .../stacks/mainnet-laconicd/stack.yaml | 9 +++ 8 files changed, 118 insertions(+), 81 deletions(-) create mode 100644 .gitignore delete mode 100644 stack-orchestrator/compose/docker-compose-create-gentx.yml create mode 100644 stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml delete mode 100755 stack-orchestrator/config/laconicd/create-gentx.sh create mode 100755 stack-orchestrator/config/laconicd/run-laconicd.sh rename stack-orchestrator/stacks/{create-gentx => mainnet-laconicd}/README.md (100%) create mode 100644 stack-orchestrator/stacks/mainnet-laconicd/stack.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..abaaaab --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*-deployment +*-spec.yml diff --git a/README.md b/README.md index 450b5e3..2d49303 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# mainnet-laconicd-stack +# laconicd-stack diff --git a/stack-orchestrator/compose/docker-compose-create-gentx.yml b/stack-orchestrator/compose/docker-compose-create-gentx.yml deleted file mode 100644 index bf126aa..0000000 --- a/stack-orchestrator/compose/docker-compose-create-gentx.yml +++ /dev/null @@ -1,25 +0,0 @@ -services: - laconicd: - restart: unless-stopped - image: cerc/laconicd:local - command: ["bash", "-c", "/opt/create-gentx.sh"] - environment: - CERC_MONIKER: ${CERC_MONIKER:-TestnetNode} - CERC_CHAIN_ID: ${CERC_CHAIN_ID:-laconic_9000-1} - DENOM: ${DENOM} - KEY_NAME: ${KEY_NAME:-mykey} - PVT_KEY: ${PVT_KEY} - volumes: - - laconicd-data:/root/.laconicd - - ../config/laconicd/create-gentx.sh:/opt/create-gentx.sh - healthcheck: - test: ["CMD", "nc", "-vz", "127.0.0.1", "26657"] - interval: 30s - timeout: 10s - retries: 10 - start_period: 10s - extra_hosts: - - "host.docker.internal:host-gateway" - -volumes: - laconicd-data: diff --git a/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml new file mode 100644 index 0000000..fd420ee --- /dev/null +++ b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml @@ -0,0 +1,35 @@ +services: + laconicd: + restart: unless-stopped + image: cerc/laconicd:local + command: ["bash", "-c", "/opt/run-laconicd.sh"] + environment: + CERC_MONIKER: ${CERC_MONIKER:-TestnetNode} + CERC_CHAIN_ID: ${CERC_CHAIN_ID:-laconic_9000-1} + CERC_PEERS: ${CERC_PEERS} + MIN_GAS_PRICE: ${MIN_GAS_PRICE:-0.001} + CERC_LOGLEVEL: ${CERC_LOGLEVEL:-info} + INPUT_GENESIS_FILE: ${INPUT_GENESIS_FILE} + INPUT_NODE_KEY_FILE: ${INPUT_NODE_KEY_FILE} + INPUT_PRIV_VALIDATOR_KEY_FILE: ${INPUT_PRIV_VALIDATOR_KEY_FILE} + volumes: + - laconicd-data:/root/.laconicd + - ../config/laconicd/run-laconicd.sh:/opt/run-laconicd.sh + ports: + - "6060" + - "26657" + - "26656" + - "9473" + - "9090" + - "1317" + healthcheck: + test: ["CMD", "nc", "-vz", "127.0.0.1", "26657"] + interval: 30s + timeout: 10s + retries: 10 + start_period: 10s + extra_hosts: + - "host.docker.internal:host-gateway" + +volumes: + laconicd-data: diff --git a/stack-orchestrator/config/laconicd/create-gentx.sh b/stack-orchestrator/config/laconicd/create-gentx.sh deleted file mode 100755 index fe00dc1..0000000 --- a/stack-orchestrator/config/laconicd/create-gentx.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then - set -x -fi - -if [ -z "$DENOM" ]; then - echo "DENOM environment variable not set, exiting..." - exit 1 -fi - -set -e - -echo "Env:" -echo "Moniker: $CERC_MONIKER" -echo "Chain Id: $CERC_CHAIN_ID" -echo "Denom: $DENOM" -echo "Key name: $KEY_NAME" -echo "PVT Key: $PVT_KEY" - -NODE_HOME=/root/.laconicd - -KEYRING=test - -# Set chain id in config -laconicd config set client chain-id $CERC_CHAIN_ID --home $NODE_HOME - -export CERC_MONIKER=$(echo "$CERC_MONIKER" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') -export CERC_CHAIN_ID=$(echo "$CERC_CHAIN_ID" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') -export DENOM=$(echo "$DENOM" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') - -# TODO: Update amounts -BALANCE=100000000000000000000000$DENOM -STAKE_AMOUNT=100000000000000000000$DENOM - -# Init node -echo "Initializing a new laconicd node with moniker $CERC_MONIKER and chain id $CERC_CHAIN_ID" -laconicd init $CERC_MONIKER --chain-id=$CERC_CHAIN_ID --home $NODE_HOME - -# Support both importing key and generating account -if [ -n "$PVT_KEY" ]; then - # If PVT_KEY is provided, import the key - laconicd keys import-hex "$KEY_NAME" "$PVT_KEY" -else - # If PVT_KEY is not provided, create a new key - laconicd keys add "$KEY_NAME" -fi - -laconicd genesis add-genesis-account $KEY_NAME $BALANCE --keyring-backend $KEYRING --home $NODE_HOME - -laconicd genesis gentx $KEY_NAME $STAKE_AMOUNT --keyring-backend $KEYRING --home $NODE_HOME - -echo "Genesis transaction created successfully..." -# Keep the script running indefinitely -tail -f /dev/null diff --git a/stack-orchestrator/config/laconicd/run-laconicd.sh b/stack-orchestrator/config/laconicd/run-laconicd.sh new file mode 100755 index 0000000..c0ea753 --- /dev/null +++ b/stack-orchestrator/config/laconicd/run-laconicd.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then + set -x +fi + +set -e + +input_genesis_file=$INPUT_GENESIS_FILE +if [ ! -f ${input_genesis_file} ]; then + echo "Genesis file not provided, exiting..." + exit 1 +fi + +input_node_key_file=$INPUT_NODE_KEY_FILE +if [ ! -f ${input_node_key_file} ]; then + echo "Node key file not provided, exiting..." + exit 1 +fi + +input_priv_validator_key_file=$INPUT_PRIV_VALIDATOR_KEY_FILE +if [ ! -f ${input_priv_validator_key_file} ]; then + echo "Priv validator key file not provided, exiting..." + exit 1 +fi + +if [ -z "$CERC_PEERS" ]; then + echo "Persistent peers not provided, exiting..." + exit 1 +fi + +echo "Env:" +echo "Moniker: $CERC_MONIKER" +echo "Chain Id: $CERC_CHAIN_ID" +echo "Persistent peers: $CERC_PEERS" +echo "Min gas price: $MIN_GAS_PRICE" +echo "Log level: $CERC_LOGLEVEL" + +NODE_HOME=/root/.laconicd + +# Set chain id in config +laconicd config set client chain-id $CERC_CHAIN_ID --home $NODE_HOME + +# Check if node data dir already exists +if [ -z "$(ls -A "$NODE_HOME/data")" ]; then + # Init node + echo "Initializing a new laconicd node with moniker $CERC_MONIKER and chain id $CERC_CHAIN_ID" + laconicd init $CERC_MONIKER --chain-id=$CERC_CHAIN_ID --home $NODE_HOME + + # Use provided config files + cp $input_genesis_file $NODE_HOME/config/genesis.json + cp $input_node_key_file $NODE_HOME/config/node_key.json + cp $input_priv_validator_key_file $NODE_HOME/config/priv_validator_key.json +else + echo "Node data dir $NODE_HOME/data already exists, skipping initialization..." +fi + +# Enable cors +sed -i 's/cors_allowed_origins.*$/cors_allowed_origins = ["*"]/' $NODE_HOME/.laconicd/config/config.toml + +# Update config with persistent peers +sed -i "s/^persistent_peers *=.*/persistent_peers = \"$CERC_PEERS\"/g" $NODE_HOME/config/config.toml + +echo "Starting laconicd node..." +laconicd start \ + --api.enable \ + --minimum-gas-prices=${MIN_GAS_PRICE}alnt \ + --rpc.laddr="tcp://0.0.0.0:26657" \ + --gql-playground --gql-server \ + --log_level $CERC_LOGLEVEL \ + --home $NODE_HOME diff --git a/stack-orchestrator/stacks/create-gentx/README.md b/stack-orchestrator/stacks/mainnet-laconicd/README.md similarity index 100% rename from stack-orchestrator/stacks/create-gentx/README.md rename to stack-orchestrator/stacks/mainnet-laconicd/README.md diff --git a/stack-orchestrator/stacks/mainnet-laconicd/stack.yaml b/stack-orchestrator/stacks/mainnet-laconicd/stack.yaml new file mode 100644 index 0000000..d65a7e0 --- /dev/null +++ b/stack-orchestrator/stacks/mainnet-laconicd/stack.yaml @@ -0,0 +1,9 @@ +version: "1.0" +name: mainnet-laconicd +description: "Laconicd full node" +repos: + - git.vdb.to/cerc-io/laconicd@v0.1.11 +containers: + - cerc/laconicd +pods: + - mainnet-laconicd -- 2.45.2 From 08847a391286d344c6cdb036dbb66c39aff11a29 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 13 May 2025 16:38:22 +0530 Subject: [PATCH 04/31] Update scripts --- .../docker-compose-mainnet-laconicd.yml | 3 -- .../config/mainnet-laconicd/allocate-lps.sh | 45 +++++++++++++++++++ .../run-laconicd.sh | 10 ++--- .../{stack.yaml => stack.yml} | 0 4 files changed, 50 insertions(+), 8 deletions(-) create mode 100755 stack-orchestrator/config/mainnet-laconicd/allocate-lps.sh rename stack-orchestrator/config/{laconicd => mainnet-laconicd}/run-laconicd.sh (91%) rename stack-orchestrator/stacks/mainnet-laconicd/{stack.yaml => stack.yml} (100%) diff --git a/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml index fd420ee..5a1a22f 100644 --- a/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml +++ b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml @@ -9,9 +9,6 @@ services: CERC_PEERS: ${CERC_PEERS} MIN_GAS_PRICE: ${MIN_GAS_PRICE:-0.001} CERC_LOGLEVEL: ${CERC_LOGLEVEL:-info} - INPUT_GENESIS_FILE: ${INPUT_GENESIS_FILE} - INPUT_NODE_KEY_FILE: ${INPUT_NODE_KEY_FILE} - INPUT_PRIV_VALIDATOR_KEY_FILE: ${INPUT_PRIV_VALIDATOR_KEY_FILE} volumes: - laconicd-data:/root/.laconicd - ../config/laconicd/run-laconicd.sh:/opt/run-laconicd.sh diff --git a/stack-orchestrator/config/mainnet-laconicd/allocate-lps.sh b/stack-orchestrator/config/mainnet-laconicd/allocate-lps.sh new file mode 100755 index 0000000..3dfc1c1 --- /dev/null +++ b/stack-orchestrator/config/mainnet-laconicd/allocate-lps.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then + set -x +fi + +set -e + +# Early supports: 12960 * 10^18 alps (10% of 129600 * 10^18 alps) +EARLY_SUPPORTS="12960000000000000000000" + +DENOM=alps + +input_genesis_file=$INPUT_GENESIS_FILE +if [ ! -f ${input_genesis_file} ]; then + echo "Genesis file not provided, exiting..." + exit 1 +fi + +if [ -z "$RECIPIENT_ADDRESS" ]; then + echo "Recipient address not provided, exiting..." + exit 1 +fi + +update_genesis() { + jq "$1" ${input_genesis_file} > ${input_genesis_file}.tmp && + mv ${input_genesis_file}.tmp ${input_genesis_file} +} + +# Add new account to auth.accounts +update_genesis '.app_state["auth"]["accounts"] += [{"@type": "/cosmos.auth.v1beta1.BaseAccount", "address": "'$RECIPIENT_ADDRESS'", "pub_key": null, "account_number": "0", "sequence": "0"}]' + +# Add balance for the new account +update_genesis '.app_state["bank"]["balances"] += [{"address": "'$RECIPIENT_ADDRESS'", "coins": [{"denom": "'$DENOM'", "amount": "'$EARLY_SUPPORTS'"}]}]' + +# Get current supply +CURRENT_SUPPLY=$(jq -r '.app_state["bank"]["supply"][0]["amount"]' ${input_genesis_file}) + +# Calculate new supply +NEW_SUPPLY=$((CURRENT_SUPPLY + EARLY_SUPPORTS)) + +# Update total supply +update_genesis '.app_state["bank"]["supply"][0]["amount"] = "'$NEW_SUPPLY'"' + +echo "Genesis file updated with new account ${RECIPIENT_ADDRESS} and allocated ${EARLY_SUPPORTS} ${DENOM}" diff --git a/stack-orchestrator/config/laconicd/run-laconicd.sh b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh similarity index 91% rename from stack-orchestrator/config/laconicd/run-laconicd.sh rename to stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh index c0ea753..0a6d363 100755 --- a/stack-orchestrator/config/laconicd/run-laconicd.sh +++ b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh @@ -6,19 +6,21 @@ fi set -e -input_genesis_file=$INPUT_GENESIS_FILE +NODE_HOME=/root/.laconicd + +input_genesis_file=$NODE_HOME/tmp/genesis.json if [ ! -f ${input_genesis_file} ]; then echo "Genesis file not provided, exiting..." exit 1 fi -input_node_key_file=$INPUT_NODE_KEY_FILE +input_node_key_file=$NODE_HOME/tmp/node_key.json if [ ! -f ${input_node_key_file} ]; then echo "Node key file not provided, exiting..." exit 1 fi -input_priv_validator_key_file=$INPUT_PRIV_VALIDATOR_KEY_FILE +input_priv_validator_key_file=$NODE_HOME/tmp/priv_validator_key.json if [ ! -f ${input_priv_validator_key_file} ]; then echo "Priv validator key file not provided, exiting..." exit 1 @@ -36,8 +38,6 @@ echo "Persistent peers: $CERC_PEERS" echo "Min gas price: $MIN_GAS_PRICE" echo "Log level: $CERC_LOGLEVEL" -NODE_HOME=/root/.laconicd - # Set chain id in config laconicd config set client chain-id $CERC_CHAIN_ID --home $NODE_HOME diff --git a/stack-orchestrator/stacks/mainnet-laconicd/stack.yaml b/stack-orchestrator/stacks/mainnet-laconicd/stack.yml similarity index 100% rename from stack-orchestrator/stacks/mainnet-laconicd/stack.yaml rename to stack-orchestrator/stacks/mainnet-laconicd/stack.yml -- 2.45.2 From 31a560bb151110622a047bde6782698a4dff185b Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 13 May 2025 16:42:25 +0530 Subject: [PATCH 05/31] Update run script path --- stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml index 5a1a22f..33d3b26 100644 --- a/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml +++ b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml @@ -11,7 +11,7 @@ services: CERC_LOGLEVEL: ${CERC_LOGLEVEL:-info} volumes: - laconicd-data:/root/.laconicd - - ../config/laconicd/run-laconicd.sh:/opt/run-laconicd.sh + - ../config/mainnet-laconicd/run-laconicd.sh:/opt/run-laconicd.sh ports: - "6060" - "26657" -- 2.45.2 From 404951bda700849671bb9aac3a38e1cb85a00033 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 13 May 2025 16:45:03 +0530 Subject: [PATCH 06/31] Update script --- stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh index 0a6d363..3013891 100755 --- a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh +++ b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh @@ -56,7 +56,7 @@ else fi # Enable cors -sed -i 's/cors_allowed_origins.*$/cors_allowed_origins = ["*"]/' $NODE_HOME/.laconicd/config/config.toml +sed -i 's/cors_allowed_origins.*$/cors_allowed_origins = ["*"]/' $NODE_HOME/config/config.toml # Update config with persistent peers sed -i "s/^persistent_peers *=.*/persistent_peers = \"$CERC_PEERS\"/g" $NODE_HOME/config/config.toml -- 2.45.2 From afd2082f6e605e2b94a59f06592c092e90de0d44 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Tue, 13 May 2025 17:39:09 +0530 Subject: [PATCH 07/31] Add scripts to generate genesis file for mainnet --- scripts/generate-mainnet-genesis.sh | 51 +++++++++++++++++++++++++++++ scripts/genesis.sh | 28 ++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100755 scripts/generate-mainnet-genesis.sh create mode 100755 scripts/genesis.sh diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh new file mode 100755 index 0000000..bc24eb2 --- /dev/null +++ b/scripts/generate-mainnet-genesis.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# Exit on error +set -e +set -u + +# Check args +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +TESTNET_DEPLOYMENT_DIR="$1" +MAINNET_GENESIS_DIR=mainnet-genesis + +# Create a temporary target directory +mkdir -p $MAINNET_GENESIS_DIR + +# -------- + +# Export state from testnet chain +# Use cerc/laconicd-testnet:local image for testnet laconicd build + +testnet_state_file="$MAINNET_GENESIS_DIR/testnet-state.json" +docker run -it \ + -v ${TESTNET_DEPLOYMENT_DIR}/data/laconicd-data:/root/testnet-deployment/.laconicd \ + cerc/laconicd-testnet:local bash -c "laconicd export --home /root/testnet-deployment/.laconicd" \ + | jq .app_state.onboarding > "$testnet_state_file" + +echo "Exported state from testnet" + +# -------- + +# Run a script with cerc/laconicd:local to generate the genesis file +# with onboarding module state and given allocations +docker run -it \ + -v ./$MAINNET_GENESIS_DIR:/root/.laconicd \ + -v ./scripts:/scripts \ + cerc/laconicd:local bash -c "/scripts/genesis.sh" + +# Copy over the genesis file to output folder +OUTPUT_DIR=output +mkdir -p $OUTPUT_DIR +cp ./$MAINNET_GENESIS_DIR/config/genesis.json $OUTPUT_DIR/genesis.json + +echo "Genesis file for mainnet written to $OUTPUT_DIR/genesis.json" + +# -------- + +# Clean up +echo "Please remove the temporary data directory: sudo rm -rf $MAINNET_GENESIS_DIR" diff --git a/scripts/genesis.sh b/scripts/genesis.sh new file mode 100755 index 0000000..4c5dee0 --- /dev/null +++ b/scripts/genesis.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Exit on error +set -e +set -u + +# Note: Needs to be run in a docker container with image cerc/laconicd:local + +CHAINID=${CHAINID:-"laconic-mainnet"} +MONIKER=${MONIKER:-"mainnet-node"} +NODE_HOME="/root/.laconicd" + +testnet_state_file="$NODE_HOME/testnet-state.json" +mainnet_genesis_file="$NODE_HOME/config/genesis.json" + +laconicd config set client chain-id $CHAINID +laconicd init $MONIKER --chain-id $CHAINID --default-denom alnt + +# Import required state +jq --slurpfile nested $testnet_state_file '.app_state.auth = $nested[0].app_state' "$mainnet_genesis_file" > tmp.$$.json && mv tmp.$$.json "$mainnet_genesis_file" +jq --slurpfile nested $testnet_state_file '.consensus.auth = $nested[0].consensus' "$mainnet_genesis_file" > tmp.$$.json && mv tmp.$$.json "$mainnet_genesis_file" + +# Update any module params if required here + +# TODO: Perform alps allocations + +# Ensure that resulting genesis file is valid +laconicd genesis validate -- 2.45.2 From f181e67045d1fb8949e93bb4d70fc4eeafc4bfa2 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 13 May 2025 18:02:23 +0530 Subject: [PATCH 08/31] Add playbook to run mainnet validator node --- .../mainnet-laconicd/run-validator-vars.yml | 8 ++ playbooks/mainnet-laconicd/run-validator.yml | 87 +++++++++++++++++++ .../mainnet-laconicd-spec-template.yml.j2 | 9 ++ 3 files changed, 104 insertions(+) create mode 100644 playbooks/mainnet-laconicd/run-validator-vars.yml create mode 100644 playbooks/mainnet-laconicd/run-validator.yml create mode 100644 playbooks/mainnet-laconicd/templates/specs/mainnet-laconicd-spec-template.yml.j2 diff --git a/playbooks/mainnet-laconicd/run-validator-vars.yml b/playbooks/mainnet-laconicd/run-validator-vars.yml new file mode 100644 index 0000000..d2ad6e1 --- /dev/null +++ b/playbooks/mainnet-laconicd/run-validator-vars.yml @@ -0,0 +1,8 @@ +cerc_moniker: "TestnetNode" +cerc_chain_id: "laconic_9000-1" +cerc_peers: +min_gas_price: 0.001 +cerc_loglevel: "info" +genesis_file: +node_key_file: +priv_validator_key_file: diff --git a/playbooks/mainnet-laconicd/run-validator.yml b/playbooks/mainnet-laconicd/run-validator.yml new file mode 100644 index 0000000..a8d5f68 --- /dev/null +++ b/playbooks/mainnet-laconicd/run-validator.yml @@ -0,0 +1,87 @@ +--- +- name: Run mainnet validator node + hosts: localhost + vars_files: + - run-validator-vars.yml + vars: + data_directory: "{{ lookup('env', 'DATA_DIRECTORY') }}" + mainnet_deployment_dir: "{{ lookup('env', 'MAINNET_DEPLOYMENT_DIR') }}" + spec_file: "{{data_directory}}/mainnet-laconicd-spec.yml" + spec_template: "./templates/specs/mainnet-laconicd-spec-template.yml.j2" + tasks: + - name: Fail if DATA_DIRECTORY or MAINNET_DEPLOYMENT_DIR env vars are not set + fail: + msg: >- + Required environment variables are not set. + Please export both DATA_DIRECTORY and MAINNET_DEPLOYMENT_DIR before running the playbook. + when: lookup('env', 'DATA_DIRECTORY') == '' or lookup('env', 'MAINNET_DEPLOYMENT_DIR') == '' + + - name: Fail if required key files are not defined + fail: + msg: >- + Required key files are not defined. + Please set genesis_file, node_key_file, and priv_validator_key_file in run-validator-vars.yml. + when: not genesis_file or not node_key_file or not priv_validator_key_file + + - name: Fetch laconicd stack + shell: laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull + + - name: Setup required repositories + shell: > + laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd + setup-repositories --git-ssh --pull + + - name: Build container images + shell: | + laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd build-containers + + - name: Create deployment spec file + shell: | + laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd deploy init --output {{ spec_file }} + + - name: Replace network section in spec_file + shell: > + yq eval '(.network) = load("{{ spec_template }}").network' -i {{ spec_file }} + + - name: Create deployment from spec file + shell: | + laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd deploy create --spec-file {{ spec_file }} --deployment-dir {{data_directory}}/{{ mainnet_deployment_dir }} + + - name: Create config.env + copy: + dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/config.env" + content: | + CERC_MONIKER: {{ cerc_moniker }} + CERC_CHAIN_ID: {{ cerc_chain_id }} + CERC_PEERS: {{ cerc_peers}} + MIN_GAS_PRICE: {{ min_gas_price }} + CERC_LOGLEVEL: {{ cerc_loglevel }} + mode: '0777' + + - name: Ensure tmp directory exists inside laconicd-data + file: + path: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp" + state: directory + mode: '0755' + + - name: Copy genesis file to laconicd-data tmp directory + copy: + src: "{{ genesis_file }}" + dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/genesis.json" + mode: '0644' + + - name: Copy node key file to laconicd-data tmp directory + copy: + src: "{{ node_key_file }}" + dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/node_key.json" + mode: '0644' + + - name: Copy priv validator key file to laconicd-data tmp directory + copy: + src: "{{ priv_validator_key_file }}" + dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/priv_validator_key.json" + mode: '0644' + + - name: Run validator node + shell: | + laconic-so deployment --dir {{data_directory}}/{{ mainnet_deployment_dir }} start diff --git a/playbooks/mainnet-laconicd/templates/specs/mainnet-laconicd-spec-template.yml.j2 b/playbooks/mainnet-laconicd/templates/specs/mainnet-laconicd-spec-template.yml.j2 new file mode 100644 index 0000000..9ae553e --- /dev/null +++ b/playbooks/mainnet-laconicd/templates/specs/mainnet-laconicd-spec-template.yml.j2 @@ -0,0 +1,9 @@ +network: + ports: + laconicd: + - '6060:6060' + - '26657:26657' + - '26656:26656' + - '9473:9473' + - '9090:9090' + - '1317:1317' -- 2.45.2 From d769c6e05535347e562ef95741247629f90be884 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 13 May 2025 18:39:19 +0530 Subject: [PATCH 09/31] Remove persistent peers check --- playbooks/mainnet-laconicd/run-validator.yml | 10 +++++----- .../config/mainnet-laconicd/run-laconicd.sh | 5 ----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/playbooks/mainnet-laconicd/run-validator.yml b/playbooks/mainnet-laconicd/run-validator.yml index a8d5f68..ecca34b 100644 --- a/playbooks/mainnet-laconicd/run-validator.yml +++ b/playbooks/mainnet-laconicd/run-validator.yml @@ -51,11 +51,11 @@ copy: dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/config.env" content: | - CERC_MONIKER: {{ cerc_moniker }} - CERC_CHAIN_ID: {{ cerc_chain_id }} - CERC_PEERS: {{ cerc_peers}} - MIN_GAS_PRICE: {{ min_gas_price }} - CERC_LOGLEVEL: {{ cerc_loglevel }} + CERC_MONIKER: "{{ cerc_moniker }}" + CERC_CHAIN_ID: "{{ cerc_chain_id }}" + CERC_PEERS: "{{ cerc_peers}}" + MIN_GAS_PRICE: "{{ min_gas_price }}" + CERC_LOGLEVEL: "{{ cerc_loglevel }}" mode: '0777' - name: Ensure tmp directory exists inside laconicd-data diff --git a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh index 3013891..8acc05e 100755 --- a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh +++ b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh @@ -26,11 +26,6 @@ if [ ! -f ${input_priv_validator_key_file} ]; then exit 1 fi -if [ -z "$CERC_PEERS" ]; then - echo "Persistent peers not provided, exiting..." - exit 1 -fi - echo "Env:" echo "Moniker: $CERC_MONIKER" echo "Chain Id: $CERC_CHAIN_ID" -- 2.45.2 From 74e5f470e2e00f849c94647af23efe66453412d7 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Tue, 13 May 2025 18:57:09 +0530 Subject: [PATCH 10/31] Perform alps allocations --- scripts/generate-mainnet-genesis.sh | 5 ++++- scripts/genesis.sh | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh index bc24eb2..d9c6e7f 100755 --- a/scripts/generate-mainnet-genesis.sh +++ b/scripts/generate-mainnet-genesis.sh @@ -5,7 +5,7 @@ set -e set -u # Check args -if [ "$#" -ne 2 ]; then +if [ "$#" -ne 1 ]; then echo "Usage: $0 " exit 1 fi @@ -36,6 +36,9 @@ echo "Exported state from testnet" docker run -it \ -v ./$MAINNET_GENESIS_DIR:/root/.laconicd \ -v ./scripts:/scripts \ + -e "CHAIN_ID=$CHAIN_ID" \ + -e "EARLY_SUPPORTS_ACC_ADDRESS=$EARLY_SUPPORTS_ACC_ADDRESS" \ + -e "LPS_LOCKUP_ACC_ADDRESS=$LPS_LOCKUP_ACC_ADDRESS" \ cerc/laconicd:local bash -c "/scripts/genesis.sh" # Copy over the genesis file to output folder diff --git a/scripts/genesis.sh b/scripts/genesis.sh index 4c5dee0..8a60944 100755 --- a/scripts/genesis.sh +++ b/scripts/genesis.sh @@ -10,6 +10,20 @@ CHAINID=${CHAINID:-"laconic-mainnet"} MONIKER=${MONIKER:-"mainnet-node"} NODE_HOME="/root/.laconicd" +EARLY_SUPPORTS_ACC_ADDRESS=${EARLY_SUPPORTS_ACC_ADDRESS} +LPS_LOCKUP_ACC_ADDRESS=${LPS_LOCKUP_ACC_ADDRESS} + +if [ -z "$EARLY_SUPPORTS_ACC_ADDRESS" ] || [ -z "$LPS_LOCKUP_ACC_ADDRESS" ]; then + echo "EARLY_SUPPORTS_ACC_ADDRESS or LPS_LOCKUP_ACC_ADDRESS not provided, exiting..." + exit 1 +fi + +# alps allocations +# Total supply: 129600 * 10^18 alps +EARLY_SUPPORTS_ALLOC="12960000000000000000000" # Early supports: 12960 * 10^18 alps (10% of total supply) +LOCKUP_ALLOC="116640000000000000000000" # Lockup: 116640 * 10^18 alps (90% of total supply) +LPS_LOCKUP_MODULE_ACCOUNT="lps_lockup" + testnet_state_file="$NODE_HOME/testnet-state.json" mainnet_genesis_file="$NODE_HOME/config/genesis.json" @@ -22,7 +36,12 @@ jq --slurpfile nested $testnet_state_file '.consensus.auth = $nested[0].consensu # Update any module params if required here -# TODO: Perform alps allocations +# Perform alps allocations +laconicd genesis add-genesis-account $ADDRESS $EARLY_SUPPORTS$DENOM --keyring-backend $KEYRING + +# Use zero address to add an account for lps_lockup +zero_address="laconic1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqklcls0" +laconicd genesis add-genesis-account $zero_address $EARLY_SUPPORTS$DENOM --keyring-backend $KEYRING --module-name $LPS_LOCKUP_MODULE_ACCOUNT # Ensure that resulting genesis file is valid laconicd genesis validate -- 2.45.2 From 67405d3809919595fe879dbb77a5a68bd8073571 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Tue, 13 May 2025 19:00:11 +0530 Subject: [PATCH 11/31] Update readme --- stack-orchestrator/stacks/mainnet-laconicd/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stack-orchestrator/stacks/mainnet-laconicd/README.md b/stack-orchestrator/stacks/mainnet-laconicd/README.md index b88e13f..aaffda9 100644 --- a/stack-orchestrator/stacks/mainnet-laconicd/README.md +++ b/stack-orchestrator/stacks/mainnet-laconicd/README.md @@ -1,3 +1,3 @@ -# create-gentx +# mainnet-laconicd -Instructions for creating gentxs for joining as a validator +Instructions for running validator nodes -- 2.45.2 From d284d4c321e5c42128df6207c7a1a8cb69ce0a8c Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Tue, 13 May 2025 19:30:33 +0530 Subject: [PATCH 12/31] Update address for lockup account in genesis file --- scripts/genesis.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/genesis.sh b/scripts/genesis.sh index 8a60944..385b715 100755 --- a/scripts/genesis.sh +++ b/scripts/genesis.sh @@ -43,5 +43,11 @@ laconicd genesis add-genesis-account $ADDRESS $EARLY_SUPPORTS$DENOM --keyring-ba zero_address="laconic1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqklcls0" laconicd genesis add-genesis-account $zero_address $EARLY_SUPPORTS$DENOM --keyring-backend $KEYRING --module-name $LPS_LOCKUP_MODULE_ACCOUNT +# Update the lps_lockup address in bank module state +lps_lockup_address=$(jq -r '.app_state.auth.accounts[] | select(.name == "lps_lockup") | .base_account.address' $HOME/.laconicd/config/genesis.json) +jq --arg old "$zero_address" --arg new "$lps_lockup_address" \ + '.app_state.bank.balances |= map(if .address == $old then .address = $new else . end)' "$mainnet_genesis_file" > tmp.$$.json \ + && mv tmp.$$.json "$mainnet_genesis_file" + # Ensure that resulting genesis file is valid laconicd genesis validate -- 2.45.2 From 13c95e61c53bd8b221de4db8dfd138cc4c10e8cf Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 14 May 2025 10:39:14 +0530 Subject: [PATCH 13/31] Remove usage of validator private key files --- .../config/mainnet-laconicd/run-laconicd.sh | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh index 8acc05e..6056d65 100755 --- a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh +++ b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh @@ -14,18 +14,6 @@ if [ ! -f ${input_genesis_file} ]; then exit 1 fi -input_node_key_file=$NODE_HOME/tmp/node_key.json -if [ ! -f ${input_node_key_file} ]; then - echo "Node key file not provided, exiting..." - exit 1 -fi - -input_priv_validator_key_file=$NODE_HOME/tmp/priv_validator_key.json -if [ ! -f ${input_priv_validator_key_file} ]; then - echo "Priv validator key file not provided, exiting..." - exit 1 -fi - echo "Env:" echo "Moniker: $CERC_MONIKER" echo "Chain Id: $CERC_CHAIN_ID" @@ -44,8 +32,6 @@ if [ -z "$(ls -A "$NODE_HOME/data")" ]; then # Use provided config files cp $input_genesis_file $NODE_HOME/config/genesis.json - cp $input_node_key_file $NODE_HOME/config/node_key.json - cp $input_priv_validator_key_file $NODE_HOME/config/priv_validator_key.json else echo "Node data dir $NODE_HOME/data already exists, skipping initialization..." fi -- 2.45.2 From daad25a0491cb70e714fdb2442e18cc36da58749 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 14 May 2025 11:05:51 +0530 Subject: [PATCH 14/31] Add script to create and collect gentx --- .../create-and-collect-gentx.sh | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100755 stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh diff --git a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh new file mode 100755 index 0000000..f6fb9bd --- /dev/null +++ b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +set -e + +NODE_HOME=/root/.laconicd +genesis_file_path=$NODE_HOME/config/genesis.json + +if [ -f "$genesis_file_path" ]; then + echo "Genesis file already created, exiting..." + exit 0 +fi + +if [ -z "$PVT_KEY" ]; then + echo "PVT_KEY environment variable not set, exiting..." + exit 1 +fi + +if [ -z "$KEY_NAME" ]; then + echo "KEY_NAME environment variable not set, exiting..." + exit 1 +fi + +if [ -z "$DENOM" ]; then + echo "DENOM environment variable not set, exiting..." + exit 1 +fi + +input_genesis_file=$NODE_HOME/tmp/genesis.json +if [ ! -f ${input_genesis_file} ]; then + echo "Genesis file not provided, exiting..." + exit 1 +fi + +# Strip leading and trailing quotes ("") if they exist +export MONIKER=$(echo "$MONIKER" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') +export CHAIN_ID=$(echo "$CHAIN_ID" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') +export DENOM=$(echo "$DENOM" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') + +# Init +laconicd config set client chain-id $CHAIN_ID --home $NODE_HOME +laconicd init $MONIKER --chain-id=$CHAIN_ID --home $NODE_HOME + +# Copy over provided genesis config +cp $input_genesis_file $genesis_file_path + +# Import private key passed via PVT_KEY +laconicd keys import-hex "$KEY_NAME" "$PVT_KEY" + +account_address=$(laconicd keys list | awk -v key_name="$KEY_NAME" ' + $1 == "name:" && $2 == key_name {found=1} + found && $1 == "- address:" {print $3; exit} +') + +stake_amount=$(jq -r --arg address "$account_address" --arg denom "$DENOM" '.app_state.bank.balances[] | select(.address == $address) | .coins[] | select(.denom == $denom) | .amount' $genesis_file_path) + +# Create gentx with staked amount equal to allocated balance +laconicd genesis gentx $KEY_NAME $stake_amount$DENOM --chain-id $CHAIN_ID + +# Collect the gentx and validate +laconicd genesis collect-gentxs +laconicd genesis validate + +# Update the input genesis file +cp $genesis_file_path $input_genesis_file -- 2.45.2 From b3ebd324991da59b6bbbbd09d07d5325e052e4af Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Wed, 14 May 2025 11:05:44 +0530 Subject: [PATCH 15/31] Add a script to export testnet state --- scripts/export-testnet-state.sh | 28 ++++++++++++++++++++++++++++ scripts/generate-mainnet-genesis.sh | 16 ++++------------ 2 files changed, 32 insertions(+), 12 deletions(-) create mode 100755 scripts/export-testnet-state.sh diff --git a/scripts/export-testnet-state.sh b/scripts/export-testnet-state.sh new file mode 100755 index 0000000..81812a9 --- /dev/null +++ b/scripts/export-testnet-state.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Note: Needs to be run in a docker container with image testnet cerc/laconicd:local + +# Exit on error +set -e +set -u + +# Check args +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +TESTNET_DEPLOYMENT_DIR="$1" + +# Create a temporary target directory +OUTPUT_DIR=${TESTNET_DEPLOYMENT_DIR}/export +mkdir -p $OUTPUT_DIR + +# Export state from testnet chain +testnet_state_file="$OUTPUT_DIR/testnet-state.json" +docker run -it \ + -v ${TESTNET_DEPLOYMENT_DIR}/data/laconicd-data:/root/testnet-deployment/.laconicd \ + cerc/laconicd:local bash -c "laconicd export --home /root/testnet-deployment/.laconicd" \ + | jq .app_state.onboarding > "$testnet_state_file" + +echo "Exported state from testnet to $testnet_state_file" diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh index d9c6e7f..ae249fe 100755 --- a/scripts/generate-mainnet-genesis.sh +++ b/scripts/generate-mainnet-genesis.sh @@ -6,11 +6,11 @@ set -u # Check args if [ "$#" -ne 1 ]; then - echo "Usage: $0 " + echo "Usage: $0 " exit 1 fi -TESTNET_DEPLOYMENT_DIR="$1" +TESTNET_STATE_FILE="$1" MAINNET_GENESIS_DIR=mainnet-genesis # Create a temporary target directory @@ -18,16 +18,8 @@ mkdir -p $MAINNET_GENESIS_DIR # -------- -# Export state from testnet chain -# Use cerc/laconicd-testnet:local image for testnet laconicd build - -testnet_state_file="$MAINNET_GENESIS_DIR/testnet-state.json" -docker run -it \ - -v ${TESTNET_DEPLOYMENT_DIR}/data/laconicd-data:/root/testnet-deployment/.laconicd \ - cerc/laconicd-testnet:local bash -c "laconicd export --home /root/testnet-deployment/.laconicd" \ - | jq .app_state.onboarding > "$testnet_state_file" - -echo "Exported state from testnet" +# Copy testnet state file to required dir +cp $TESTNET_STATE_FILE $MAINNET_GENESIS_DIR/testnet-state.json # -------- -- 2.45.2 From 1de4a3dc3e963f261a9c16f36a4296318d8e2e82 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 14 May 2025 12:10:06 +0530 Subject: [PATCH 16/31] Add playbook to run first validator node --- .../run-first-validator-vars.yml | 13 +++++ .../run-first-validator.yml} | 50 +++++++++++-------- .../templates/specs/spec-template.yml.j2} | 0 .../mainnet-laconicd/run-validator-vars.yml | 8 --- .../create-and-collect-gentx.sh | 4 +- 5 files changed, 44 insertions(+), 31 deletions(-) create mode 100644 playbooks/first-validator/run-first-validator-vars.yml rename playbooks/{mainnet-laconicd/run-validator.yml => first-validator/run-first-validator.yml} (65%) rename playbooks/{mainnet-laconicd/templates/specs/mainnet-laconicd-spec-template.yml.j2 => first-validator/templates/specs/spec-template.yml.j2} (100%) delete mode 100644 playbooks/mainnet-laconicd/run-validator-vars.yml diff --git a/playbooks/first-validator/run-first-validator-vars.yml b/playbooks/first-validator/run-first-validator-vars.yml new file mode 100644 index 0000000..c0b1697 --- /dev/null +++ b/playbooks/first-validator/run-first-validator-vars.yml @@ -0,0 +1,13 @@ +cerc_moniker: "TestnetNode" +cerc_chain_id: "laconic_9000-1" +cerc_peers: +min_gas_price: 0.001 +cerc_loglevel: "info" +# Token denomination (alnt or alps) +denom: "alnt" +# Validator key name +key_name: "validator" +# Private key in hex format (required for gentx) +pvt_key: "" +# Required files +genesis_file: diff --git a/playbooks/mainnet-laconicd/run-validator.yml b/playbooks/first-validator/run-first-validator.yml similarity index 65% rename from playbooks/mainnet-laconicd/run-validator.yml rename to playbooks/first-validator/run-first-validator.yml index ecca34b..8aa0a4c 100644 --- a/playbooks/mainnet-laconicd/run-validator.yml +++ b/playbooks/first-validator/run-first-validator.yml @@ -2,12 +2,12 @@ - name: Run mainnet validator node hosts: localhost vars_files: - - run-validator-vars.yml + - run-first-validator-vars.yml vars: data_directory: "{{ lookup('env', 'DATA_DIRECTORY') }}" mainnet_deployment_dir: "{{ lookup('env', 'MAINNET_DEPLOYMENT_DIR') }}" - spec_file: "{{data_directory}}/mainnet-laconicd-spec.yml" - spec_template: "./templates/specs/mainnet-laconicd-spec-template.yml.j2" + spec_file: "{{data_directory}}/laconicd-spec.yml" + spec_template: "./templates/specs/spec-template.yml.j2" tasks: - name: Fail if DATA_DIRECTORY or MAINNET_DEPLOYMENT_DIR env vars are not set fail: @@ -20,9 +20,8 @@ fail: msg: >- Required key files are not defined. - Please set genesis_file, node_key_file, and priv_validator_key_file in run-validator-vars.yml. - when: not genesis_file or not node_key_file or not priv_validator_key_file - + Please set genesis_file in run-first-validator-vars.yml. + when: not genesis_file - name: Fetch laconicd stack shell: laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull @@ -51,11 +50,13 @@ copy: dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/config.env" content: | - CERC_MONIKER: "{{ cerc_moniker }}" - CERC_CHAIN_ID: "{{ cerc_chain_id }}" - CERC_PEERS: "{{ cerc_peers}}" - MIN_GAS_PRICE: "{{ min_gas_price }}" - CERC_LOGLEVEL: "{{ cerc_loglevel }}" + CERC_MONIKER: "{{ cerc_moniker }}" + CERC_CHAIN_ID: "{{ cerc_chain_id }}" + CERC_PEERS: "{{ cerc_peers}}" + MIN_GAS_PRICE: "{{ min_gas_price }}" + CERC_LOGLEVEL: "{{ cerc_loglevel }}" + DENOM: "{{ denom }}" + KEY_NAME: "{{ key_name }}" mode: '0777' - name: Ensure tmp directory exists inside laconicd-data @@ -70,17 +71,24 @@ dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/genesis.json" mode: '0644' - - name: Copy node key file to laconicd-data tmp directory - copy: - src: "{{ node_key_file }}" - dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/node_key.json" - mode: '0644' + - name: Fail if pvt_key is not set + fail: + msg: >- + Private key (pvt_key) is not set in run-first-validator-vars.yml. + This is required for creating the gentx. + when: not pvt_key - - name: Copy priv validator key file to laconicd-data tmp directory - copy: - src: "{{ priv_validator_key_file }}" - dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/priv_validator_key.json" - mode: '0644' + - name: Run script to create and collect gentx + shell: | + docker run -it \ + -v {{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data:/root/.laconicd \ + -v {{data_directory}}/{{ mainnet_deployment_dir }}/config/mainnet-laconicd:/scripts \ + -e "PVT_KEY={{ pvt_key }}" \ + -e "KEY_NAME={{ key_name }}" \ + -e "DENOM={{ denom }}" \ + -e "CERC_MONIKER={{ cerc_moniker }}" \ + -e "CERC_CHAIN_ID={{ cerc_chain_id }}" \ + cerc/laconicd:local bash -c "/scripts/create-and-collect-gentx.sh" - name: Run validator node shell: | diff --git a/playbooks/mainnet-laconicd/templates/specs/mainnet-laconicd-spec-template.yml.j2 b/playbooks/first-validator/templates/specs/spec-template.yml.j2 similarity index 100% rename from playbooks/mainnet-laconicd/templates/specs/mainnet-laconicd-spec-template.yml.j2 rename to playbooks/first-validator/templates/specs/spec-template.yml.j2 diff --git a/playbooks/mainnet-laconicd/run-validator-vars.yml b/playbooks/mainnet-laconicd/run-validator-vars.yml deleted file mode 100644 index d2ad6e1..0000000 --- a/playbooks/mainnet-laconicd/run-validator-vars.yml +++ /dev/null @@ -1,8 +0,0 @@ -cerc_moniker: "TestnetNode" -cerc_chain_id: "laconic_9000-1" -cerc_peers: -min_gas_price: 0.001 -cerc_loglevel: "info" -genesis_file: -node_key_file: -priv_validator_key_file: diff --git a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh index f6fb9bd..c035533 100755 --- a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh +++ b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh @@ -32,8 +32,8 @@ if [ ! -f ${input_genesis_file} ]; then fi # Strip leading and trailing quotes ("") if they exist -export MONIKER=$(echo "$MONIKER" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') -export CHAIN_ID=$(echo "$CHAIN_ID" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') +export MONIKER=$(echo "$CERC_MONIKER" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') +export CHAIN_ID=$(echo "$CERC_CHAIN_ID" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') export DENOM=$(echo "$DENOM" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') # Init -- 2.45.2 From f3158584792dd17a091ac09cb2699866fde0bcd1 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 14 May 2025 12:26:15 +0530 Subject: [PATCH 17/31] Update script for getting account address --- .../config/mainnet-laconicd/create-and-collect-gentx.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh index c035533..bda1459 100755 --- a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh +++ b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh @@ -47,8 +47,8 @@ cp $input_genesis_file $genesis_file_path laconicd keys import-hex "$KEY_NAME" "$PVT_KEY" account_address=$(laconicd keys list | awk -v key_name="$KEY_NAME" ' - $1 == "name:" && $2 == key_name {found=1} - found && $1 == "- address:" {print $3; exit} + $1 == "- address:" {addr=$3} + $1 == "name:" && $2 == key_name {print addr; exit} ') stake_amount=$(jq -r --arg address "$account_address" --arg denom "$DENOM" '.app_state.bank.balances[] | select(.address == $address) | .coins[] | select(.denom == $denom) | .amount' $genesis_file_path) -- 2.45.2 From f07aa1a76668536c051430851b639901b7411a56 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 14 May 2025 13:31:32 +0530 Subject: [PATCH 18/31] Fix create and collect gentx script --- .../first-validator/run-first-validator.yml | 21 ++++++++++--------- .../create-and-collect-gentx.sh | 16 ++++++++------ .../config/mainnet-laconicd/run-laconicd.sh | 6 +++--- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/playbooks/first-validator/run-first-validator.yml b/playbooks/first-validator/run-first-validator.yml index 8aa0a4c..8c61be7 100644 --- a/playbooks/first-validator/run-first-validator.yml +++ b/playbooks/first-validator/run-first-validator.yml @@ -22,17 +22,18 @@ Required key files are not defined. Please set genesis_file in run-first-validator-vars.yml. when: not genesis_file - - name: Fetch laconicd stack - shell: laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull - - name: Setup required repositories - shell: > - laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd - setup-repositories --git-ssh --pull + # - name: Fetch laconicd stack + # shell: laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull - - name: Build container images - shell: | - laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd build-containers + # - name: Setup required repositories + # shell: > + # laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd + # setup-repositories --git-ssh --pull + + # - name: Build container images + # shell: | + # laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd build-containers - name: Create deployment spec file shell: | @@ -80,7 +81,7 @@ - name: Run script to create and collect gentx shell: | - docker run -it \ + docker run -i \ -v {{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data:/root/.laconicd \ -v {{data_directory}}/{{ mainnet_deployment_dir }}/config/mainnet-laconicd:/scripts \ -e "PVT_KEY={{ pvt_key }}" \ diff --git a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh index bda1459..18d8d80 100755 --- a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh +++ b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh @@ -4,6 +4,7 @@ set -e NODE_HOME=/root/.laconicd genesis_file_path=$NODE_HOME/config/genesis.json +KEYRING="test" if [ -f "$genesis_file_path" ]; then echo "Genesis file already created, exiting..." @@ -44,17 +45,20 @@ laconicd init $MONIKER --chain-id=$CHAIN_ID --home $NODE_HOME cp $input_genesis_file $genesis_file_path # Import private key passed via PVT_KEY -laconicd keys import-hex "$KEY_NAME" "$PVT_KEY" +laconicd keys import-hex "$KEY_NAME" "$PVT_KEY" --keyring-backend $KEYRING -account_address=$(laconicd keys list | awk -v key_name="$KEY_NAME" ' - $1 == "- address:" {addr=$3} - $1 == "name:" && $2 == key_name {print addr; exit} -') +account_address=$(laconicd keys show "$KEY_NAME" --keyring-backend "$KEYRING" | grep 'address:' | awk -F': ' '{print $2}' | xargs) + +if [ -z "$account_address" ]; then + echo "Failed to get account address for key name $KEY_NAME, exiting..." + laconicd keys list --keyring-backend $KEYRING + exit 1 +fi stake_amount=$(jq -r --arg address "$account_address" --arg denom "$DENOM" '.app_state.bank.balances[] | select(.address == $address) | .coins[] | select(.denom == $denom) | .amount' $genesis_file_path) # Create gentx with staked amount equal to allocated balance -laconicd genesis gentx $KEY_NAME $stake_amount$DENOM --chain-id $CHAIN_ID +laconicd genesis gentx $KEY_NAME $stake_amount$DENOM --chain-id $CHAIN_ID --keyring-backend $KEYRING # Collect the gentx and validate laconicd genesis collect-gentxs diff --git a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh index 6056d65..9e35027 100755 --- a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh +++ b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh @@ -29,13 +29,13 @@ if [ -z "$(ls -A "$NODE_HOME/data")" ]; then # Init node echo "Initializing a new laconicd node with moniker $CERC_MONIKER and chain id $CERC_CHAIN_ID" laconicd init $CERC_MONIKER --chain-id=$CERC_CHAIN_ID --home $NODE_HOME - - # Use provided config files - cp $input_genesis_file $NODE_HOME/config/genesis.json else echo "Node data dir $NODE_HOME/data already exists, skipping initialization..." fi +# Use provided config files +cp $input_genesis_file $NODE_HOME/config/genesis.json + # Enable cors sed -i 's/cors_allowed_origins.*$/cors_allowed_origins = ["*"]/' $NODE_HOME/config/config.toml -- 2.45.2 From 2a05149a8a98eb523554ea69eca3e8560c688553 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 14 May 2025 14:45:45 +0530 Subject: [PATCH 19/31] Add default keyring backend --- .../first-validator/run-first-validator.yml | 19 +++++++++---------- .../create-and-collect-gentx.sh | 1 + 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/playbooks/first-validator/run-first-validator.yml b/playbooks/first-validator/run-first-validator.yml index 8c61be7..a81b998 100644 --- a/playbooks/first-validator/run-first-validator.yml +++ b/playbooks/first-validator/run-first-validator.yml @@ -22,18 +22,17 @@ Required key files are not defined. Please set genesis_file in run-first-validator-vars.yml. when: not genesis_file + - name: Fetch laconicd stack + shell: laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull - # - name: Fetch laconicd stack - # shell: laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull + - name: Setup required repositories + shell: > + laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd + setup-repositories --git-ssh --pull - # - name: Setup required repositories - # shell: > - # laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd - # setup-repositories --git-ssh --pull - - # - name: Build container images - # shell: | - # laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd build-containers + - name: Build container images + shell: | + laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd build-containers - name: Create deployment spec file shell: | diff --git a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh index 18d8d80..9f8902f 100755 --- a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh +++ b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh @@ -39,6 +39,7 @@ export DENOM=$(echo "$DENOM" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') # Init laconicd config set client chain-id $CHAIN_ID --home $NODE_HOME +laconicd config set client keyring-backend $KEYRING laconicd init $MONIKER --chain-id=$CHAIN_ID --home $NODE_HOME # Copy over provided genesis config -- 2.45.2 From 71d58c7c2c6e059b786db4750d38d0261e81e169 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 14 May 2025 16:21:46 +0530 Subject: [PATCH 20/31] Add README instructions to run first validator node --- README.md | 2 + genesis/.gitkeep | 0 node-addresses.yml | 4 ++ playbooks/README.md | 42 +++++++++++ .../run-first-validator-vars.yml | 10 +-- .../first-validator/run-first-validator.yml | 3 - run-first-validator.md | 72 +++++++++++++++++++ .../docker-compose-mainnet-laconicd.yml | 4 +- .../create-and-collect-gentx.sh | 12 ++-- 9 files changed, 129 insertions(+), 20 deletions(-) create mode 100644 genesis/.gitkeep create mode 100644 node-addresses.yml create mode 100644 playbooks/README.md create mode 100644 run-first-validator.md diff --git a/README.md b/README.md index 2d49303..c870d42 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # laconicd-stack + +- Follow [run-first-validator.md](run-first-validator.md) to run the first validator node diff --git a/genesis/.gitkeep b/genesis/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node-addresses.yml b/node-addresses.yml new file mode 100644 index 0000000..5ff7b09 --- /dev/null +++ b/node-addresses.yml @@ -0,0 +1,4 @@ +# Add your node addresses here +# Example: +# - node-1-id@node-1-host:26656 +# - node-2-id@node-2-host:26656 diff --git a/playbooks/README.md b/playbooks/README.md new file mode 100644 index 0000000..679dd14 --- /dev/null +++ b/playbooks/README.md @@ -0,0 +1,42 @@ +# Ansible Installation + +- Install [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-and-upgrading-ansible-with-pip) + +- Add location of the directory containing the ansible binary to your `PATH` + +- Set Locale Encoding to `UTF-8` + + Ansible requires the locale encoding to be `UTF-8`. You can either use the `LANG` prefix when running Ansible commands or set the system-wide locale + + - Option 1: Use `LANG` Prefix in Commands + + If you prefer not to change the system-wide locale, you can use the `LANG` prefix when running Ansible commands: + + ```bash + LANG=en_US.UTF-8 ansible-playbook your_playbook.yml + ``` + + - Option 2: Set System-Wide Locale + + - Edit the `/etc/default/locale` file: + + ```bash + sudo nano /etc/default/locale + ``` + + - Set the `LANG` variable to en_US.UTF-8: + + ```bash + LANG="en_US.UTF-8" + ``` + + - Reboot your system or log out and log back in to apply the changes + + - Reference: + +- Verify ansible installation by running the following command: + + ```bash + ansible --version + # ansible [core 2.17.2] + ``` diff --git a/playbooks/first-validator/run-first-validator-vars.yml b/playbooks/first-validator/run-first-validator-vars.yml index c0b1697..78d11ec 100644 --- a/playbooks/first-validator/run-first-validator-vars.yml +++ b/playbooks/first-validator/run-first-validator-vars.yml @@ -1,13 +1,7 @@ -cerc_moniker: "TestnetNode" -cerc_chain_id: "laconic_9000-1" -cerc_peers: +cerc_moniker: "MainnetNode" +cerc_chain_id: "laconic-mainnet" min_gas_price: 0.001 cerc_loglevel: "info" -# Token denomination (alnt or alps) -denom: "alnt" -# Validator key name key_name: "validator" -# Private key in hex format (required for gentx) pvt_key: "" -# Required files genesis_file: diff --git a/playbooks/first-validator/run-first-validator.yml b/playbooks/first-validator/run-first-validator.yml index a81b998..8b90468 100644 --- a/playbooks/first-validator/run-first-validator.yml +++ b/playbooks/first-validator/run-first-validator.yml @@ -52,10 +52,8 @@ content: | CERC_MONIKER: "{{ cerc_moniker }}" CERC_CHAIN_ID: "{{ cerc_chain_id }}" - CERC_PEERS: "{{ cerc_peers}}" MIN_GAS_PRICE: "{{ min_gas_price }}" CERC_LOGLEVEL: "{{ cerc_loglevel }}" - DENOM: "{{ denom }}" KEY_NAME: "{{ key_name }}" mode: '0777' @@ -85,7 +83,6 @@ -v {{data_directory}}/{{ mainnet_deployment_dir }}/config/mainnet-laconicd:/scripts \ -e "PVT_KEY={{ pvt_key }}" \ -e "KEY_NAME={{ key_name }}" \ - -e "DENOM={{ denom }}" \ -e "CERC_MONIKER={{ cerc_moniker }}" \ -e "CERC_CHAIN_ID={{ cerc_chain_id }}" \ cerc/laconicd:local bash -c "/scripts/create-and-collect-gentx.sh" diff --git a/run-first-validator.md b/run-first-validator.md new file mode 100644 index 0000000..9c8d543 --- /dev/null +++ b/run-first-validator.md @@ -0,0 +1,72 @@ +# Run First Validator Node + +## Prerequisites + +- [ansible](playbooks/README.md#ansible-installation) +- [laconic-so](https://github.com/cerc-io/stack-orchestrator/?tab=readme-ov-file#install) + +## Generate mainnet genesis file + + + +## Run node + +- Update [run-first-validator-vars.yml](playbooks/first-validator/run-first-validator-vars.yml) with required values: + + - Use the mainnet genesis file generated in the previous step + + ```bash + # Private key of the existing account in hex format (required for gentx) + pvt_key: "" + + # Path to the generated mainnet genesis file + genesis_file: "" + + # Optional + cerc_chain_id: "laconic-mainnet" + cerc_moniker: "MainnetNode" + min_gas_price: 0.001 + cerc_loglevel: "info" + key_name: "validator" + ``` + +- Export the data directory and mainnet deployment directory as environment variables: + + ```bash + # Parent directory where the deployment directory will live + export DATA_DIRECTORY= + + # Set mainnet deployment directory + # for eg: mainnet-laconicd-deployment + export MAINNET_DEPLOYMENT_DIR= + ``` + +- Run ansible playbook to submit the gentx and run the node: + + ```bash + ansible-playbook -i localhost, -c local playbooks/first-validator/run-first-validator.yml + ``` + +- Check logs to ensure that node is running: + + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR logs laconicd -f + ``` + +## Publish Genesis File and Node Address + +- Copy the genesis file to [genesis](./genesis) folder: + + ```bash + sudo cp $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/data/laconicd-data/config/genesis.json ./genesis/mainnet-genesis.json + ``` + +- Get your node's address: + + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR exec laconicd 'echo $(laconicd cometbft show-node-id)@YOUR_PUBLIC_IP_ADDRESS:26656' + ``` + +- Add your node's address to [node-addresses.yml](./node-addresses.yml) + +- Submit a PR with this genesis file and node address so that it is available to other validators diff --git a/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml index 33d3b26..e649dea 100644 --- a/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml +++ b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml @@ -4,8 +4,8 @@ services: image: cerc/laconicd:local command: ["bash", "-c", "/opt/run-laconicd.sh"] environment: - CERC_MONIKER: ${CERC_MONIKER:-TestnetNode} - CERC_CHAIN_ID: ${CERC_CHAIN_ID:-laconic_9000-1} + CERC_MONIKER: ${CERC_MONIKER:-MainnetNode} + CERC_CHAIN_ID: ${CERC_CHAIN_ID:-laconic-mainnet} CERC_PEERS: ${CERC_PEERS} MIN_GAS_PRICE: ${MIN_GAS_PRICE:-0.001} CERC_LOGLEVEL: ${CERC_LOGLEVEL:-info} diff --git a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh index 9f8902f..b6a446d 100755 --- a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh +++ b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh @@ -21,21 +21,17 @@ if [ -z "$KEY_NAME" ]; then exit 1 fi -if [ -z "$DENOM" ]; then - echo "DENOM environment variable not set, exiting..." - exit 1 -fi - input_genesis_file=$NODE_HOME/tmp/genesis.json if [ ! -f ${input_genesis_file} ]; then echo "Genesis file not provided, exiting..." exit 1 fi +DENOM=alnt + # Strip leading and trailing quotes ("") if they exist export MONIKER=$(echo "$CERC_MONIKER" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') export CHAIN_ID=$(echo "$CERC_CHAIN_ID" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') -export DENOM=$(echo "$DENOM" | sed -e 's/^["'\'']//g' -e 's/["'\'']$//g') # Init laconicd config set client chain-id $CHAIN_ID --home $NODE_HOME @@ -45,9 +41,10 @@ laconicd init $MONIKER --chain-id=$CHAIN_ID --home $NODE_HOME # Copy over provided genesis config cp $input_genesis_file $genesis_file_path -# Import private key passed via PVT_KEY +# Import private key laconicd keys import-hex "$KEY_NAME" "$PVT_KEY" --keyring-backend $KEYRING +# Get account address corresponding to the imported key account_address=$(laconicd keys show "$KEY_NAME" --keyring-backend "$KEYRING" | grep 'address:' | awk -F': ' '{print $2}' | xargs) if [ -z "$account_address" ]; then @@ -56,6 +53,7 @@ if [ -z "$account_address" ]; then exit 1 fi +# Get balance of account stake_amount=$(jq -r --arg address "$account_address" --arg denom "$DENOM" '.app_state.bank.balances[] | select(.address == $address) | .coins[] | select(.denom == $denom) | .amount' $genesis_file_path) # Create gentx with staked amount equal to allocated balance -- 2.45.2 From b8924fa7fb426cedc21696110f18ed0d3b7c16c0 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Wed, 14 May 2025 18:28:00 +0530 Subject: [PATCH 21/31] Add a script to allocate back staked tokens --- scripts/export-testnet-state.sh | 2 +- scripts/generate-mainnet-genesis.sh | 14 +++- scripts/genesis.sh | 18 ++--- scripts/init-mainnet.sh | 13 ++++ scripts/transfer-state.py | 112 ++++++++++++++++++++++++++++ 5 files changed, 145 insertions(+), 14 deletions(-) create mode 100755 scripts/init-mainnet.sh create mode 100644 scripts/transfer-state.py diff --git a/scripts/export-testnet-state.sh b/scripts/export-testnet-state.sh index 81812a9..a6b21d4 100755 --- a/scripts/export-testnet-state.sh +++ b/scripts/export-testnet-state.sh @@ -23,6 +23,6 @@ testnet_state_file="$OUTPUT_DIR/testnet-state.json" docker run -it \ -v ${TESTNET_DEPLOYMENT_DIR}/data/laconicd-data:/root/testnet-deployment/.laconicd \ cerc/laconicd:local bash -c "laconicd export --home /root/testnet-deployment/.laconicd" \ - | jq .app_state.onboarding > "$testnet_state_file" + | jq > "$testnet_state_file" echo "Exported state from testnet to $testnet_state_file" diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh index ae249fe..c76e75e 100755 --- a/scripts/generate-mainnet-genesis.sh +++ b/scripts/generate-mainnet-genesis.sh @@ -23,6 +23,19 @@ cp $TESTNET_STATE_FILE $MAINNET_GENESIS_DIR/testnet-state.json # -------- +docker run -it \ + -v ./$MAINNET_GENESIS_DIR:/root/.laconicd \ + -v ./scripts:/scripts \ + -e "CHAIN_ID=$CHAIN_ID" \ + cerc/laconicd:local bash -c "/scripts/init-mainnet.sh" + +# -------- + +# Carry over state from testnet to mainnet +python transfer-state.py + +# -------- + # Run a script with cerc/laconicd:local to generate the genesis file # with onboarding module state and given allocations docker run -it \ @@ -30,7 +43,6 @@ docker run -it \ -v ./scripts:/scripts \ -e "CHAIN_ID=$CHAIN_ID" \ -e "EARLY_SUPPORTS_ACC_ADDRESS=$EARLY_SUPPORTS_ACC_ADDRESS" \ - -e "LPS_LOCKUP_ACC_ADDRESS=$LPS_LOCKUP_ACC_ADDRESS" \ cerc/laconicd:local bash -c "/scripts/genesis.sh" # Copy over the genesis file to output folder diff --git a/scripts/genesis.sh b/scripts/genesis.sh index 385b715..31589b1 100755 --- a/scripts/genesis.sh +++ b/scripts/genesis.sh @@ -8,13 +8,13 @@ set -u CHAINID=${CHAINID:-"laconic-mainnet"} MONIKER=${MONIKER:-"mainnet-node"} +KEYRING="test" NODE_HOME="/root/.laconicd" EARLY_SUPPORTS_ACC_ADDRESS=${EARLY_SUPPORTS_ACC_ADDRESS} -LPS_LOCKUP_ACC_ADDRESS=${LPS_LOCKUP_ACC_ADDRESS} -if [ -z "$EARLY_SUPPORTS_ACC_ADDRESS" ] || [ -z "$LPS_LOCKUP_ACC_ADDRESS" ]; then - echo "EARLY_SUPPORTS_ACC_ADDRESS or LPS_LOCKUP_ACC_ADDRESS not provided, exiting..." +if [ -z "$EARLY_SUPPORTS_ACC_ADDRESS" ]; then + echo "EARLY_SUPPORTS_ACC_ADDRESS not provided, exiting..." exit 1 fi @@ -23,25 +23,19 @@ fi EARLY_SUPPORTS_ALLOC="12960000000000000000000" # Early supports: 12960 * 10^18 alps (10% of total supply) LOCKUP_ALLOC="116640000000000000000000" # Lockup: 116640 * 10^18 alps (90% of total supply) LPS_LOCKUP_MODULE_ACCOUNT="lps_lockup" +LPS_DENOM="alps" testnet_state_file="$NODE_HOME/testnet-state.json" mainnet_genesis_file="$NODE_HOME/config/genesis.json" -laconicd config set client chain-id $CHAINID -laconicd init $MONIKER --chain-id $CHAINID --default-denom alnt - -# Import required state -jq --slurpfile nested $testnet_state_file '.app_state.auth = $nested[0].app_state' "$mainnet_genesis_file" > tmp.$$.json && mv tmp.$$.json "$mainnet_genesis_file" -jq --slurpfile nested $testnet_state_file '.consensus.auth = $nested[0].consensus' "$mainnet_genesis_file" > tmp.$$.json && mv tmp.$$.json "$mainnet_genesis_file" - # Update any module params if required here # Perform alps allocations -laconicd genesis add-genesis-account $ADDRESS $EARLY_SUPPORTS$DENOM --keyring-backend $KEYRING +laconicd genesis add-genesis-account $EARLY_SUPPORTS_ACC_ADDRESS $EARLY_SUPPORTS_ALLOC$LPS_DENOM --keyring-backend $KEYRING # Use zero address to add an account for lps_lockup zero_address="laconic1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqklcls0" -laconicd genesis add-genesis-account $zero_address $EARLY_SUPPORTS$DENOM --keyring-backend $KEYRING --module-name $LPS_LOCKUP_MODULE_ACCOUNT +laconicd genesis add-genesis-account $zero_address $LOCKUP_ALLOC$LPS_DENOM --keyring-backend $KEYRING --module-name $LPS_LOCKUP_MODULE_ACCOUNT # Update the lps_lockup address in bank module state lps_lockup_address=$(jq -r '.app_state.auth.accounts[] | select(.name == "lps_lockup") | .base_account.address' $HOME/.laconicd/config/genesis.json) diff --git a/scripts/init-mainnet.sh b/scripts/init-mainnet.sh new file mode 100755 index 0000000..bcb887a --- /dev/null +++ b/scripts/init-mainnet.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Exit on error +set -e +set -u + +# Note: Needs to be run in a docker container with image cerc/laconicd:local + +CHAINID=${CHAINID:-"laconic-mainnet"} +MONIKER=${MONIKER:-"mainnet-node"} + +laconicd config set client chain-id $CHAINID +laconicd init $MONIKER --chain-id $CHAINID --default-denom alnt diff --git a/scripts/transfer-state.py b/scripts/transfer-state.py new file mode 100644 index 0000000..5d67b54 --- /dev/null +++ b/scripts/transfer-state.py @@ -0,0 +1,112 @@ +import json + +from decimal import Decimal +from collections import defaultdict + +mainnet_genesis_dir="mainnet-genesis" +testnet_state_file=f"{mainnet_genesis_dir}/testnet-state.json" +mainnet_genesis_file=f"{mainnet_genesis_dir}/config/genesis.json" + +with open(testnet_state_file) as f: + testnet_state = json.load(f) + +with open(mainnet_genesis_file) as f: + mainnet_state = json.load(f) + +#------ + +# Import required module state +mainnet_state["app_state"]["auth"] = testnet_state["app_state"]["auth"] +mainnet_state["app_state"]["bond"] = testnet_state["app_state"]["bond"] +mainnet_state["app_state"]["bank"] = testnet_state["app_state"]["bank"] +mainnet_state["app_state"]["registry"] = testnet_state["app_state"]["registry"] +mainnet_state["app_state"]["slashing"]["params"] = testnet_state["app_state"]["slashing"]["params"] +mainnet_state["consensus"]["params"] = testnet_state["consensus"]["params"] + +#------ + +# Allocate back delegation stakes + +# Build map of address -> extra balance to add (as integers) +deltas = {} +for delegation in testnet_state["app_state"]["staking"]["delegations"]: + addr = delegation["delegator_address"] + amount = int(Decimal(delegation["shares"])) + deltas[addr] = deltas.get(addr, 0) + amount + +# Now apply the deltas to existing balances +supply_increment = 0 +for balance in mainnet_state["app_state"]["bank"]["balances"]: + addr = balance["address"] + if addr in deltas: + for coin in balance["coins"]: + if coin["denom"] == "alnt": + coin["amount"] = str(int(coin["amount"]) + deltas[addr]) + supply_increment += deltas[addr] + break + del deltas[addr] + +# Increase the total supply +for coin in mainnet_state["app_state"]["bank"]["supply"]: + if coin["denom"] == "alnt": + coin["amount"] = str(int(coin["amount"]) + supply_increment) + +#------ + +# Remove non-required module accounts + +# Addresses to remove +addresses_to_remove = { + "bonded_tokens_pool", + "not_bonded_tokens_pool", + "distribution" +} + +# Remove from auth.accounts and get their addresses +removed_addresses = set() +new_accounts = [] +for account in mainnet_state["app_state"]["auth"]["accounts"]: + account_type = account.get("@type", "") + if "ModuleAccount" in account_type and account.get("name") in addresses_to_remove: + removed_addresses.add(account["base_account"]["address"]) + continue + new_accounts.append(account) + +mainnet_state["app_state"]["auth"]["accounts"] = new_accounts + +# Remove from bank.balances and tally removed amounts +new_balances = [] +removed_amounts = defaultdict(int) + +for bal in mainnet_state["app_state"]["bank"]["balances"]: + if bal["address"] in removed_addresses: + # Skip this account + for coin in bal["coins"]: + denom = coin["denom"] + amount = int(coin["amount"]) + removed_amounts[denom] += amount + + continue + + new_balances.append(bal) + +mainnet_state["app_state"]["bank"]["balances"] = new_balances + +# Reduce from bank supply +new_supply = [] +for coin in mainnet_state["app_state"]["bank"]["supply"]: + denom = coin["denom"] + amount = int(coin["amount"]) + amount -= removed_amounts.get(denom, 0) + new_supply.append({ + "denom": denom, + "amount": str(amount) + }) + +mainnet_state["app_state"]["bank"]["supply"] = new_supply + +#------ + +# Write back modified state +with open(mainnet_genesis_file, "w") as f: + json.dump(mainnet_state, f, indent=2) -- 2.45.2 From 0e8153cb3a1f4cd0db875b58976dcf681128f819 Mon Sep 17 00:00:00 2001 From: Nabarun Date: Wed, 14 May 2025 19:28:49 +0530 Subject: [PATCH 22/31] Add steps to generate exported state and mainnet genesis file --- run-first-validator.md | 54 ++++++++++++++++--- scripts/genesis.sh | 2 + .../stacks/mainnet-laconicd/stack.yml | 2 +- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/run-first-validator.md b/run-first-validator.md index 9c8d543..53f7b43 100644 --- a/run-first-validator.md +++ b/run-first-validator.md @@ -7,26 +7,64 @@ ## Generate mainnet genesis file - +- Fetch the stack in machine where the testnet chain node is running + + ```bash + laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull + ``` + +- Run script to export state from testnet chain + + ```bash + ~/cerc/laconicd-stack/scripts/export-testnet-state.sh + ``` + + - The file will be generated in `/export/testnet-state.json` + + + + +- If mainnet node will be setup in new machine, fetch the stack again + +- Build container image + + ```bash + # Fetch laconicd repo specified in stack + laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd setup-repositories --git-ssh --pull + + # Build image + laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd build-containers + ``` + +- Copy the generated exported state from earlier + + ```bash + cp ~/cerc/laconicd-stack/testnet-state.json + ``` + +- Run script to generate genesis file using the exported state + + ```bash + ~/cerc/laconicd-stack/scripts/generate-mainnet-genesis.sh ~/cerc/laconicd-stack/testnet-state.json + ``` + + - Genesis file will generated in `output/genesis.json` ## Run node - Update [run-first-validator-vars.yml](playbooks/first-validator/run-first-validator-vars.yml) with required values: - - Use the mainnet genesis file generated in the previous step - ```bash # Private key of the existing account in hex format (required for gentx) pvt_key: "" - # Path to the generated mainnet genesis file + # Path to the generated mainnet genesis file generated in the previous step genesis_file: "" - # Optional - cerc_chain_id: "laconic-mainnet" + # Set custom moniker for the node cerc_moniker: "MainnetNode" - min_gas_price: 0.001 - cerc_loglevel: "info" + + # Set desired key name key_name: "validator" ``` diff --git a/scripts/genesis.sh b/scripts/genesis.sh index 31589b1..d055438 100755 --- a/scripts/genesis.sh +++ b/scripts/genesis.sh @@ -43,5 +43,7 @@ jq --arg old "$zero_address" --arg new "$lps_lockup_address" \ '.app_state.bank.balances |= map(if .address == $old then .address = $new else . end)' "$mainnet_genesis_file" > tmp.$$.json \ && mv tmp.$$.json "$mainnet_genesis_file" +# TODO: Dump JSON for allocations in LPS_LOCKUP_MODULE_ACCOUNT state + # Ensure that resulting genesis file is valid laconicd genesis validate diff --git a/stack-orchestrator/stacks/mainnet-laconicd/stack.yml b/stack-orchestrator/stacks/mainnet-laconicd/stack.yml index d65a7e0..3240acd 100644 --- a/stack-orchestrator/stacks/mainnet-laconicd/stack.yml +++ b/stack-orchestrator/stacks/mainnet-laconicd/stack.yml @@ -2,7 +2,7 @@ version: "1.0" name: mainnet-laconicd description: "Laconicd full node" repos: - - git.vdb.to/cerc-io/laconicd@v0.1.11 + - git.vdb.to/cerc-io/laconicd@mainnet containers: - cerc/laconicd pods: -- 2.45.2 From be5258c732b053f87fb71448d753f65fc3df1ea2 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Wed, 14 May 2025 19:37:41 +0530 Subject: [PATCH 23/31] Fix python script invocation --- scripts/generate-mainnet-genesis.sh | 7 ++++++- scripts/genesis.sh | 2 -- scripts/init-mainnet.sh | 6 +++--- stack-orchestrator/stacks/mainnet-laconicd/stack.yml | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh index c76e75e..9071c49 100755 --- a/scripts/generate-mainnet-genesis.sh +++ b/scripts/generate-mainnet-genesis.sh @@ -23,6 +23,7 @@ cp $TESTNET_STATE_FILE $MAINNET_GENESIS_DIR/testnet-state.json # -------- +echo "Initializing a new empty chain with chain-id $CHAIN_ID..." docker run -it \ -v ./$MAINNET_GENESIS_DIR:/root/.laconicd \ -v ./scripts:/scripts \ @@ -32,12 +33,15 @@ docker run -it \ # -------- # Carry over state from testnet to mainnet -python transfer-state.py +echo "Carrying over state from testnet state to mainnet genesis..." +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +python $script_dir/transfer-state.py # -------- # Run a script with cerc/laconicd:local to generate the genesis file # with onboarding module state and given allocations +echo "Performing alps allocations..." docker run -it \ -v ./$MAINNET_GENESIS_DIR:/root/.laconicd \ -v ./scripts:/scripts \ @@ -50,6 +54,7 @@ OUTPUT_DIR=output mkdir -p $OUTPUT_DIR cp ./$MAINNET_GENESIS_DIR/config/genesis.json $OUTPUT_DIR/genesis.json +# TODO: chown the output dir to user echo "Genesis file for mainnet written to $OUTPUT_DIR/genesis.json" # -------- diff --git a/scripts/genesis.sh b/scripts/genesis.sh index d055438..72c8f55 100755 --- a/scripts/genesis.sh +++ b/scripts/genesis.sh @@ -6,8 +6,6 @@ set -u # Note: Needs to be run in a docker container with image cerc/laconicd:local -CHAINID=${CHAINID:-"laconic-mainnet"} -MONIKER=${MONIKER:-"mainnet-node"} KEYRING="test" NODE_HOME="/root/.laconicd" diff --git a/scripts/init-mainnet.sh b/scripts/init-mainnet.sh index bcb887a..1e8d9d8 100755 --- a/scripts/init-mainnet.sh +++ b/scripts/init-mainnet.sh @@ -6,8 +6,8 @@ set -u # Note: Needs to be run in a docker container with image cerc/laconicd:local -CHAINID=${CHAINID:-"laconic-mainnet"} +CHAIN_ID=${CHAIN_ID:-"laconic-mainnet"} MONIKER=${MONIKER:-"mainnet-node"} -laconicd config set client chain-id $CHAINID -laconicd init $MONIKER --chain-id $CHAINID --default-denom alnt +laconicd config set client chain-id $CHAIN_ID +laconicd init $MONIKER --chain-id $CHAIN_ID --default-denom alnt diff --git a/stack-orchestrator/stacks/mainnet-laconicd/stack.yml b/stack-orchestrator/stacks/mainnet-laconicd/stack.yml index 3240acd..acfb443 100644 --- a/stack-orchestrator/stacks/mainnet-laconicd/stack.yml +++ b/stack-orchestrator/stacks/mainnet-laconicd/stack.yml @@ -2,7 +2,7 @@ version: "1.0" name: mainnet-laconicd description: "Laconicd full node" repos: - - git.vdb.to/cerc-io/laconicd@mainnet + - git.vdb.to/cerc-io/laconicd@mainnet # TODO: Use a release containers: - cerc/laconicd pods: -- 2.45.2 From cc0a325da6138a88ef352650dc552414a1293a07 Mon Sep 17 00:00:00 2001 From: Nabarun Date: Wed, 14 May 2025 20:19:40 +0530 Subject: [PATCH 24/31] Add playbook to generate mainnet genesis from exported testnet state --- ...ator-vars.yml => first-validator-vars.yml} | 0 .../first-validator/generate-genesis.yml | 40 +++++++++++++++++++ .../first-validator/run-first-validator.yml | 2 +- run-first-validator.md | 29 +++++--------- scripts/generate-mainnet-genesis.sh | 13 +++--- 5 files changed, 58 insertions(+), 26 deletions(-) rename playbooks/first-validator/{run-first-validator-vars.yml => first-validator-vars.yml} (100%) create mode 100644 playbooks/first-validator/generate-genesis.yml diff --git a/playbooks/first-validator/run-first-validator-vars.yml b/playbooks/first-validator/first-validator-vars.yml similarity index 100% rename from playbooks/first-validator/run-first-validator-vars.yml rename to playbooks/first-validator/first-validator-vars.yml diff --git a/playbooks/first-validator/generate-genesis.yml b/playbooks/first-validator/generate-genesis.yml new file mode 100644 index 0000000..e639ecd --- /dev/null +++ b/playbooks/first-validator/generate-genesis.yml @@ -0,0 +1,40 @@ +--- +- name: Generate Mainnet Genesis File + hosts: localhost + vars_files: + - first-validator-vars.yml + connection: local + tasks: + - name: Fetch repositories + ansible.builtin.shell: + cmd: "laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd setup-repositories --git-ssh --pull" + + - name: Build containers + ansible.builtin.shell: + cmd: "laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd build-containers" + + - name: Copy exported testnet state file + ansible.builtin.copy: + src: "{{ exported_state_path }}" + dest: "~/cerc/laconicd-stack/testnet-state.json" + remote_src: true # Set to true if exported_state_path is on the target host + + - block: + - name: Run script to generate genesis file + ansible.builtin.shell: + cmd: "CHAIN_ID={{ cerc_chain_id }} EARLY_SUPPORTS_ACC_ADDRESS={{ early_supports_acc_address }} ~/cerc/laconicd-stack/scripts/generate-mainnet-genesis.sh ~/cerc/laconicd-stack/testnet-state.json" + always: + - name: Clean up temporary genesis directory + become: true + ansible.builtin.file: + path: "{{ ansible_env.HOME }}/cerc/laconicd-stack/playbooks/first-validator/mainnet-genesis" + state: absent + + - name: Remove temporary copied state file + ansible.builtin.file: + path: "~/cerc/laconicd-stack/testnet-state.json" + state: absent + + - name: Display genesis file location + ansible.builtin.debug: + msg: "Mainnet genesis file generated at output/genesis.json" diff --git a/playbooks/first-validator/run-first-validator.yml b/playbooks/first-validator/run-first-validator.yml index 8b90468..5317547 100644 --- a/playbooks/first-validator/run-first-validator.yml +++ b/playbooks/first-validator/run-first-validator.yml @@ -2,7 +2,7 @@ - name: Run mainnet validator node hosts: localhost vars_files: - - run-first-validator-vars.yml + - first-validator-vars.yml vars: data_directory: "{{ lookup('env', 'DATA_DIRECTORY') }}" mainnet_deployment_dir: "{{ lookup('env', 'MAINNET_DEPLOYMENT_DIR') }}" diff --git a/run-first-validator.md b/run-first-validator.md index 53f7b43..143539b 100644 --- a/run-first-validator.md +++ b/run-first-validator.md @@ -22,34 +22,25 @@ - The file will be generated in `/export/testnet-state.json` - - - If mainnet node will be setup in new machine, fetch the stack again -- Build container image - ```bash - # Fetch laconicd repo specified in stack - laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd setup-repositories --git-ssh --pull - - # Build image - laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd build-containers + laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull ``` -- Copy the generated exported state from earlier +- Copy over the exported `testnet-state.json` file to target machine + +- Set envs + ``` + export EXPORTED_STATE_PATH= + export EARLY_SUPPORTS_ACC_ADDR= + +- Run playbook to use exported state for generating mainnet genesis ```bash - cp ~/cerc/laconicd-stack/testnet-state.json + ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/first-validator/generate-genesis.yml -e "exported_state_path=$EXPORTED_STATE_PATH" -e "early_supports_acc_address=$EARLY_SUPPORTS_ACC_ADDR" --ask-become-pass ``` -- Run script to generate genesis file using the exported state - - ```bash - ~/cerc/laconicd-stack/scripts/generate-mainnet-genesis.sh ~/cerc/laconicd-stack/testnet-state.json - ``` - - - Genesis file will generated in `output/genesis.json` - ## Run node - Update [run-first-validator-vars.yml](playbooks/first-validator/run-first-validator-vars.yml) with required values: diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh index 9071c49..a85ecf2 100755 --- a/scripts/generate-mainnet-genesis.sh +++ b/scripts/generate-mainnet-genesis.sh @@ -23,10 +23,12 @@ cp $TESTNET_STATE_FILE $MAINNET_GENESIS_DIR/testnet-state.json # -------- +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + echo "Initializing a new empty chain with chain-id $CHAIN_ID..." -docker run -it \ +docker run \ -v ./$MAINNET_GENESIS_DIR:/root/.laconicd \ - -v ./scripts:/scripts \ + -v $script_dir:/scripts \ -e "CHAIN_ID=$CHAIN_ID" \ cerc/laconicd:local bash -c "/scripts/init-mainnet.sh" @@ -34,17 +36,16 @@ docker run -it \ # Carry over state from testnet to mainnet echo "Carrying over state from testnet state to mainnet genesis..." -script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -python $script_dir/transfer-state.py +python3 $script_dir/transfer-state.py # -------- # Run a script with cerc/laconicd:local to generate the genesis file # with onboarding module state and given allocations echo "Performing alps allocations..." -docker run -it \ +docker run \ -v ./$MAINNET_GENESIS_DIR:/root/.laconicd \ - -v ./scripts:/scripts \ + -v $script_dir:/scripts \ -e "CHAIN_ID=$CHAIN_ID" \ -e "EARLY_SUPPORTS_ACC_ADDRESS=$EARLY_SUPPORTS_ACC_ADDRESS" \ cerc/laconicd:local bash -c "/scripts/genesis.sh" -- 2.45.2 From ab333da5be24cbc5d870b778920c201c22671721 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 15 May 2025 10:03:32 +0530 Subject: [PATCH 25/31] Update script to calculate common staking amount --- scripts/generate-mainnet-genesis.sh | 8 ++++- scripts/genesis.sh | 2 +- scripts/transfer-state.py | 55 ++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh index a85ecf2..a2ddc8e 100755 --- a/scripts/generate-mainnet-genesis.sh +++ b/scripts/generate-mainnet-genesis.sh @@ -12,9 +12,11 @@ fi TESTNET_STATE_FILE="$1" MAINNET_GENESIS_DIR=mainnet-genesis +OUTPUT_DIR=output -# Create a temporary target directory +# Create a required target directories mkdir -p $MAINNET_GENESIS_DIR +mkdir -p $OUTPUT_DIR # -------- @@ -34,6 +36,10 @@ docker run \ # -------- +# Install required bech32 dependency +# TODO: Avoid installing bech32 system-wide +python -m pip install bech32 --break-system-packages + # Carry over state from testnet to mainnet echo "Carrying over state from testnet state to mainnet genesis..." python3 $script_dir/transfer-state.py diff --git a/scripts/genesis.sh b/scripts/genesis.sh index 72c8f55..301fa90 100755 --- a/scripts/genesis.sh +++ b/scripts/genesis.sh @@ -29,7 +29,7 @@ mainnet_genesis_file="$NODE_HOME/config/genesis.json" # Update any module params if required here # Perform alps allocations -laconicd genesis add-genesis-account $EARLY_SUPPORTS_ACC_ADDRESS $EARLY_SUPPORTS_ALLOC$LPS_DENOM --keyring-backend $KEYRING +laconicd genesis add-genesis-account $EARLY_SUPPORTS_ACC_ADDRESS $EARLY_SUPPORTS_ALLOC$LPS_DENOM --keyring-backend $KEYRING --append # Use zero address to add an account for lps_lockup zero_address="laconic1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqklcls0" diff --git a/scripts/transfer-state.py b/scripts/transfer-state.py index 5d67b54..a8081f7 100644 --- a/scripts/transfer-state.py +++ b/scripts/transfer-state.py @@ -2,10 +2,56 @@ import json from decimal import Decimal from collections import defaultdict +from bech32 import bech32_decode, bech32_encode, convertbits + +#------ + +# Helper methods + +def valoper_to_account_address(valoper_addr: str, new_prefix = "laconic") -> str: + hrp, data = bech32_decode(valoper_addr) + if hrp is None or data is None: + raise ValueError("Invalid bech32 address") + + # Convert back from 5-bit to 8-bit + decoded = convertbits(data, 5, 8, False) + if decoded is None: + raise ValueError("Failed to convert bits") + + # Re-encode with new prefix + converted_data = convertbits(decoded, 8, 5, True) + return bech32_encode(new_prefix, converted_data) + +def get_min_delegation_share(state): + validators = state["app_state"]["staking"]["validators"] + delegations = state["app_state"]["staking"]["delegations"] + + shares_list = [] + + for val in validators: + valoper_addr = val["operator_address"] + orig_delegator_addr = valoper_to_account_address(valoper_addr) + + # Find delegations where the delegator is the original delegator and delegated to their validator + for delegation in delegations: + if (delegation["delegator_address"] == orig_delegator_addr and + delegation["validator_address"] == valoper_addr): + shares = int(Decimal(delegation["shares"])) + shares_list.append(shares) + + break + + # Find minimum + return min(shares_list) + +#------ + +# Read testnet and mainnet states mainnet_genesis_dir="mainnet-genesis" testnet_state_file=f"{mainnet_genesis_dir}/testnet-state.json" mainnet_genesis_file=f"{mainnet_genesis_dir}/config/genesis.json" +staking_amount_file=f"output/staking-amount.json" with open(testnet_state_file) as f: testnet_state = json.load(f) @@ -107,6 +153,13 @@ mainnet_state["app_state"]["bank"]["supply"] = new_supply #------ +# Find minimum delegation share for common staking amount + +min_delegation_share = get_min_delegation_share(testnet_state) +with open(staking_amount_file, "w") as f: + json.dump({"common_staking_amount": min_delegation_share}, f, indent=2) +print(f"Staking amount written to {staking_amount_file}") + # Write back modified state with open(mainnet_genesis_file, "w") as f: - json.dump(mainnet_state, f, indent=2) + json.dump(mainnet_state, f, indent=2) -- 2.45.2 From a8f6a8f73f038607565eee48871378ebd2dceb8d Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 15 May 2025 10:28:55 +0530 Subject: [PATCH 26/31] Update permissions for generated files --- playbooks/first-validator/generate-genesis.yml | 5 ++++- scripts/generate-mainnet-genesis.sh | 4 +--- scripts/init-mainnet.sh | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/playbooks/first-validator/generate-genesis.yml b/playbooks/first-validator/generate-genesis.yml index e639ecd..0fe8b2e 100644 --- a/playbooks/first-validator/generate-genesis.yml +++ b/playbooks/first-validator/generate-genesis.yml @@ -25,7 +25,6 @@ cmd: "CHAIN_ID={{ cerc_chain_id }} EARLY_SUPPORTS_ACC_ADDRESS={{ early_supports_acc_address }} ~/cerc/laconicd-stack/scripts/generate-mainnet-genesis.sh ~/cerc/laconicd-stack/testnet-state.json" always: - name: Clean up temporary genesis directory - become: true ansible.builtin.file: path: "{{ ansible_env.HOME }}/cerc/laconicd-stack/playbooks/first-validator/mainnet-genesis" state: absent @@ -38,3 +37,7 @@ - name: Display genesis file location ansible.builtin.debug: msg: "Mainnet genesis file generated at output/genesis.json" + + - name: Display staking-amount file location + ansible.builtin.debug: + msg: "Staking amount written to output/staking-amount.json" diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh index a2ddc8e..f20b615 100755 --- a/scripts/generate-mainnet-genesis.sh +++ b/scripts/generate-mainnet-genesis.sh @@ -57,8 +57,6 @@ docker run \ cerc/laconicd:local bash -c "/scripts/genesis.sh" # Copy over the genesis file to output folder -OUTPUT_DIR=output -mkdir -p $OUTPUT_DIR cp ./$MAINNET_GENESIS_DIR/config/genesis.json $OUTPUT_DIR/genesis.json # TODO: chown the output dir to user @@ -67,4 +65,4 @@ echo "Genesis file for mainnet written to $OUTPUT_DIR/genesis.json" # -------- # Clean up -echo "Please remove the temporary data directory: sudo rm -rf $MAINNET_GENESIS_DIR" +rm -rf $MAINNET_GENESIS_DIR diff --git a/scripts/init-mainnet.sh b/scripts/init-mainnet.sh index 1e8d9d8..a6a0c01 100755 --- a/scripts/init-mainnet.sh +++ b/scripts/init-mainnet.sh @@ -8,6 +8,10 @@ set -u CHAIN_ID=${CHAIN_ID:-"laconic-mainnet"} MONIKER=${MONIKER:-"mainnet-node"} +NODE_HOME="/root/.laconicd" laconicd config set client chain-id $CHAIN_ID laconicd init $MONIKER --chain-id $CHAIN_ID --default-denom alnt + +# Allow all permissions to process further +chmod -R 777 $NODE_HOME/data $NODE_HOME/config -- 2.45.2 From c9eb1099fc31a9bf36c58b30df190abbabbcd69c Mon Sep 17 00:00:00 2001 From: Nabarun Date: Thu, 15 May 2025 10:36:32 +0530 Subject: [PATCH 27/31] Update playbook to generate genesis output in CWD --- playbooks/first-validator/generate-genesis.yml | 3 ++- run-first-validator.md | 4 +++- scripts/generate-mainnet-genesis.sh | 2 +- .../config/mainnet-laconicd/create-and-collect-gentx.sh | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/playbooks/first-validator/generate-genesis.yml b/playbooks/first-validator/generate-genesis.yml index 0fe8b2e..d265fd2 100644 --- a/playbooks/first-validator/generate-genesis.yml +++ b/playbooks/first-validator/generate-genesis.yml @@ -22,7 +22,8 @@ - block: - name: Run script to generate genesis file ansible.builtin.shell: - cmd: "CHAIN_ID={{ cerc_chain_id }} EARLY_SUPPORTS_ACC_ADDRESS={{ early_supports_acc_address }} ~/cerc/laconicd-stack/scripts/generate-mainnet-genesis.sh ~/cerc/laconicd-stack/testnet-state.json" + cmd: "CHAIN_ID={{ cerc_chain_id }} EARLY_SUPPORTS_ACC_ADDRESS={{ early_supports_acc_address }} {{ ansible_env.HOME }}/cerc/laconicd-stack/scripts/generate-mainnet-genesis.sh {{ ansible_env.HOME }}/cerc/laconicd-stack/testnet-state.json" + chdir: "{{ lookup('env', 'PWD') }}" always: - name: Clean up temporary genesis directory ansible.builtin.file: diff --git a/run-first-validator.md b/run-first-validator.md index 143539b..fe467d6 100644 --- a/run-first-validator.md +++ b/run-first-validator.md @@ -38,11 +38,13 @@ - Run playbook to use exported state for generating mainnet genesis ```bash - ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/first-validator/generate-genesis.yml -e "exported_state_path=$EXPORTED_STATE_PATH" -e "early_supports_acc_address=$EARLY_SUPPORTS_ACC_ADDR" --ask-become-pass + ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/first-validator/generate-genesis.yml -e "exported_state_path=$EXPORTED_STATE_PATH" -e "early_supports_acc_address=$EARLY_SUPPORTS_ACC_ADDR" ``` ## Run node + + - Update [run-first-validator-vars.yml](playbooks/first-validator/run-first-validator-vars.yml) with required values: ```bash diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh index f20b615..67836b8 100755 --- a/scripts/generate-mainnet-genesis.sh +++ b/scripts/generate-mainnet-genesis.sh @@ -38,7 +38,7 @@ docker run \ # Install required bech32 dependency # TODO: Avoid installing bech32 system-wide -python -m pip install bech32 --break-system-packages +python3 -m pip install bech32 --break-system-packages # Carry over state from testnet to mainnet echo "Carrying over state from testnet state to mainnet genesis..." diff --git a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh index b6a446d..f213846 100755 --- a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh +++ b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh @@ -53,6 +53,7 @@ if [ -z "$account_address" ]; then exit 1 fi +# TODO: Use staking amount from output/staking-amount.json # Get balance of account stake_amount=$(jq -r --arg address "$account_address" --arg denom "$DENOM" '.app_state.bank.balances[] | select(.address == $address) | .coins[] | select(.denom == $denom) | .amount' $genesis_file_path) -- 2.45.2 From be81ee46393b1f4208492e0a41345a90705d330d Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 15 May 2025 11:23:37 +0530 Subject: [PATCH 28/31] Remove unused script --- .../config/mainnet-laconicd/allocate-lps.sh | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100755 stack-orchestrator/config/mainnet-laconicd/allocate-lps.sh diff --git a/stack-orchestrator/config/mainnet-laconicd/allocate-lps.sh b/stack-orchestrator/config/mainnet-laconicd/allocate-lps.sh deleted file mode 100755 index 3dfc1c1..0000000 --- a/stack-orchestrator/config/mainnet-laconicd/allocate-lps.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then - set -x -fi - -set -e - -# Early supports: 12960 * 10^18 alps (10% of 129600 * 10^18 alps) -EARLY_SUPPORTS="12960000000000000000000" - -DENOM=alps - -input_genesis_file=$INPUT_GENESIS_FILE -if [ ! -f ${input_genesis_file} ]; then - echo "Genesis file not provided, exiting..." - exit 1 -fi - -if [ -z "$RECIPIENT_ADDRESS" ]; then - echo "Recipient address not provided, exiting..." - exit 1 -fi - -update_genesis() { - jq "$1" ${input_genesis_file} > ${input_genesis_file}.tmp && - mv ${input_genesis_file}.tmp ${input_genesis_file} -} - -# Add new account to auth.accounts -update_genesis '.app_state["auth"]["accounts"] += [{"@type": "/cosmos.auth.v1beta1.BaseAccount", "address": "'$RECIPIENT_ADDRESS'", "pub_key": null, "account_number": "0", "sequence": "0"}]' - -# Add balance for the new account -update_genesis '.app_state["bank"]["balances"] += [{"address": "'$RECIPIENT_ADDRESS'", "coins": [{"denom": "'$DENOM'", "amount": "'$EARLY_SUPPORTS'"}]}]' - -# Get current supply -CURRENT_SUPPLY=$(jq -r '.app_state["bank"]["supply"][0]["amount"]' ${input_genesis_file}) - -# Calculate new supply -NEW_SUPPLY=$((CURRENT_SUPPLY + EARLY_SUPPORTS)) - -# Update total supply -update_genesis '.app_state["bank"]["supply"][0]["amount"] = "'$NEW_SUPPLY'"' - -echo "Genesis file updated with new account ${RECIPIENT_ADDRESS} and allocated ${EARLY_SUPPORTS} ${DENOM}" -- 2.45.2 From 5c83f75c62c7ba4f49bb40c97080a3f48f1c5d6b Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 15 May 2025 11:40:49 +0530 Subject: [PATCH 29/31] Set empty permissions for lps lockup account --- scripts/genesis.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/genesis.sh b/scripts/genesis.sh index 301fa90..32822f8 100755 --- a/scripts/genesis.sh +++ b/scripts/genesis.sh @@ -40,6 +40,8 @@ lps_lockup_address=$(jq -r '.app_state.auth.accounts[] | select(.name == "lps_lo jq --arg old "$zero_address" --arg new "$lps_lockup_address" \ '.app_state.bank.balances |= map(if .address == $old then .address = $new else . end)' "$mainnet_genesis_file" > tmp.$$.json \ && mv tmp.$$.json "$mainnet_genesis_file" +jq '(.app_state.auth.accounts[] | select(.name == "lps_lockup") | .permissions) = []' "$mainnet_genesis_file" > tmp.$$.json \ + && mv tmp.$$.json "$mainnet_genesis_file" # TODO: Dump JSON for allocations in LPS_LOCKUP_MODULE_ACCOUNT state -- 2.45.2 From 0a4c5bd25a11d0d5de7173845360cd55ba6e4e16 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 15 May 2025 11:52:18 +0530 Subject: [PATCH 30/31] Fix formatting --- run-first-validator.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/run-first-validator.md b/run-first-validator.md index fe467d6..a1405ce 100644 --- a/run-first-validator.md +++ b/run-first-validator.md @@ -21,7 +21,6 @@ - The file will be generated in `/export/testnet-state.json` - - If mainnet node will be setup in new machine, fetch the stack again ```bash @@ -31,9 +30,11 @@ - Copy over the exported `testnet-state.json` file to target machine - Set envs - ``` + + ```bash export EXPORTED_STATE_PATH= export EARLY_SUPPORTS_ACC_ADDR= + ``` - Run playbook to use exported state for generating mainnet genesis @@ -57,7 +58,7 @@ # Set custom moniker for the node cerc_moniker: "MainnetNode" - # Set desired key name + # Set desired key name key_name: "validator" ``` -- 2.45.2 From 5dd89f83eefb7fe8308e4dfb3cbb001716baee3d Mon Sep 17 00:00:00 2001 From: Nabarun Date: Thu, 15 May 2025 12:04:54 +0530 Subject: [PATCH 31/31] Update distribution params to disable staking rewards --- .gitignore | 3 +++ ...vars.yml => first-validator-vars.example.yml} | 2 +- .../first-validator/run-first-validator.yml | 4 ++-- run-first-validator.md | 16 ++++++++++++++-- scripts/generate-mainnet-genesis.sh | 1 - scripts/genesis.sh | 15 +++++++++++++++ .../compose/docker-compose-mainnet-laconicd.yml | 2 +- .../config/mainnet-laconicd/run-laconicd.sh | 12 ++++++++++++ .../stacks/mainnet-laconicd/README.md | 2 -- 9 files changed, 48 insertions(+), 9 deletions(-) rename playbooks/first-validator/{first-validator-vars.yml => first-validator-vars.example.yml} (77%) diff --git a/.gitignore b/.gitignore index abaaaab..2948191 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ *-deployment *-spec.yml + +# Playbook vars +playbooks/first-validator/first-validator-vars.yml diff --git a/playbooks/first-validator/first-validator-vars.yml b/playbooks/first-validator/first-validator-vars.example.yml similarity index 77% rename from playbooks/first-validator/first-validator-vars.yml rename to playbooks/first-validator/first-validator-vars.example.yml index 78d11ec..6d8b34f 100644 --- a/playbooks/first-validator/first-validator-vars.yml +++ b/playbooks/first-validator/first-validator-vars.example.yml @@ -1,4 +1,4 @@ -cerc_moniker: "MainnetNode" +cerc_moniker: "LaconicMainnetNode" cerc_chain_id: "laconic-mainnet" min_gas_price: 0.001 cerc_loglevel: "info" diff --git a/playbooks/first-validator/run-first-validator.yml b/playbooks/first-validator/run-first-validator.yml index 5317547..8022454 100644 --- a/playbooks/first-validator/run-first-validator.yml +++ b/playbooks/first-validator/run-first-validator.yml @@ -20,7 +20,7 @@ fail: msg: >- Required key files are not defined. - Please set genesis_file in run-first-validator-vars.yml. + Please set genesis_file in first-validator-vars.yml. when: not genesis_file - name: Fetch laconicd stack shell: laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull @@ -72,7 +72,7 @@ - name: Fail if pvt_key is not set fail: msg: >- - Private key (pvt_key) is not set in run-first-validator-vars.yml. + Private key (pvt_key) is not set in first-validator-vars.yml. This is required for creating the gentx. when: not pvt_key diff --git a/run-first-validator.md b/run-first-validator.md index a1405ce..ffb5d0a 100644 --- a/run-first-validator.md +++ b/run-first-validator.md @@ -42,11 +42,23 @@ ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/first-validator/generate-genesis.yml -e "exported_state_path=$EXPORTED_STATE_PATH" -e "early_supports_acc_address=$EARLY_SUPPORTS_ACC_ADDR" ``` +- Genesis file will be generated in output directory along with a file specifying the staking amount + + ```bash + # List files in output directory - genesis.json and staking-amount.json + ls -l output + ``` + ## Run node -- Update [run-first-validator-vars.yml](playbooks/first-validator/run-first-validator-vars.yml) with required values: +- Copy the example variables file: + ```bash + cp ~/cerc/laconicd-stack/playbooks/first-validator/first-validator-vars.example.yml ~/cerc/laconicd-stack/playbooks/first-validator/first-validator-vars.yml + ``` + +- Update `~/cerc/laconicd-stack/playbooks/first-validator/first-validator-vars.yml` with required values: ```bash # Private key of the existing account in hex format (required for gentx) @@ -56,7 +68,7 @@ genesis_file: "" # Set custom moniker for the node - cerc_moniker: "MainnetNode" + cerc_moniker: "LaconicMainnetNode" # Set desired key name key_name: "validator" diff --git a/scripts/generate-mainnet-genesis.sh b/scripts/generate-mainnet-genesis.sh index 67836b8..e1e4982 100755 --- a/scripts/generate-mainnet-genesis.sh +++ b/scripts/generate-mainnet-genesis.sh @@ -59,7 +59,6 @@ docker run \ # Copy over the genesis file to output folder cp ./$MAINNET_GENESIS_DIR/config/genesis.json $OUTPUT_DIR/genesis.json -# TODO: chown the output dir to user echo "Genesis file for mainnet written to $OUTPUT_DIR/genesis.json" # -------- diff --git a/scripts/genesis.sh b/scripts/genesis.sh index 32822f8..da012c7 100755 --- a/scripts/genesis.sh +++ b/scripts/genesis.sh @@ -27,6 +27,21 @@ testnet_state_file="$NODE_HOME/testnet-state.json" mainnet_genesis_file="$NODE_HOME/config/genesis.json" # Update any module params if required here +update_genesis() { + jq "$1" $NODE_HOME/config/genesis.json > $NODE_HOME/config/tmp_genesis.json && + mv $NODE_HOME/config/tmp_genesis.json $NODE_HOME/config/genesis.json +} + +# Set distribution community tax to 1 for disabling staking rewards and redirect them to the community pool +update_genesis '.app_state["distribution"]["params"]["community_tax"]="1.000000000000000000"' + +# Increase threshold in gov proposals for making it difficult to spend community pool funds +echo "Setting high threshold for accepting governance proposal" +update_genesis '.app_state["gov"]["params"]["quorum"]="1.000000000000000000"' +# Set expedited threshold to 100% +update_genesis '.app_state["gov"]["params"]["expedited_threshold"]="1.000000000000000000"' +# Set normal threshold to 99% since it needs to be lesser than expedited threshold +update_genesis '.app_state["gov"]["params"]["threshold"]="0.990000000000000000"' # Perform alps allocations laconicd genesis add-genesis-account $EARLY_SUPPORTS_ACC_ADDRESS $EARLY_SUPPORTS_ALLOC$LPS_DENOM --keyring-backend $KEYRING --append diff --git a/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml index e649dea..6822d82 100644 --- a/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml +++ b/stack-orchestrator/compose/docker-compose-mainnet-laconicd.yml @@ -4,7 +4,7 @@ services: image: cerc/laconicd:local command: ["bash", "-c", "/opt/run-laconicd.sh"] environment: - CERC_MONIKER: ${CERC_MONIKER:-MainnetNode} + CERC_MONIKER: ${CERC_MONIKER} CERC_CHAIN_ID: ${CERC_CHAIN_ID:-laconic-mainnet} CERC_PEERS: ${CERC_PEERS} MIN_GAS_PRICE: ${MIN_GAS_PRICE:-0.001} diff --git a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh index 9e35027..047b659 100755 --- a/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh +++ b/stack-orchestrator/config/mainnet-laconicd/run-laconicd.sh @@ -42,6 +42,18 @@ sed -i 's/cors_allowed_origins.*$/cors_allowed_origins = ["*"]/' $NODE_HOME/conf # Update config with persistent peers sed -i "s/^persistent_peers *=.*/persistent_peers = \"$CERC_PEERS\"/g" $NODE_HOME/config/config.toml +# Enable telemetry (prometheus metrics: http://localhost:1317/metrics?format=prometheus) +if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' 's/enabled = false/enabled = true/g' $NODE_HOME/config/app.toml + sed -i '' 's/prometheus-retention-time = 0/prometheus-retention-time = 60/g' $NODE_HOME/config/app.toml + sed -i '' 's/prometheus = false/prometheus = true/g' $NODE_HOME/config/config.toml +else + sed -i 's/enabled = false/enabled = true/g' $NODE_HOME/config/app.toml + sed -i 's/prometheus-retention-time = 0/prometheus-retention-time = 60/g' $NODE_HOME/config/app.toml + sed -i 's/prometheus = false/prometheus = true/g' $NODE_HOME/config/config.toml +fi + + echo "Starting laconicd node..." laconicd start \ --api.enable \ diff --git a/stack-orchestrator/stacks/mainnet-laconicd/README.md b/stack-orchestrator/stacks/mainnet-laconicd/README.md index aaffda9..3ab806d 100644 --- a/stack-orchestrator/stacks/mainnet-laconicd/README.md +++ b/stack-orchestrator/stacks/mainnet-laconicd/README.md @@ -1,3 +1 @@ # mainnet-laconicd - -Instructions for running validator nodes -- 2.45.2