Skip to content

SP1 stylus compiler#4587

Open
pmikolajczyk41 wants to merge 30 commits intomasterfrom
pmikolajczyk/nit-4729-stylus-compiler
Open

SP1 stylus compiler#4587
pmikolajczyk41 wants to merge 30 commits intomasterfrom
pmikolajczyk/nit-4729-stylus-compiler

Conversation

@pmikolajczyk41
Copy link
Copy Markdown
Member

@pmikolajczyk41 pmikolajczyk41 commented Mar 31, 2026

Changed

  1. prover crate:
    • Introduced kzg feature, to hide c_kzg dependency - SP1 crates won't use relevant functionalities, but fail to include it as a dependency (due to some non-digestible C-bindings).
    • Made structopt an optional dependency (enabled in default features set) - it is used only for the binary, not used in the library part. Caused similar problem for SP1 crates as c_kzg (above).
  2. brotli crate:
    • Added unsafe impl<T> Send for ForceSync<T> {}: when compiling for SP1, the compiler demands it.
    • Added target/lib-sp1/lib dir for searching for C-compiled brotli lib for the riscv64 architecture.
  3. Old CI:
    • Installed protobuf-compiler in the ci-setup action - required for compiling SP1 programs
    • Do not run clippy on the new SP1 crates - one of them requires building another and including artifact bytes before it can be validated. Since building requires special env and toolchain, we move clippy checks on SP1 crates to ZK-related workflow.

Added

  1. New CI:
    • Added a new workflow dedicated to the new crates. Installs required toolchains, libs (like brotli), etc.
    • Runs clippy on the new crates.
    • Runs basic consistency test for the stylus compiler - see below.
  2. Building SP1:
    • Added a script sp1/build.sh, that fetches and installs sp1up with C support. Compiles brotli for the riscv64 target.
    • Added sp1/brotli_cmake_patch.txt‎ to make brotli work for riscv64.
  3. Dependencies:
    • wasmer pin points at the feature branch - essentially it is 7.1.0 with a few, feature-gated amendments to make it work for riscv64
    • Add patched sp1 dependencies. In the future we might be able to depend on the official releases (will have to talk with Succinct)
  4. stylus-compiler-program package:
    • Lib crate exposes only a function: compile(input: &CompileInput) -> Result<Vec<u8>> that compiles a Stylus WASM program to a rv64 binary using the wasmer singlepass compiler. Just it. Pure Rust, works on every arch. Nothing related to SP1.
    • Binary crate wraps the compile function into a full ZK VM program for SP1 execution. Ready to be fed into SP1 ZK VM.
  5. stylus-compiler-runner crate
    • Just a binary crate (CLI) that serves as an auxiliary tool for working/testing/checking the stylus-compiler-program package.
    • Can compile Stylus wasm into riscv in three modes:
      • Native: simply runs the compile method in the host environment. Nothing ZK related. Pure native Rust compilation.
      • Execute: runs the stylus-compiler-program binary crate inside SP1 ZK VM in the 'fast' mode, i.e. without producing proof.
      • Prove: as Execute, but generates proof. Slow.
      • Compare: is an additional mode that runs Native, then Execute and compares byte-by-byte, that their results are identical. Used for ensuring consistency in CI.

closes NIT-4729
initiates ZK on master

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 34.14%. Comparing base (bb1e24b) to head (98d4d19).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4587      +/-   ##
==========================================
+ Coverage   34.12%   34.14%   +0.02%     
==========================================
  Files         495      495              
  Lines       59062    59062              
==========================================
+ Hits        20152    20169      +17     
+ Misses      35348    35339       -9     
+ Partials     3562     3554       -8     

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

❌ 7 Tests Failed:

Tests completed Failed Passed Skipped
4805 7 4798 0
View the top 3 failed tests by shortest run time
TestAliasingFlaky
Stack Traces | -0.000s run time
=== RUN   TestAliasingFlaky
=== PAUSE TestAliasingFlaky
=== CONT  TestAliasingFlaky
    common_test.go:777: BuildL1 deployConfig: DeployBold=true, DeployReferenceDAContracts=false
INFO [04-08|10:02:34.947] Started log indexer
TestBatchPosterL1SurplusMatchesBatchGasFlaky
Stack Traces | 0.550s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
panic: runtime error: invalid memory address or nil pointer dereference [recovered, repanicked]
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x20f4332]

goroutine 32 [running]:
testing.tRunner.func1.2({0x3869a60, 0x63029b0})
	/opt/hostedtoolcache/go/1.25.8/x64/src/testing/testing.go:1872 +0x237
testing.tRunner.func1()
	/opt/hostedtoolcache/go/1.25.8/x64/src/testing/testing.go:1875 +0x35b
panic({0x3869a60?, 0x63029b0?})
	/opt/hostedtoolcache/go/1.25.8/x64/src/runtime/panic.go:783 +0x132
github.com/offchainlabs/nitro/arbnode.(*InboxTracker).GetBatchCount(0x13fa5900?)
	/home/runner/work/nitro/nitro/arbnode/inbox_tracker.go:210 +0x12
github.com/offchainlabs/nitro/arbnode.(*InboxTracker).FindInboxBatchContainingMessage(0x0, 0x8)
	/home/runner/work/nitro/nitro/arbnode/inbox_tracker.go:225 +0x2f
github.com/offchainlabs/nitro/system_tests.TestBatchPosterL1SurplusMatchesBatchGasFlaky(0xc000503340)
	/home/runner/work/nitro/nitro/system_tests/batch_poster_test.go:839 +0x725
testing.tRunner(0xc000503340, 0x4245498)
	/opt/hostedtoolcache/go/1.25.8/x64/src/testing/testing.go:1934 +0xea
created by testing.(*T).Run in goroutine 1
	/opt/hostedtoolcache/go/1.25.8/x64/src/testing/testing.go:1997 +0x465
TestParentChainEthConfigForkTransition
Stack Traces | 9.190s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
INFO [04-08|10:11:20.635] Imported new potential chain segment     number=27   hash=44fc17..3045ab blocks=1  txs=1   mgas=0.087  elapsed=4.657ms      mgasps=18.754   triediffs=133.05KiB  triedirty=0.00B
INFO [04-08|10:11:20.635] Chain head was updated                   number=27   hash=44fc17..3045ab root=08987a..19fd1d elapsed="87.503µs"
INFO [04-08|10:11:20.638] Submitted transaction                    hash=0x62ef9a5f864a322216ec17570d635f9413c349d6d8df96ebd244de99595dfd82 from=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A nonce=17  recipient=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A value=1,000,000,000,000
INFO [04-08|10:11:20.639] Starting work on payload                 id=0x03a771a15371f6ab
INFO [04-08|10:11:20.640] Updated payload                          id=0x03a771a15371f6ab number=57   hash=7d7547..769201 txs=1   withdrawals=0 gas=21000      fees=0.002098136592 root=4f6db1..4f0d09 elapsed="741.571µs"
INFO [04-08|10:11:20.641] Stopping work on payload                 id=0x03a771a15371f6ab reason=delivery
INFO [04-08|10:11:20.643] Imported new potential chain segment     number=57   hash=7d7547..769201 blocks=1  txs=1   mgas=0.021  elapsed=2.535ms      mgasps=8.284    triediffs=268.21KiB  triedirty=0.00B
INFO [04-08|10:11:20.643] Chain head was updated                   number=57   hash=7d7547..769201 root=4f6db1..4f0d09 elapsed="65.028µs"
INFO [04-08|10:11:20.648] Starting peer-to-peer node               instance=test-stack-name/linux-amd64/go1.25.8
WARN [04-08|10:11:20.648] P2P server will be useless, neither dialing nor listening
INFO [04-08|10:11:20.649] Submitted transaction                    hash=0x8252556e5e9aedbc67b31e28d2628615f9d3f8163ea73e44166bcc7229bbcec8 from=0xb386a74Dcab67b66F8AC07B4f08365d37495Dd23 nonce=412 recipient=0x2e78C674bc63A430CAF6Ecc890B59e34C6B10500 value=0
INFO [04-08|10:11:20.649] DataPoster sent transaction              nonce=412 hash=825255..bbcec8 feeCap=50,000,000,070 tipCap=5,000,000,000 blobFeeCap=&lt;nil&gt; gas=153,176
INFO [04-08|10:11:20.649] BatchPoster: batch sent                  sequenceNumber=413 from=474 to=475 prevDelayed=3   currentDelayed=3   totalSegments=3  numBlobs=0
INFO [04-08|10:11:20.651] Starting work on payload                 id=0x035c431655c924ba
INFO [04-08|10:11:20.654] Updated payload                          id=0x035c431655c924ba number=583  hash=355fa6..edfbda txs=1   withdrawals=0 gas=140,891    fees=0.000704455    root=f0d279..7e7315 elapsed=2.697ms
INFO [04-08|10:11:20.655] Submitted transaction                    hash=0x45a4d8447c19653cea6f10ca638cb9bd8557584dd9b85a9191887febab07a330 from=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A nonce=18  recipient=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A value=1,000,000,000,000
INFO [04-08|10:11:20.656] Submitted transaction                    hash=0x2a54b62d3339b442317df2e550e9fc41456522a4f7ca5f7dd4bf4814a15915c7 from=0x57Ff0F473737a1c161bfF9efDF016F7991585088 nonce=27  recipient=0x4C4Ac1257945782bf52A724e75687d9010C770DE value=0
INFO [04-08|10:11:20.657] Stopping work on payload                 id=0x035c431655c924ba reason=delivery
WARN [04-08|10:11:20.657] Getting file info                        dir= error="stat : no such file or directory"
INFO [04-08|10:11:20.657] Starting work on payload                 id=0x0311a11f2d4e003a

📣 Thoughts on this report? Let Codecov know! | Powered by Codecov

@pmikolajczyk41 pmikolajczyk41 force-pushed the pmikolajczyk/nit-4729-stylus-compiler branch from aeb9210 to 0d7b35e Compare April 2, 2026 07:27
Base automatically changed from pmikolajczyk/nit-4723-ffi to master April 2, 2026 09:16
@pmikolajczyk41 pmikolajczyk41 force-pushed the pmikolajczyk/nit-4729-stylus-compiler branch from 0d7b35e to 9b27233 Compare April 2, 2026 11:50
@pmikolajczyk41 pmikolajczyk41 marked this pull request as ready for review April 2, 2026 12:52
@bragaigor bragaigor added the after-next-version This PR shouldn't be merged until after the next version is released label Apr 6, 2026
Copy link
Copy Markdown
Contributor

@bragaigor bragaigor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall, just some minor comments

Comment thread crates/tools/wasmer
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if it would be to our advantage to have someone review the changes in this branch even though it's not a PR?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a very good idea - before I write a request to Succinct, just wanted to confirm: OffchainLabs/wasmer#34 is the full diff we want to consult, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct

Comment thread crates/sp1/build.sh
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: I'm not sure if it's the same for you but locally in my local Mac, in order to make build.sh work I need to run make test-go-deps first before I run ./crates/sp1/build.sh. And at the of such script brotli brotli/CMakeLists.txt file gets modified which is a bit annoying (because of line 21) so:

  • Wondering if we should add a check to run make test-go-deps first if the script is being run on MacOS (if this still a problem
  • Add a line at the end of this script to restore brotli/CMakeLists.txt?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

restoring CMakeLists.txt was added in 6f6ff2f

as for the make test-go-deps - I don't have this problem, probably because I already have required things available - what was the exact error you got? so that we can pinpoint missing dependency (I wanted to avoid blindly adding make test-go-deps to the script)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a fresh clone and ran ./crates/sp1/build.sh and got:

 => ERROR [brotli-wasm-builder 6/6] RUN cd emsdk && . ./emsdk_env.sh && cd .. && ./scripts/build-brotli.sh -w -t /workspace/install/                                                                                                         1.7s 
------                                                                                                                                                                                                                                            
 > [brotli-wasm-builder 6/6] RUN cd emsdk && . ./emsdk_env.sh && cd .. && ./scripts/build-brotli.sh -w -t /workspace/install/:                                                                                                                    
0.130 Setting up EMSDK environment (suppress these messages with EMSDK_QUIET=1)                                                                                                                                                                   
0.130 Adding directories to PATH:                                                                                                                                                                                                                 
0.130 PATH += /workspace/emsdk                                                                                                                                                                                                                    
0.130 PATH += /workspace/emsdk/upstream/emscripten                                                                                                                                                                                                
0.130 PATH += /workspace/emsdk/node/22.16.0_64bit/bin
0.130 
0.130 Setting environment variables:
0.130 PATH = /workspace/emsdk:/workspace/emsdk/upstream/emscripten:/workspace/emsdk/node/22.16.0_64bit/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0.130 EMSDK = /workspace/emsdk
0.130 EMSDK_NODE = /workspace/emsdk/node/22.16.0_64bit/bin/node
0.148 CMake Deprecation Warning at CMakeLists.txt:5 (cmake_minimum_required):
0.148   Compatibility with CMake < 2.8.12 will be removed from a future version of
...
1.684 CMake Error at CMakeLists.txt:348 (add_test):
1.684   Error evaluating generator expression:
1.684 
1.684     $<TARGET_FILE:brotli>
1.684 
1.684   No target "brotli"
1.684 
1.684 
1.685 CMake Warning:
1.685   Manually-specified variables were not used by the project:
1.685 
1.685     CMAKE_POLICY_VERSION_MINIMUM
1.685 
1.685 
1.685 CMake Generate step failed.  Build files cannot be regenerated correctly.
------
Dockerfile:11
--------------------
   9 |     COPY scripts/build-brotli.sh scripts/
  10 |     COPY brotli brotli
  11 | >>> RUN cd emsdk && . ./emsdk_env.sh && cd .. && ./scripts/build-brotli.sh -w -t /workspace/install/
  12 |     
  13 |     FROM scratch AS brotli-wasm-export
--------------------
ERROR: failed to build: failed to solve: process "/bin/sh -c cd emsdk && . ./emsdk_env.sh && cd .. && ./scripts/build-brotli.sh -w -t /workspace/install/" did not complete successfully: exit code: 1
make: *** [.make/cbrotli-wasm] Error 1

And I thought that to be related to the CMakeLists.txt addition but I'm not sure.

  • I tried such to delete CMakeLists.txt addition to then run ./crates/sp1/build.sh again and got the same error as above.
  • But when I run make test-go-deps before ./crates/sp1/build.sh it works.
  • notice I was using the other branch pmikolajczyk/nit-4729-stylus-compiler to run the above.

If I use the current branch and run ./crates/sp1/build.sh I'm getting:

   Compiling arbutil v0.1.0 (/Users/braga/repos/nitro/crates/arbutil)
   Compiling serde_with v3.9.0
   Compiling cargo_metadata v0.18.1
error: could not find native static library `brotlienc-static`, perhaps an -L flag is missing?

error: could not compile `brotli` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
+ git -C /Users/braga/repos/nitro/crates/sp1/../../brotli checkout -- CMakeLists.txt

It was similar to above, when I run make test-go-deps before ./crates/sp1/build.sh it works. But wondering if it could be just me. Maybe it would be nice to get a 3rd data point to make sure it's not just me?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

best apologies from my side - I didn't copy make build-replay-env test-go-deps from the original build.sh - at the time I was sure it is only required for block inputs generation and I happily ignored it; everything worked well for me locally because I had all the artifacts ready from previous runs

I restored it in 6f04660

the only thing that keeps me wondering is that CI passed all green... so I'm not sure why you experienced these problems, but adding make build-replay-env test-go-deps will be needed here anyway, so maybe we shouldn't spend more time here

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's all good, just wanted to make sure the build scripts works seamlessly and I'm sure we'll keep improving it. So that's all good to me

Comment thread crates/sp1/brotli_cmake_patch.txt Outdated
set_property(TARGET ${lib} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${BROTLI_INCLUDE_DIRS}")
endforeach()

if(NOT (BROTLI_EMSCRIPTEN AND BROTLI_RISCV))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think here we meant to be if(NOT (BROTLI_EMSCRIPTEN OR BROTLI_RISCV))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in f41c734

Comment thread crates/sp1/brotli_cmake_patch.txt Outdated
)
endif()

if(NOT (BROTLI_EMSCRIPTEN AND BROTLI_RISCV))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar here if(NOT (BROTLI_EMSCRIPTEN OR BROTLI_RISCV)), I don't think we ever reach here which is why it went unoticed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in f41c734

Comment thread crates/brotli/src/dicts/mod.rs Outdated
Comment on lines +32 to +36
@@ -33,6 +33,7 @@ unsafe extern "C" {
struct ForceSync<T>(T);

unsafe impl<T> Sync for ForceSync<T> {}
unsafe impl<T> Send for ForceSync<T> {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that ForceSync forces both Sync and Send should we update it's name or just the comment?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulling from #4361:

/// Forces a type to implement [`Sync`] and [`Send`].
/// Only used to wrap static dictionary pointers (`*const EncoderPreparedDictionary`)
/// which point to immutable, process-lifetime data initialized once via `lazy_static`.
struct ForceSync<T>(T);

// SAFETY: ForceSync only wraps raw pointers to immutable, static dictionary data.
// The data is initialized once (via lazy_static) and never mutated or freed,
// so sharing across threads is safe.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in 0588397

@bragaigor bragaigor assigned pmikolajczyk41 and unassigned bragaigor Apr 6, 2026
Copy link
Copy Markdown
Contributor

@bragaigor bragaigor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bragaigor
Copy link
Copy Markdown
Contributor

Assigning it back to you @pmikolajczyk41 until we have 3.10 feature branch

@bragaigor bragaigor assigned pmikolajczyk41 and unassigned bragaigor Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

after-next-version This PR shouldn't be merged until after the next version is released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants