From 6c152959aa4c95808a14309072d1525df7c20868 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 11 Jun 2025 14:17:31 +0530 Subject: [PATCH 1/4] Add TMKMS stack --- README.md | 1 + .../compose/docker-compose-tmkms.yml | 18 ++++++ stack-orchestrator/config/tmkms/run.sh | 58 +++++++++++++++++++ .../container-build/cerc-tmkms/Dockerfile | 56 ++++++++++++++++++ .../container-build/cerc-tmkms/build.sh | 10 ++++ stack-orchestrator/stacks/tmkms/stack.yml | 9 +++ 6 files changed, 152 insertions(+) create mode 100644 stack-orchestrator/compose/docker-compose-tmkms.yml create mode 100755 stack-orchestrator/config/tmkms/run.sh create mode 100644 stack-orchestrator/container-build/cerc-tmkms/Dockerfile create mode 100755 stack-orchestrator/container-build/cerc-tmkms/build.sh create mode 100644 stack-orchestrator/stacks/tmkms/stack.yml diff --git a/README.md b/README.md index e69de29..04c1d13 100644 --- a/README.md +++ b/README.md @@ -0,0 +1 @@ +# tmkms-stack diff --git a/stack-orchestrator/compose/docker-compose-tmkms.yml b/stack-orchestrator/compose/docker-compose-tmkms.yml new file mode 100644 index 0000000..f6807cf --- /dev/null +++ b/stack-orchestrator/compose/docker-compose-tmkms.yml @@ -0,0 +1,18 @@ +services: + tmkms: + restart: unless-stopped + image: cerc/tmkms:local + command: ["bash", "-c", "/opt/run.sh"] + environment: + CERC_CHAIN_ID: ${CERC_CHAIN_ID:-laconic-mainnet} + NODE_IP: ${NODE_IP} + NODE_PORT: ${NODE_PORT:-26659} + CERC_KEY_PREFIX: ${CERC_KEY_PREFIX:-laconic} + volumes: + - tmkms-data:/home/tmkmsuser/tmkms + - ../config/tmkms/run.sh:/opt/run.sh + extra_hosts: + - "host.docker.internal:host-gateway" + +volumes: + tmkms-data: diff --git a/stack-orchestrator/config/tmkms/run.sh b/stack-orchestrator/config/tmkms/run.sh new file mode 100755 index 0000000..342fd99 --- /dev/null +++ b/stack-orchestrator/config/tmkms/run.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then + set -x +fi + +set -e + +TMKMS_HOME=/home/tmkmsuser/tmkms +INPUT_PRIV_KEY_FILE=$TMKMS_HOME/tmp/priv_validator_key.json +TMKMS_SECRETS_DIR=$TMKMS_HOME/secrets +TMKMS_STATE_DIR=$TMKMS_HOME/state + +echo "Initializing tmkms configuration..." + +# Initialize tmkms config +tmkms init $TMKMS_HOME + +# Generate a new softsign key +echo "Generating new softsign key..." +tmkms softsign keygen $TMKMS_SECRETS_DIR/kms-identity.key + +# Update tmkms.toml +echo "Updating tmkms.toml with chain_id, node IP, and key prefixes..." + +# Add chain configuration +cat < $TMKMS_HOME/tmkms.toml + +[[chain]] +id = "$CERC_CHAIN_ID" +key_format = { type = "cosmos-json", account_key_prefix = "${CERC_KEY_PREFIX}pub", consensus_key_prefix = "${CERC_KEY_PREFIX}valconspub" } +state_file = "$TMKMS_STATE_DIR/priv_validator_state.json" + +[[validator]] +chain_id = "$CERC_CHAIN_ID" +addr = "tcp://$NODE_IP:$NODE_PORT" +secret_key = "$TMKMS_SECRETS_DIR/kms-identity.key" +protocol_version = "v0.34" +reconnect = true + +[[providers.softsign]] +key_type = "consensus" +path = "$TMKMS_SECRETS_DIR/priv_validator_key" +chain_ids = ["$CERC_CHAIN_ID"] +EOF + +# Place validator key in secrets directory +cp $INPUT_PRIV_KEY_FILE $TMKMS_SECRETS_DIR/priv_validator_key.json + +# Import the private validator key into tmkms +echo "Importing private validator key into tmkms..." +tmkms softsign import $TMKMS_SECRETS_DIR/priv_validator_key.json $TMKMS_SECRETS_DIR/priv_validator_key + +# Remove the JSON key file +rm $TMKMS_SECRETS_DIR/priv_validator_key.json + +echo "Starting tmkms..." +tmkms start --config $TMKMS_HOME/tmkms.toml diff --git a/stack-orchestrator/container-build/cerc-tmkms/Dockerfile b/stack-orchestrator/container-build/cerc-tmkms/Dockerfile new file mode 100644 index 0000000..ccd1473 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-tmkms/Dockerfile @@ -0,0 +1,56 @@ +# -------- Stage 1: Build -------- +FROM debian:bookworm-slim AS builder + +ARG BACKEND=softsign +ARG VERSION=main + +# Install build dependencies +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + build-essential \ + clang \ + curl \ + git \ + pkg-config \ + libsodium-dev \ + libssl-dev \ + ca-certificates && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Create non-root user +RUN useradd -m builder +USER builder +WORKDIR /home/builder + +ENV PATH="/home/builder/.cargo/bin:$PATH" + +# Install Rust +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y && \ + rustup component add rustfmt clippy + +# Clone and build TMKMS +RUN git clone --depth 1 --branch ${VERSION} https://github.com/iqlusioninc/tmkms.git && \ + cd tmkms && \ + cargo build --release --features=${BACKEND} + +# -------- Stage 2: Runtime -------- +FROM debian:bookworm-slim + +# Install runtime dependencies only +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + libssl3 \ + libsodium23 \ + ca-certificates && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Copy compiled binary +COPY --from=builder /home/builder/tmkms/target/release/tmkms /usr/local/bin/tmkms + +# Create runtime user +RUN useradd -m tmkmsuser +USER tmkmsuser +WORKDIR /home/tmkmsuser + +# Default command, override with `docker run ... bash` etc. +CMD ["tmkms"] diff --git a/stack-orchestrator/container-build/cerc-tmkms/build.sh b/stack-orchestrator/container-build/cerc-tmkms/build.sh new file mode 100755 index 0000000..72fe654 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-tmkms/build.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +# Build cerc/tmkms +source ${CERC_CONTAINER_BASE_DIR}/build-base.sh + +# See: https://stackoverflow.com/a/246128/1701505 +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +# TODO: Use BACKEND=yubihsm build command arg +docker build -t cerc/tmkms:local ${build_command_args} -f ${SCRIPT_DIR}/Dockerfile ${CERC_REPO_BASE_DIR}/tmkms diff --git a/stack-orchestrator/stacks/tmkms/stack.yml b/stack-orchestrator/stacks/tmkms/stack.yml new file mode 100644 index 0000000..8d01b40 --- /dev/null +++ b/stack-orchestrator/stacks/tmkms/stack.yml @@ -0,0 +1,9 @@ +version: "1.0" +name: tmkms +description: "TMKMS for signing consensus messages" +repos: + - github.com/iqlusioninc/tmkms@v0.14.0 +containers: + - cerc/tmkms +pods: + - tmkms -- 2.45.2 From 11f7fbb6e307aaa1a30ac1156bc35bcfe418ef70 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 11 Jun 2025 14:42:01 +0530 Subject: [PATCH 2/4] Add readme to setup and start the tmkms stack --- README.md | 2 + .../compose/docker-compose-tmkms.yml | 4 +- stack-orchestrator/stacks/tmkms/README.md | 85 +++++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 stack-orchestrator/stacks/tmkms/README.md diff --git a/README.md b/README.md index 04c1d13..e50de74 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # tmkms-stack + +- [Run TMKMS service](stacks/tmkms/README.md) diff --git a/stack-orchestrator/compose/docker-compose-tmkms.yml b/stack-orchestrator/compose/docker-compose-tmkms.yml index f6807cf..07edf86 100644 --- a/stack-orchestrator/compose/docker-compose-tmkms.yml +++ b/stack-orchestrator/compose/docker-compose-tmkms.yml @@ -4,10 +4,10 @@ services: image: cerc/tmkms:local command: ["bash", "-c", "/opt/run.sh"] environment: - CERC_CHAIN_ID: ${CERC_CHAIN_ID:-laconic-mainnet} + CERC_CHAIN_ID: ${CERC_CHAIN_ID} NODE_IP: ${NODE_IP} NODE_PORT: ${NODE_PORT:-26659} - CERC_KEY_PREFIX: ${CERC_KEY_PREFIX:-laconic} + CERC_KEY_PREFIX: ${CERC_KEY_PREFIX} volumes: - tmkms-data:/home/tmkmsuser/tmkms - ../config/tmkms/run.sh:/opt/run.sh diff --git a/stack-orchestrator/stacks/tmkms/README.md b/stack-orchestrator/stacks/tmkms/README.md new file mode 100644 index 0000000..8de0032 --- /dev/null +++ b/stack-orchestrator/stacks/tmkms/README.md @@ -0,0 +1,85 @@ +# tmkms + +Instructions for running TMKMS service + +## Prerequisites + +- [laconic-so](https://github.com/cerc-io/stack-orchestrator/?tab=readme-ov-file#install) + +- A cosmos-sdk based node setup + +## Setup + +- Clone the stack repo: + + ```bash + laconic-so fetch-stack git.vdb.to/LaconicNetwork/tmkms-stack --git-ssh --pull + ``` + +- Clone required repositories: + + ```bash + laconic-so --stack ~/cerc/tmkms-stack/stack-orchestrator/stacks/tmkms setup-repositories --git-ssh --pull + + # If this throws an error as a result of being already checked out to a branch/tag in a repo, remove the repository and re-run the command + ``` + +- Build the container images: + + ```bash + laconic-so --stack ~/cerc/tmkms-stack/stack-orchestrator/stacks/tmkms build-containers --force-rebuild + ``` + + This should create the `cerc/tmkms` docker image locally + +## Create a deployment + +- Create a spec file for the deployment: + + ```bash + laconic-so --stack ~/cerc/tmkms-stack/stack-orchestrator/stacks/tmkms deploy init --output tmkms-spec.yml + ``` + +- Create deployment from the spec file: + + ```bash + laconic-so --stack ~/cerc/tmkms-stack/stack-orchestrator/stacks/tmkms deploy create --spec-file tmkms-spec.yml --deployment-dir tmkms-deployment + ``` + +## Configuration + +- Copy the private validator key to the tmp directory: + + ```bash + cp tmkms-deployment/data/tmkms-data/tmp + ``` + +- Inside the `tmkms-deployment` deployment directory, open `config.env` file and set following env variables: + + ```bash + # Chain ID + CERC_CHAIN_ID= + + # Public IP address of the node + NODE_IP= + + # Port on which the node is listening for consensus messages (default: 26659) + NODE_PORT= + + # Key prefix (for ex. laconic) + CERC_KEY_PREFIX= + ``` + +## Run + +- Start the deployment: + + ```bash + laconic-so --dir tmkms-deployment start + ``` + +- Check the logs: + + ```bash + laconic-so --dir tmkms-deployment logs -f + ``` -- 2.45.2 From 4e083cec49d4450f1be44a7960536ac2a9fde8eb Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Wed, 11 Jun 2025 19:07:47 +0530 Subject: [PATCH 3/4] Update script to check for existing priv validator key --- README.md | 2 + .../compose/docker-compose-tmkms.yml | 4 +- stack-orchestrator/config/tmkms/run.sh | 70 +++++++++++-------- .../container-build/cerc-tmkms/build.sh | 2 +- stack-orchestrator/stacks/tmkms/README.md | 36 +++++++--- stack-orchestrator/stacks/tmkms/stack.yml | 3 +- 6 files changed, 70 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index e50de74..bc19fcf 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # tmkms-stack +- Reference: + - [Run TMKMS service](stacks/tmkms/README.md) diff --git a/stack-orchestrator/compose/docker-compose-tmkms.yml b/stack-orchestrator/compose/docker-compose-tmkms.yml index 07edf86..fab23c9 100644 --- a/stack-orchestrator/compose/docker-compose-tmkms.yml +++ b/stack-orchestrator/compose/docker-compose-tmkms.yml @@ -4,10 +4,10 @@ services: image: cerc/tmkms:local command: ["bash", "-c", "/opt/run.sh"] environment: - CERC_CHAIN_ID: ${CERC_CHAIN_ID} + CHAIN_ID: ${CHAIN_ID} NODE_IP: ${NODE_IP} NODE_PORT: ${NODE_PORT:-26659} - CERC_KEY_PREFIX: ${CERC_KEY_PREFIX} + KEY_PREFIX: ${KEY_PREFIX} volumes: - tmkms-data:/home/tmkmsuser/tmkms - ../config/tmkms/run.sh:/opt/run.sh diff --git a/stack-orchestrator/config/tmkms/run.sh b/stack-orchestrator/config/tmkms/run.sh index 342fd99..ac22282 100755 --- a/stack-orchestrator/config/tmkms/run.sh +++ b/stack-orchestrator/config/tmkms/run.sh @@ -11,48 +11,56 @@ INPUT_PRIV_KEY_FILE=$TMKMS_HOME/tmp/priv_validator_key.json TMKMS_SECRETS_DIR=$TMKMS_HOME/secrets TMKMS_STATE_DIR=$TMKMS_HOME/state -echo "Initializing tmkms configuration..." +# Check if priv_validator_key in SECRETS_DIR exists +if [[ ! -f "$TMKMS_SECRETS_DIR/priv_validator_key" ]]; then -# Initialize tmkms config -tmkms init $TMKMS_HOME + # Initialize tmkms config + echo "Initializing tmkms configuration..." + tmkms init $TMKMS_HOME -# Generate a new softsign key -echo "Generating new softsign key..." -tmkms softsign keygen $TMKMS_SECRETS_DIR/kms-identity.key + # Generate a new softsign key + echo "Generating new softsign key..." + tmkms softsign keygen $TMKMS_SECRETS_DIR/kms-identity.key -# Update tmkms.toml -echo "Updating tmkms.toml with chain_id, node IP, and key prefixes..." + # Update tmkms.toml + echo "Updating tmkms.toml with chain_id, node IP, and key prefixes..." -# Add chain configuration -cat < $TMKMS_HOME/tmkms.toml + # Add chain configuration + cat < $TMKMS_HOME/tmkms.toml -[[chain]] -id = "$CERC_CHAIN_ID" -key_format = { type = "cosmos-json", account_key_prefix = "${CERC_KEY_PREFIX}pub", consensus_key_prefix = "${CERC_KEY_PREFIX}valconspub" } -state_file = "$TMKMS_STATE_DIR/priv_validator_state.json" + [[chain]] + id = "$CHAIN_ID" + key_format = { type = "cosmos-json", account_key_prefix = "${KEY_PREFIX}pub", consensus_key_prefix = "${KEY_PREFIX}valconspub" } + state_file = "$TMKMS_STATE_DIR/priv_validator_state.json" -[[validator]] -chain_id = "$CERC_CHAIN_ID" -addr = "tcp://$NODE_IP:$NODE_PORT" -secret_key = "$TMKMS_SECRETS_DIR/kms-identity.key" -protocol_version = "v0.34" -reconnect = true + [[validator]] + chain_id = "$CHAIN_ID" + addr = "tcp://$NODE_IP:$NODE_PORT" + secret_key = "$TMKMS_SECRETS_DIR/kms-identity.key" + protocol_version = "v0.34" + reconnect = true -[[providers.softsign]] -key_type = "consensus" -path = "$TMKMS_SECRETS_DIR/priv_validator_key" -chain_ids = ["$CERC_CHAIN_ID"] + [[providers.softsign]] + key_type = "consensus" + path = "$TMKMS_SECRETS_DIR/priv_validator_key" + chain_ids = ["$CHAIN_ID"] EOF -# Place validator key in secrets directory -cp $INPUT_PRIV_KEY_FILE $TMKMS_SECRETS_DIR/priv_validator_key.json + # Import the private validator key into tmkms + echo "Importing private validator key into tmkms..." + tmkms softsign import $INPUT_PRIV_KEY_FILE $TMKMS_SECRETS_DIR/priv_validator_key -# Import the private validator key into tmkms -echo "Importing private validator key into tmkms..." -tmkms softsign import $TMKMS_SECRETS_DIR/priv_validator_key.json $TMKMS_SECRETS_DIR/priv_validator_key + # Remove the original private validator key + rm -rf $INPUT_PRIV_KEY_FILE -# Remove the JSON key file -rm $TMKMS_SECRETS_DIR/priv_validator_key.json +else + echo "tmkms configuration already exists. Skipping initialization..." + # Throw error if tmp/priv_validator_key.json exists + if [[ -f "$INPUT_PRIV_KEY_FILE" ]]; then + echo "ERROR: $INPUT_PRIV_KEY_FILE already exists. Please remove it and try again." + exit 1 + fi +fi echo "Starting tmkms..." tmkms start --config $TMKMS_HOME/tmkms.toml diff --git a/stack-orchestrator/container-build/cerc-tmkms/build.sh b/stack-orchestrator/container-build/cerc-tmkms/build.sh index 72fe654..918cceb 100755 --- a/stack-orchestrator/container-build/cerc-tmkms/build.sh +++ b/stack-orchestrator/container-build/cerc-tmkms/build.sh @@ -7,4 +7,4 @@ source ${CERC_CONTAINER_BASE_DIR}/build-base.sh SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) # TODO: Use BACKEND=yubihsm build command arg -docker build -t cerc/tmkms:local ${build_command_args} -f ${SCRIPT_DIR}/Dockerfile ${CERC_REPO_BASE_DIR}/tmkms +docker build -t cerc/tmkms:local ${build_command_args} -f ${SCRIPT_DIR}/Dockerfile ${SCRIPT_DIR} diff --git a/stack-orchestrator/stacks/tmkms/README.md b/stack-orchestrator/stacks/tmkms/README.md index 8de0032..2e1128d 100644 --- a/stack-orchestrator/stacks/tmkms/README.md +++ b/stack-orchestrator/stacks/tmkms/README.md @@ -16,14 +16,6 @@ Instructions for running TMKMS service laconic-so fetch-stack git.vdb.to/LaconicNetwork/tmkms-stack --git-ssh --pull ``` -- Clone required repositories: - - ```bash - laconic-so --stack ~/cerc/tmkms-stack/stack-orchestrator/stacks/tmkms setup-repositories --git-ssh --pull - - # If this throws an error as a result of being already checked out to a branch/tag in a repo, remove the repository and re-run the command - ``` - - Build the container images: ```bash @@ -58,7 +50,7 @@ Instructions for running TMKMS service ```bash # Chain ID - CERC_CHAIN_ID= + CHAIN_ID= # Public IP address of the node NODE_IP= @@ -66,8 +58,8 @@ Instructions for running TMKMS service # Port on which the node is listening for consensus messages (default: 26659) NODE_PORT= - # Key prefix (for ex. laconic) - CERC_KEY_PREFIX= + # Key prefix + KEY_PREFIX= ``` ## Run @@ -83,3 +75,25 @@ Instructions for running TMKMS service ```bash laconic-so --dir tmkms-deployment logs -f ``` + +## Clean up + +- Stop the deployment: + + ```bash + laconic-so --dir tmkms-deployment stop + ``` + +- To stop the deployment and also delete data: + + ```bash + laconic-so --dir tmkms-deployment stop --delete-volumes + + sudo rm -rf tmkms-deployment + ``` + +- Remove `cerc/tmkms` docker image: + + ```bash + docker rmi cerc/tmkms:local + ``` diff --git a/stack-orchestrator/stacks/tmkms/stack.yml b/stack-orchestrator/stacks/tmkms/stack.yml index 8d01b40..de0473e 100644 --- a/stack-orchestrator/stacks/tmkms/stack.yml +++ b/stack-orchestrator/stacks/tmkms/stack.yml @@ -1,8 +1,7 @@ version: "1.0" name: tmkms -description: "TMKMS for signing consensus messages" +description: "Key Management System for Tendermint applications" repos: - - github.com/iqlusioninc/tmkms@v0.14.0 containers: - cerc/tmkms pods: -- 2.45.2 From 88c7911af3850f1bf75d14f0a83ebc657bf5626c Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 12 Jun 2025 12:58:11 +0530 Subject: [PATCH 4/4] Update run script to allow editing config file on restart --- stack-orchestrator/config/tmkms/run.sh | 42 +++++++++++--------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/stack-orchestrator/config/tmkms/run.sh b/stack-orchestrator/config/tmkms/run.sh index ac22282..d317944 100755 --- a/stack-orchestrator/config/tmkms/run.sh +++ b/stack-orchestrator/config/tmkms/run.sh @@ -13,20 +13,30 @@ TMKMS_STATE_DIR=$TMKMS_HOME/state # Check if priv_validator_key in SECRETS_DIR exists if [[ ! -f "$TMKMS_SECRETS_DIR/priv_validator_key" ]]; then - # Initialize tmkms config echo "Initializing tmkms configuration..." tmkms init $TMKMS_HOME - # Generate a new softsign key - echo "Generating new softsign key..." - tmkms softsign keygen $TMKMS_SECRETS_DIR/kms-identity.key + # Import the private validator key into tmkms + echo "Importing private validator key into tmkms..." + tmkms softsign import $INPUT_PRIV_KEY_FILE $TMKMS_SECRETS_DIR/priv_validator_key - # Update tmkms.toml - echo "Updating tmkms.toml with chain_id, node IP, and key prefixes..." + # Remove the original private validator key + rm -rf $INPUT_PRIV_KEY_FILE - # Add chain configuration - cat < $TMKMS_HOME/tmkms.toml +else + echo "tmkms configuration already exists. Skipping initialization and cleaning up any existing input private validator key files..." + # Remove the original private validator key as it is not needed + if [[ -f "$INPUT_PRIV_KEY_FILE" ]]; then + rm -rf $INPUT_PRIV_KEY_FILE + fi +fi + +# Update tmkms.toml +echo "Updating tmkms.toml with chain_id, node IP, and key prefixes..." + +# Add chain configuration +cat < $TMKMS_HOME/tmkms.toml [[chain]] id = "$CHAIN_ID" @@ -46,21 +56,5 @@ if [[ ! -f "$TMKMS_SECRETS_DIR/priv_validator_key" ]]; then chain_ids = ["$CHAIN_ID"] EOF - # Import the private validator key into tmkms - echo "Importing private validator key into tmkms..." - tmkms softsign import $INPUT_PRIV_KEY_FILE $TMKMS_SECRETS_DIR/priv_validator_key - - # Remove the original private validator key - rm -rf $INPUT_PRIV_KEY_FILE - -else - echo "tmkms configuration already exists. Skipping initialization..." - # Throw error if tmp/priv_validator_key.json exists - if [[ -f "$INPUT_PRIV_KEY_FILE" ]]; then - echo "ERROR: $INPUT_PRIV_KEY_FILE already exists. Please remove it and try again." - exit 1 - fi -fi - echo "Starting tmkms..." tmkms start --config $TMKMS_HOME/tmkms.toml -- 2.45.2