Redo Dockerfile generation (#530)

Moves from concatted Dockerfiles to pseudo-templated Dockerfiles via a dedicated Rust program.

Removes the unmaintained kubernetes, not because we shouldn't have/use it, but because it's unmaintained and needs to be reworked before it's present again.

Replaces the compose with the work in the new orchestrator binary which spawns everything as expected. While this arguably re-invents the wheel, it correctly manages secrets and handles the variadic Dockerfiles.

Also adds an unrelated patch for zstd and simplifies running services a bit by greater utilizing the existing infrastructure.

---

* Delete all Dockerfile fragments, add new orchestator to generate Dockerfiles

Enables greater templating.

Also delete the unmaintained kubernetes folder *for now*. This should be
restored in the future.

* Use Dockerfiles from the orchestator

* Ignore Dockerfiles in the git repo

* Remove CI job to check Dockerfiles are as expected now that they're no longer committed

* Remove old Dockerfiles from repo

* Use Debian for monero-wallet-rpc

* Remove replace_cmds for proper usage of entry-dev

Consolidates ports a bit.

Updates serai-docker-tests from "compose" to "build".

* Only write a new dockerfile if it's distinct

Preserves the updated time metadata.

* Update serai-docker-tests

* Correct the path Dockerfiles are built from

* Correct inclusion of orchestration folder in Docker builds

* Correct debug/release flagging in the cargo command

Apparently, --debug isn't an effective NOP yet an error.

* Correct path used to run the Serai node within a Dockerfile

* Correct path in Monero Dockerfile

* Attempt storing monerod in /usr/bin

* Use sudo to move into /usr/bin in CI

* Correct 18.3.0 to 18.3.1

* Escape * with quotes

* Update deny.toml, ADD orchestration in runtime Dockerfile

* Add --detach to the Monero GH CI

* Diversify dockerfiles by network

* Fixes to network-diversified orchestration

* Bitcoin and Monero testnet scripts

* Permissions and tweaks

* Flatten scripts folders

* Add missing folder specification to Monero Dockerfile

* Have monero-wallet-rpc specify the monerod login

* Have the Docker CMD specify env variables inserted at time of Dockerfile generation

They're overrideable with the global enviornment as for tests. This enables
variable generation in orchestrator and output to productionized Docker files
without creating a life-long file within the Docker container.

* Don't add Dockerfiles into Docker containers now that they have secrets

Solely add the source code for them as needed to satisfy the workspace bounds.

* Download arm64 Monero on arm64

* Ensure constant host architecture when reproducibly building the wasm

Host architecture, for some reason, can effect the generated code despite the
target architecture always being foreign to the host architecture.

* Randomly generate infrastructure keys

* Have orchestrator generate a key, be able to create/start containers

* Ensure bash is used over sh

* Clean dated docs

* Change how quoting occurs

* Standardize to sh

* Have Docker test build the dev Dockerfiles

* Only key_gen once

* cargo update

Adds a patch for zstd and reconciles the breaking nightly change which just
occurred.

* Use a dedicated network for Serai

Also fixes SERAI_HOSTNAME passed to coordinator.

* Support providing a key over the env for the Serai node

* Enable and document running daemons for tests via serai-orchestrator

Has running containers under the dev network port forward the RPC ports.

* Use volumes for bitcoin/monero

* Use bitcoin's run.sh in GH CI

* Only use the volume for testnet (not dev)
This commit is contained in:
Luke Parker
2024-02-09 02:48:44 -05:00
committed by GitHub
parent 347d4cf413
commit 337e54c672
131 changed files with 1403 additions and 2695 deletions

30
orchestration/Cargo.toml Normal file
View File

@@ -0,0 +1,30 @@
[package]
name = "serai-orchestrator"
version = "0.0.1"
description = "Generates Dockerfiles for Serai"
license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/orchestration/"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = []
edition = "2021"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
hex = { version = "0.4", default-features = false, features = ["std"] }
zeroize = { version = "1", default-features = false, features = ["std"] }
rand_core = { version = "0.6", default-features = false, features = ["std", "getrandom"] }
rand_chacha = { version = "0.3", default-features = false, features = ["std"] }
transcript = { package = "flexible-transcript", path = "../crypto/transcript", default-features = false, features = ["std", "recommended"] }
ciphersuite = { path = "../crypto/ciphersuite", default-features = false, features = ["std", "ristretto"] }
zalloc = { path = "../common/zalloc" }
home = "0.5"

View File

@@ -1,6 +0,0 @@
FROM alpine:latest as image
COPY --from=mimalloc libmimalloc.so /usr/lib
ENV LD_PRELOAD=libmimalloc.so
RUN apk update && apk upgrade

View File

@@ -1,6 +0,0 @@
FROM debian:bookworm-slim as image
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean

View File

@@ -1,39 +0,0 @@
FROM rust:1.75-slim-bookworm as builder
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Add dev dependencies
RUN apt install -y pkg-config clang
# Dependencies for the Serai node
RUN apt install -y make protobuf-compiler
# Add the wasm toolchain
RUN rustup target add wasm32-unknown-unknown
# Add files for build
ADD common /serai/common
ADD crypto /serai/crypto
ADD coins /serai/coins
ADD message-queue /serai/message-queue
ADD processor /serai/processor
ADD coordinator /serai/coordinator
ADD substrate /serai/substrate
ADD mini /serai/mini
ADD tests /serai/tests
ADD patches /serai/patches
ADD Cargo.toml /serai
ADD Cargo.lock /serai
ADD AGPL-3.0 /serai
WORKDIR /serai
# Mount the caches and build
RUN --mount=type=cache,target=/root/.cargo \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/serai/target \
mkdir /serai/bin && \

View File

@@ -1,11 +0,0 @@
FROM alpine:latest as mimalloc
RUN apk update && apk upgrade && apk --no-cache add gcc g++ libc-dev make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so

View File

@@ -1,11 +0,0 @@
FROM debian:bookworm-slim as mimalloc
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so

View File

@@ -1,65 +1,12 @@
# Deploy
# Orchestration
## Run with Docker Compose
This folder contains the tool which generates various dockerfiles and manage
deployments of Serai.
Running the Serai infrastructure is easy with Docker.
To start, run:
We utilize compose profiles to easily orchestrate various pieces of the
infrastructure.
```sh
cargo run -p serai-orchestrator
```
**Example:** `docker compose --profile cluster-coins-sm up`
All commands are assumed to be ran from `/deploy`, not the root folder.
### Profiles:
* `bitcoin` - Bitcoin node
* `monero` - Monero node
* `ethereum` - Ethereum node
* `coins` - Nodes for all external networks (BTC, ETH, XMR)
* `message-queue` - The message queue service.
* `processor` - Serai processor for one external network.
* `coordinator` - Serai coordinator for the entire Serai stack.
* `serai` - Serai node
* `cluster-sm` - "Alice", "Bob", "Charlie", and "Dave" Serai nodes, all as
validators (enough to achieve BFT with one faulty node)
* `cluster-lg` - `cluster-sm` with non-validators "Eve" and "Ferdie"
You can supply one or more profiles to the docker compose command to orchestrate
the desired components.
**Example:** `docker compose --profile coins --profile serai up`
## Orchestration Approach
### Builds
The Serai infrastructure is locally compiled. This may take several minutes.
Images for external networks download binaries, before verifying their checksums
and signatures.
**Stage 1 -- Builder**
* Configure environment.
* Get the binary.
* Verify binary using GPG.
* Decompress binary to prepare image.
**Stage 2 -- Image**
* Copy needed files from builder.
* Move executables to bin folder.
* Copy scripts folder.
* Expose necessary ports.
* Map necessary volumes.
### Entrypoint
The Serai node and external networks' nodes are each started from an entrypoint
script inside the `/scripts `folder.
To update the scripts on the image you must rebuild the updated images using the
`--build` flag after `up` in `docker compose`.
**Example:** `docker compose --profile bitcoin up --build`
to generate all of the dockerfiles needed for development.

View File

@@ -1,22 +0,0 @@
FROM alpine:latest as bitcoin
ENV BITCOIN_VERSION=26.0
RUN apk --no-cache add git gnupg
# Download Bitcoin
RUN wget https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/bitcoin-${BITCOIN_VERSION}-$(uname -m)-linux-gnu.tar.gz \
&& wget https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/SHA256SUMS \
&& wget https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/SHA256SUMS.asc
# Verify all sigs and check for a valid signature from laanwj -- 71A3
RUN git clone https://github.com/bitcoin-core/guix.sigs && \
cd guix.sigs/builder-keys && \
find . -iname '*.gpg' -exec gpg --import {} \; && \
gpg --verify --status-fd 1 --verify ../../SHA256SUMS.asc ../../SHA256SUMS | grep "^\[GNUPG:\] VALIDSIG.*71A3B16735405025D447E8F274810B012346C9A6"
RUN grep bitcoin-${BITCOIN_VERSION}-$(uname -m)-linux-gnu.tar.gz SHA256SUMS | sha256sum -c
# Prepare Image
RUN tar xzvf bitcoin-${BITCOIN_VERSION}-$(uname -m)-linux-gnu.tar.gz
RUN mv bitcoin-${BITCOIN_VERSION}/bin/bitcoind .

View File

@@ -1,10 +0,0 @@
# Switch to a non-root user
RUN useradd --system --create-home --shell /sbin/nologin bitcoin
USER bitcoin
WORKDIR /home/bitcoin
COPY --from=bitcoin --chown=bitcoin bitcoind /bin
COPY ./scripts /scripts
EXPOSE 8332 8333 18332 18333 18443 18444
# VOLUME ["/home/bitcoin/.bitcoin"]

View File

@@ -1,8 +0,0 @@
#!/bin/bash
RPC_USER="${RPC_USER:=serai}"
RPC_PASS="${RPC_PASS:=seraidex}"
bitcoind -txindex -regtest \
-rpcuser=$RPC_USER -rpcpassword=$RPC_PASS \
-rpcbind=0.0.0.0 -rpcallowip=0.0.0.0/0

View File

@@ -1,37 +0,0 @@
# Prepare Environment
FROM alpine:latest as builder
ENV GETH_VERSION=1.10.23-d901d853
WORKDIR /home/ethereum
RUN apk update \
&& apk --no-cache add ca-certificates gnupg bash su-exec
# Get Binary
RUN wget https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-${GETH_VERSION}.tar.gz\
&& wget https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-${GETH_VERSION}.tar.gz.asc
# Verify Binary
# Refer to https://geth.ethereum.org/downloads/#openpgp_signatures for the PGP
# PGP keys of builders and developers
ENV KEYS 9BA28146 E058A81C 05A5DDF0 1CCB7DD2
RUN gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys ${KEYS} \
&& gpg --verify geth-linux-amd64-${GETH_VERSION}.tar.gz.asc geth-linux-amd64-${GETH_VERSION}.tar.gz
# Prepare Image
RUN tar xzvf geth-linux-amd64-${GETH_VERSION}.tar.gz
# Prepare Image
FROM ubuntu:latest as image
WORKDIR /home/ethereum
COPY --from=builder /home/ethereum/* .
RUN mv * /bin/
COPY ./scripts /scripts
EXPOSE 8545 8546 30303 30303/udp
# Run
CMD ["geth"]

View File

@@ -1,50 +0,0 @@
FROM debian:bookworm-slim as mimalloc
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
FROM alpine:latest as monero
# https://downloads.getmonero.org/cli/monero-linux-x64-v0.18.3.1.tar.bz2
# Verification will fail if MONERO_VERSION doesn't match the latest
# due to the way monero publishes releases. They overwrite a single hashes.txt
# file with each release, meaning we can only grab the SHA256 of the latest
# release.
# Most publish a asc file for each release / build architecture ¯\_(ツ)_/¯
ENV MONERO_VERSION=0.18.3.1
RUN apk --no-cache add gnupg
# Download Monero
RUN wget https://downloads.getmonero.org/cli/monero-linux-x64-v${MONERO_VERSION}.tar.bz2
# Verify Binary -- fingerprint from https://github.com/monero-project/monero-site/issues/1949
ADD ./temp/hashes-v${MONERO_VERSION}.txt .
RUN gpg --keyserver hkp://keyserver.ubuntu.com:80 --keyserver-options no-self-sigs-only --receive-keys 81AC591FE9C4B65C5806AFC3F0AF4D462A0BDF92 && \
gpg --verify hashes-v${MONERO_VERSION}.txt && \
grep "$(sha256sum monero-linux-x64-v${MONERO_VERSION}.tar.bz2 | cut -c 1-64)" hashes-v${MONERO_VERSION}.txt
# Extract it
RUN tar -xvjf monero-linux-x64-v${MONERO_VERSION}.tar.bz2 --strip-components=1
FROM debian:bookworm-slim as image
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Switch to a non-root user
# System user (not a human), shell of nologin, no password assigned
RUN useradd --system --create-home --shell /sbin/nologin monero
USER monero
WORKDIR /home/monero
COPY --from=monero --chown=monero monero-wallet-rpc /bin
ADD scripts /scripts
EXPOSE 6061

View File

@@ -1,10 +0,0 @@
# Switch to a non-root user
# System user (not a human), shell of nologin, no password assigned
RUN useradd --system --create-home --shell /sbin/nologin monero
USER monero
WORKDIR /home/monero
COPY --from=monero --chown=monero monero-wallet-rpc /bin
ADD scripts /scripts
EXPOSE 6061

View File

@@ -1,3 +0,0 @@
#!/bin/sh
monero-wallet-rpc --disable-rpc-login --rpc-bind-port 6061 --rpc-bind-ip=0.0.0.0 --confirm-external-bind --daemon-address monero:18081 --allow-mismatched-daemon-version --wallet-dir /home/monero

View File

@@ -1,53 +0,0 @@
FROM alpine:latest as mimalloc
RUN apk update && apk upgrade && apk --no-cache add gcc g++ libc-dev make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
FROM alpine:latest as monero
# https://downloads.getmonero.org/cli/monero-linux-x64-v0.18.3.1.tar.bz2
# Verification will fail if MONERO_VERSION doesn't match the latest
# due to the way monero publishes releases. They overwrite a single hashes.txt
# file with each release, meaning we can only grab the SHA256 of the latest
# release.
# Most publish a asc file for each release / build architecture ¯\_(ツ)_/¯
ENV MONERO_VERSION=0.18.3.1
RUN apk --no-cache add gnupg
# Download Monero
RUN wget https://downloads.getmonero.org/cli/monero-linux-x64-v${MONERO_VERSION}.tar.bz2
# Verify Binary -- fingerprint from https://github.com/monero-project/monero-site/issues/1949
ADD ./temp/hashes-v${MONERO_VERSION}.txt .
RUN gpg --keyserver hkp://keyserver.ubuntu.com:80 --keyserver-options no-self-sigs-only --receive-keys 81AC591FE9C4B65C5806AFC3F0AF4D462A0BDF92 && \
gpg --verify hashes-v${MONERO_VERSION}.txt && \
grep "$(sha256sum monero-linux-x64-v${MONERO_VERSION}.tar.bz2 | cut -c 1-64)" hashes-v${MONERO_VERSION}.txt
# Extract it
RUN tar -xvjf monero-linux-x64-v${MONERO_VERSION}.tar.bz2 --strip-components=1
FROM alpine:latest as image
COPY --from=mimalloc libmimalloc.so /usr/lib
ENV LD_PRELOAD=libmimalloc.so
RUN apk update && apk upgrade
RUN apk --no-cache add gcompat
# Switch to a non-root user
# System user (not a human), shell of nologin, no password assigned
RUN adduser -S -s /sbin/nologin -D monero
USER monero
WORKDIR /home/monero
COPY --from=monero --chown=monero monerod /bin
ADD scripts /scripts
EXPOSE 18080 18081
# VOLUME /home/monero/.bitmonero

View File

@@ -1,23 +0,0 @@
FROM alpine:latest as monero
# https://downloads.getmonero.org/cli/monero-linux-x64-v0.18.3.1.tar.bz2
# Verification will fail if MONERO_VERSION doesn't match the latest
# due to the way monero publishes releases. They overwrite a single hashes.txt
# file with each release, meaning we can only grab the SHA256 of the latest
# release.
# Most publish a asc file for each release / build architecture ¯\_(ツ)_/¯
ENV MONERO_VERSION=0.18.3.1
RUN apk --no-cache add gnupg
# Download Monero
RUN wget https://downloads.getmonero.org/cli/monero-linux-x64-v${MONERO_VERSION}.tar.bz2
# Verify Binary -- fingerprint from https://github.com/monero-project/monero-site/issues/1949
ADD ./temp/hashes-v${MONERO_VERSION}.txt .
RUN gpg --keyserver hkp://keyserver.ubuntu.com:80 --keyserver-options no-self-sigs-only --receive-keys 81AC591FE9C4B65C5806AFC3F0AF4D462A0BDF92 && \
gpg --verify hashes-v${MONERO_VERSION}.txt && \
grep "$(sha256sum monero-linux-x64-v${MONERO_VERSION}.tar.bz2 | cut -c 1-64)" hashes-v${MONERO_VERSION}.txt
# Extract it
RUN tar -xvjf monero-linux-x64-v${MONERO_VERSION}.tar.bz2 --strip-components=1

View File

@@ -1,13 +0,0 @@
RUN apk --no-cache add gcompat
# Switch to a non-root user
# System user (not a human), shell of nologin, no password assigned
RUN adduser -S -s /sbin/nologin -D monero
USER monero
WORKDIR /home/monero
COPY --from=monero --chown=monero monerod /bin
ADD scripts /scripts
EXPOSE 18080 18081
# VOLUME /home/monero/.bitmonero

View File

@@ -1,10 +0,0 @@
#!/bin/sh
RPC_USER="${RPC_USER:=serai}"
RPC_PASS="${RPC_PASS:=seraidex}"
# Run Monero
# TODO: Restore Auth
monerod --non-interactive --regtest --offline --fixed-difficulty=1 \
--no-zmq --rpc-bind-ip=0.0.0.0 --confirm-external-bind \
--rpc-access-control-origins * --disable-rpc-ban

View File

@@ -1,73 +0,0 @@
FROM debian:bookworm-slim as mimalloc
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
FROM rust:1.75-slim-bookworm as builder
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Add dev dependencies
RUN apt install -y pkg-config clang
# Dependencies for the Serai node
RUN apt install -y make protobuf-compiler
# Add the wasm toolchain
RUN rustup target add wasm32-unknown-unknown
# Add files for build
ADD common /serai/common
ADD crypto /serai/crypto
ADD coins /serai/coins
ADD message-queue /serai/message-queue
ADD processor /serai/processor
ADD coordinator /serai/coordinator
ADD substrate /serai/substrate
ADD mini /serai/mini
ADD tests /serai/tests
ADD patches /serai/patches
ADD Cargo.toml /serai
ADD Cargo.lock /serai
ADD AGPL-3.0 /serai
WORKDIR /serai
# Mount the caches and build
RUN --mount=type=cache,target=/root/.cargo \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/serai/target \
mkdir /serai/bin && \
cargo build -p serai-coordinator --features "parity-db longer-reattempts" && \
mv /serai/target/debug/serai-coordinator /serai/bin
FROM debian:bookworm-slim as image
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Install ca-certificates
RUN apt install -y ca-certificates
# Switch to a non-root user
RUN useradd --system --create-home --shell /sbin/nologin coordinator
USER coordinator
WORKDIR /home/coordinator
# Copy the Coordinator binary and relevant license
COPY --from=builder --chown=processor /serai/bin/serai-coordinator /bin/
COPY --from=builder --chown=processor /serai/AGPL-3.0 .
# Run coordinator
CMD ["serai-coordinator"]

View File

@@ -1,2 +0,0 @@
cargo build -p serai-coordinator --features "parity-db longer-reattempts" && \
mv /serai/target/debug/serai-coordinator /serai/bin

View File

@@ -1,15 +0,0 @@
# Install ca-certificates
RUN apt install -y ca-certificates
# Switch to a non-root user
RUN useradd --system --create-home --shell /sbin/nologin coordinator
USER coordinator
WORKDIR /home/coordinator
# Copy the Coordinator binary and relevant license
COPY --from=builder --chown=processor /serai/bin/serai-coordinator /bin/
COPY --from=builder --chown=processor /serai/AGPL-3.0 .
# Run coordinator
CMD ["serai-coordinator"]

View File

@@ -1,9 +0,0 @@
#!/bin/bash
export MESSAGE_QUEUE_KEY="0000000000000000000000000000000000000000000000000000000000000000"
export MESSAGE_QUEUE_RPC="http://127.0.0.1:2287"
export DB_PATH="./coordinator-db"
export SERAI_HOSTNAME="127.0.0.1"
serai-coordinator

View File

@@ -0,0 +1,9 @@
#!/bin/sh
RPC_USER="${RPC_USER:=serai}"
RPC_PASS="${RPC_PASS:=seraidex}"
bitcoind -txindex -regtest --port=8333 \
-rpcuser=$RPC_USER -rpcpassword=$RPC_PASS \
-rpcbind=0.0.0.0 -rpcallowip=0.0.0.0/0 -rpcport=8332 \
$1

View File

@@ -0,0 +1,7 @@
#!/bin/sh
monero-wallet-rpc \
--allow-mismatched-daemon-version \
--daemon-address serai-dev-monero:18081 --daemon-login serai:seraidex \
--disable-rpc-login --rpc-bind-ip=0.0.0.0 --rpc-bind-port 18082 --confirm-external-bind \
--wallet-dir /home/monero

View File

@@ -0,0 +1,11 @@
#!/bin/sh
RPC_USER="${RPC_USER:=serai}"
RPC_PASS="${RPC_PASS:=seraidex}"
# Run Monero
monerod --non-interactive --regtest --offline --fixed-difficulty=1 \
--no-zmq --rpc-bind-ip=0.0.0.0 --rpc-bind-port=18081 --confirm-external-bind \
--rpc-access-control-origins "*" --disable-rpc-ban \
--rpc-login=$RPC_USER:$RPC_PASS \
$1

View File

View File

3
orchestration/dev/serai/run.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
serai-node --unsafe-rpc-external --rpc-cors all --chain local --$SERAI_NAME

View File

@@ -1,221 +0,0 @@
version: "3.9"
name: serai-dev
volumes:
serai:
serai-alice:
serai-bob:
serai-charlie:
serai-dave:
serai-eve:
serai-ferdie:
services:
# Coin services
bitcoin:
profiles:
- bitcoin
- coins
build:
context: ./coins/bitcoin/
restart: unless-stopped
volumes:
- "./coins/bitcoin/scripts:/scripts"
entrypoint: /scripts/entry-dev.sh
# TODO: Use expose, not ports
ports:
- "18443:18443"
ethereum:
profiles:
- ethereum
- coins
build:
context: ./coins/ethereum/
restart: unless-stopped
volumes:
- "./coins/ethereum/scripts:/scripts"
entrypoint: /scripts/entry-dev.sh
monero:
profiles:
- monero
- coins
build:
context: ./coins/monero/
restart: unless-stopped
volumes:
- "./coins/monero/scripts:/scripts"
entrypoint: /scripts/entry-dev.sh
# TODO: Use expose, not ports
ports:
- "18081:18081"
monero-wallet-rpc:
profiles:
- monero
- coins
build:
context: ./coins/monero-wallet-rpc/
restart: unless-stopped
volumes:
- "./coins/monero-wallet-rpc/scripts:/scripts"
entrypoint: /scripts/entry-dev.sh
# TODO: Use expose, not ports
ports:
- "6061:6061"
# Infrastructure
message-queue:
profiles:
- message-queue
build:
context: ../
dockerfile: ./orchestration/message-queue/Dockerfile
restart: unless-stopped
volumes:
- "./message-queue/scripts:/scripts"
entrypoint: /scripts/entry-dev.sh
expose:
- "2287"
bitcoin-processor:
profiles:
- bitcoin-processor
build:
context: ../
dockerfile: ./orchestration/processor/bitcoin/Dockerfile
restart: unless-stopped
volumes:
- "./processor/scripts:/scripts"
entrypoint: /scripts/entry-dev.sh
monero-processor:
profiles:
- monero-processor
build:
context: ../
dockerfile: ./orchestration/processor/monero/Dockerfile
restart: unless-stopped
volumes:
- "./processor/scripts:/scripts"
entrypoint: /scripts/entry-dev.sh
coordinator:
profiles:
- coordinator
build:
context: ../
dockerfile: ./orchestration/coordinator/Dockerfile
restart: unless-stopped
volumes:
- "./coordinator/scripts:/scripts"
entrypoint: /scripts/entry-dev.sh
# Serai runtime
runtime:
profiles:
- runtime
build:
context: ../
dockerfile: ./orchestration/runtime/Dockerfile
entrypoint: |
sh -c "cd /serai/substrate/runtime && cargo clean && cargo build --release && \
sha256sum /serai/target/release/wbuild/serai-runtime/serai_runtime.wasm"
# Serai nodes
_serai:
&serai_defaults
restart: unless-stopped
# image: serai:dev
profiles:
- _
build:
context: ../
dockerfile: ./orchestration/serai/Dockerfile
args:
TAG: serai
entrypoint: /scripts/entry-dev.sh
volumes:
- "./serai/scripts:/scripts"
serai:
<<: *serai_defaults
hostname: serai
profiles:
- serai
environment:
CHAIN: local
NAME: node
serai-alice:
<<: *serai_defaults
hostname: serai-alice
profiles:
- alice
- cluster-sm
- cluster-lg
environment:
CHAIN: local
NAME: alice
VALIDATOR: true
serai-bob:
<<: *serai_defaults
hostname: serai-bob
profiles:
- bob
- cluster-sm
- cluster-lg
environment:
CHAIN: local
NAME: bob
VALIDATOR: true
serai-charlie:
<<: *serai_defaults
hostname: serai-charlie
profiles:
- charlie
- cluster-sm
- cluster-lg
environment:
CHAIN: local
NAME: charlie
VALIDATOR: true
serai-dave:
<<: *serai_defaults
hostname: serai-dave
profiles:
- dave
- cluster-sm
- cluster-lg
environment:
CHAIN: local
NAME: dave
VALIDATOR: true
serai-eve:
<<: *serai_defaults
hostname: serai-eve
profiles:
- eve
- cluster-lg
environment:
CHAIN: local
NAME: eve
serai-ferdie:
<<: *serai_defaults
hostname: serai-ferdie
profiles:
- ferdie
- cluster-lg
environment:
CHAIN: local
NAME: ferdie

View File

@@ -1,70 +0,0 @@
# Bitcoin
rm ./coins/bitcoin/Dockerfile
cat \
./Dockerfile.parts/mimalloc/Dockerfile.debian \
./coins/bitcoin/Dockerfile.bitcoin \
./Dockerfile.parts/Dockerfile.debian.start \
./coins/bitcoin/Dockerfile.bitcoin.end >> ./coins/bitcoin/Dockerfile
# Monero
rm ./coins/monero/Dockerfile
cat \
./Dockerfile.parts/mimalloc/Dockerfile.alpine \
./coins/monero/Dockerfile.monero \
./Dockerfile.parts/Dockerfile.alpine.start \
./coins/monero/Dockerfile.monero.end >> ./coins/monero/Dockerfile
# Monero wallet rpc
rm -f ./coins/monero-wallet-rpc/Dockerfile
mkdir -p ./coins/monero-wallet-rpc/temp/
cp ./coins/monero/temp/hashes-v* ./coins/monero-wallet-rpc/temp/
cat \
./Dockerfile.parts/mimalloc/Dockerfile.debian \
./coins/monero/Dockerfile.monero \
./Dockerfile.parts/Dockerfile.debian.start \
./coins/monero-wallet-rpc/Dockerfile.monero-wallet-rpc.end >> ./coins/monero-wallet-rpc/Dockerfile
# Message Queue
rm ./message-queue/Dockerfile
cat \
./Dockerfile.parts/mimalloc/Dockerfile.debian \
./Dockerfile.parts/Dockerfile.serai.build \
./message-queue/Dockerfile.message-queue \
./Dockerfile.parts/Dockerfile.debian.start \
./message-queue/Dockerfile.message-queue.end >> ./message-queue/Dockerfile
# Bitcoin Processor
rm ./processor/bitcoin/Dockerfile
cat \
./Dockerfile.parts/mimalloc/Dockerfile.debian \
./Dockerfile.parts/Dockerfile.serai.build \
./processor/bitcoin/Dockerfile.processor.bitcoin \
./Dockerfile.parts/Dockerfile.debian.start \
./processor/Dockerfile.processor.end >> ./processor/bitcoin/Dockerfile
# Monero Processor
rm ./processor/monero/Dockerfile
cat \
./Dockerfile.parts/mimalloc/Dockerfile.debian \
./Dockerfile.parts/Dockerfile.serai.build \
./processor/monero/Dockerfile.processor.monero \
./Dockerfile.parts/Dockerfile.debian.start \
./processor/Dockerfile.processor.end >> ./processor/monero/Dockerfile
# Coordinator
rm ./coordinator/Dockerfile
cat \
./Dockerfile.parts/mimalloc/Dockerfile.debian \
./Dockerfile.parts/Dockerfile.serai.build \
./coordinator/Dockerfile.coordinator \
./Dockerfile.parts/Dockerfile.debian.start \
./coordinator/Dockerfile.coordinator.end >> ./coordinator/Dockerfile
# Node
rm ./serai/Dockerfile
cat \
./Dockerfile.parts/mimalloc/Dockerfile.debian \
./Dockerfile.parts/Dockerfile.serai.build \
./serai/Dockerfile.serai \
./Dockerfile.parts/Dockerfile.debian.start \
./serai/Dockerfile.serai.end >> ./serai/Dockerfile

View File

@@ -1,103 +0,0 @@
SHELL := /bin/bash
check-helm:
@helm version || $(MAKE) install-helm
check-kubectl:
@kubectl version || $(MAKE) install-kubectl
install-helm:
@curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
@chmod 700 get_helm.sh
@./get_helm.sh
@rm get_helm.sh
install-kubectl:
@curl -LO 'https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl'
@sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
@rm kubectl
deploy-base:
@docker compose -f ../docker-compose.yml --profile base build --quiet
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-base charts/serai/\
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-base,nameOverride=serai-base,\
image.envVariables[1].value=base,configMapFile=%
deploy-bitcoin:
@docker compose -f ../docker-compose.yml --profile bitcoin build --quiet
@(cat ../coins/bitcoin/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install bitcoin-daemon\
charts/bitcoin/ --values charts/bitcoin/values.yaml --set configMapFile=%
deploy-ethereum:
@docker compose -f ../docker-compose.yml --profile ethereum build --quiet
@(cat ../coins/ethereum/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install ethereum-daemon\
charts/ethereum/ --values charts/ethereum/values.yaml --set configMapFile=%
deploy-monero:
@docker compose -f ../docker-compose.yml --profile monero build --quiet
@(cat ../coins/monero/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install monero-daemon\
charts/monero/ --values charts/monero/values.yaml --set configMapFile=%
deploy-cluster-sm:
@docker compose -f ../docker-compose.yml --profile cluster-sm build --quiet
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-alice charts/serai/\
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-alice,nameOverride=serai-alice,\
image.envVariables[1].value=Alice,image.envVariables[2].value="'1'",configMapFile=%
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-charlie charts/serai/\
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-charlie,nameOverride=serai-charlie,\
image.envVariables[1].value=Charlie,configMapFile=%
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-bob charts/serai/\
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-bob,nameOverride=serai-bob,\
image.envVariables[1].value=Bob,configMapFile=%
deploy-cluster-lg: deploy-cluster-sm
@docker compose -f ../docker-compose.yml --profile cluster-lg build --quiet
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-dave charts/serai/\
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-dave,nameOverride=serai-dave,\
image.envVariables[1].value=Dave,configMapFile=%
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-eve charts/serai/\
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-eve,nameOverride=serai-eve,\
image.envVariables[1].value=Eve,configMapFile=%
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-ferdie charts/serai/\
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-ferdie,nameOverride=serai-ferdie,\
image.envVariables[1].value=Ferdie,configMapFile=%
deploy-coins: deploy-bitcoin deploy-ethereum deploy-monero
deploy-cluster-coins-sm: deploy-cluster-sm deploy-coins
deploy-cluster-coins-lg: deploy-cluster-lg deploy-coins
deploy-all: deploy-cluster-coins-lg
delete-base:
@helm delete serai-base
delete-bitcoin:
@helm delete bitcoin-daemon
delete-ethereum:
@helm delete ethereum-daemon
delete-monero:
@helm delete monero-daemon
delete-cluster-lg: delete-cluster-sm
@helm delete serai-dave
@helm delete serai-eve
@helm delete serai-ferdie
delete-cluster-sm:
@helm delete serai-alice
@helm delete serai-charlie
@helm delete serai-bob
delete-coins: delete-bitcoin delete-ethereum delete-monero
delete-cluster-coins-sm: delete-cluster-sm delete-coins
delete-cluster-coins-lg: delete-cluster-lg delete-coins
delete-all: delete-cluster-coins-lg
check-dependencies: check-helm check-kubectl

View File

@@ -1,41 +0,0 @@
# Kubernetes
## Run with Kubernetes
Running the Serai infrastructure is easy with Kubernetes.
We utilize Makefile to easily orchestrate various pieces of the infrastructure on kubernetes.
**Example to deploy:** `make deploy-<Profile_Name>`
```bash
make deploy-cluster-sm
```
**Example to delete:** `make -i delete-<Profile_Name>`
```bash
make delete-cluster-sm
```
All commands are assumed to be ran from the kubernetes folder, not the serai root folder.
### Profiles:
* deploy-base - single node, named base
* deploy-coins - node clients for coins only (BTC, ETH, XMR)
* deploy-cluster-sm - Alice (Validator), Bob, Charlie
* deploy-cluster-coins-sm - cluster-sm with coins
* deploy-cluster-lg - Alice (Validator), Bob, Charlie, Dave, Eve, Ferdie
* deploy-cluster-coins-lg - cluster-lg with coins
* deploy-monero - full node monero only
* deploy-bitcoin - full node bitcoin only
* deploy-ethereum - full node ethereum only
## Requirements for Linux
* Local built images of serai and coins, please follow the Instructions [here](../README.md)
* Running kubernetes cluster (version >= 1.19)
* Curl tool
* Make tool
* Kubectl, check if not installed
```bash
make check-kubectl
```
* Helm, check if not installed
```bash
make check-helm
```

View File

@@ -1,5 +0,0 @@
apiVersion: v2
name: bitcoin
description: A Helm chart for bitcoin-daemon
type: application
version: 0.1.0

View File

@@ -1,42 +0,0 @@
{{- define "bitcoin.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- define "bitcoin.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 253 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 253 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{- define "bitcoin.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- define "bitcoin.labels" -}}
helm.sh/chart: {{ include "bitcoin.chart" . }}
{{ include "bitcoin.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "bitcoin.selectorLabels" -}}
app.kubernetes.io/name: {{ include "bitcoin.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{- define "bitcoin.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "bitcoin.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
entry-dev.sh: |
{{ .Values.configMapFile | b64dec | indent 4}}

View File

@@ -1,88 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "bitcoin.fullname" . }}
labels:
{{- include "bitcoin.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "bitcoin.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "bitcoin.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "bitcoin.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if hasKey .Values.image "ports" }}
ports:
{{- range .Values.image.ports }}
- name: {{ .name }}
containerPort: {{ .containerPort }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "command" }}
command:
{{- toYaml .Values.image.command | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "args" }}
args:
{{- toYaml .Values.image.args | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "envVariables" }}
env:
{{- toYaml .Values.image.envVariables | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "volumeMounts" }}
volumeMounts:
{{- range .Values.image.volumeMounts }}
- mountPath: {{ .mountPath }}
name: {{ $.Release.Name}}-{{ .name }}
{{- end }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if hasKey .Values "volumes" }}
volumes:
{{- range .Values.volumes }}
- configMap:
defaultMode: {{ .configMap.defaultMode }}
name: {{ $.Release.Name}}-{{ .configMap.name }}
name: {{ $.Release.Name}}-{{ .name }}
{{- end }}
{{- end }}

View File

@@ -1,50 +0,0 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "bitcoin.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "bitcoin.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if .pathType }}
pathType: {{ .pathType }}
{{- end }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1,24 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "bitcoin.fullname" . }}
labels:
{{- include "bitcoin.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
{{- if hasKey .Values.service "ports" }}
{{- range .Values.service.ports }}
- port: {{ .port }}
name: {{ .name }}
targetPort: {{ .targetPort }}
protocol: {{ .protocol }}
{{- end }}
{{- else }}
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
{{- end }}
selector:
{{- include "bitcoin.selectorLabels" . | nindent 4 }}

View File

@@ -1,74 +0,0 @@
replicaCount: 1
net: mainnet
image:
repository: serai-dev-bitcoin
pullPolicy: IfNotPresent
tag: "latest"
ports:
- name: p2p
containerPort: 18444
protocol: TCP
- name: rpc
containerPort: 18443
protocol: TCP
volumeMounts:
- mountPath: /scripts
name: configmap-volume
args:
- bash
- /scripts/entry-dev.sh
volumes:
- configMap:
defaultMode: 420
name: configmap
name: configmap-volume
configMapFile: "entry-dev.sh"
imagePullSecrets: []
serviceAccount:
create: false
name: ""
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
service:
type: ClusterIP
ports:
- name: p2p
port: 18444
targetPort: p2p
protocol: TCP
- name: rpc
port: 18443
targetPort: rpc
protocol: TCP
ingress:
enabled: false
className: ""
annotations: {}
hosts: []
tls: []
resources: {}
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}

View File

@@ -1,5 +0,0 @@
apiVersion: v2
name: ethereum
description: A Helm chart for ethereum-daemon
type: application
version: 0.1.0

View File

@@ -1,42 +0,0 @@
{{- define "ethereum.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- define "ethereum.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 253 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 253 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{- define "ethereum.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- define "ethereum.labels" -}}
helm.sh/chart: {{ include "ethereum.chart" . }}
{{ include "ethereum.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "ethereum.selectorLabels" -}}
app.kubernetes.io/name: {{ include "ethereum.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{- define "ethereum.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "ethereum.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
entry-dev.sh: |
{{ .Values.configMapFile | b64dec | indent 4}}

View File

@@ -1,89 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "ethereum.fullname" . }}
labels:
{{- include "ethereum.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "ethereum.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "ethereum.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "ethereum.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if hasKey .Values.image "ports" }}
ports:
{{- range .Values.image.ports }}
- name: {{ .name }}
containerPort: {{ .containerPort }}
protocol: {{ .protocol }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "command" }}
command:
{{- toYaml .Values.image.command | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "args" }}
args:
{{- toYaml .Values.image.args | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "envVariables" }}
env:
{{- toYaml .Values.image.envVariables | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "volumeMounts" }}
volumeMounts:
{{- range .Values.image.volumeMounts }}
- mountPath: {{ .mountPath }}
name: {{ $.Release.Name}}-{{ .name }}
{{- end }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if hasKey .Values "volumes" }}
volumes:
{{- range .Values.volumes }}
- configMap:
defaultMode: {{ .configMap.defaultMode }}
name: {{ $.Release.Name}}-{{ .configMap.name }}
name: {{ $.Release.Name}}-{{ .name }}
{{- end }}
{{- end }}

View File

@@ -1,50 +0,0 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "ethereum.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "ethereum.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if .pathType }}
pathType: {{ .pathType }}
{{- end }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1,24 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "ethereum.fullname" . }}
labels:
{{- include "ethereum.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
{{- if hasKey .Values.service "ports" }}
{{- range .Values.service.ports }}
- port: {{ .port }}
name: {{ .name }}
targetPort: {{ .targetPort }}
protocol: {{ .protocol }}
{{- end }}
{{- else }}
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
{{- end }}
selector:
{{- include "ethereum.selectorLabels" . | nindent 4 }}

View File

@@ -1,60 +0,0 @@
replicaCount: 1
image:
repository: serai-dev-ethereum
pullPolicy: IfNotPresent
tag: "latest"
ports:
- name: rpc
containerPort: 8545
protocol: TCP
volumeMounts:
- mountPath: /scripts
name: configmap-volume
args:
- bash
- /scripts/entry-dev.sh
volumes:
- configMap:
defaultMode: 420
name: configmap
name: configmap-volume
configMapFile: "entry-dev.sh"
imagePullSecrets: []
serviceAccount:
create: false
name: ""
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
service:
type: ClusterIP
port: 8545
ingress:
enabled: false
className: ""
annotations: {}
hosts: []
tls: []
resources: {}
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}

View File

@@ -1,5 +0,0 @@
apiVersion: v2
name: monero
description: A Helm chart for monero-daemon
type: application
version: 0.1.0

View File

@@ -1,42 +0,0 @@
{{- define "monero.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- define "monero.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 253 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 253 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{- define "monero.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- define "monero.labels" -}}
helm.sh/chart: {{ include "monero.chart" . }}
{{ include "monero.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "monero.selectorLabels" -}}
app.kubernetes.io/name: {{ include "monero.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{- define "monero.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "monero.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
entry-dev.sh: |
{{ .Values.configMapFile | b64dec | indent 4}}

View File

@@ -1,88 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "monero.fullname" . }}
labels:
{{- include "monero.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "monero.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "monero.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "monero.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if hasKey .Values.image "ports" }}
ports:
{{- range .Values.image.ports }}
- name: {{ .name }}
containerPort: {{ .containerPort }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "command" }}
command:
{{- toYaml .Values.image.command | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "args" }}
args:
{{- toYaml .Values.image.args | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "envVariables" }}
env:
{{- toYaml .Values.image.envVariables | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "volumeMounts" }}
volumeMounts:
{{- range .Values.image.volumeMounts }}
- mountPath: {{ .mountPath }}
name: {{ $.Release.Name}}-{{ .name }}
{{- end }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if hasKey .Values "volumes" }}
volumes:
{{- range .Values.volumes }}
- configMap:
defaultMode: {{ .configMap.defaultMode }}
name: {{ $.Release.Name}}-{{ .configMap.name }}
name: {{ $.Release.Name}}-{{ .name }}
{{- end }}
{{- end }}

View File

@@ -1,50 +0,0 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "monero.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "monero.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if .pathType }}
pathType: {{ .pathType }}
{{- end }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1,24 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "monero.fullname" . }}
labels:
{{- include "monero.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
{{- if hasKey .Values.service "ports" }}
{{- range .Values.service.ports }}
- port: {{ .port }}
name: {{ .name }}
targetPort: {{ .targetPort }}
protocol: {{ .protocol }}
{{- end }}
{{- else }}
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
{{- end }}
selector:
{{- include "monero.selectorLabels" . | nindent 4 }}

View File

@@ -1,72 +0,0 @@
replicaCount: 1
image:
repository: serai-dev-monero
pullPolicy: IfNotPresent
tag: "latest"
ports:
- name: p2p
containerPort: 18080
protocol: TCP
- name: rpc
containerPort: 18081
protocol: TCP
volumeMounts:
- mountPath: /scripts
name: configmap-volume
args:
- bash
- /scripts/entry-dev.sh
volumes:
- configMap:
defaultMode: 420
name: configmap
name: configmap-volume
configMapFile: "entry-dev.sh"
imagePullSecrets: []
serviceAccount:
create: false
name: ""
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
service:
type: ClusterIP
ports:
- name: p2p
port: 18080
targetPort: p2p
protocol: TCP
- name: rpc
port: 18081
targetPort: rpc
protocol: TCP
ingress:
enabled: false
className: ""
annotations: {}
hosts: []
tls: []
resources: {}
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}

View File

@@ -1,5 +0,0 @@
apiVersion: v2
name: serai
description: A Helm chart for serai
type: application
version: 0.1.0

View File

@@ -1,42 +0,0 @@
{{- define "serai-base.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- define "serai-base.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 253 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 253 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{- define "serai-base.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 253 | trimSuffix "-" }}
{{- end }}
{{- define "serai-base.labels" -}}
helm.sh/chart: {{ include "serai-base.chart" . }}
{{ include "serai-base.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "serai-base.selectorLabels" -}}
app.kubernetes.io/name: {{ include "serai-base.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{- define "serai-base.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "serai-base.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
entry-dev.sh: |
{{ .Values.configMapFile | b64dec | indent 4}}

View File

@@ -1,88 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "serai-base.fullname" . }}
labels:
{{- include "serai-base.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "serai-base.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "serai-base.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "serai-base.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if hasKey .Values.image "ports" }}
ports:
{{- range .Values.image.ports }}
- name: {{ .name }}
containerPort: {{ .containerPort }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "command" }}
command:
{{- toYaml .Values.image.command | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "args" }}
args:
{{- toYaml .Values.image.args | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "envVariables" }}
env:
{{- toYaml .Values.image.envVariables | nindent 12 }}
{{- end }}
{{- if hasKey .Values.image "volumeMounts" }}
volumeMounts:
{{- range .Values.image.volumeMounts }}
- mountPath: {{ .mountPath }}
name: {{ $.Release.Name}}-{{ .name }}
{{- end }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if hasKey .Values "volumes" }}
volumes:
{{- range .Values.volumes }}
- configMap:
defaultMode: {{ .configMap.defaultMode }}
name: {{ $.Release.Name}}-{{ .configMap.name }}
name: {{ $.Release.Name}}-{{ .name }}
{{- end }}
{{- end }}

View File

@@ -1,50 +0,0 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "serai-base.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "serai-base.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if .pathType }}
pathType: {{ .pathType }}
{{- end }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1,24 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "serai-base.fullname" . }}
labels:
{{- include "serai-base.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
{{- if hasKey .Values.service "ports" }}
{{- range .Values.service.ports }}
- port: {{ .port }}
name: {{ .name }}
targetPort: {{ .targetPort }}
protocol: {{ .protocol }}
{{- end }}
{{- else }}
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
{{- end }}
selector:
{{- include "serai-base.selectorLabels" . | nindent 4 }}

View File

@@ -1,92 +0,0 @@
replicaCount: 1
image:
repository: serai
pullPolicy: IfNotPresent
tag: "dev"
ports:
- name: p2p
containerPort: 30333
protocol: TCP
- name: prometheus
containerPort: 9615
protocol: TCP
- name: rpc
containerPort: 9933
protocol: TCP
- name: ws
containerPort: 9944
protocol: TCP
volumeMounts:
- mountPath: /scripts
name: configmap-volume
envVariables:
- name: CHAIN
value: dev
- name: NAME
value: base
- name: VALIDATOR
value:
args:
- bash
- /scripts/entry-dev.sh
volumes:
- configMap:
defaultMode: 420
name: configmap
name: configmap-volume
configMapFile: "entry-dev.sh"
imagePullSecrets: []
serviceAccount:
create: false
name: ""
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
service:
type: ClusterIP
ports:
- name: p2p
port: 30333
targetPort: p2p
protocol: TCP
- name: prometheus
port: 9615
targetPort: prometheus
protocol: TCP
- name: rpc
port: 9933
targetPort: rpc
protocol: TCP
- name: ws
port: 9944
targetPort: ws
protocol: TCP
ingress:
enabled: false
className: ""
annotations: {}
hosts: []
tls: []
resources: {}
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}

View File

@@ -1,71 +0,0 @@
FROM debian:bookworm-slim as mimalloc
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
FROM rust:1.75-slim-bookworm as builder
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Add dev dependencies
RUN apt install -y pkg-config clang
# Dependencies for the Serai node
RUN apt install -y make protobuf-compiler
# Add the wasm toolchain
RUN rustup target add wasm32-unknown-unknown
# Add files for build
ADD common /serai/common
ADD crypto /serai/crypto
ADD coins /serai/coins
ADD message-queue /serai/message-queue
ADD processor /serai/processor
ADD coordinator /serai/coordinator
ADD substrate /serai/substrate
ADD mini /serai/mini
ADD tests /serai/tests
ADD patches /serai/patches
ADD Cargo.toml /serai
ADD Cargo.lock /serai
ADD AGPL-3.0 /serai
WORKDIR /serai
# Mount the caches and build
RUN --mount=type=cache,target=/root/.cargo \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/serai/target \
mkdir /serai/bin && \
cargo build --features parity-db -p serai-message-queue && \
mv /serai/target/debug/serai-message-queue /serai/bin
FROM debian:bookworm-slim as image
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Switch to a non-root user
RUN useradd --system --home /home/message-queue --create-home --shell /sbin/nologin messagequeue
USER messagequeue
WORKDIR /home/message-queue
# Copy the Message Queue binary and relevant license
COPY --from=builder --chown=messagequeue /serai/bin/serai-message-queue /bin
COPY --from=builder --chown=messagequeue /serai/AGPL-3.0 .
# Run message-queue
EXPOSE 2287
CMD ["serai-message-queue"]

View File

@@ -1,2 +0,0 @@
cargo build --features parity-db -p serai-message-queue && \
mv /serai/target/debug/serai-message-queue /serai/bin

View File

@@ -1,13 +0,0 @@
# Switch to a non-root user
RUN useradd --system --home /home/message-queue --create-home --shell /sbin/nologin messagequeue
USER messagequeue
WORKDIR /home/message-queue
# Copy the Message Queue binary and relevant license
COPY --from=builder --chown=messagequeue /serai/bin/serai-message-queue /bin
COPY --from=builder --chown=messagequeue /serai/AGPL-3.0 .
# Run message-queue
EXPOSE 2287
CMD ["serai-message-queue"]

View File

@@ -1,10 +0,0 @@
#!/bin/bash
export BITCOIN_KEY="0000000000000000000000000000000000000000000000000000000000000000"
export ETHEREUM_KEY="0000000000000000000000000000000000000000000000000000000000000000"
export MONERO_KEY="0000000000000000000000000000000000000000000000000000000000000000"
export COORDINATOR_KEY="0000000000000000000000000000000000000000000000000000000000000000"
export DB_PATH="./message-queue-db"
serai-message-queue

View File

@@ -1,15 +0,0 @@
# Install ca-certificates
RUN apt install -y ca-certificates
# Switch to a non-root user
RUN useradd --system --create-home --shell /sbin/nologin processor
USER processor
WORKDIR /home/processor
# Copy the Processor binary and relevant license
COPY --from=builder --chown=processor /serai/bin/serai-processor /bin/
COPY --from=builder --chown=processor /serai/AGPL-3.0 .
# Run processor
CMD ["serai-processor"]

View File

@@ -1,73 +0,0 @@
FROM debian:bookworm-slim as mimalloc
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
FROM rust:1.75-slim-bookworm as builder
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Add dev dependencies
RUN apt install -y pkg-config clang
# Dependencies for the Serai node
RUN apt install -y make protobuf-compiler
# Add the wasm toolchain
RUN rustup target add wasm32-unknown-unknown
# Add files for build
ADD common /serai/common
ADD crypto /serai/crypto
ADD coins /serai/coins
ADD message-queue /serai/message-queue
ADD processor /serai/processor
ADD coordinator /serai/coordinator
ADD substrate /serai/substrate
ADD mini /serai/mini
ADD tests /serai/tests
ADD patches /serai/patches
ADD Cargo.toml /serai
ADD Cargo.lock /serai
ADD AGPL-3.0 /serai
WORKDIR /serai
# Mount the caches and build
RUN --mount=type=cache,target=/root/.cargo \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/serai/target \
mkdir /serai/bin && \
cargo build --features "binaries parity-db bitcoin" -p serai-processor && \
mv /serai/target/debug/serai-processor /serai/bin
FROM debian:bookworm-slim as image
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Install ca-certificates
RUN apt install -y ca-certificates
# Switch to a non-root user
RUN useradd --system --create-home --shell /sbin/nologin processor
USER processor
WORKDIR /home/processor
# Copy the Processor binary and relevant license
COPY --from=builder --chown=processor /serai/bin/serai-processor /bin/
COPY --from=builder --chown=processor /serai/AGPL-3.0 .
# Run processor
CMD ["serai-processor"]

View File

@@ -1,2 +0,0 @@
cargo build --features "binaries parity-db bitcoin" -p serai-processor && \
mv /serai/target/debug/serai-processor /serai/bin

View File

@@ -1,73 +0,0 @@
FROM debian:bookworm-slim as mimalloc
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
FROM rust:1.75-slim-bookworm as builder
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Add dev dependencies
RUN apt install -y pkg-config clang
# Dependencies for the Serai node
RUN apt install -y make protobuf-compiler
# Add the wasm toolchain
RUN rustup target add wasm32-unknown-unknown
# Add files for build
ADD common /serai/common
ADD crypto /serai/crypto
ADD coins /serai/coins
ADD message-queue /serai/message-queue
ADD processor /serai/processor
ADD coordinator /serai/coordinator
ADD substrate /serai/substrate
ADD mini /serai/mini
ADD tests /serai/tests
ADD patches /serai/patches
ADD Cargo.toml /serai
ADD Cargo.lock /serai
ADD AGPL-3.0 /serai
WORKDIR /serai
# Mount the caches and build
RUN --mount=type=cache,target=/root/.cargo \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/serai/target \
mkdir /serai/bin && \
cargo build --features "binaries parity-db monero" -p serai-processor && \
mv /serai/target/debug/serai-processor /serai/bin
FROM debian:bookworm-slim as image
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Install ca-certificates
RUN apt install -y ca-certificates
# Switch to a non-root user
RUN useradd --system --create-home --shell /sbin/nologin processor
USER processor
WORKDIR /home/processor
# Copy the Processor binary and relevant license
COPY --from=builder --chown=processor /serai/bin/serai-processor /bin/
COPY --from=builder --chown=processor /serai/AGPL-3.0 .
# Run processor
CMD ["serai-processor"]

View File

@@ -1,2 +0,0 @@
cargo build --features "binaries parity-db monero" -p serai-processor && \
mv /serai/target/debug/serai-processor /serai/bin

View File

@@ -1,13 +0,0 @@
#!/bin/bash
export MESSAGE_QUEUE_KEY="0000000000000000000000000000000000000000000000000000000000000000"
export MESSAGE_QUEUE_RPC="http://127.0.0.1:2287"
export DB_PATH="./processor-bitcoin-db"
export ENTROPY="0001020304050607080910111213141516171819202122232425262728293031"
export NETWORK="bitcoin"
export NETWORK_RPC_LOGIN="serai:seraidex"
export NETWORK_RPC_HOSTNAME="127.0.0.1"
export NETWORK_RPC_PORT="18443"
serai-processor

View File

@@ -1,4 +1,4 @@
FROM rust:1.75.0-slim-bookworm as builder
FROM --platform=linux/amd64 rust:1.75.0-slim-bookworm as builder
# Move to a Debian package snapshot
RUN rm -rf /etc/apt/sources.list.d/debian.sources && \
@@ -13,6 +13,7 @@ RUN apt install clang -y
RUN rustup target add wasm32-unknown-unknown
# Add files for build
ADD patches /serai/patches
ADD common /serai/common
ADD crypto /serai/crypto
ADD coins /serai/coins
@@ -20,9 +21,10 @@ ADD message-queue /serai/message-queue
ADD processor /serai/processor
ADD coordinator /serai/coordinator
ADD substrate /serai/substrate
ADD orchestration/Cargo.toml /serai/orchestration/Cargo.toml
ADD orchestration/src /serai/orchestration/src
ADD mini /serai/mini
ADD tests /serai/tests
ADD patches /serai/patches
ADD Cargo.toml /serai
ADD Cargo.lock /serai
ADD AGPL-3.0 /serai

View File

@@ -1,71 +0,0 @@
FROM debian:bookworm-slim as mimalloc
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
FROM rust:1.75-slim-bookworm as builder
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Add dev dependencies
RUN apt install -y pkg-config clang
# Dependencies for the Serai node
RUN apt install -y make protobuf-compiler
# Add the wasm toolchain
RUN rustup target add wasm32-unknown-unknown
# Add files for build
ADD common /serai/common
ADD crypto /serai/crypto
ADD coins /serai/coins
ADD message-queue /serai/message-queue
ADD processor /serai/processor
ADD coordinator /serai/coordinator
ADD substrate /serai/substrate
ADD mini /serai/mini
ADD tests /serai/tests
ADD patches /serai/patches
ADD Cargo.toml /serai
ADD Cargo.lock /serai
ADD AGPL-3.0 /serai
WORKDIR /serai
# Mount the caches and build
RUN --mount=type=cache,target=/root/.cargo \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/serai/target \
mkdir /serai/bin && \
cargo build --release -p serai-node && \
mv /serai/target/release/serai-node /serai/bin
FROM debian:bookworm-slim as image
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Switch to a non-root user
RUN useradd --system --home /home/serai --shell /sbin/nologin serai
USER serai
WORKDIR /home/serai
# Copy the Serai binary and relevant license
COPY --from=builder --chown=serai /serai/bin/serai-node /bin/
COPY --from=builder --chown=serai /serai/AGPL-3.0 .
# Run node
EXPOSE 30333 9615 9933 9944
CMD ["serai-node"]

View File

@@ -1,2 +0,0 @@
cargo build --release -p serai-node && \
mv /serai/target/release/serai-node /serai/bin

View File

@@ -1,13 +0,0 @@
# Switch to a non-root user
RUN useradd --system --home /home/serai --shell /sbin/nologin serai
USER serai
WORKDIR /home/serai
# Copy the Serai binary and relevant license
COPY --from=builder --chown=serai /serai/bin/serai-node /bin/
COPY --from=builder --chown=serai /serai/AGPL-3.0 .
# Run node
EXPOSE 30333 9615 9933 9944
CMD ["serai-node"]

View File

@@ -1,7 +0,0 @@
#!/bin/bash
if [[ -z $VALIDATOR ]]; then
serai-node --tmp --chain $CHAIN --name $NAME
else
serai-node --tmp --chain $CHAIN --$NAME
fi

View File

@@ -1,14 +1,10 @@
FROM debian:bookworm-slim as mimalloc
use std::{path::Path};
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
use crate::{Network, Os, mimalloc, os, write_dockerfile};
pub fn bitcoin(orchestration_path: &Path, network: Network) {
#[rustfmt::skip]
const DOWNLOAD_BITCOIN: &str = r#"
FROM alpine:latest as bitcoin
ENV BITCOIN_VERSION=26.0
@@ -31,19 +27,30 @@ RUN grep bitcoin-${BITCOIN_VERSION}-$(uname -m)-linux-gnu.tar.gz SHA256SUMS | sh
# Prepare Image
RUN tar xzvf bitcoin-${BITCOIN_VERSION}-$(uname -m)-linux-gnu.tar.gz
RUN mv bitcoin-${BITCOIN_VERSION}/bin/bitcoind .
FROM debian:bookworm-slim as image
"#;
COPY --from=mimalloc libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Switch to a non-root user
RUN useradd --system --create-home --shell /sbin/nologin bitcoin
USER bitcoin
WORKDIR /home/bitcoin
let setup = mimalloc(Os::Debian).to_string() + DOWNLOAD_BITCOIN;
let run_bitcoin = format!(
r#"
COPY --from=bitcoin --chown=bitcoin bitcoind /bin
COPY ./scripts /scripts
EXPOSE 8332 8333 18332 18333 18443 18444
# VOLUME ["/home/bitcoin/.bitcoin"]
EXPOSE 8332 8333
ADD /orchestration/{}/coins/bitcoin/run.sh /
CMD ["/run.sh"]
"#,
network.label()
);
let run =
os(Os::Debian, "RUN mkdir /volume && chown bitcoin:bitcoin /volume", "bitcoin") + &run_bitcoin;
let res = setup + &run;
let mut bitcoin_path = orchestration_path.to_path_buf();
bitcoin_path.push("coins");
bitcoin_path.push("bitcoin");
bitcoin_path.push("Dockerfile");
write_dockerfile(bitcoin_path, &res);
}

View File

@@ -0,0 +1,5 @@
use std::path::Path;
pub fn ethereum(_orchestration_path: &Path) {
// TODO
}

View File

@@ -0,0 +1,8 @@
mod bitcoin;
pub use bitcoin::*;
mod ethereum;
pub use ethereum::*;
mod monero;
pub use monero::*;

View File

@@ -0,0 +1,87 @@
use std::{path::Path};
use crate::{Network, Os, mimalloc, write_dockerfile};
fn monero_internal(
network: Network,
os: Os,
orchestration_path: &Path,
folder: &str,
monero_binary: &str,
ports: &str,
) {
const MONERO_VERSION: &str = "0.18.3.1";
let arch = match std::env::consts::ARCH {
// We probably would run this without issues yet it's not worth needing to provide support for
"x86" | "arm" => panic!("unsupported architecture, please download a 64-bit OS"),
"x86_64" => "x64",
"aarch64" => "armv8",
_ => panic!("unsupported architecture"),
};
#[rustfmt::skip]
let download_monero = format!(r#"
FROM alpine:latest as monero
RUN apk --no-cache add gnupg
# Download Monero
RUN wget https://downloads.getmonero.org/cli/monero-linux-{arch}-v{MONERO_VERSION}.tar.bz2
# Verify Binary -- fingerprint from https://github.com/monero-project/monero-site/issues/1949
ADD orchestration/{}/coins/monero/hashes-v{MONERO_VERSION}.txt .
RUN gpg --keyserver hkp://keyserver.ubuntu.com:80 --keyserver-options no-self-sigs-only --receive-keys 81AC591FE9C4B65C5806AFC3F0AF4D462A0BDF92 && \
gpg --verify hashes-v{MONERO_VERSION}.txt && \
grep "$(sha256sum monero-linux-{arch}-v{MONERO_VERSION}.tar.bz2 | cut -c 1-64)" hashes-v{MONERO_VERSION}.txt
# Extract it
RUN tar -xvjf monero-linux-{arch}-v{MONERO_VERSION}.tar.bz2 --strip-components=1
"#,
network.label(),
);
let setup = mimalloc(os).to_string() + &download_monero;
let run_monero = format!(
r#"
COPY --from=monero --chown=monero {monero_binary} /bin
EXPOSE {ports}
ADD /orchestration/{}/coins/{folder}/run.sh /
CMD ["/run.sh"]
"#,
network.label(),
);
let run = crate::os(
os,
&("RUN mkdir /volume && chown monero /volume\r\n".to_string() +
if os == Os::Alpine { "RUN apk --no-cache add gcompat" } else { "" }),
"monero",
) + &run_monero;
let res = setup + &run;
let mut monero_path = orchestration_path.to_path_buf();
monero_path.push("coins");
monero_path.push(folder);
monero_path.push("Dockerfile");
write_dockerfile(monero_path, &res);
}
pub fn monero(orchestration_path: &Path, network: Network) {
monero_internal(network, Os::Alpine, orchestration_path, "monero", "monerod", "18080 18081")
}
pub fn monero_wallet_rpc(orchestration_path: &Path) {
monero_internal(
Network::Dev,
Os::Debian,
orchestration_path,
"monero-wallet-rpc",
"monero-wallet-rpc",
"18082",
)
}

View File

@@ -0,0 +1,62 @@
use std::{path::Path};
use zeroize::Zeroizing;
use ciphersuite::{group::ff::PrimeField, Ciphersuite, Ristretto};
use crate::{Network, Os, mimalloc, os, build_serai_service, write_dockerfile};
#[allow(clippy::needless_pass_by_value)]
pub fn coordinator(
orchestration_path: &Path,
network: Network,
coordinator_key: Zeroizing<<Ristretto as Ciphersuite>::F>,
serai_key: Zeroizing<<Ristretto as Ciphersuite>::F>,
) {
let db = network.db();
let longer_reattempts = if network == Network::Dev { "longer-reattempts" } else { "" };
let setup = mimalloc(Os::Debian).to_string() +
&build_serai_service(
network.release(),
&format!("{db} {longer_reattempts}"),
"serai-coordinator",
);
const ADDITIONAL_ROOT: &str = r#"
# Install ca-certificates
RUN apt install -y ca-certificates
"#;
let env_vars = [
("MESSAGE_QUEUE_RPC", format!("serai-{}-message-queue", network.label())),
("MESSAGE_QUEUE_KEY", hex::encode(coordinator_key.to_repr())),
("DB_PATH", "./coordinator-db".to_string()),
("SERAI_KEY", hex::encode(serai_key.to_repr())),
("SERAI_HOSTNAME", format!("serai-{}-serai", network.label())),
("RUST_LOG", "serai_coordinator=debug,tributary_chain=debug,tendermint=debug".to_string()),
];
let mut env_vars_str = String::new();
for (env_var, value) in env_vars {
env_vars_str += &format!(r#"{env_var}=${{{env_var}:="{value}"}} "#);
}
let run_coordinator = format!(
r#"
# Copy the Coordinator binary and relevant license
COPY --from=builder --chown=coordinator /serai/bin/serai-coordinator /bin/
COPY --from=builder --chown=coordinator /serai/AGPL-3.0 .
# Run coordinator
CMD {env_vars_str} serai-coordinator
"#
);
let run = os(Os::Debian, ADDITIONAL_ROOT, "coordinator") + &run_coordinator;
let res = setup + &run;
let mut coordinator_path = orchestration_path.to_path_buf();
coordinator_path.push("coordinator");
coordinator_path.push("Dockerfile");
write_dockerfile(coordinator_path, &res);
}

View File

@@ -0,0 +1,47 @@
use std::{collections::HashSet, path::Path, env, process::Command};
use crate::Network;
pub fn build(orchestration_path: &Path, network: Network, name: &str) {
let mut repo_path = env::current_exe().unwrap();
repo_path.pop();
if repo_path.as_path().ends_with("deps") {
repo_path.pop();
}
assert!(repo_path.as_path().ends_with("debug") || repo_path.as_path().ends_with("release"));
repo_path.pop();
assert!(repo_path.as_path().ends_with("target"));
repo_path.pop();
let mut dockerfile_path = orchestration_path.to_path_buf();
if HashSet::from(["bitcoin", "ethereum", "monero", "monero-wallet-rpc"]).contains(name) {
dockerfile_path = dockerfile_path.join("coins");
}
if name.contains("-processor") {
dockerfile_path =
dockerfile_path.join("processor").join(name.split('-').next().unwrap()).join("Dockerfile");
} else {
dockerfile_path = dockerfile_path.join(name).join("Dockerfile");
}
println!("Building {}...", &name);
if !Command::new("docker")
.current_dir(&repo_path)
.arg("build")
.arg("-f")
.arg(dockerfile_path)
.arg(".")
.arg("-t")
.arg(format!("serai-{}-{name}-img", network.label()))
.spawn()
.unwrap()
.wait()
.unwrap()
.success()
{
panic!("failed to build {name}");
}
println!("Built!");
}

445
orchestration/src/main.rs Normal file
View File

@@ -0,0 +1,445 @@
// TODO: Generate randomized RPC credentials for all services
// TODO: Generate keys for a validator and the infra
use core::ops::Deref;
use std::{collections::HashSet, env, path::PathBuf, io::Write, fs, process::Command};
use zeroize::Zeroizing;
use rand_core::{RngCore, SeedableRng, OsRng};
use rand_chacha::ChaCha20Rng;
use transcript::{Transcript, RecommendedTranscript};
use ciphersuite::{
group::{
ff::{Field, PrimeField},
GroupEncoding,
},
Ciphersuite, Ristretto,
};
mod mimalloc;
use mimalloc::mimalloc;
mod coins;
use coins::*;
mod message_queue;
use message_queue::message_queue;
mod processor;
use processor::processor;
mod coordinator;
use coordinator::coordinator;
mod serai;
use serai::serai;
mod docker;
#[global_allocator]
static ALLOCATOR: zalloc::ZeroizingAlloc<std::alloc::System> =
zalloc::ZeroizingAlloc(std::alloc::System);
#[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
pub enum Network {
Dev,
Testnet,
}
impl Network {
pub fn db(&self) -> &'static str {
match self {
Network::Dev => "parity-db",
Network::Testnet => "rocksdb",
}
}
pub fn release(&self) -> bool {
match self {
Network::Dev => false,
Network::Testnet => true,
}
}
pub fn label(&self) -> &'static str {
match self {
Network::Dev => "dev",
Network::Testnet => "testnet",
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
enum Os {
Alpine,
Debian,
}
fn os(os: Os, additional_root: &str, user: &str) -> String {
match os {
Os::Alpine => format!(
r#"
FROM alpine:latest as image
COPY --from=mimalloc-alpine libmimalloc.so /usr/lib
ENV LD_PRELOAD=libmimalloc.so
RUN apk update && apk upgrade
# System user (not a human), shell of nologin, no password assigned
RUN adduser -S -s /sbin/nologin -D {user}
{additional_root}
# Switch to a non-root user
USER {user}
WORKDIR /home/{user}
"#
),
Os::Debian => format!(
r#"
FROM debian:bookworm-slim as image
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
RUN useradd --system --create-home --shell /sbin/nologin {user}
{additional_root}
# Switch to a non-root user
USER {user}
WORKDIR /home/{user}
"#
),
}
}
fn build_serai_service(release: bool, features: &str, package: &str) -> String {
let profile = if release { "release" } else { "debug" };
let profile_flag = if release { "--release" } else { "" };
format!(
r#"
FROM rust:1.75-slim-bookworm as builder
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
# Add dev dependencies
RUN apt install -y pkg-config clang
# Dependencies for the Serai node
RUN apt install -y make protobuf-compiler
# Add the wasm toolchain
RUN rustup target add wasm32-unknown-unknown
# Add files for build
ADD patches /serai/patches
ADD common /serai/common
ADD crypto /serai/crypto
ADD coins /serai/coins
ADD message-queue /serai/message-queue
ADD processor /serai/processor
ADD coordinator /serai/coordinator
ADD substrate /serai/substrate
ADD orchestration/Cargo.toml /serai/orchestration/Cargo.toml
ADD orchestration/src /serai/orchestration/src
ADD mini /serai/mini
ADD tests /serai/tests
ADD Cargo.toml /serai
ADD Cargo.lock /serai
ADD AGPL-3.0 /serai
WORKDIR /serai
# Mount the caches and build
RUN --mount=type=cache,target=/root/.cargo \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/serai/target \
mkdir /serai/bin && \
cargo build {profile_flag} --features "{features}" -p {package} && \
mv /serai/target/{profile}/{package} /serai/bin
"#
)
}
pub fn write_dockerfile(path: PathBuf, dockerfile: &str) {
if let Ok(existing) = fs::read_to_string(&path).as_ref() {
if existing == dockerfile {
return;
}
}
fs::File::create(path).unwrap().write_all(dockerfile.as_bytes()).unwrap();
}
fn orchestration_path(network: Network) -> PathBuf {
let mut repo_path = env::current_exe().unwrap();
repo_path.pop();
assert!(repo_path.as_path().ends_with("debug"));
repo_path.pop();
assert!(repo_path.as_path().ends_with("target"));
repo_path.pop();
let mut orchestration_path = repo_path.clone();
orchestration_path.push("orchestration");
orchestration_path.push(network.label());
orchestration_path
}
fn dockerfiles(network: Network) {
let orchestration_path = orchestration_path(network);
bitcoin(&orchestration_path, network);
ethereum(&orchestration_path);
monero(&orchestration_path, network);
if network == Network::Dev {
monero_wallet_rpc(&orchestration_path);
}
// TODO: Generate infra keys in key_gen, yet service entropy here?
// Generate entropy for the infrastructure keys
let mut entropy = Zeroizing::new([0; 32]);
// Only use actual entropy if this isn't a development environment
if network != Network::Dev {
OsRng.fill_bytes(entropy.as_mut());
}
let mut transcript = RecommendedTranscript::new(b"Serai Orchestrator Transcript");
transcript.append_message(b"entropy", entropy);
let mut new_rng = |label| ChaCha20Rng::from_seed(transcript.rng_seed(label));
let mut message_queue_keys_rng = new_rng(b"message_queue_keys");
let mut key_pair = || {
let key = Zeroizing::new(<Ristretto as Ciphersuite>::F::random(&mut message_queue_keys_rng));
let public = Ristretto::generator() * key.deref();
(key, public)
};
let coordinator_key = key_pair();
let bitcoin_key = key_pair();
let ethereum_key = key_pair();
let monero_key = key_pair();
message_queue(
&orchestration_path,
network,
coordinator_key.1,
bitcoin_key.1,
ethereum_key.1,
monero_key.1,
);
let mut processor_entropy_rng = new_rng(b"processor_entropy");
let mut new_entropy = || {
let mut res = Zeroizing::new([0; 32]);
processor_entropy_rng.fill_bytes(res.as_mut());
res
};
processor(
&orchestration_path,
network,
"bitcoin",
coordinator_key.1,
bitcoin_key.0,
new_entropy(),
);
processor(
&orchestration_path,
network,
"ethereum",
coordinator_key.1,
ethereum_key.0,
new_entropy(),
);
processor(&orchestration_path, network, "monero", coordinator_key.1, monero_key.0, new_entropy());
let serai_key = {
let serai_key = Zeroizing::new(
fs::read(home::home_dir().unwrap().join(".serai").join(network.label()).join("key"))
.expect("couldn't read key for this network"),
);
let mut serai_key_repr =
Zeroizing::new(<<Ristretto as Ciphersuite>::F as PrimeField>::Repr::default());
serai_key_repr.as_mut().copy_from_slice(serai_key.as_ref());
Zeroizing::new(<Ristretto as Ciphersuite>::F::from_repr(*serai_key_repr).unwrap())
};
coordinator(&orchestration_path, network, coordinator_key.0, serai_key);
serai(&orchestration_path, network);
}
fn key_gen(network: Network) {
let serai_dir = home::home_dir().unwrap().join(".serai").join(network.label());
let key_file = serai_dir.join("key");
if fs::File::open(&key_file).is_ok() {
println!("already created key");
return;
}
let key = <Ristretto as Ciphersuite>::F::random(&mut OsRng);
let _ = fs::create_dir_all(&serai_dir);
fs::write(key_file, key.to_repr()).expect("couldn't write key");
println!(
"Public Key: {}",
hex::encode((<Ristretto as Ciphersuite>::generator() * key).to_bytes())
);
}
fn start(network: Network, services: HashSet<String>) {
// Create the serai network
Command::new("docker")
.arg("network")
.arg("create")
.arg("--driver")
.arg("bridge")
.arg("serai")
.output()
.unwrap();
for service in services {
println!("Starting {service}");
let name = match service.as_ref() {
"serai" => "serai",
"coordinator" => "coordinator",
"message-queue" => "message-queue",
"bitcoin-daemon" => "bitcoin",
"bitcoin-processor" => "bitcoin-processor",
"monero-daemon" => "monero",
"monero-processor" => "monero-processor",
"monero-wallet-rpc" => "monero-wallet-rpc",
_ => panic!("starting unrecognized service"),
};
// Build it
println!("Building {service}");
docker::build(&orchestration_path(network), network, name);
let docker_name = format!("serai-{}-{name}", network.label());
let docker_image = format!("{docker_name}-img");
if !Command::new("docker")
.arg("container")
.arg("inspect")
.arg(&docker_name)
.status()
.unwrap()
.success()
{
// Create the docker container
println!("Creating new container for {service}");
let volume = format!("serai-{}-{name}-volume:/volume", network.label());
let mut command = Command::new("docker");
let command = command.arg("create").arg("--name").arg(&docker_name);
let command = command.arg("--network").arg("serai");
let command = match name {
"bitcoin" => {
if network == Network::Dev {
command.arg("-p").arg("8332:8332")
} else {
command.arg("--volume").arg(volume)
}
}
"monero" => {
if network == Network::Dev {
command.arg("-p").arg("18081:18081")
} else {
command.arg("--volume").arg(volume)
}
}
"monero-wallet-rpc" => {
assert_eq!(network, Network::Dev, "monero-wallet-rpc is only for dev");
command.arg("-p").arg("18082:18082")
}
_ => command,
};
assert!(
command.arg(docker_image).status().unwrap().success(),
"couldn't create the container"
);
}
// Start it
// TODO: Check it successfully started
println!("Starting existing container for {service}");
let _ = Command::new("docker").arg("start").arg(docker_name).output();
}
}
fn main() {
let help = || -> ! {
println!(
r#"
Serai Orchestrator v0.0.1
Commands:
key_gen *network*
Generates a key for the validator.
setup *network*
Generate infrastructure keys and the Dockerfiles for every Serai service.
start *network* [service1, service2...]
Start the specified services for the specified network ("dev" or "testnet").
- `serai`
- `coordinator`
- `message-queue`
- `bitcoin-daemon`
- `bitcoin-processor`
- `monero-daemon`
- `monero-processor`
- `monero-wallet-rpc` (if "dev")
are valid services.
`*network*-processor` will automatically start `*network*-daemon`.
"#
);
std::process::exit(1);
};
let mut args = env::args();
args.next();
let command = args.next();
let network = match args.next().as_ref().map(AsRef::as_ref) {
Some("dev") => Network::Dev,
Some("testnet") => Network::Testnet,
Some(_) => panic!(r#"unrecognized network. only "dev" and "testnet" are recognized"#),
None => help(),
};
match command.as_ref().map(AsRef::as_ref) {
Some("key_gen") => {
key_gen(network);
}
Some("setup") => {
dockerfiles(network);
}
Some("start") => {
let mut services = HashSet::new();
for arg in args {
if let Some(ext_network) = arg.strip_suffix("-processor") {
services.insert(ext_network.to_string() + "-daemon");
}
services.insert(arg);
}
start(network, services);
}
_ => help(),
}
}

View File

@@ -0,0 +1,51 @@
use std::{path::Path};
use ciphersuite::{group::GroupEncoding, Ciphersuite, Ristretto};
use crate::{Network, Os, mimalloc, os, build_serai_service, write_dockerfile};
pub fn message_queue(
orchestration_path: &Path,
network: Network,
coordinator_key: <Ristretto as Ciphersuite>::G,
bitcoin_key: <Ristretto as Ciphersuite>::G,
ethereum_key: <Ristretto as Ciphersuite>::G,
monero_key: <Ristretto as Ciphersuite>::G,
) {
let setup = mimalloc(Os::Debian).to_string() +
&build_serai_service(network.release(), network.db(), "serai-message-queue");
let env_vars = [
("COORDINATOR_KEY", hex::encode(coordinator_key.to_bytes())),
("BITCOIN_KEY", hex::encode(bitcoin_key.to_bytes())),
("ETHEREUM_KEY", hex::encode(ethereum_key.to_bytes())),
("MONERO_KEY", hex::encode(monero_key.to_bytes())),
("DB_PATH", "./message-queue-db".to_string()),
("RUST_LOG", "serai_message_queue=trace".to_string()),
];
let mut env_vars_str = String::new();
for (env_var, value) in env_vars {
env_vars_str += &format!(r#"{env_var}=${{{env_var}:="{value}"}} "#);
}
let run_message_queue = format!(
r#"
# Copy the Message Queue binary and relevant license
COPY --from=builder --chown=messagequeue /serai/bin/serai-message-queue /bin
COPY --from=builder --chown=messagequeue /serai/AGPL-3.0 .
# Run message-queue
EXPOSE 2287
CMD {env_vars_str} serai-message-queue
"#
);
let run = os(Os::Debian, "", "messagequeue") + &run_message_queue;
let res = setup + &run;
let mut message_queue_path = orchestration_path.to_path_buf();
message_queue_path.push("message-queue");
message_queue_path.push("Dockerfile");
write_dockerfile(message_queue_path, &res);
}

View File

@@ -0,0 +1,36 @@
use crate::Os;
pub fn mimalloc(os: Os) -> &'static str {
const ALPINE_MIMALLOC: &str = r#"
FROM alpine:latest as mimalloc-alpine
RUN apk update && apk upgrade && apk --no-cache add gcc g++ libc-dev make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
"#;
const DEBIAN_MIMALLOC: &str = r#"
FROM debian:bookworm-slim as mimalloc-debian
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
"#;
match os {
Os::Alpine => ALPINE_MIMALLOC,
Os::Debian => DEBIAN_MIMALLOC,
}
}

View File

@@ -0,0 +1,78 @@
use std::{path::Path};
use zeroize::Zeroizing;
use ciphersuite::{group::ff::PrimeField, Ciphersuite, Ristretto};
use crate::{Network, Os, mimalloc, os, build_serai_service, write_dockerfile};
#[allow(clippy::needless_pass_by_value)]
pub fn processor(
orchestration_path: &Path,
network: Network,
coin: &'static str,
_coordinator_key: <Ristretto as Ciphersuite>::G,
coin_key: Zeroizing<<Ristretto as Ciphersuite>::F>,
entropy: Zeroizing<[u8; 32]>,
) {
let setup = mimalloc(Os::Debian).to_string() +
&build_serai_service(
network.release(),
&format!("binaries {} {coin}", network.db()),
"serai-processor",
);
const ADDITIONAL_ROOT: &str = r#"
# Install ca-certificates
RUN apt install -y ca-certificates
"#;
// TODO: Randomly generate these
const RPC_USER: &str = "serai";
const RPC_PASS: &str = "seraidex";
// TODO: Isolate networks
let hostname = format!("serai-{}-{coin}", network.label());
let port = match coin {
"bitcoin" => 8332,
"ethereum" => return, // TODO
"monero" => 18081,
_ => panic!("unrecognized external network"),
};
let env_vars = [
("MESSAGE_QUEUE_RPC", format!("serai-{}-message_queue", network.label())),
("MESSAGE_QUEUE_KEY", hex::encode(coin_key.to_repr())),
("ENTROPY", hex::encode(entropy.as_ref())),
("NETWORK", coin.to_string()),
("NETWORK_RPC_LOGIN", format!("{RPC_USER}:{RPC_PASS}")),
("NETWORK_RPC_HOSTNAME", hostname),
("NETWORK_RPC_PORT", format!("{port}")),
("DB_PATH", "./processor-db".to_string()),
("RUST_LOG", "serai_processor=debug".to_string()),
];
let mut env_vars_str = String::new();
for (env_var, value) in env_vars {
env_vars_str += &format!(r#"{env_var}=${{{env_var}:="{value}"}} "#);
}
let run_processor = format!(
r#"
# Copy the Processor binary and relevant license
COPY --from=builder --chown=processor /serai/bin/serai-processor /bin/
COPY --from=builder --chown=processor /serai/AGPL-3.0 .
# Run processor
CMD {env_vars_str} serai-processor
"#
);
let run = os(Os::Debian, ADDITIONAL_ROOT, "processor") + &run_processor;
let res = setup + &run;
let mut processor_path = orchestration_path.to_path_buf();
processor_path.push("processor");
processor_path.push(coin);
processor_path.push("Dockerfile");
write_dockerfile(processor_path, &res);
}

View File

@@ -0,0 +1,33 @@
use std::{path::Path};
use crate::{Network, Os, mimalloc, os, build_serai_service, write_dockerfile};
pub fn serai(orchestration_path: &Path, network: Network) {
// Always builds in release for performance reasons
let setup = mimalloc(Os::Debian).to_string() + &build_serai_service(true, "", "serai-node");
// TODO: Review the ports exposed here
let run_serai = format!(
r#"
# Copy the Serai binary and relevant license
COPY --from=builder --chown=serai /serai/bin/serai-node /bin/
COPY --from=builder --chown=serai /serai/AGPL-3.0 .
# Run the Serai node
EXPOSE 30333 9615 9933 9944
ADD /orchestration/{}/serai/run.sh /
CMD ["/run.sh"]
"#,
network.label()
);
let run = os(Os::Debian, "", "serai") + &run_serai;
let res = setup + &run;
let mut serai_path = orchestration_path.to_path_buf();
serai_path.push("serai");
serai_path.push("Dockerfile");
write_dockerfile(serai_path, &res);
}

View File

@@ -0,0 +1,9 @@
#!/bin/sh
RPC_USER="${RPC_USER:=serai}"
RPC_PASS="${RPC_PASS:=seraidex}"
bitcoind -txindex -testnet -port=8333 \
-rpcuser=$RPC_USER -rpcpassword=$RPC_PASS \
-rpcbind=0.0.0.0 -rpcallowip=0.0.0.0/0 -rpcport=8332 \
--datadir=/volume

View File

@@ -0,0 +1,3 @@
#!/bin/sh
exit 1

View File

@@ -0,0 +1,49 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
# This GPG-signed message exists to confirm the SHA256 sums of Monero binaries.
#
# Please verify the signature against the key for binaryFate in the
# source code repository (/utils/gpg_keys).
#
#
## CLI
fc6a93eabc3fd524ff1ceedbf502b8d43c61a7805728b7ed5f9e7204e26b91f5 monero-android-armv7-v0.18.3.1.tar.bz2
6d9c7d31942dde86ce39757fd55027448ceb260b60b3c8d32ed018211eb4f1e4 monero-android-armv8-v0.18.3.1.tar.bz2
3e2d9964a9e52c146b4d26b5eb53e691b3ba88e2468dc4fbfee4c318a367a90e monero-freebsd-x64-v0.18.3.1.tar.bz2
2ea2c8898cbab88f49423f4f6c15f2a94046cb4bbe827493dd061edc0fd5f1ca monero-linux-armv7-v0.18.3.1.tar.bz2
445032e88dc07e51ac5fff7034752be530d1c4117d8d605100017bcd87c7b21f monero-linux-armv8-v0.18.3.1.tar.bz2
23af572fdfe3459b9ab97e2e9aa7e3c11021c955d6064b801a27d7e8c21ae09d monero-linux-x64-v0.18.3.1.tar.bz2
c8553558dece79a4c23e1114fdf638b15e46899d7cf0af41457f18bbbee83986 monero-linux-x86-v0.18.3.1.tar.bz2
915288b023cb5811e626e10052adc6ac5323dd283c5a25b91059b0fb86a21fb6 monero-mac-armv8-v0.18.3.1.tar.bz2
7f8bd9364ef16482b418aa802a65be0e4cc660c794bb5d77b2d17bc84427883a monero-mac-x64-v0.18.3.1.tar.bz2
35dcc4bee4caad3442659d37837e0119e4649a77f2e3b5e80dd6d9b8fc4fb6ad monero-win-x64-v0.18.3.1.zip
5bcbeddce32b50ebe18289d0560ebf779441526ec84d73b6a83094f092365271 monero-win-x86-v0.18.3.1.zip
4d217e2aa61a6f105054dddbab52c0301f52766e88783de2480316c5a8661e0c monero-source-v0.18.3.1.tar.bz2
#
## GUI
792271147ad71a2eaa02fc37d61d72cd92f2f9857dcc09ea032f48481f87e279 monero-gui-install-win-x64-v0.18.3.1.exe
06f6e600db51205116d52522964cf9b96337d7b5cb1e101730ccb0039b30e15b monero-gui-linux-x64-v0.18.3.1.tar.bz2
b0c8d07f8d8ade49d08419b196ddb9f691717ef05cae066e220db707e4dfedc4 monero-gui-mac-armv8-v0.18.3.1.dmg
8ae53f0908f9bc03452f23d5092bf1eb1d2ad9f1224580486b486cf0a2020401 monero-gui-mac-x64-v0.18.3.1.dmg
f263ce5863fd87ea959f79420e28ef0002649fa02bd57ae34efda926bdcf1a70 monero-gui-win-x64-v0.18.3.1.zip
045a84e343423a62ed617f200465b290267ff0a071375fdfc49ea02dcdb1a785 monero-gui-source-v0.18.3.1.tar.bz2
#
#
# ~binaryFate
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEgaxZH+nEtlxYBq/D8K9NRioL35IFAmUljRIACgkQ8K9NRioL
35IJjBAAqzoh4saUkTPWPAXOdLMLEcpJ5TvzQpImBNKzegjVMV4VYm+0llZw5uMP
/9OvkW7Ho5nLfslsF+C/qkfTc+EXm4h7J7iOyIpj8sr52RttfXjecEla5Ah75qZk
X9puVFd18nEDMktrNp4tkx/WQvzxpPAnsIRwsrX912rOc0jPwqCZ1DFn5JsB4KsK
dSjyWdRjKuxbMv+97GEpxiG6wAkN5lnEzj9LFZcaOLHAtBhxfZhwDBWTWFdPp2cM
TL3dNkMgpONGBEpX/7PJTFbmfba8gRZy7jXFVI0KqLLJC+6vpfGGr+NSX1zdIqrR
Z0Dvl3AA43E/Cjl5ma4L381wEul+7qFB2HN+fB1S6nNHzn/zWVepjD4bvgPvQiVI
d7PK5jhrX9c0XkR4kQrtPoONJW6blhoGiM2CWCfrifXzGA51WvZ1Vc5s8yuUG2p7
e5+7c6AWFqOIP/8RexPx4ViYmFqE59P9/JCs+JRNgo7A2/JHGCyjdZalmt3/79Bf
aBmfv5mcPe/zPbngU9W6DfKbysYozv2/IQ5nUknU8Qgnaq3PADN2Xx5GlAsC69e0
tZid955OAmtVzMjNO0KPiGEea2t/a8f3lSir2Irdz/LwIv8RID5/VeyafnUoOvGl
kv15IYnJAQ7vjlskoE/Tzaym/LSaILOHzU5CskI/HjG+7P50mo4=
=6gw4
-----END PGP SIGNATURE-----

View File

@@ -0,0 +1,11 @@
#!/bin/sh
RPC_USER="${RPC_USER:=serai}"
RPC_PASS="${RPC_PASS:=seraidex}"
# Run Monero
monerod --non-interactive --stagenet \
--no-zmq --rpc-bind-ip=0.0.0.0 --rpc-bind-port=18081 --confirm-external-bind \
--rpc-access-control-origins "*" --disable-rpc-ban \
--rpc-login=$RPC_USER:$RPC_PASS \
--data-dir=/volume

Some files were not shown because too many files have changed in this diff Show More