mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-07-02 21:19:44 +00:00
build: add shared guest program build
This commit is contained in:
parent
0a120bd42c
commit
a26debd592
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@ -0,0 +1,4 @@
|
||||
.git
|
||||
target
|
||||
programs/*/methods/guest/target
|
||||
node_modules
|
||||
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
@ -125,6 +125,24 @@ jobs:
|
||||
env:
|
||||
RISC0_DEV_MODE: 1
|
||||
|
||||
build-programs:
|
||||
name: Build Guest Programs
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Build guest program binaries
|
||||
run: make build-programs
|
||||
|
||||
- name: Check guest program binaries
|
||||
run: |
|
||||
set -eu
|
||||
for manifest in programs/*/methods/guest/Cargo.toml; do
|
||||
program="$(basename "$(dirname "$(dirname "$(dirname "${manifest}")")")")"
|
||||
test -s "target/guest/${program}.bin"
|
||||
done
|
||||
|
||||
check-idl:
|
||||
name: Check IDL
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,2 @@
|
||||
target/
|
||||
token/methods/guest/target/
|
||||
amm/methods/guest/target/
|
||||
*.bin
|
||||
|
||||
27
CLAUDE.md
27
CLAUDE.md
@ -32,11 +32,27 @@ RISC0_DEV_MODE=1 cargo test -p twap_oracle_program
|
||||
# Format
|
||||
make fmt
|
||||
|
||||
# Build the guest ZK binary (requires risc0 toolchain)
|
||||
# Build all guest ZK binaries
|
||||
make build-programs
|
||||
|
||||
# Build one guest directly only when debugging a single guest build
|
||||
cargo risczero build --manifest-path programs/<program>/methods/guest/Cargo.toml
|
||||
```
|
||||
|
||||
Built binaries output to: `<program>/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/<program>.bin`
|
||||
`make build-programs` uses `scripts/build-guests.sh` and
|
||||
`scripts/build-guests.Dockerfile` to compile every guest crate in one Docker
|
||||
BuildKit build. Cargo git, registry, and target artifacts are shared through
|
||||
BuildKit cache mounts. Each raw guest ELF is packaged into the deployable RISC
|
||||
Zero `.bin` format, and only those final program binaries are exported.
|
||||
|
||||
Built binaries output to:
|
||||
`target/guest/<program>.bin`
|
||||
|
||||
Use `RISC0_DOCKER_CONTAINER_TAG` to override the guest builder image tag. Use
|
||||
`RISC0_BUILD_CACHE_ID` to isolate BuildKit caches for clean benchmarks or
|
||||
parallel experiments. Use `RISC0_DOCKER_BUILD_NETWORK` to opt in to a custom
|
||||
Docker build network mode, such as `host`, when the default Docker build
|
||||
network is not sufficient.
|
||||
|
||||
## IDL Generation
|
||||
|
||||
@ -77,11 +93,14 @@ strip = "symbols"
|
||||
That profile is part of program identity. After every release build, inspect the binary and update every value that depends on the ImageID before submitting transactions: deployed program IDs, client/config files, PDA-derived account addresses, AMM `token_program_id` and `twap_oracle_program_id`, and ATA `token_program_id` inputs. Do not mix raw or old ImageIDs with release-profile binaries.
|
||||
|
||||
```bash
|
||||
# Build all guest binaries with the shared BuildKit cache
|
||||
make build-programs
|
||||
|
||||
# Deploy a program binary to the sequencer
|
||||
wallet deploy-program <path-to-binary>
|
||||
wallet deploy-program target/guest/<program>.bin
|
||||
|
||||
# Inspect the ProgramId of a built binary
|
||||
spel inspect <path-to-binary>
|
||||
spel inspect target/guest/<program>.bin
|
||||
```
|
||||
|
||||
## Workspace Structure
|
||||
|
||||
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -3133,6 +3133,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "risc0-packager"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"risc0-binfmt",
|
||||
"risc0-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "risc0-zkos-v1compat"
|
||||
version = "2.2.2"
|
||||
|
||||
@ -17,6 +17,7 @@ members = [
|
||||
"programs/stablecoin/methods",
|
||||
"programs/integration_tests",
|
||||
"tools/idl-gen",
|
||||
"tools/risc0-packager",
|
||||
]
|
||||
exclude = [
|
||||
"programs/token/methods/guest",
|
||||
|
||||
5
Makefile
5
Makefile
@ -1,4 +1,7 @@
|
||||
.PHONY: clippy clippy-guest clippy-all test integration-test fmt idl
|
||||
.PHONY: build-programs clippy clippy-guest clippy-all test integration-test fmt idl
|
||||
|
||||
build-programs:
|
||||
./scripts/build-guests.sh
|
||||
|
||||
clippy:
|
||||
RISC0_SKIP_BUILD=1 cargo clippy --workspace --all-targets -- -D warnings
|
||||
|
||||
44
scripts/build-guests.Dockerfile
Normal file
44
scripts/build-guests.Dockerfile
Normal file
@ -0,0 +1,44 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
ARG RISC0_DOCKER_CONTAINER_TAG=r0.1.88.0
|
||||
FROM risczero/risc0-guest-builder:${RISC0_DOCKER_CONTAINER_TAG} AS build
|
||||
ARG RISC0_BUILD_CACHE_ID=lez-programs-risc0-guests
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
||||
ENV CARGO_TARGET_DIR=/src/target/risc0-guests
|
||||
ENV RISC0_FEATURE_bigint2=""
|
||||
ENV CC_riscv32im_risc0_zkvm_elf=/root/.risc0/cpp/bin/riscv32-unknown-elf-gcc
|
||||
ENV CFLAGS_riscv32im_risc0_zkvm_elf="-march=rv32im -nostdlib"
|
||||
|
||||
RUN --mount=type=cache,id=${RISC0_BUILD_CACHE_ID}-cargo-git,sharing=locked,target=/root/.cargo/git \
|
||||
--mount=type=cache,id=${RISC0_BUILD_CACHE_ID}-cargo-registry,sharing=locked,target=/root/.cargo/registry \
|
||||
--mount=type=cache,id=${RISC0_BUILD_CACHE_ID}-target,sharing=locked,target=/src/target/risc0-guests <<'EOF'
|
||||
set -eu
|
||||
|
||||
target_triple="riscv32im-risc0-zkvm-elf"
|
||||
programs="amm ata stablecoin token twap_oracle"
|
||||
unit_separator="$(printf '\037')"
|
||||
guest_rustflags="-C${unit_separator}passes=lower-atomic${unit_separator}-C${unit_separator}link-arg=-Ttext=0x00200800${unit_separator}-C${unit_separator}link-arg=--fatal-warnings${unit_separator}-C${unit_separator}panic=abort${unit_separator}--cfg${unit_separator}getrandom_backend=\"custom\""
|
||||
export CARGO_ENCODED_RUSTFLAGS="${guest_rustflags}"
|
||||
|
||||
for program in ${programs}; do
|
||||
manifest="programs/${program}/methods/guest/Cargo.toml"
|
||||
echo "==> Building ${program}"
|
||||
cargo +risc0 build --release --locked --target "${target_triple}" --manifest-path "${manifest}"
|
||||
done
|
||||
|
||||
mkdir -p /guest-output
|
||||
unset CARGO_ENCODED_RUSTFLAGS
|
||||
cargo +risc0 build --locked -p risc0-packager
|
||||
packager="${CARGO_TARGET_DIR}/debug/risc0-packager"
|
||||
|
||||
for program in ${programs}; do
|
||||
elf="${CARGO_TARGET_DIR}/${target_triple}/release/${program}"
|
||||
"${packager}" "${elf}" "/guest-output/${program}.bin"
|
||||
done
|
||||
EOF
|
||||
|
||||
FROM scratch AS export
|
||||
COPY --from=build /guest-output /
|
||||
34
scripts/build-guests.sh
Executable file
34
scripts/build-guests.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
||||
risc0_tag="${RISC0_DOCKER_CONTAINER_TAG:-r0.1.88.0}"
|
||||
cache_id="${RISC0_BUILD_CACHE_ID:-lez-programs-risc0-guests}"
|
||||
network_mode="${RISC0_DOCKER_BUILD_NETWORK:-}"
|
||||
staging_dir="$(mktemp -d)"
|
||||
|
||||
cleanup() {
|
||||
rm -rf "${staging_dir}"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
network_args=()
|
||||
if [[ -n "${network_mode}" ]]; then
|
||||
network_args=(--network "${network_mode}")
|
||||
fi
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build ${network_args[@]+"${network_args[@]}"} \
|
||||
--build-arg "RISC0_DOCKER_CONTAINER_TAG=${risc0_tag}" \
|
||||
--build-arg "RISC0_BUILD_CACHE_ID=${cache_id}" \
|
||||
--output="${staging_dir}" \
|
||||
-f "${repo_root}/scripts/build-guests.Dockerfile" \
|
||||
"${repo_root}"
|
||||
|
||||
out_dir="${repo_root}/target/guest"
|
||||
rm -rf "${out_dir}"
|
||||
mkdir -p "${out_dir}"
|
||||
|
||||
for program in amm ata stablecoin token twap_oracle; do
|
||||
rm -rf "${repo_root}/programs/${program}/methods/guest/target"
|
||||
install -m 0644 "${staging_dir}/${program}.bin" "${out_dir}/${program}.bin"
|
||||
done
|
||||
12
tools/risc0-packager/Cargo.toml
Normal file
12
tools/risc0-packager/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "risc0-packager"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
risc0-binfmt = "=3.0.4"
|
||||
risc0-build = "=3.0.5"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
52
tools/risc0-packager/src/main.rs
Normal file
52
tools/risc0-packager/src/main.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use std::{env, ffi::OsString, fs, path::PathBuf};
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use risc0_binfmt::ProgramBinary;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut args = env::args_os();
|
||||
let command = args
|
||||
.next()
|
||||
.unwrap_or_else(|| OsString::from("risc0-packager"));
|
||||
let input = required_arg(&mut args, &command, "guest ELF")?;
|
||||
let output = required_arg(&mut args, &command, "output .bin")?;
|
||||
|
||||
if args.next().is_some() {
|
||||
bail!(
|
||||
"usage: {} <guest-elf> <output-bin>",
|
||||
command.to_string_lossy()
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(parent) = output
|
||||
.parent()
|
||||
.filter(|parent| !parent.as_os_str().is_empty())
|
||||
{
|
||||
fs::create_dir_all(parent)
|
||||
.with_context(|| format!("failed to create {}", parent.display()))?;
|
||||
}
|
||||
|
||||
let user_elf =
|
||||
fs::read(&input).with_context(|| format!("failed to read {}", input.display()))?;
|
||||
let kernel_elf = risc0_build::GuestOptions::default().kernel();
|
||||
let binary = ProgramBinary::new(&user_elf, &kernel_elf);
|
||||
|
||||
fs::write(&output, binary.encode())
|
||||
.with_context(|| format!("failed to write {}", output.display()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn required_arg(
|
||||
args: &mut impl Iterator<Item = OsString>,
|
||||
command: &OsString,
|
||||
name: &str,
|
||||
) -> Result<PathBuf> {
|
||||
match args.next() {
|
||||
Some(value) => Ok(PathBuf::from(value)),
|
||||
None => bail!(
|
||||
"missing {name}; usage: {} <guest-elf> <output-bin>",
|
||||
command.to_string_lossy()
|
||||
),
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user