diff --git a/.gitignore b/.gitignore index 2948191..d4564bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *-deployment *-spec.yml +mainnet-genesis # Playbook vars -playbooks/first-validator/first-validator-vars.yml +*-vars.yml diff --git a/README.md b/README.md index c870d42..3973081 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # laconicd-stack - Follow [run-first-validator.md](run-first-validator.md) to run the first validator node +- Follow [run-validator.md](run-validator.md) to run subsequent validator nodes diff --git a/demo.md b/demo.md new file mode 100644 index 0000000..b17db00 --- /dev/null +++ b/demo.md @@ -0,0 +1,83 @@ +# demo + +## Prerequisites + +- [ansible](playbooks/README.md#ansible-installation) +- [laconic-so](https://github.com/cerc-io/stack-orchestrator/?tab=readme-ov-file#install) + +## Run node + +- Follow these steps to run first validator node: [run-first-validator.md](run-first-validator.md) + +- Following steps can be used to run subsequent validator nodes + +- 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 + ``` + +- Check first validator node address using: + + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR exec laconicd 'echo $(laconicd cometbft show-node-id)@host.docker.internal:26656' + ``` + + NOTE: Make sure that DATA_DIRECTORY and MAINNET_DEPLOYMENT_DIR values are that of first validator deployment + +- Update `cerc_peers` in `~/cerc/laconicd-stack/playbooks/validator/validator-vars.yml`: + + ```bash + cerc_peers: "@host.docker.internal:26656" + ``` + +- 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-validator-deployment + export MAINNET_DEPLOYMENT_DIR= + ``` + +- Update port mappings in `~/cerc/laconicd-stack/playbooks/validator/templates/specs/spec-template.yml.j2` with: + + ```bash + network: + ports: + laconicd: + - '3060:6060' + - '36657:26657' + - '36656:26656' + - '3473:9473' + - '3090:9090' + - '3317:1317' + ``` + +- Update permission for `genesis/mainnet-genesis.json`: + + ```bash + sudo chmod 777 ~/cerc/laconicd-stack/genesis/mainnet-genesis.json + ``` + +- Run ansible playbook to set up and start your validator node: + + ```bash + ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/validator/run-validator.yml + ``` + +- Check logs to ensure that node is running: + + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR logs laconicd -f + ``` diff --git a/playbooks/first-validator/run-first-validator.yml b/playbooks/first-validator/run-first-validator.yml index 8022454..732a7c9 100644 --- a/playbooks/first-validator/run-first-validator.yml +++ b/playbooks/first-validator/run-first-validator.yml @@ -54,7 +54,6 @@ CERC_CHAIN_ID: "{{ cerc_chain_id }}" MIN_GAS_PRICE: "{{ min_gas_price }}" CERC_LOGLEVEL: "{{ cerc_loglevel }}" - KEY_NAME: "{{ key_name }}" mode: '0777' - name: Ensure tmp directory exists inside laconicd-data diff --git a/playbooks/validator/run-validator.yml b/playbooks/validator/run-validator.yml new file mode 100644 index 0000000..9a5bd2b --- /dev/null +++ b/playbooks/validator/run-validator.yml @@ -0,0 +1,74 @@ +--- +- name: Run mainnet validator node + hosts: localhost + vars_files: + - validator-vars.yml + vars: + data_directory: "{{ lookup('env', 'DATA_DIRECTORY') }}" + mainnet_deployment_dir: "{{ lookup('env', 'MAINNET_DEPLOYMENT_DIR') }}" + spec_file: "{{data_directory}}/laconicd-validator-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: + 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 in 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: 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: Run validator node + shell: | + laconic-so deployment --dir {{data_directory}}/{{ mainnet_deployment_dir }} start diff --git a/playbooks/validator/templates/specs/spec-template.yml.j2 b/playbooks/validator/templates/specs/spec-template.yml.j2 new file mode 100644 index 0000000..9ae553e --- /dev/null +++ b/playbooks/validator/templates/specs/spec-template.yml.j2 @@ -0,0 +1,9 @@ +network: + ports: + laconicd: + - '6060:6060' + - '26657:26657' + - '26656:26656' + - '9473:9473' + - '9090:9090' + - '1317:1317' diff --git a/playbooks/validator/validator-vars.example.yml b/playbooks/validator/validator-vars.example.yml new file mode 100644 index 0000000..4fa9440 --- /dev/null +++ b/playbooks/validator/validator-vars.example.yml @@ -0,0 +1,6 @@ +cerc_moniker: "LaconicMainnetNode" +cerc_chain_id: "laconic-mainnet" +min_gas_price: 0.001 +cerc_loglevel: "info" +genesis_file: "~/cerc/laconicd-stack/genesis/mainnet-genesis.json" +cerc_peers: "" diff --git a/run-first-validator.md b/run-first-validator.md index ffb5d0a..a8507c8 100644 --- a/run-first-validator.md +++ b/run-first-validator.md @@ -5,23 +5,31 @@ - [ansible](playbooks/README.md#ansible-installation) - [laconic-so](https://github.com/cerc-io/stack-orchestrator/?tab=readme-ov-file#install) +## Stop testnet node + +- Stop the testnet node: + + ```bash + laconic-so deployment --dir stop + ``` + ## Generate mainnet genesis file -- Fetch the stack in machine where the testnet chain node is running +- 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 +- Run script to export state from testnet chain: ```bash - ~/cerc/laconicd-stack/scripts/export-testnet-state.sh + ~/cerc/laconicd-stack/scripts/export-testnet-state.sh ``` - - The file will be generated in `/export/testnet-state.json` + - The file will be generated in `/export/testnet-state.json` -- If mainnet node will be setup in new machine, fetch the stack again +- If mainnet node is to be setup in a new machine, fetch the stack again: ```bash laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull @@ -29,14 +37,20 @@ - Copy over the exported `testnet-state.json` file to target machine -- Set envs +- Set envs: ```bash export EXPORTED_STATE_PATH= export EARLY_SUPPORTS_ACC_ADDR= ``` -- Run playbook to use exported state for generating mainnet genesis +- 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 + ``` + +- 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" @@ -53,7 +67,8 @@ -- Copy the example variables file: +- 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 ``` @@ -88,7 +103,7 @@ - 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 + ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/first-validator/run-first-validator.yml ``` - Check logs to ensure that node is running: @@ -97,12 +112,18 @@ laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR logs laconicd -f ``` +- Check bonds list to confirm that testnet state was transferred properly: + + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR exec laconicd 'laconicd query bond list' + ``` + ## 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 + sudo cp $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/data/laconicd-data/config/genesis.json ~/cerc/laconicd-stack/genesis/mainnet-genesis.json ``` - Get your node's address: diff --git a/run-validator.md b/run-validator.md new file mode 100644 index 0000000..5126284 --- /dev/null +++ b/run-validator.md @@ -0,0 +1,88 @@ +# Run Validator Node + +## Prerequisites + +- [ansible](playbooks/README.md#ansible-installation) +- [laconic-so](https://github.com/cerc-io/stack-orchestrator/?tab=readme-ov-file#install) + +## Stop testnet node + +- Stop the testnet node: + + ```bash + laconic-so deployment --dir stop + ``` + +## Run node + +- 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 + # Path to the genesis file published by the first validator + genesis_file: "~/cerc/laconicd-stack/genesis/mainnet-genesis.json" + + # Set custom moniker for the node + cerc_moniker: "LaconicMainnetNode" + + # Set chain ID (should match the one in the genesis file) + cerc_chain_id: "laconic-mainnet" + + # Set minimum gas price + min_gas_price: 0.001 + + # Set log level + cerc_loglevel: "info" + + # Set persistent peers (comma-separated list of node IDs and addresses) + # You can find the list of available peers in node-addresses.yml + cerc_peers: "@:26656,@:26656" + ``` + +- 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 set up and start your validator node: + + ```bash + ansible-playbook -i localhost, -c local ~/cerc/laconicd-stack/playbooks/validator/run-validator.yml + ``` + +- Check logs to ensure that node is running: + + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR logs laconicd -f + ``` + +## Register Your Node + +- 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 the `~/cerc/laconicd-stack/node-addresses.yml` file + +- Submit a PR to add your node address to the repository diff --git a/scripts/transfer-state.py b/scripts/transfer-state.py index a8081f7..39ee7dc 100644 --- a/scripts/transfer-state.py +++ b/scripts/transfer-state.py @@ -116,6 +116,9 @@ for account in mainnet_state["app_state"]["auth"]["accounts"]: if "ModuleAccount" in account_type and account.get("name") in addresses_to_remove: removed_addresses.add(account["base_account"]["address"]) continue + + if "ModuleAccount" not in account_type: + account["sequence"] = "0" new_accounts.append(account) mainnet_state["app_state"]["auth"]["accounts"] = new_accounts 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 f213846..1e1e111 100755 --- a/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh +++ b/stack-orchestrator/config/mainnet-laconicd/create-and-collect-gentx.sh @@ -54,8 +54,7 @@ if [ -z "$account_address" ]; then 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) +stake_amount=900000000 # Create gentx with staked amount equal to allocated balance laconicd genesis gentx $KEY_NAME $stake_amount$DENOM --chain-id $CHAIN_ID --keyring-backend $KEYRING @@ -64,5 +63,7 @@ laconicd genesis gentx $KEY_NAME $stake_amount$DENOM --chain-id $CHAIN_ID --keyr laconicd genesis collect-gentxs laconicd genesis validate +chmod 777 $genesis_file_path + # Update the input genesis file cp $genesis_file_path $input_genesis_file