diff --git a/README.md b/README.md index e69de29..bc19fcf 100644 --- a/README.md +++ b/README.md @@ -0,0 +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 new file mode 100644 index 0000000..fab23c9 --- /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: + CHAIN_ID: ${CHAIN_ID} + NODE_IP: ${NODE_IP} + NODE_PORT: ${NODE_PORT:-26659} + KEY_PREFIX: ${KEY_PREFIX} + 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..d317944 --- /dev/null +++ b/stack-orchestrator/config/tmkms/run.sh @@ -0,0 +1,60 @@ +#!/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 + +# 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 + + # 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 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" + 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 = "$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 = ["$CHAIN_ID"] +EOF + +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..918cceb --- /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 ${SCRIPT_DIR} diff --git a/stack-orchestrator/stacks/tmkms/README.md b/stack-orchestrator/stacks/tmkms/README.md new file mode 100644 index 0000000..2e1128d --- /dev/null +++ b/stack-orchestrator/stacks/tmkms/README.md @@ -0,0 +1,99 @@ +# 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 + ``` + +- 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 + 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 + KEY_PREFIX= + ``` + +## Run + +- Start the deployment: + + ```bash + laconic-so --dir tmkms-deployment start + ``` + +- Check the logs: + + ```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 new file mode 100644 index 0000000..de0473e --- /dev/null +++ b/stack-orchestrator/stacks/tmkms/stack.yml @@ -0,0 +1,8 @@ +version: "1.0" +name: tmkms +description: "Key Management System for Tendermint applications" +repos: +containers: + - cerc/tmkms +pods: + - tmkms