From 44ab959af5874b4cfd1e433bfb345fdf2b907b7a Mon Sep 17 00:00:00 2001 From: shreerang Date: Mon, 9 Jun 2025 12:37:50 +0000 Subject: [PATCH] Update playbooks to sign txs on a separate machine from the one running `laconicd` node (#5) Part of https://www.notion.so/Create-stacks-for-mainnet-1f2a6b22d4728034be4be2c51decf94e Co-authored-by: Shreerang Kale Reviewed-on: https://git.vdb.to/cerc-io/laconicd-stack/pulls/5 Co-authored-by: shreerang Co-committed-by: shreerang --- docs/run-first-validator.md | 172 +++++++++++------- docs/run-validator.md | 84 ++++++--- .../first-validator-vars.example.yml | 4 +- .../first-validator/generate-genesis.yml | 75 +++++++- .../first-validator/setup-first-validator.yml | 46 +---- playbooks/validator/create-validator.yml | 99 +++++++++- .../validator/validator-vars.example.yml | 7 +- scripts/generate-lps-lock.sh | 17 +- .../create-and-collect-gentx.sh | 11 +- .../mainnet-laconicd/create-validator.sh | 15 +- 10 files changed, 375 insertions(+), 155 deletions(-) diff --git a/docs/run-first-validator.md b/docs/run-first-validator.md index 71c2ee0..df223c9 100644 --- a/docs/run-first-validator.md +++ b/docs/run-first-validator.md @@ -7,8 +7,56 @@ - LPS distribution Google spreadsheet URL or CSV file path - Install `zstd` using `sudo apt install zstd` +## Setup node + +- Run the following steps in the machine where the mainnet node is to be setup + +- Copy the example variables file if not already done: + + ```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 + # Set custom moniker for the node + cerc_moniker: "LaconicMainnetNode" + + # Set desired key name + key_name: "laconic-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 + export MAINNET_DEPLOYMENT_DIR=mainnet-laconicd-deployment + ``` + +- Run ansible playbook to setup the node: + + ```bash + ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/first-validator/setup-first-validator.yml + ``` + +- Get the public key of your node: + + ```bash + docker run -it \ + -v $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/data/laconicd-data:/root/.laconicd \ + cerc/laconicd:local bash -c "laconicd tendermint show-validator" + ``` + + NOTE: This public key is required in next step to generate the genesis file + ## Export testnet state +- Run the following steps in machine where the testnet node is running + - Get your private key from testnet deployment: ```bash @@ -39,7 +87,9 @@ ## Generate mainnet genesis file -- If mainnet node is to be setup in a new machine, fetch the stack again: +- Run the following steps in secure machine separate from the one where the node is setup + +- Fetch the stack: ```bash laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull @@ -47,10 +97,28 @@ - Copy over compressed `testnet-state.zst` file to target machine -- Extract the testnet-state JSON file +- Set envs: + ```bash + # Path where exported testnet state JSON file will be created + export EXPORTED_STATE_PATH= + + # Path where LPS distribution JSON file will be created + export LPS_DISTRIBUTION_PATH= + + export EARLY_SUPPORTS_ACC_ADDR= + + # Parent directory where the deployment directory will live + export DATA_DIRECTORY= + + # Set mainnet deployment directory + export MAINNET_DEPLOYMENT_DIR=mainnet-laconicd-deployment ``` - zstd -dc /testnet-state.zst > testnet-state.json + +- Extract the testnet-state JSON file: + + ```bash + zstd -dc /testnet-state.zst > $EXPORTED_STATE_PATH # Remove zst folder rm -rf /testnet-state.zst @@ -59,20 +127,10 @@ - Generate LPS lockup distribution JSON file ```bash - ~/cerc/laconicd-stack/scripts/generate-lps-lock.sh -i "" -d "" + ~/cerc/laconicd-stack/scripts/generate-lps-lock.sh -i "" -o $LPS_DISTRIBUTION_PATH ``` - - This will generate the `distribution.json` file - -- Copy over the LPS lockup distribution `distribution.json` file to target machine - -- Set envs: - - ```bash - export EXPORTED_STATE_PATH= - export LPS_DISTRIBUTION_PATH= - export EARLY_SUPPORTS_ACC_ADDR= - ``` + - This will generate the `distribution.json` file at `$LPS_DISTRIBUTION_PATH` - Copy the example variables file: @@ -80,12 +138,21 @@ cp ~/cerc/laconicd-stack/playbooks/first-validator/first-validator-vars.example.yml ~/cerc/laconicd-stack/playbooks/first-validator/first-validator-vars.yml ``` -- Run playbook to use exported state for generating mainnet genesis: +- Edit `~/cerc/laconicd-stack/playbooks/first-validator/first-validator-vars.yml` with required values: + + ```bash + # Use the public key exported in previous step (make sure to wrap it with single quotes ['']) + validator_pub_key: '' + ``` + +- Run playbook to use exported state for generating mainnet genesis file with gentx: ```bash ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/first-validator/generate-genesis.yml -e "exported_state_path=$EXPORTED_STATE_PATH" -e "lps_distribution_path=$LPS_DISTRIBUTION_PATH" -e "early_supports_acc_address=$EARLY_SUPPORTS_ACC_ADDR" ``` + - Input private key of the existing account that was exported in previous steps when prompted + - Genesis file will be generated in output directory along with a file specifying the staking amount ```bash @@ -93,50 +160,9 @@ ls -l output ``` -## Setup node +## Run node -- Copy the example variables file if not already done: - - ```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 - # Use the private key of the existing account that was exported in previous steps - pvt_key: "" - - # Path to the generated mainnet genesis file - # Use the absolute path of generated output directory in the previous steps - genesis_file: "/genesis.json" - - # Path to staking-amount.json generated in previous steps - staking_amount_file: "/staking-amount.json" - - # Set custom moniker for the node - cerc_moniker: "LaconicMainnetNode" - - # Set desired key name - key_name: "laconic-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 gentx and setup the node: - - ```bash - ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/first-validator/setup-first-validator.yml - ``` +- Run the following steps in the machine where the mainnet node is setup ### Setup TMKMS (Optional but Recommended) @@ -156,6 +182,7 @@ ``` - Update the TMKMS configuration file `$TMKMS_HOME/tmkms.toml`: + ```toml [[chain]] id = "laconic-mainnet" @@ -186,40 +213,44 @@ - Place the validator key file in TMKMS config directory at `$TMKMS_HOME/secrets/` - Import the private validator key into tmkms: - + ```bash tmkms softsign import $TMKMS_HOME/secrets/priv_validator_key.json $TMKMS_HOME/secrets/priv_validator_key ``` - + - Remove the JSON key file - + ```bash rm $TMKMS_HOME/secrets/priv_validator_key.json ``` - Start TMKMS: + ```bash tmkms start --config $TMKMS_HOME/tmkms.toml ``` - Expected example output: + ```bash INFO tmkms::commands::start: tmkms 0.14.0 starting up... INFO tmkms::keyring: [keyring:softsign] added consensus Ed25519 key: {"@type":"/cosmos.crypto.ed25519.PubKey","key":"T24No1A1FmetNRVCOSg2G2XAKWh97oBXuELdAD6DFgw="} INFO tmkms::connection::tcp: KMS node ID: 7f5fd8dae8953e964e7e56edd4700f597ea0d45c ERROR tmkms::client: [laconic-mainnet@tcp://localhost:26659] I/O error: Connection refused (os error 111) ``` + NOTE: The errors dissapear once the laconicd node starts - Note the pubkey logged at start for comparing later with validator pubkey on chain - Enable TMKMS in the laconicd node configuration: + ```bash # Set TMKMS_ENABLED to true in the node's config.env echo "TMKMS_ENABLED=true" >> $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/config.env ``` -- Remove the validator key from node deployment as it is no longer required +- Remove the validator key from node deployment as it is no longer required: ```bash rm $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/data/laconicd-data/config/priv_validator_key.json @@ -227,9 +258,15 @@ NOTE: Store it safely offline in case of an emergency -## Run node +### Start node -- Command to run node +- Copy the genesis file to the mainnet deployment tmp directory: + + ```bash + cp $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/data/laconicd-data/tmp/genesis.json + ``` + +- Command to run node: ```bash laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR start @@ -241,14 +278,15 @@ laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR logs laconicd -f ``` -- If TMKMS has been configured verify that validator and TMKMS pubkeys match +- If TMKMS has been configured verify that validator and TMKMS pubkeys match: - Get validator pubkey on chain + ```bash # Check consensus_pubkey in output laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR exec laconicd 'laconicd query staking validators -o json | jq .validators' ``` - + - Compare it with the pubkey noted from logs in TMKMS - Check bonds list to confirm that testnet state was transferred properly: diff --git a/docs/run-validator.md b/docs/run-validator.md index ef684c6..30bce96 100644 --- a/docs/run-validator.md +++ b/docs/run-validator.md @@ -7,6 +7,8 @@ ## Setup Node +- Run the following steps in the machine where the validator node is to be setup + - Get your private key from testnet deployment: ```bash @@ -53,8 +55,7 @@ export DATA_DIRECTORY= # Set mainnet deployment directory - # for eg: mainnet-laconicd-deployment - export MAINNET_DEPLOYMENT_DIR= + export MAINNET_DEPLOYMENT_DIR=mainnet-validator-deployment ``` - Run ansible playbook to set up your validator node deployment: @@ -81,6 +82,7 @@ ``` - Update the TMKMS configuration file `$TMKMS_HOME/tmkms.toml`: + ```toml [[chain]] id = "laconic-mainnet" @@ -111,23 +113,25 @@ - Place the validator key file in TMKMS config directory at `$TMKMS_HOME/secrets/` - Import the private validator key into tmkms: - + ```bash tmkms softsign import $TMKMS_HOME/secrets/priv_validator_key.json $TMKMS_HOME/secrets/priv_validator_key ``` - + - Remove the JSON key file - + ```bash rm $TMKMS_HOME/secrets/priv_validator_key.json ``` - Start TMKMS: + ```bash tmkms start --config $TMKMS_HOME/tmkms.toml ``` - Enable TMKMS in the laconicd node configuration: + ```bash # Set TMKMS_ENABLED to true in the node's config.env echo "TMKMS_ENABLED=true" >> $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/config.env @@ -136,28 +140,61 @@ ## Start Node - Start the laconicd node: + ```bash laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR start ``` - Check logs to ensure that node is running: + ```bash laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR logs laconicd -f ``` +- Get the public key of your node: + + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR exec laconicd "laconicd tendermint show-validator" + ``` + + NOTE: This public key is required in next step to create validator + ## Create Validator +- Run these steps in a secure machine separate from the one where the node is setup + +- Fetch the stack: + + ```bash + laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull + ``` + + This command clones the entire repository into the `~/cerc` folder, which includes the genesis file published by the first validator. + +- Copy the example variables file: + + ```bash + cp ~/cerc/laconicd-stack/playbooks/validator/validator-vars.example.yml ~/cerc/laconicd-stack/playbooks/validator/validator-vars.yml + ``` + +- Update `~/cerc/laconicd-stack/playbooks/validator/validator-vars.yml` with required values: + + ```bash + # Same moniker as set above + cerc_moniker: "" + + # Use the public key exported in previous step (make sure to wrap it with single quotes ['']) + validator_pub_key: '' + + # Set the public IP address of the machine where your node is running + node_url: "tcp://NODE_PUBLIC_IP_ADDRESS:26657" + ``` + - Export required env vars: ```bash - # Use the private key of the existing account that was exported in previous steps - export PVT_KEY= - - # desired key name - export KEY_NAME= - export DATA_DIRECTORY= - export MAINNET_DEPLOYMENT_DIR= + export MAINNET_DEPLOYMENT_DIR=mainnet-validator-deployment ``` - Run ansible playbook to create validator on running chain: @@ -166,18 +203,23 @@ ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/validator/create-validator.yml ``` -- Check the validator list: + - Input private key of the existing account that was exported in previous steps when prompted - ```bash - laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR exec laconicd 'laconicd query staking validators' - ``` +- Run the following commands in the machine where the validator node is setup -- If TMKMS has been configured, remove the validator key from node deployment as it is no longer required: - ```bash - rm $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/data/laconicd-data/config/priv_validator_key.json - ``` + - Check the validator list: - NOTE: Store it safely offline in case of an emergency + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR exec laconicd 'laconicd query staking validators' + ``` + + - If TMKMS has been configured, remove the validator key from node deployment as it is no longer required: + + ```bash + rm $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/data/laconicd-data/config/priv_validator_key.json + ``` + + NOTE: Store it safely offline in case of an emergency ## Register Your Node diff --git a/playbooks/first-validator/first-validator-vars.example.yml b/playbooks/first-validator/first-validator-vars.example.yml index c66ff5f..fd788c0 100644 --- a/playbooks/first-validator/first-validator-vars.example.yml +++ b/playbooks/first-validator/first-validator-vars.example.yml @@ -3,6 +3,4 @@ cerc_chain_id: "laconic-mainnet" min_gas_price: 0.001 cerc_loglevel: "info" key_name: "laconic-validator" -pvt_key: "" -genesis_file: "" -staking_amount_file: "" +validator_pub_key: '' diff --git a/playbooks/first-validator/generate-genesis.yml b/playbooks/first-validator/generate-genesis.yml index 4409bf3..c464615 100644 --- a/playbooks/first-validator/generate-genesis.yml +++ b/playbooks/first-validator/generate-genesis.yml @@ -3,13 +3,24 @@ hosts: localhost vars_files: - first-validator-vars.yml + vars: + data_directory: "{{ lookup('env', 'DATA_DIRECTORY') }}" + mainnet_deployment_dir: "{{ lookup('env', 'MAINNET_DEPLOYMENT_DIR') }}" + spec_file: "{{data_directory}}/laconicd-spec.yml" connection: local 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: Fetch repositories ansible.builtin.shell: cmd: "laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd setup-repositories --git-ssh --pull" - # TODO: Add a playbook flag to control force rebuild + # TODO: Add a flag to control force rebuild - name: Build containers ansible.builtin.shell: cmd: "laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd build-containers --force-rebuild" @@ -43,3 +54,65 @@ - name: Display staking-amount file location ansible.builtin.debug: msg: "Staking amount written to output/staking-amount.json" + + - name: Create deployment spec file + shell: | + laconic-so --stack ~/cerc/laconicd-stack/stack-orchestrator/stacks/mainnet-laconicd deploy init --output {{ 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: Ensure tmp directory exists inside laconicd-data + file: + path: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp" + state: directory + mode: '0755' + + - name: Copy staking amount file to laconicd-data tmp directory + copy: + src: "{{ lookup('env', 'PWD') }}/output/staking-amount.json" + dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/staking-amount.json" + mode: '0644' + + - name: Copy genesis file to laconicd-data tmp directory + copy: + src: "{{ lookup('env', 'PWD') }}/output/genesis.json" + dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/genesis.json" + mode: '0644' + + - name: Prompt for validator private key + vars: + private_key_prompt: "Please enter your validator private key: " + pause: + prompt: "{{ private_key_prompt }}" + echo: no + register: private_key_input + + - name: Fail if private key is not provided + fail: + msg: "Private key is required for creating the gentx." + when: private_key_input.user_input | default('') | trim == '' + + - name: Run script to create and collect gentx + shell: | + 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={{ private_key_input.user_input }}" \ + -e "KEY_NAME={{ key_name }}" \ + -e "CERC_MONIKER={{ cerc_moniker }}" \ + -e "CERC_CHAIN_ID={{ cerc_chain_id }}" \ + -e "VALIDATOR_PUB_KEY={{ validator_pub_key | to_json }}" \ + cerc/laconicd:local bash -c "/scripts/create-and-collect-gentx.sh" + + - name: Update genesis file in output + copy: + src: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/config/genesis.json" + dest: "{{ lookup('env', 'PWD') }}/output/genesis.json" + mode: '0644' + + - name: Clear tmp directory + file: + path: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp" + state: absent diff --git a/playbooks/first-validator/setup-first-validator.yml b/playbooks/first-validator/setup-first-validator.yml index 86ce682..3c32bff 100644 --- a/playbooks/first-validator/setup-first-validator.yml +++ b/playbooks/first-validator/setup-first-validator.yml @@ -16,13 +16,6 @@ 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 and staking_amount_file in first-validator-vars.yml. - when: not genesis_file or not staking_amount_file - - name: Fetch laconicd stack shell: laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull @@ -57,38 +50,17 @@ CERC_LOGLEVEL: "{{ cerc_loglevel }}" mode: '0777' + - name: Initialize laconicd node + shell: | + 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 "CERC_MONIKER={{ cerc_moniker }}" \ + -e "CERC_CHAIN_ID={{ cerc_chain_id }}" \ + cerc/laconicd:local bash -c "/scripts/setup-laconicd.sh" + - 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 staking amount file to laconicd-data tmp directory - copy: - src: "{{ staking_amount_file }}" - dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/staking-amount.json" - mode: '0644' - - - 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: Fail if pvt_key is not set - fail: - msg: >- - Private key (pvt_key) is not set in first-validator-vars.yml. - This is required for creating the gentx. - when: not pvt_key - - - name: Run script to create and collect gentx - shell: | - 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 }}" \ - -e "KEY_NAME={{ key_name }}" \ - -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/playbooks/validator/create-validator.yml b/playbooks/validator/create-validator.yml index feafe29..734f3d4 100644 --- a/playbooks/validator/create-validator.yml +++ b/playbooks/validator/create-validator.yml @@ -1,11 +1,12 @@ --- - name: Create validator on running chain hosts: localhost + vars_files: + - validator-vars.yml vars: data_directory: "{{ lookup('env', 'DATA_DIRECTORY') }}" - deployment_dir: "{{ lookup('env', 'MAINNET_DEPLOYMENT_DIR') }}" - key_name: "{{ lookup('env', 'KEY_NAME') }}" - pvt_key: "{{ lookup('env', 'PVT_KEY') }}" + mainnet_deployment_dir: "{{ lookup('env', 'MAINNET_DEPLOYMENT_DIR') }}" + spec_file: "{{data_directory}}/laconicd-validator-spec.yml" tasks: - name: Fail if DATA_DIRECTORY or MAINNET_DEPLOYMENT_DIR env vars are not set fail: @@ -14,17 +15,97 @@ 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 pvt_key is not set + - name: Fail if required key files are not defined fail: msg: >- - Neither private key (pvt_key) is set. - Please export PVT_KEY. - when: not pvt_key + Required key files are not defined. + Please set staking_amount_file in validator-vars.yml. + when: not staking_amount_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: 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 }}" + 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 staking amount file to laconicd-data tmp directory + copy: + src: "{{ staking_amount_file }}" + dest: "{{data_directory}}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/staking-amount.json" + mode: '0644' + + - name: Prompt for validator private key + vars: + private_key_prompt: "Please enter your validator private key: " + pause: + prompt: "{{ private_key_prompt }}" + echo: no + register: private_key_input + + - name: Fail if private key is not provided + fail: + msg: "Private key is required for creating the gentx." + when: private_key_input.user_input | default('') | trim == '' - name: Import private key in laconicd shell: | - laconic-so deployment --dir {{ data_directory }}/{{ deployment_dir }} exec laconicd "laconicd keys import-hex {{ key_name }} {{ pvt_key }} --keyring-backend test" + docker run -i \ + -v {{ data_directory }}/{{ mainnet_deployment_dir }}/data/laconicd-data:/root/.laconicd \ + --network=host \ + cerc/laconicd:local \ + laconicd keys import-hex {{ key_name }} {{ private_key_input.user_input }} --keyring-backend test \ + + - name: Get the key information + shell: | + docker run -i \ + -v {{ data_directory }}/{{ mainnet_deployment_dir }}/data/laconicd-data:/root/.laconicd \ + --network=host \ + cerc/laconicd:local \ + laconicd keys show {{ key_name }} --keyring-backend test + register: key_info - name: Run create-validator script shell: | - laconic-so deployment --dir {{ data_directory }}/{{ deployment_dir }} exec laconicd "KEY_NAME={{ key_name }} /scripts/create-validator.sh" + docker run -i \ + -v {{ data_directory }}/{{ mainnet_deployment_dir }}/data/laconicd-data:/root/.laconicd \ + -v {{ data_directory }}/{{ mainnet_deployment_dir }}/data/laconicd-data/tmp/staking-amount.json:/scripts/staking-amount.json \ + -v ~/cerc/laconicd-stack/stack-orchestrator/config/mainnet-laconicd/create-validator.sh:/scripts/create-validator.sh \ + -e "KEY_NAME={{ key_name }}" \ + -e "NODE_URL={{ node_url }}" \ + -e "CERC_MONIKER={{ cerc_moniker }}" \ + -e "CERC_CHAIN_ID={{ cerc_chain_id }}" \ + -e "MIN_GAS_PRICE={{ min_gas_price }}" \ + -e "VALIDATOR_PUB_KEY={{ validator_pub_key | to_json }}" \ + --network=host \ + cerc/laconicd:local \ + sh -c "/scripts/create-validator.sh" diff --git a/playbooks/validator/validator-vars.example.yml b/playbooks/validator/validator-vars.example.yml index df003fe..a9b99ae 100644 --- a/playbooks/validator/validator-vars.example.yml +++ b/playbooks/validator/validator-vars.example.yml @@ -1,7 +1,10 @@ +node_url: "" +validator_pub_key: '' +cerc_moniker: "" +cerc_peers: "" cerc_chain_id: "laconic-mainnet" min_gas_price: 0.001 cerc_loglevel: "info" genesis_file: "~/cerc/laconicd-stack/config/mainnet-genesis.json" staking_amount_file: "~/cerc/laconicd-stack/config/staking-amount.json" -cerc_moniker: "" -cerc_peers: "" +key_name: "laconic-validator" diff --git a/scripts/generate-lps-lock.sh b/scripts/generate-lps-lock.sh index b43f123..0765c4d 100755 --- a/scripts/generate-lps-lock.sh +++ b/scripts/generate-lps-lock.sh @@ -4,7 +4,7 @@ set -e # Default values INPUT="" -OUTPUT_DIR="." +OUTPUT_FILE="./distribution.json" # Parse command line arguments while [[ $# -gt 0 ]]; do @@ -13,13 +13,13 @@ while [[ $# -gt 0 ]]; do INPUT="$2" shift 2 ;; - -d|--dir) - OUTPUT_DIR="$2" + -o|--output) + OUTPUT_FILE="$2" shift 2 ;; *) echo "Unknown option: $1" - echo "Usage: $0 -i|--input [-d|--dir ]" + echo "Usage: $0 -i|--input [-o|--output ]" exit 1 ;; esac @@ -28,13 +28,10 @@ done # Check if input is provided if [ -z "$INPUT" ]; then echo "Error: Input URL or path is required" - echo "Usage: $0 -i|--input [-d|--dir ]" - exit 1 + echo "Usage: $0 -i|--input [-o|--output ]" + exit 1 fi -# Create output directory if it doesn't exist -mkdir -p "$OUTPUT_DIR" - venv_dir="$PWD/venv-lps-lock" script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -50,7 +47,7 @@ fi echo "Running LPS lock generation script..." "$venv_dir/bin/python" "$script_dir/generate-lps-distribution-json.py" \ --input "$INPUT" \ - --output "$OUTPUT_DIR/distribution.json" + --output "$OUTPUT_FILE" # Clean up venv echo "Cleaning up..." 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 d2fcd9c..5693d6d 100755 --- a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh +++ b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh @@ -21,6 +21,11 @@ if [ -z "$KEY_NAME" ]; then exit 1 fi +if [ -z "$VALIDATOR_PUB_KEY" ]; then + echo "VALIDATOR_PUB_KEY 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..." @@ -66,7 +71,7 @@ fi stake_amount=$(jq -r '.common_staking_amount' "$staking_amount_file") # Create gentx with staked amount equal to allocated balance -laconicd genesis gentx $KEY_NAME $stake_amount$DENOM --chain-id $CHAIN_ID --keyring-backend $KEYRING +laconicd genesis gentx $KEY_NAME $stake_amount$DENOM --chain-id $CHAIN_ID --keyring-backend $KEYRING --pubkey "$VALIDATOR_PUB_KEY" # Collect the gentx and validate laconicd genesis collect-gentxs @@ -74,5 +79,5 @@ laconicd genesis validate chmod 777 $genesis_file_path -# Update the input genesis file -cp $genesis_file_path $input_genesis_file +# Clear tmp directory +rm -rf $NODE_HOME/tmp diff --git a/stack-orchestrator/config/mainnet-laconicd/create-validator.sh b/stack-orchestrator/config/mainnet-laconicd/create-validator.sh index e9c04aa..2b90d90 100755 --- a/stack-orchestrator/config/mainnet-laconicd/create-validator.sh +++ b/stack-orchestrator/config/mainnet-laconicd/create-validator.sh @@ -12,7 +12,7 @@ if [ ! -f "$staking_amount_file" ]; then exit 1 fi -if [-z "$KEY_NAME" ]; then +if [ -z "$KEY_NAME" ]; then echo "KEY_NAME environment variable not set, exiting..." exit 1 fi @@ -22,6 +22,16 @@ if [ -z "$CERC_MONIKER" ]; then exit 1 fi +if [ -z "$NODE_URL" ]; then + echo "NODE_URL environment variable not set, exiting..." + exit 1 +fi + +if [ -z "$VALIDATOR_PUB_KEY" ]; then + echo "VALIDATOR_PUB_KEY environment variable not set, exiting..." + exit 1 +fi + # Set staking amount stake_amount=$(jq -r '.common_staking_amount' "$staking_amount_file") @@ -29,7 +39,7 @@ stake_amount=$(jq -r '.common_staking_amount' "$staking_amount_file") validator_json="$NODE_HOME/tmp/validator.json" cat > "$validator_json" << EOF { - "pubkey": $(laconicd tendermint show-validator), + "pubkey": $VALIDATOR_PUB_KEY, "amount": "${stake_amount}${DENOM}", "moniker": "${CERC_MONIKER}", "commission-rate": "0.0", @@ -47,4 +57,5 @@ laconicd tx staking create-validator "$validator_json" \ --gas-prices $MIN_GAS_PRICE$DENOM \ --from $KEY_NAME \ --keyring-backend $KEYRING \ + --node $NODE_URL \ --yes