Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions .github/workflows/build-libstylus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: "Build libstylus"

# Publishes libstylus.so as a COPY-only image for each GitHub Release so
# leafage-evm can pull the native Stylus runtime by release tag or latest.
on:
release:
types:
- published

concurrency:
group: ${{ github.workflow }}-${{ github.event.release.tag_name }}
cancel-in-progress: false

env:
AWS_REGION: us-east-1
REGISTRY: public.ecr.aws/b2h7a5c4/chaintable
IMAGE: libstylus
DOCKERFILE: Dockerfile.libstylus
REVISION: ${{ github.event.release.tag_name }}

jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-latest
arch: amd64
- runner: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.runner }}
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
clean: true
ref: ${{ github.event.release.tag_name }}
# crates/tools/wasmer and brotli are submodules the build links against.
submodules: recursive

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v2
with:
registry-type: public

- name: Set up Buildx
uses: docker/setup-buildx-action@v3

- name: Build and push
uses: docker/build-push-action@v5
with:
file: ${{ env.DOCKERFILE }}
context: .
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ matrix.arch }}-${{ env.REVISION }}
provenance: false

merge-manifest:
runs-on: ubuntu-latest
needs: build
permissions:
id-token: write
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v2
with:
registry-type: public

- name: Set up Buildx
uses: docker/setup-buildx-action@v3

- name: Merge manifest
run: |
docker buildx imagetools create \
--tag "${REGISTRY}/${IMAGE}:${REVISION}" \
--tag "${REGISTRY}/${IMAGE}:latest" \
"${REGISTRY}/${IMAGE}:amd64-${REVISION}" \
"${REGISTRY}/${IMAGE}:arm64-${REVISION}"
49 changes: 49 additions & 0 deletions Dockerfile.libstylus
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# libstylus.so — the native Stylus runtime that leafage-evm dlopens to execute
# WASM contracts (via LEAFAGE_ARB_STYLUS_LIB). The result is a COPY-only image:
# it has no entrypoint and is never meant to run. Consumers pull the library out
# with `COPY --from=<this image>:<tag> /libstylus.so ...`.
#
# The builder is pinned to bookworm (glibc 2.36) deliberately: leafage-evm runs
# on ubuntu:24.04 (glibc 2.39), and a library built against an older glibc loads
# on a newer one but not the other way round. If leafage-evm's runtime base ever
# moves, this base must stay at or below it.
ARG RUST_VERSION=1.93

FROM rust:${RUST_VERSION}-bookworm AS builder

RUN apt-get update && apt-get install -y --no-install-recommends \
cmake \
make \
g++ \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /src

# Only what the Rust workspace needs — every workspace member lives under
# crates/, and the Go tree plays no part in this build.
COPY rust-toolchain.toml Cargo.toml Cargo.lock ./
COPY scripts/build-brotli.sh scripts/
COPY brotli brotli
COPY crates crates

# crates/brotli links the C static libs, so they have to be built first;
# without this the stylus build fails on `brotlienc-static not found`.
RUN ./scripts/build-brotli.sh -l

RUN cargo build --release --lib -p stylus

# The release profile carries debuginfo, which leaves the library around 237MB
# and would land whole in every consumer's image. --strip-debug drops only the
# DWARF sections; the dynamic symbol table leafage resolves against survives.
RUN strip --strip-debug target/release/libstylus.so

# The symbols leafage resolves at runtime, checked *after* stripping so the
# assertion covers what actually ships. Turns ABI drift into a failed build
# rather than a failed dlopen in production.
RUN for sym in stylus_activate stylus_compile stylus_call stylus_target_set free_rust_bytes; do \
nm -D target/release/libstylus.so | grep -q " ${sym}\$" \
|| { echo "libstylus.so is missing exported symbol: ${sym}" >&2; exit 1; }; \
done

FROM scratch
COPY --from=builder /src/target/release/libstylus.so /libstylus.so
2 changes: 1 addition & 1 deletion crates/stylus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ rayon = ["prover/rayon"]
cc_brotli = ["brotli/cc_brotli"]

[lib]
crate-type = ["lib", "staticlib"]
crate-type = ["lib", "staticlib", "cdylib"]
Loading