mirror of
https://github.com/logos-blockchain/logos-blockchain-circuits.git
synced 2026-02-16 19:23:08 +00:00
feat(build): add scripts and Dockerfile to enable easy build on RPi
This commit is contained in:
parent
0674fa2ac0
commit
8cd3be1cce
37
.dockerignore
Normal file
37
.dockerignore
Normal file
@ -0,0 +1,37 @@
|
||||
# Docker build context ignore file
|
||||
# Exclude files that don't need to be in the Docker build context
|
||||
|
||||
# Build artifacts
|
||||
nomos-circuits-*/
|
||||
prover-*/
|
||||
verifier-*/
|
||||
witness-generators/
|
||||
proving-keys/
|
||||
*.tar.gz
|
||||
|
||||
# Powers of Tau file (large, will be downloaded inside if needed)
|
||||
*.ptau
|
||||
|
||||
# Circom build (will be done inside container)
|
||||
circom/
|
||||
|
||||
# Generated circuit files
|
||||
*_cpp/
|
||||
*.r1cs
|
||||
*.zkey
|
||||
*_verification_key.json
|
||||
|
||||
# Git
|
||||
.git/
|
||||
.github/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Cache
|
||||
.docker-cache/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
11
.github/resources/prover/Makefile
vendored
11
.github/resources/prover/Makefile
vendored
@ -43,6 +43,17 @@ host_arm64:
|
||||
cmake .. -DTARGET_PLATFORM=aarch64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_arm64 && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
host_linux_arm64_static:
|
||||
rm -rf build_prover && mkdir build_prover && cd build_prover && \
|
||||
cmake .. \
|
||||
-DTARGET_PLATFORM=aarch64 \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=../package \
|
||||
-DCMAKE_EXE_LINKER_FLAGS="-static -static-libstdc++ -static-libgcc -no-pie" \
|
||||
-DOpenMP_gomp_LIBRARY=$(LIBGOMP_A) \
|
||||
-DCMAKE_PREFIX_PATH=depends/gmp/package && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
android:
|
||||
rm -rf build_prover_android && mkdir build_prover_android && cd build_prover_android && \
|
||||
cmake .. -DTARGET_PLATFORM=ANDROID -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android -DBUILD_TESTS=OFF -DUSE_OPENMP=OFF && \
|
||||
|
||||
81
scripts/Dockerfile
Normal file
81
scripts/Dockerfile
Normal file
@ -0,0 +1,81 @@
|
||||
# Dockerfile for building Logos Blockchain Circuits
|
||||
# This provides an isolated build environment to avoid polluting the host system
|
||||
#
|
||||
# Usage:
|
||||
# docker build -t logos-circuits-builder .
|
||||
# docker run --rm -v $(pwd):/workspace logos-circuits-builder [OPTIONS]
|
||||
#
|
||||
# Or use the helper script:
|
||||
# ./docker-build.sh [OPTIONS]
|
||||
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# Avoid interactive prompts during package installation
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
libgmp-dev \
|
||||
libsodium-dev \
|
||||
nasm \
|
||||
curl \
|
||||
m4 \
|
||||
nlohmann-json3-dev \
|
||||
git \
|
||||
xxd \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Node.js 20.x
|
||||
RUN mkdir -p /etc/apt/keyrings \
|
||||
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
|
||||
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install snarkjs globally
|
||||
RUN npm install -g snarkjs@latest
|
||||
|
||||
# Install Rust
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
|
||||
# Clone and build Circom
|
||||
RUN git clone https://github.com/iden3/circom.git /opt/circom \
|
||||
&& cd /opt/circom \
|
||||
&& RUSTFLAGS="-A dead_code" cargo build --release \
|
||||
&& RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
|
||||
# Verify installations
|
||||
RUN circom --version && node --version && npm --version
|
||||
|
||||
# Set up working directory
|
||||
WORKDIR /workspace
|
||||
|
||||
# Create entrypoint script
|
||||
RUN echo '#!/bin/bash\n\
|
||||
set -e\n\
|
||||
cd /workspace\n\
|
||||
\n\
|
||||
# Mark all directories as safe for git (needed for mounted volumes with different ownership)\n\
|
||||
# This is safe in a container context where we control the environment\n\
|
||||
git config --global --add safe.directory "*"\n\
|
||||
\n\
|
||||
# Initialize git submodules if needed (including nested submodules like rapidsnark/depends/*)\n\
|
||||
if [ -f .gitmodules ]; then\n\
|
||||
git submodule update --init --recursive\n\
|
||||
fi\n\
|
||||
\n\
|
||||
# Run the build script with provided arguments\n\
|
||||
# Skip deps, circom, and snarkjs as they are already installed in the container\n\
|
||||
exec ./scripts/build-local.sh --skip-deps --skip-circom --skip-snarkjs "$@"\n\
|
||||
' > /entrypoint.sh && chmod +x /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
||||
# Default: run full build (pass --help to see options)
|
||||
CMD []
|
||||
103
scripts/README.md
Normal file
103
scripts/README.md
Normal file
@ -0,0 +1,103 @@
|
||||
# Scripts Directory
|
||||
|
||||
This directory contains build scripts for compiling the Logos Blockchain Circuits.
|
||||
|
||||
## Files
|
||||
|
||||
### [`build-local.sh`](build-local.sh)
|
||||
|
||||
The main local build script that replicates the GitHub Actions workflow for local execution on Linux. It handles the complete build pipeline including:
|
||||
|
||||
- Installing system dependencies (build-essential, cmake, libgmp-dev, etc.)
|
||||
- Installing Rust and Circom compiler
|
||||
- Installing Node.js and snarkjs
|
||||
- Downloading Powers of Tau file (~3GB)
|
||||
- Generating proving keys for all circuits (pol, poq, zksign, poc)
|
||||
- Compiling witness generators
|
||||
- Building prover and verifier from rapidsnark
|
||||
- Creating the final release bundle
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
./build-local.sh [OPTIONS]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--version VERSION` | Set the version (default: v0.0.0-local) |
|
||||
| `--skip-deps` | Skip installing system dependencies |
|
||||
| `--skip-circom` | Skip Circom installation |
|
||||
| `--skip-snarkjs` | Skip snarkjs installation |
|
||||
| `--skip-ptau` | Skip Powers of Tau download |
|
||||
| `--skip-proving-keys` | Skip proving key generation |
|
||||
| `--skip-prover` | Skip prover/verifier compilation |
|
||||
| `--skip-witness` | Skip witness generator compilation |
|
||||
| `--circuit CIRCUIT` | Build only specified circuit (pol, poq, zksign, poc) |
|
||||
| `--clean` | Clean all build artifacts before building |
|
||||
| `--help` | Show help message |
|
||||
|
||||
### [`docker-build.sh`](docker-build.sh)
|
||||
|
||||
A wrapper script that runs the build inside a Docker container to avoid polluting your host system with dependencies.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
./docker-build.sh [OPTIONS]
|
||||
```
|
||||
|
||||
All options are passed directly to `build-local.sh` inside the container.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
./docker-build.sh # Full build
|
||||
./docker-build.sh --help # Show build-local.sh help
|
||||
./docker-build.sh --circuit pol # Build only PoL circuit
|
||||
./docker-build.sh --clean # Clean and rebuild
|
||||
./docker-build.sh --skip-ptau # Skip Powers of Tau download
|
||||
```
|
||||
|
||||
**Environment Variables:**
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `DOCKER_BUILD=0` | Skip rebuilding the Docker image |
|
||||
| `DOCKER_NOCACHE=1` | Force rebuild Docker image without cache |
|
||||
| `SKIP_INSTALL=true` | Install artifacts to `~/.nomos-circuits` after build |
|
||||
|
||||
### [`Dockerfile`](Dockerfile)
|
||||
|
||||
Defines the Docker build environment based on Ubuntu 22.04 with all required dependencies pre-installed:
|
||||
|
||||
- Build tools (gcc, cmake, make, nasm)
|
||||
- Libraries (libgmp, libsodium, nlohmann-json)
|
||||
- Node.js 20.x and snarkjs
|
||||
- Rust and Circom compiler
|
||||
|
||||
The container automatically initializes git submodules and runs the build with `--skip-deps --skip-circom --skip-snarkjs` since these are pre-installed.
|
||||
|
||||
## Output
|
||||
|
||||
The build produces a tarball named `nomos-circuits-{VERSION}-{OS}-{ARCH}.tar.gz` containing:
|
||||
|
||||
```
|
||||
nomos-circuits-v0.0.0-local-linux-x86_64/
|
||||
├── VERSION
|
||||
├── prover # Rapidsnark prover binary
|
||||
├── verifier # Rapidsnark verifier binary
|
||||
├── pol/
|
||||
│ ├── witness_generator
|
||||
│ ├── witness_generator.dat
|
||||
│ ├── proving_key.zkey
|
||||
│ └── verification_key.json
|
||||
├── poq/
|
||||
│ └── ...
|
||||
├── zksign/
|
||||
│ └── ...
|
||||
└── poc/
|
||||
└── ...
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Local build:** Linux x86_64 or aarch64, root access for dependencies
|
||||
- **Docker build:** Docker installed and running
|
||||
707
scripts/build-local.sh
Executable file
707
scripts/build-local.sh
Executable file
@ -0,0 +1,707 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Local Build Script for Logos Blockchain Circuits
|
||||
# This script replicates the GitHub Actions workflow for local execution on Linux.
|
||||
#
|
||||
# Usage:
|
||||
# ./build-local.sh [OPTIONS]
|
||||
#
|
||||
# Options:
|
||||
# --version VERSION Set the version (default: v0.0.0-local)
|
||||
# --skip-deps Skip installing system dependencies
|
||||
# --skip-circom Skip Circom installation (assumes circom is in PATH)
|
||||
# --skip-snarkjs Skip snarkjs installation (assumes snarkjs is in PATH)
|
||||
# --skip-ptau Skip Powers of Tau download (assumes file exists)
|
||||
# --skip-proving-keys Skip proving key generation (assumes they exist)
|
||||
# --skip-prover Skip prover/verifier compilation
|
||||
# --skip-witness Skip witness generator compilation
|
||||
# --circuit CIRCUIT Build only specified circuit (pol, poq, zksign, poc)
|
||||
# --clean Clean all build artifacts before building
|
||||
# --help Show this help message
|
||||
#
|
||||
# Requirements:
|
||||
# - Linux x86_64
|
||||
# - Root access (for installing dependencies) or pre-installed dependencies
|
||||
# - Internet connection (for downloading dependencies)
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
# Default configuration
|
||||
VERSION="v0.0.0-local"
|
||||
OS="linux"
|
||||
# Auto-detect architecture
|
||||
MACHINE_ARCH="$(uname -m)"
|
||||
case "$MACHINE_ARCH" in
|
||||
x86_64|amd64)
|
||||
ARCH="x86_64"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
ARCH="aarch64"
|
||||
;;
|
||||
*)
|
||||
ARCH="$MACHINE_ARCH"
|
||||
;;
|
||||
esac
|
||||
PTAU_URL="https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_17.ptau"
|
||||
PTAU_FILE="powersOfTau28_hez_final_17.ptau"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Flags
|
||||
SKIP_DEPS=false
|
||||
SKIP_CIRCOM=false
|
||||
SKIP_SNARKJS=false
|
||||
SKIP_PTAU=false
|
||||
SKIP_PROVING_KEYS=false
|
||||
SKIP_PROVER=false
|
||||
SKIP_WITNESS=false
|
||||
CLEAN=false
|
||||
SINGLE_CIRCUIT=""
|
||||
|
||||
# Circuit definitions
|
||||
declare -A CIRCUITS=(
|
||||
["pol"]="mantle/pol.circom:pol:PoL"
|
||||
["poq"]="blend/poq.circom:poq:PoQ"
|
||||
["zksign"]="mantle/signature.circom:signature:ZKSign"
|
||||
["poc"]="mantle/poc.circom:poc:PoC"
|
||||
)
|
||||
|
||||
# Parse command line arguments
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--version)
|
||||
VERSION="$2"
|
||||
shift 2
|
||||
;;
|
||||
--skip-deps)
|
||||
SKIP_DEPS=true
|
||||
shift
|
||||
;;
|
||||
--skip-circom)
|
||||
SKIP_CIRCOM=true
|
||||
shift
|
||||
;;
|
||||
--skip-snarkjs)
|
||||
SKIP_SNARKJS=true
|
||||
shift
|
||||
;;
|
||||
--skip-ptau)
|
||||
SKIP_PTAU=true
|
||||
shift
|
||||
;;
|
||||
--skip-proving-keys)
|
||||
SKIP_PROVING_KEYS=true
|
||||
shift
|
||||
;;
|
||||
--skip-prover)
|
||||
SKIP_PROVER=true
|
||||
shift
|
||||
;;
|
||||
--skip-witness)
|
||||
SKIP_WITNESS=true
|
||||
shift
|
||||
;;
|
||||
--circuit)
|
||||
SINGLE_CIRCUIT="$2"
|
||||
shift 2
|
||||
;;
|
||||
--clean)
|
||||
CLEAN=true
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
head -n 25 "$0" | tail -n +2 | sed 's/^# //' | sed 's/^#//'
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Clean build artifacts
|
||||
clean_artifacts() {
|
||||
log_info "Cleaning build artifacts..."
|
||||
|
||||
# Clean circom build directories
|
||||
rm -rf circom/ 2>/dev/null || true
|
||||
|
||||
# Clean rapidsnark build
|
||||
if [[ -d "rapidsnark" ]]; then
|
||||
cd rapidsnark
|
||||
make clean 2>/dev/null || true
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# Clean circuit build directories
|
||||
for circuit_key in "${!CIRCUITS[@]}"; do
|
||||
IFS=':' read -r circuit_path circuit_name display_name <<< "${CIRCUITS[$circuit_key]}"
|
||||
circuit_dir=$(dirname "$circuit_path")
|
||||
circuit_filestem=$(basename "$circuit_path" .circom)
|
||||
|
||||
rm -rf "${circuit_dir}/${circuit_filestem}_cpp" 2>/dev/null || true
|
||||
rm -f "${circuit_dir}/${circuit_filestem}.r1cs" 2>/dev/null || true
|
||||
rm -f "${circuit_dir}/${circuit_key}.zkey" 2>/dev/null || true
|
||||
rm -f "${circuit_dir}/${circuit_key}-0.zkey" 2>/dev/null || true
|
||||
rm -f "${circuit_dir}/${circuit_key}_verification_key.json" 2>/dev/null || true
|
||||
done
|
||||
|
||||
# Clean bundle directories
|
||||
rm -rf nomos-circuits-* 2>/dev/null || true
|
||||
rm -rf prover-* 2>/dev/null || true
|
||||
rm -rf verifier-* 2>/dev/null || true
|
||||
rm -rf witness-generators/ 2>/dev/null || true
|
||||
rm -rf proving-keys/ 2>/dev/null || true
|
||||
|
||||
log_success "Cleaned build artifacts"
|
||||
}
|
||||
|
||||
# Check system requirements
|
||||
check_requirements() {
|
||||
log_info "Checking system requirements..."
|
||||
|
||||
# Check OS
|
||||
if [[ "$(uname -s)" != "Linux" ]]; then
|
||||
log_error "This script is designed for Linux. Detected: $(uname -s)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check architecture
|
||||
if [[ "$ARCH" != "x86_64" && "$ARCH" != "aarch64" ]]; then
|
||||
log_warn "This script supports x86_64 and aarch64. Detected: $(uname -m)"
|
||||
else
|
||||
log_info "Detected architecture: $ARCH"
|
||||
fi
|
||||
|
||||
log_success "System requirements check passed"
|
||||
}
|
||||
|
||||
# Install system dependencies
|
||||
install_dependencies() {
|
||||
if [[ "$SKIP_DEPS" == true ]]; then
|
||||
log_info "Skipping system dependency installation..."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Installing system dependencies..."
|
||||
|
||||
# Detect package manager
|
||||
if command -v apt-get &> /dev/null; then
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
libgmp-dev \
|
||||
libsodium-dev \
|
||||
nasm \
|
||||
curl \
|
||||
m4 \
|
||||
nlohmann-json3-dev \
|
||||
git
|
||||
elif command -v dnf &> /dev/null; then
|
||||
sudo dnf install -y \
|
||||
gcc \
|
||||
gcc-c++ \
|
||||
make \
|
||||
cmake \
|
||||
gmp-devel \
|
||||
libsodium-devel \
|
||||
nasm \
|
||||
curl \
|
||||
m4 \
|
||||
json-devel \
|
||||
git
|
||||
elif command -v pacman &> /dev/null; then
|
||||
sudo pacman -S --noconfirm \
|
||||
base-devel \
|
||||
cmake \
|
||||
gmp \
|
||||
libsodium \
|
||||
nasm \
|
||||
curl \
|
||||
m4 \
|
||||
nlohmann-json \
|
||||
git
|
||||
else
|
||||
log_error "Unsupported package manager. Please install dependencies manually:"
|
||||
log_error " build-essential, cmake, libgmp-dev, libsodium-dev, nasm, curl, m4, nlohmann-json3-dev, git"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "System dependencies installed"
|
||||
}
|
||||
|
||||
# Install Rust and Circom
|
||||
install_circom() {
|
||||
if [[ "$SKIP_CIRCOM" == true ]]; then
|
||||
log_info "Skipping Circom installation..."
|
||||
if ! command -v circom &> /dev/null; then
|
||||
log_error "circom not found in PATH. Please install it or remove --skip-circom"
|
||||
exit 1
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Installing Circom..."
|
||||
|
||||
# Check if Rust is installed
|
||||
if ! command -v cargo &> /dev/null; then
|
||||
log_info "Installing Rust..."
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
fi
|
||||
|
||||
# Clone and build Circom
|
||||
if [[ ! -d "circom" ]]; then
|
||||
git clone https://github.com/iden3/circom.git
|
||||
fi
|
||||
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
cd ..
|
||||
|
||||
# Verify installation
|
||||
circom --version
|
||||
|
||||
log_success "Circom installed successfully"
|
||||
}
|
||||
|
||||
# Install Node.js and snarkjs
|
||||
install_snarkjs() {
|
||||
if [[ "$SKIP_SNARKJS" == true ]]; then
|
||||
log_info "Skipping snarkjs installation..."
|
||||
if ! command -v snarkjs &> /dev/null; then
|
||||
log_error "snarkjs not found in PATH. Please install it or remove --skip-snarkjs"
|
||||
exit 1
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Installing snarkjs..."
|
||||
|
||||
# Check if Node.js is installed
|
||||
if ! command -v node &> /dev/null; then
|
||||
log_info "Installing Node.js..."
|
||||
|
||||
# Use NodeSource to install Node.js 20
|
||||
if command -v apt-get &> /dev/null; then
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
elif command -v dnf &> /dev/null; then
|
||||
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
|
||||
sudo dnf install -y nodejs
|
||||
else
|
||||
log_error "Please install Node.js 20 manually"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install snarkjs globally
|
||||
sudo npm install -g snarkjs@latest
|
||||
|
||||
# Verify installation
|
||||
snarkjs --version || true
|
||||
|
||||
log_success "snarkjs installed successfully"
|
||||
}
|
||||
|
||||
# Initialize git submodules
|
||||
init_submodules() {
|
||||
log_info "Initializing git submodules..."
|
||||
git submodule update --init --recursive
|
||||
log_success "Git submodules initialized"
|
||||
}
|
||||
|
||||
# Download Powers of Tau file
|
||||
download_ptau() {
|
||||
if [[ "$SKIP_PTAU" == true ]]; then
|
||||
log_info "Skipping Powers of Tau download..."
|
||||
if [[ ! -f "$PTAU_FILE" ]]; then
|
||||
log_error "Powers of Tau file not found: $PTAU_FILE"
|
||||
exit 1
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -f "$PTAU_FILE" ]]; then
|
||||
log_info "Powers of Tau file already exists, skipping download..."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Downloading Powers of Tau file (this may take a while, ~3GB)..."
|
||||
curl -L -o "$PTAU_FILE" "$PTAU_URL"
|
||||
log_success "Powers of Tau file downloaded"
|
||||
}
|
||||
|
||||
# Generate proving key for a circuit
|
||||
generate_proving_key() {
|
||||
local circuit_key="$1"
|
||||
|
||||
if [[ ! -v CIRCUITS[$circuit_key] ]]; then
|
||||
log_error "Unknown circuit: $circuit_key"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IFS=':' read -r circuit_path circuit_name display_name <<< "${CIRCUITS[$circuit_key]}"
|
||||
local circuit_dir=$(dirname "$circuit_path")
|
||||
local circuit_file=$(basename "$circuit_path")
|
||||
local circuit_filestem=$(basename "$circuit_path" .circom)
|
||||
|
||||
log_info "Generating proving key for $display_name..."
|
||||
|
||||
cd "$circuit_dir"
|
||||
|
||||
# Generate R1CS
|
||||
log_info " Generating R1CS constraints..."
|
||||
circom --r1cs --O2 "$circuit_file"
|
||||
|
||||
# Determine the R1CS file name (some circuits have different names)
|
||||
local r1cs_file="${circuit_filestem}.r1cs"
|
||||
|
||||
# Setup
|
||||
log_info " Running Groth16 setup..."
|
||||
snarkjs groth16 setup "$r1cs_file" "../$PTAU_FILE" "${circuit_key}-0.zkey"
|
||||
|
||||
# Contribute to ceremony
|
||||
log_info " Contributing to ceremony..."
|
||||
head -c 32 /dev/urandom | xxd -p -c 256 | snarkjs zkey contribute "${circuit_key}-0.zkey" "${circuit_key}.zkey" --name="LOCAL_BUILD" -v
|
||||
|
||||
# Export verification key
|
||||
log_info " Exporting verification key..."
|
||||
snarkjs zkey export verificationkey "${circuit_key}.zkey" "${circuit_key}_verification_key.json"
|
||||
|
||||
# Cleanup intermediate file
|
||||
rm -f "${circuit_key}-0.zkey"
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
log_success "Proving key generated for $display_name"
|
||||
}
|
||||
|
||||
# Generate all proving keys
|
||||
generate_all_proving_keys() {
|
||||
if [[ "$SKIP_PROVING_KEYS" == true ]]; then
|
||||
log_info "Skipping proving key generation..."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Generating proving keys for all circuits..."
|
||||
|
||||
local circuits_to_build
|
||||
if [[ -n "$SINGLE_CIRCUIT" ]]; then
|
||||
circuits_to_build=("$SINGLE_CIRCUIT")
|
||||
else
|
||||
circuits_to_build=("${!CIRCUITS[@]}")
|
||||
fi
|
||||
|
||||
for circuit_key in "${circuits_to_build[@]}"; do
|
||||
generate_proving_key "$circuit_key"
|
||||
done
|
||||
|
||||
log_success "All proving keys generated"
|
||||
}
|
||||
|
||||
# Compile witness generator for a circuit
|
||||
compile_witness_generator() {
|
||||
local circuit_key="$1"
|
||||
|
||||
if [[ ! -v CIRCUITS[$circuit_key] ]]; then
|
||||
log_error "Unknown circuit: $circuit_key"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IFS=':' read -r circuit_path circuit_name display_name <<< "${CIRCUITS[$circuit_key]}"
|
||||
local circuit_dir=$(dirname "$circuit_path")
|
||||
local circuit_file=$(basename "$circuit_path")
|
||||
local circuit_filestem=$(basename "$circuit_path" .circom)
|
||||
local circuit_cpp_dir="${circuit_dir}/${circuit_filestem}_cpp"
|
||||
|
||||
log_info "Compiling witness generator for $display_name..."
|
||||
|
||||
cd "$circuit_dir"
|
||||
|
||||
# Generate C++ code for witness computation
|
||||
log_info " Generating C++ code..."
|
||||
circom --c --r1cs --no_asm --O2 "$circuit_file"
|
||||
|
||||
# Replace Makefile with our custom one
|
||||
log_info " Copying custom Makefile..."
|
||||
cp "$SCRIPT_DIR/.github/resources/witness-generator/Makefile" "${circuit_filestem}_cpp/Makefile"
|
||||
|
||||
# Compile the witness generator
|
||||
log_info " Compiling..."
|
||||
cd "${circuit_filestem}_cpp"
|
||||
make PROJECT="$circuit_filestem" linux
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
log_success "Witness generator compiled for $display_name"
|
||||
}
|
||||
|
||||
# Compile all witness generators
|
||||
compile_all_witness_generators() {
|
||||
if [[ "$SKIP_WITNESS" == true ]]; then
|
||||
log_info "Skipping witness generator compilation..."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Compiling witness generators for all circuits..."
|
||||
|
||||
local circuits_to_build
|
||||
if [[ -n "$SINGLE_CIRCUIT" ]]; then
|
||||
circuits_to_build=("$SINGLE_CIRCUIT")
|
||||
else
|
||||
circuits_to_build=("${!CIRCUITS[@]}")
|
||||
fi
|
||||
|
||||
for circuit_key in "${circuits_to_build[@]}"; do
|
||||
compile_witness_generator "$circuit_key"
|
||||
done
|
||||
|
||||
log_success "All witness generators compiled"
|
||||
}
|
||||
|
||||
# Download GMP archive if needed
|
||||
download_gmp() {
|
||||
local gmp_dir="rapidsnark/depends"
|
||||
local gmp_file="gmp-6.2.1.tar.xz"
|
||||
|
||||
if [[ -f "$gmp_dir/$gmp_file" ]]; then
|
||||
log_info "GMP archive already exists, skipping download..."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Downloading GMP archive..."
|
||||
mkdir -p "$gmp_dir"
|
||||
curl -L -o "$gmp_dir/$gmp_file" "https://ftpmirror.gnu.org/gmp/gmp-6.2.1.tar.xz"
|
||||
log_success "GMP archive downloaded"
|
||||
}
|
||||
|
||||
# Compile prover and verifier
|
||||
compile_prover_verifier() {
|
||||
if [[ "$SKIP_PROVER" == true ]]; then
|
||||
log_info "Skipping prover/verifier compilation..."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Compiling prover and verifier..."
|
||||
|
||||
# Replace Makefile with our custom one
|
||||
log_info " Replacing Makefile..."
|
||||
cp ".github/resources/prover/Makefile" "rapidsnark/Makefile"
|
||||
|
||||
# Download GMP if needed
|
||||
download_gmp
|
||||
|
||||
cd rapidsnark
|
||||
|
||||
# Build GMP (ignore exit code if already built)
|
||||
log_info " Building GMP..."
|
||||
./build_gmp.sh host || true
|
||||
|
||||
# Verify GMP is available
|
||||
if [[ ! -d "depends/gmp/package" ]]; then
|
||||
log_error "GMP package not found after build_gmp.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# For ARM64, CMake expects package_aarch64 but build_gmp.sh host creates package
|
||||
# Create symlink to fix the path mismatch
|
||||
if [[ "$ARCH" == "aarch64" ]]; then
|
||||
if [[ -d "depends/gmp/package" && ! -e "depends/gmp/package_aarch64" ]]; then
|
||||
log_info " Creating symlink for ARM64 GMP package..."
|
||||
ln -s package depends/gmp/package_aarch64
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build prover and verifier based on architecture
|
||||
log_info " Building prover and verifier (static) for $ARCH..."
|
||||
if [[ "$ARCH" == "aarch64" ]]; then
|
||||
make host_linux_arm64_static
|
||||
else
|
||||
make host_linux_x86_64_static
|
||||
fi
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
log_success "Prover and verifier compiled"
|
||||
}
|
||||
|
||||
# Create the unified release bundle
|
||||
create_bundle() {
|
||||
local bundle_name="nomos-circuits-${VERSION}-${OS}-${ARCH}"
|
||||
|
||||
log_info "Creating unified release bundle: $bundle_name"
|
||||
|
||||
# Create bundle directory structure
|
||||
mkdir -p "${bundle_name}"/{pol,poq,zksign,poc}
|
||||
|
||||
# Create VERSION file
|
||||
echo "$VERSION" > "${bundle_name}/VERSION"
|
||||
|
||||
# Copy prover and verifier
|
||||
if [[ ! "$SKIP_PROVER" == true ]]; then
|
||||
log_info " Copying prover and verifier..."
|
||||
cp "rapidsnark/package/bin/prover" "${bundle_name}/prover"
|
||||
cp "rapidsnark/package/bin/verifier" "${bundle_name}/verifier"
|
||||
chmod +x "${bundle_name}/prover"
|
||||
chmod +x "${bundle_name}/verifier"
|
||||
fi
|
||||
|
||||
# Copy witness generators and proving keys for each circuit
|
||||
local circuits_to_bundle
|
||||
if [[ -n "$SINGLE_CIRCUIT" ]]; then
|
||||
circuits_to_bundle=("$SINGLE_CIRCUIT")
|
||||
else
|
||||
circuits_to_bundle=("${!CIRCUITS[@]}")
|
||||
fi
|
||||
|
||||
for circuit_key in "${circuits_to_bundle[@]}"; do
|
||||
IFS=':' read -r circuit_path circuit_name display_name <<< "${CIRCUITS[$circuit_key]}"
|
||||
local circuit_dir=$(dirname "$circuit_path")
|
||||
local circuit_filestem=$(basename "$circuit_path" .circom)
|
||||
local circuit_cpp_dir="${circuit_dir}/${circuit_filestem}_cpp"
|
||||
|
||||
log_info " Bundling $display_name..."
|
||||
|
||||
# Copy witness generator
|
||||
if [[ ! "$SKIP_WITNESS" == true ]]; then
|
||||
if [[ -f "${circuit_cpp_dir}/${circuit_filestem}" ]]; then
|
||||
cp "${circuit_cpp_dir}/${circuit_filestem}" "${bundle_name}/${circuit_key}/witness_generator"
|
||||
chmod +x "${bundle_name}/${circuit_key}/witness_generator"
|
||||
fi
|
||||
if [[ -f "${circuit_cpp_dir}/${circuit_filestem}.dat" ]]; then
|
||||
cp "${circuit_cpp_dir}/${circuit_filestem}.dat" "${bundle_name}/${circuit_key}/witness_generator.dat"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Copy proving key and verification key
|
||||
if [[ ! "$SKIP_PROVING_KEYS" == true ]]; then
|
||||
if [[ -f "${circuit_dir}/${circuit_key}.zkey" ]]; then
|
||||
cp "${circuit_dir}/${circuit_key}.zkey" "${bundle_name}/${circuit_key}/proving_key.zkey"
|
||||
fi
|
||||
if [[ -f "${circuit_dir}/${circuit_key}_verification_key.json" ]]; then
|
||||
cp "${circuit_dir}/${circuit_key}_verification_key.json" "${bundle_name}/${circuit_key}/verification_key.json"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Create tarball
|
||||
log_info " Creating tarball..."
|
||||
tar -czf "${bundle_name}.tar.gz" "${bundle_name}"
|
||||
|
||||
log_success "Bundle created: ${bundle_name}.tar.gz"
|
||||
|
||||
# Print bundle contents
|
||||
log_info "Bundle contents:"
|
||||
tar -tzf "${bundle_name}.tar.gz" | head -50
|
||||
}
|
||||
|
||||
# Print build summary
|
||||
print_summary() {
|
||||
echo ""
|
||||
log_info "=========================================="
|
||||
log_info "Build Summary"
|
||||
log_info "=========================================="
|
||||
log_info "Version: $VERSION"
|
||||
log_info "OS: $OS"
|
||||
log_info "Architecture: $ARCH"
|
||||
echo ""
|
||||
|
||||
if [[ -n "$SINGLE_CIRCUIT" ]]; then
|
||||
log_info "Built circuit: $SINGLE_CIRCUIT"
|
||||
else
|
||||
log_info "Built circuits: pol, poq, zksign, poc"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
log_info "Skip flags:"
|
||||
log_info " - Dependencies: $SKIP_DEPS"
|
||||
log_info " - Circom: $SKIP_CIRCOM"
|
||||
log_info " - snarkjs: $SKIP_SNARKJS"
|
||||
log_info " - Powers of Tau: $SKIP_PTAU"
|
||||
log_info " - Proving Keys: $SKIP_PROVING_KEYS"
|
||||
log_info " - Prover/Verifier: $SKIP_PROVER"
|
||||
log_info " - Witness Generators: $SKIP_WITNESS"
|
||||
echo ""
|
||||
|
||||
local bundle_name="nomos-circuits-${VERSION}-${OS}-${ARCH}"
|
||||
if [[ -f "${bundle_name}.tar.gz" ]]; then
|
||||
local size=$(du -h "${bundle_name}.tar.gz" | cut -f1)
|
||||
log_success "Output bundle: ${bundle_name}.tar.gz ($size)"
|
||||
fi
|
||||
log_info "=========================================="
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
parse_args "$@"
|
||||
|
||||
echo ""
|
||||
log_info "=========================================="
|
||||
log_info "Logos Blockchain Circuits - Local Build"
|
||||
log_info "=========================================="
|
||||
log_info "Version: $VERSION"
|
||||
log_info "Starting build process..."
|
||||
echo ""
|
||||
|
||||
# Clean if requested
|
||||
if [[ "$CLEAN" == true ]]; then
|
||||
clean_artifacts
|
||||
fi
|
||||
|
||||
# Check requirements
|
||||
check_requirements
|
||||
|
||||
# Install dependencies
|
||||
install_dependencies
|
||||
|
||||
# Initialize submodules
|
||||
init_submodules
|
||||
|
||||
# Install Circom
|
||||
install_circom
|
||||
|
||||
# Install snarkjs
|
||||
install_snarkjs
|
||||
|
||||
# Download Powers of Tau
|
||||
download_ptau
|
||||
|
||||
# Generate proving keys
|
||||
generate_all_proving_keys
|
||||
|
||||
# Compile prover and verifier
|
||||
compile_prover_verifier
|
||||
|
||||
# Compile witness generators
|
||||
compile_all_witness_generators
|
||||
|
||||
# Create bundle
|
||||
create_bundle
|
||||
|
||||
# Print summary
|
||||
print_summary
|
||||
|
||||
log_success "Build completed successfully!"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
126
scripts/docker-build.sh
Executable file
126
scripts/docker-build.sh
Executable file
@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Docker Build Script for Logos Blockchain Circuits
|
||||
# This script builds and runs the circuit compilation in a Docker container
|
||||
# to avoid polluting your host system.
|
||||
#
|
||||
# Usage:
|
||||
# ./docker-build.sh [OPTIONS]
|
||||
#
|
||||
# Options:
|
||||
# All options are passed directly to build-local.sh inside the container.
|
||||
# See ./build-local.sh --help for available options.
|
||||
#
|
||||
# Examples:
|
||||
# ./docker-build.sh # Full build
|
||||
# ./docker-build.sh --help # Show build-local.sh help
|
||||
# ./docker-build.sh --circuit pol # Build only PoL circuit
|
||||
# ./docker-build.sh --clean # Clean and rebuild
|
||||
# ./docker-build.sh --skip-ptau # Skip Powers of Tau download (if already exists)
|
||||
#
|
||||
# Advanced Options:
|
||||
# DOCKER_BUILD=0 ./docker-build.sh # Skip rebuilding the Docker image
|
||||
# DOCKER_NOCACHE=1 ./docker-build.sh # Force rebuild Docker image without cache
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
# Configuration
|
||||
IMAGE_NAME="logos-circuits-builder"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"/..
|
||||
DOCKER_BUILD="${DOCKER_BUILD:-1}"
|
||||
DOCKER_NOCACHE="${DOCKER_NOCACHE:-0}"
|
||||
SKIP_INSTALL=${SKIP_INSTALL:-false}
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
|
||||
# Check if Docker is installed
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker is not installed. Please install Docker first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if Docker daemon is running
|
||||
if ! docker info &> /dev/null; then
|
||||
log_error "Docker daemon is not running. Please start Docker first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build the Docker image if needed
|
||||
if [[ "$DOCKER_BUILD" == "1" ]]; then
|
||||
log_info "Building Docker image: $IMAGE_NAME"
|
||||
|
||||
BUILD_ARGS=""
|
||||
if [[ "$DOCKER_NOCACHE" == "1" ]]; then
|
||||
BUILD_ARGS="--no-cache"
|
||||
fi
|
||||
|
||||
ls
|
||||
docker build $BUILD_ARGS -t "$IMAGE_NAME" -f ./scripts/Dockerfile .
|
||||
log_success "Docker image built successfully"
|
||||
else
|
||||
log_info "Skipping Docker image build (DOCKER_BUILD=0)"
|
||||
fi
|
||||
|
||||
# Run the build in Docker
|
||||
log_info "Running build in Docker container..."
|
||||
log_info "Arguments: $*"
|
||||
|
||||
# Use interactive mode if terminal is available, for better output
|
||||
DOCKER_FLAGS="-it"
|
||||
if [[ ! -t 0 ]]; then
|
||||
DOCKER_FLAGS=""
|
||||
fi
|
||||
|
||||
# Run the container with the workspace mounted
|
||||
# --rm: Remove container after exit
|
||||
# -v: Mount current directory to /workspace
|
||||
# -v for ptau: Persist the Powers of Tau file to avoid re-downloading
|
||||
docker run --rm $DOCKER_FLAGS \
|
||||
-v "$SCRIPT_DIR:/workspace" \
|
||||
-v "$SCRIPT_DIR/.docker-cache:/root/.cache" \
|
||||
-e "TERM=${TERM:-xterm}" \
|
||||
"$IMAGE_NAME" "$@"
|
||||
|
||||
log_success "Docker build completed!"
|
||||
|
||||
if [[ $SKIP_INSTALL == false ]]; then
|
||||
log_info "Remember to install the built artifacts if needed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
DEFAULT_INSTALL_DIR="$HOME/.nomos-circuits"
|
||||
|
||||
log_info "Installing built artifacts to $DEFAULT_INSTALL_DIR"
|
||||
mkdir -p "$DEFAULT_INSTALL_DIR"
|
||||
|
||||
# Default configuration
|
||||
VERSION="v0.0.0-local"
|
||||
OS="linux"
|
||||
# Auto-detect architecture
|
||||
MACHINE_ARCH="$(uname -m)"
|
||||
case "$MACHINE_ARCH" in
|
||||
x86_64|amd64)
|
||||
ARCH="x86_64"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
ARCH="aarch64"
|
||||
;;
|
||||
*)
|
||||
ARCH="$MACHINE_ARCH"
|
||||
;;
|
||||
esac
|
||||
cp -r ./nomos-circuits-$VERSION-$OS-$ARCH/* "$DEFAULT_INSTALL_DIR/"
|
||||
Loading…
x
Reference in New Issue
Block a user