build(stylus): build and publish libstylus.so for leafage-evm - #37
Merged
Conversation
leafage-evm loads the stylus FFI at runtime via libloading (LEAFAGE_ARB_STYLUS_LIB), which needs a shared object; the crate previously built only lib + staticlib. The prover_ffi re-export already funnels free_rust_bytes into the linked output, so the cdylib exports the full stylus_* + free_rust_bytes symbol set with no further changes.
leafage-evm dlopens libstylus.so to execute Stylus contracts, but nothing built it for Linux and its image shipped without it, so every Stylus call fell back to a revert instead of running the WASM. Adds a Dockerfile that builds the library and a workflow that publishes it to public ECR as `libstylus:<rev>` (amd64 + arm64). The image is a scratch layer holding just the .so — consumers do `COPY --from`, it is not meant to run. Two things worth keeping in view: - The builder sits on bookworm (glibc 2.36) because 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 reverse. If that runtime base moves, this one has to stay at or below it. - The build asserts the five symbols leafage resolves at runtime (stylus_activate/compile/call/target_set, free_rust_bytes), so ABI drift fails the build instead of failing at dlopen time in production. Only the Rust workspace is copied into the build context; the Go tree is not involved.
The release profile builds with debuginfo, leaving the library at ~237MB. That would land whole in leafage-evm's image for no benefit — nothing consumes the DWARF sections there. --strip-debug keeps the dynamic symbol table, which is all leafage resolves against, and the symbol assertion now runs after the strip so it covers what actually ships.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
leafage-evm executes Stylus contracts by dlopening
libstylus.so— the samenative runtime this repo already links into the node. Nothing previously built
that library for Linux, so leafage-evm could reach the Stylus dispatch but only
fall back to an
Unconfiguredrevert.Changes
cdylibtocrates/stylus, allowing the workspace to producelibstylus.so. The existingprover_ffire-export carriesfree_rust_bytesinto the shared object.Dockerfile.libstylus, producing a scratch COPY-only image containingonly
/libstylus.so.Release policy
The workflow runs only when a GitHub Release is published
(
release.published). It checks out that release tag and publishes:libstylus:amd64-<release-tag>libstylus:arm64-<release-tag>libstylus:<release-tag>as the immutable multi-arch manifestlibstylus:latestpointing to the same multi-arch manifestPull requests no longer assume the AWS role or push images. Each release keeps
an immutable source tag while updating
latestfor consumers that deliberatelyfollow the newest published libstylus.
Why a separate image
leafage-evm can copy the native runtime from either a pinned Nitro release or
the latest published release without vendoring or rebuilding this source tree.
The release tag remains available when an explicit Nitro version is required.
glibc
The builder uses bookworm (glibc 2.36), while leafage-evm runs on Ubuntu 24.04
(glibc 2.39). The published library requires at most GLIBC_2.34 on both
architectures and loads successfully in the consumer runtime.
Symbol check
The build checks the required exported symbol names after stripping:
stylus_activate,stylus_compile,stylus_call,stylus_target_set, andfree_rust_bytes. Consumer integration tests remainthe ABI check because ELF symbol names do not encode function signatures or
repr(C)layouts.Scope and verification
Only the Rust workspace, Brotli source, and required build script are copied
into the builder. The Nitro node Dockerfile and node release workflow are
unchanged.
Before switching the trigger to release-only, the multi-arch artifact at
f7c0ab5was verified on amd64 and arm64: both libraries load on Ubuntu 24.04,resolve their dynamic dependencies, and expose the required symbols.
leafage-evm integration has also reproduced the moduleHash and matched an Arb One
writer across real Stylus calls.