diff --git a/README.md b/README.md index 337b9ff..b368cc3 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ # testnet-laconicd-stack + +Stacks to run nodes for laconic-testnet + +- [Full node stack documentation](stack-orchestrator/stacks/laconicd-full-node/README.md) diff --git a/stack-orchestrator/compose/docker-compose-laconicd-full-node.yml b/stack-orchestrator/compose/docker-compose-laconicd-full-node.yml new file mode 100644 index 0000000..83b378e --- /dev/null +++ b/stack-orchestrator/compose/docker-compose-laconicd-full-node.yml @@ -0,0 +1,31 @@ +services: + laconicd: + restart: unless-stopped + image: cerc/laconic2d: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} + CERC_LOGLEVEL: ${CERC_LOGLEVEL:-info} + volumes: + - laconicd-data:/root/.laconicd + - ../config/laconicd/scripts/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/scripts/run-laconicd.sh b/stack-orchestrator/config/laconicd/scripts/run-laconicd.sh new file mode 100755 index 0000000..99e7998 --- /dev/null +++ b/stack-orchestrator/config/laconicd/scripts/run-laconicd.sh @@ -0,0 +1,47 @@ +#!/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 "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 genesis config + cp $input_genesis_file $NODE_HOME/config/genesis.json +else + echo "Node data dir $NODE_HOME/data already exists, skipping initialization..." +fi + +# 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 --gql-playground --gql-server --log_level $CERC_LOGLEVEL --home $NODE_HOME diff --git a/stack-orchestrator/container-build/cerc-laconic2d/build.sh b/stack-orchestrator/container-build/cerc-laconic2d/build.sh new file mode 100755 index 0000000..1c4f7de --- /dev/null +++ b/stack-orchestrator/container-build/cerc-laconic2d/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/laconic2d:local ${build_command_args} ${CERC_REPO_BASE_DIR}/laconic2d diff --git a/stack-orchestrator/stacks/laconicd-full-node/README.md b/stack-orchestrator/stacks/laconicd-full-node/README.md new file mode 100644 index 0000000..05ba436 --- /dev/null +++ b/stack-orchestrator/stacks/laconicd-full-node/README.md @@ -0,0 +1,199 @@ +# laconicd-full-node + +Instructions for running a laconicd testnet full node and joining as a validator + +## Prerequisites + +* Minimum hardware requirements: + + ```bash + RAM: 8-16GB + Disk space: 200GB + CPU: 2 cores + ``` + +* Testnet genesis file (file or an URL) and peer node addresses + +## Setup + +* Clone the stack repo: + + ```bash + laconic-so fetch-stack git.vdb.to/cerc-io/testnet-laconicd-stack + ``` + +* Clone required repositories: + + ```bash + laconic-so --stack ~/cerc/testnet-laconicd-stack/stack-orchestrator/stacks/laconicd-full-node setup-repositories + ``` + +* Build the container images: + + ```bash + laconic-so --stack ~/cerc/testnet-laconicd-stack/stack-orchestrator/stacks/laconicd-full-node build-containers + ``` + + This should create the following docker images locally: + + * `cerc/laconic2d` + +## Create a deployment + +* Create a spec file for the deployment: + + ```bash + laconic-so --stack ~/cerc/testnet-laconicd-stack/stack-orchestrator/stacks/laconicd-full-node deploy init --output laconic-full-node-spec.yml + ``` + +* Edit `network` in the spec file to map container ports to host ports as required: + + ```bash + ... + network: + ports: + laconicd: + - '6060:6060' + - '26657:26657' + - '26656:26656' + - '9473:9473' + - '9090:9090' + - '1317:1317' + ``` + +* Create a deployment from the spec file: + + ```bash + laconic-so --stack ~/cerc/testnet-laconicd-stack/stack-orchestrator/stacks/laconicd-full-node deploy create --spec-file laconic-full-node-spec.yml --deployment-dir laconic-full-node-deployment + ``` + +* Copy over the published testnet genesis file (`.json`) to data directory in deployment (`laconic-full-node-deployment/data/laconicd-data/tmp`): + + ```bash + # Example + mkdir -p laconic-full-node-deployment/data/laconicd-data/tmp + cp genesis.json laconic-full-node-deployment/data/laconicd-data/tmp/genesis.json + ``` + +## Configuration + +* Inside the deployment directory, open `config.env` file and set following env variables: + + ```bash + # Comma separated list of nodes to keep persistent connections to + # Example: "node-1-id@node-1-host:26656,node-2-id@node-2-host:26656" + CERC_PEERS="" + + # Optional + + # A custom human readable name for this node (default: TestnetNode) + CERC_MONIKER= + + # Network chain ID (default: laconic_9000-1) + CERC_CHAIN_ID= + + # Output log level (default: info) + CERC_LOGLEVEL= + ``` + +## Start the deployment + +```bash +laconic-so deployment --dir laconic-full-node-deployment start +``` + +## Check status + +* To list down and monitor the running containers: + + ```bash + # With status + docker ps -a + + # Follow logs for laconicd container + laconic-so deployment --dir laconic-full-node-deployment logs laconicd -f + ``` + +* Check the sync status of your node: + + ```bash + laconic-so deployment --dir laconic-full-node-deployment exec laconicd "laconicd status | jq .sync_info" + + # `catching_up: false` indicates that node is completely synced + ``` + +## Join as testnet validator + +* Create / import a new key pair: + + ```bash + # Create new keypair + laconic-so deployment --dir laconic-full-node-deployment exec laconicd "laconicd keys add " + + # OR + # Restore existing key with mnemonic seed phrase + # You will be prompted to enter mnemonic seed + laconic-so deployment --dir laconic-full-node-deployment exec laconicd "laconicd keys add --recover" + + # Query the keystore for your account's address + laconic-so deployment --dir laconic-full-node-deployment exec laconicd "laconicd keys show -a" + ``` + +* Request tokens from the testnet faucet for your account if required + +* Check balance for your account: + + ```bash + laconic-so deployment --dir laconic-full-node-deployment exec laconicd "laconicd query bank balances " + ``` + +* Create required validator configuration: + + ```bash + # Edit the staking amount and other fields as required + laconic-so deployment --dir laconic-full-node-deployment exec laconicd 'cat < -validator.json + { + "pubkey": $(laconicd cometbft show-validator), + "amount": "900000000photon", + "moniker": "", + "commission-rate": "0.1", + "commission-max-rate": "0.2", + "commission-max-change-rate": "0.01", + "min-self-delegation": "1" + } + EOF' + ``` + +* Create a validator: + + ```bash + laconic-so deployment --dir laconic-full-node-deployment exec laconicd 'laconicd tx staking create-validator -validator.json \ + --fees 50photon \ + --chain-id=laconic_9000-1 \ + --from ' + ``` + +* View your staking validator details: + + ```bash + laconic-so deployment --dir laconic-full-node-deployment exec laconicd "laconicd query staking validator " + ``` + +## Clean up + +* Stop all services running in the background: + + ```bash + # Stop the docker containers + laconic-so deployment --dir laconic-full-node-deployment stop + ``` + +* To stop all services and also delete data: + + ```bash + # Stop the docker containers + laconic-so deployment --dir laconic-full-node-deployment stop --delete-volumes + + # Remove deployment directory (deployment will have to be recreated for a re-run) + rm -r laconic-full-node-deployment + ``` diff --git a/stack-orchestrator/stacks/laconicd-full-node/stack.yml b/stack-orchestrator/stacks/laconicd-full-node/stack.yml new file mode 100644 index 0000000..677b1d2 --- /dev/null +++ b/stack-orchestrator/stacks/laconicd-full-node/stack.yml @@ -0,0 +1,9 @@ +version: "1.0" +name: laconicd-full-node +description: "Laconicd full node" +repos: + - git.vdb.to/cerc-io/laconic2d +containers: + - cerc/laconic2d +pods: + - laconicd-full-node