Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wasm with Cairo 1 #1830

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
129c51b
refeactor cairo1-run to use no-std
FrancoGiachetta Aug 29, 2024
2416a96
cairo 1 running with wasm
FrancoGiachetta Aug 30, 2024
dd55d88
update changelog + linting
FrancoGiachetta Aug 30, 2024
fc2bc99
update changelog + linting
FrancoGiachetta Aug 30, 2024
b5f0433
fix lint errors
FrancoGiachetta Aug 30, 2024
49d14cd
compile example test in cairo1 wasm
FrancoGiachetta Aug 30, 2024
22f9787
remove example once finished testing
FrancoGiachetta Aug 30, 2024
71a5805
fix example
FrancoGiachetta Aug 30, 2024
bca85b3
change workflows
FrancoGiachetta Aug 30, 2024
aca5a0a
change workflows
FrancoGiachetta Aug 30, 2024
8ddd66d
make default the cli feature
FrancoGiachetta Aug 30, 2024
5257e47
update readme cairo1-run
FrancoGiachetta Aug 30, 2024
a53878c
fix workflows
FrancoGiachetta Aug 30, 2024
dccb10c
fix workflows
FrancoGiachetta Aug 30, 2024
8780cc6
add workflows to build the wasm example
FrancoGiachetta Sep 2, 2024
439f20d
fix workflow
FrancoGiachetta Sep 2, 2024
3f4ab6f
format workflows as before
FrancoGiachetta Sep 2, 2024
0471e28
add workflow to build cairo_1_wasm_example program
FrancoGiachetta Sep 2, 2024
4a16c73
forgot to install cairo 1 compiler
FrancoGiachetta Sep 2, 2024
6a58670
format
FrancoGiachetta Sep 2, 2024
f455fcc
workflow fix
FrancoGiachetta Sep 2, 2024
7dd993b
add sierra to wasm example
FrancoGiachetta Sep 2, 2024
2fdc435
add sierra to wasm example
FrancoGiachetta Sep 2, 2024
ab04371
fix workflows
FrancoGiachetta Sep 2, 2024
debfed4
format
FrancoGiachetta Sep 2, 2024
85dc2de
fix clippy
FrancoGiachetta Sep 2, 2024
b0e1e6d
fix cairo1-run dependency to std
FrancoGiachetta Sep 2, 2024
bdd20b3
fix cairo1-run dependency to std
FrancoGiachetta Sep 2, 2024
d559aed
fix test command on cairo1-run
FrancoGiachetta Sep 2, 2024
74ecf9f
small typo
FrancoGiachetta Sep 2, 2024
af0f3a4
comments
FrancoGiachetta Sep 2, 2024
567ea7d
format
FrancoGiachetta Sep 2, 2024
4eef4d9
place the comment better
FrancoGiachetta Sep 3, 2024
bb9ac8b
Merge branch 'main' into wasm-cairo1
FrancoGiachetta Sep 4, 2024
d249eb6
make requested changes
FrancoGiachetta Sep 4, 2024
3166484
make requested changes
FrancoGiachetta Sep 5, 2024
5dc92e8
make requested changes
FrancoGiachetta Sep 5, 2024
c7b3856
Merge branch 'main' into wasm-cairo1
FrancoGiachetta Sep 5, 2024
50bd9ee
update workflows
FrancoGiachetta Sep 5, 2024
bd66521
Merge branch 'main' into wasm-cairo1
FrancoGiachetta Oct 1, 2024
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
20 changes: 18 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,24 @@ jobs:
cairo-compile cairo_programs/array_sum.cairo --no_debug_info --output cairo_programs/array_sum.json
cd examples/wasm-demo
wasm-pack build --target=web


wasm-demo-cairo1:
name: Build the wasm demo cairo1
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Install cairo-lang and deps
run: |
npm install -g wasm-pack
- name: Build wasm-demo-cairo1
run: |
cd examples/wasm-demo-cairo1
wasm-pack build --target=web

compare-factorial-outputs-all-layouts:
name: Compare factorial outputs for all layouts
needs: [ build-programs, build-release ]
Expand Down Expand Up @@ -832,4 +849,3 @@ jobs:

- name: Run comparison
run: ./vm/src/tests/compare_all_pie_outputs.sh

2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* chore: bump `cairo-lang-` dependencies to 2.8.0 [#1833](https://github.com/lambdaclass/cairo-vm/pull/1833/files)
* chore: update Rust required version to 1.80.0

* chore: make cairo 1.0 compatible with wasm [#1830](https://github.com/lambdaclass/cairo-vm/pull/1830)

* fix: Added the following VM fixes: [#1820](https://github.com/lambdaclass/cairo-vm/pull/1820)
* Fix zero segment location.
* Fix has_zero_segment naming.
Expand Down
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"vm",
"hint_accountant",
"examples/wasm-demo",
"examples/wasm-demo-cairo1",
"cairo1-run",
"cairo-vm-tracer",
"examples/hyper_threading",
Expand All @@ -25,6 +26,7 @@ keywords = ["starknet", "cairo", "vm", "wasm", "no_std"]

[workspace.dependencies]
cairo-vm = { path = "./vm", version = "1.0.1", default-features = false }
cairo1-run = { path = "./cairo1-run", version = "1.0.1", default-features = false }
cairo-vm-tracer = { path = "./cairo-vm-tracer", version = "1.0.1", default-features = false }
mimalloc = { version = "0.1.37", default-features = false }
num-bigint = { version = "0.4", default-features = false, features = [
Expand Down Expand Up @@ -89,6 +91,9 @@ lto = "fat"
# Tell `rustc` to optimize for small code size.
opt-level = "s"

[profile.release.package.wasm-demo-cairo1]
opt-level = "s"

[profile.test.package.proptest]
opt-level = 3

Expand Down
12 changes: 10 additions & 2 deletions cairo1-run/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ keywords.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cairo-vm = { workspace = true, features = ["std", "cairo-1-hints", "clap"] }
cairo-vm = {workspace = true, features = ["cairo-1-hints", "clap"]}

serde_json = { workspace = true }

cairo-lang-sierra-type-size = { version = "2.8.0", default-features = false }
Expand All @@ -23,7 +24,8 @@ cairo-lang-utils.workspace = true
cairo-lang-casm.workspace = true
itertools = "0.11.0"
clap = { version = "4.3.10", features = ["derive"] }
thiserror = { version = "1.0.40" }
thiserror = { version = "1.0.40", optional = true }
thiserror-no-std = { workspace = true }
bincode.workspace = true
assert_matches = "1.5.0"
rstest = "0.17.0"
Expand All @@ -34,3 +36,9 @@ num-bigint.workspace = true
[features]
default = ["with_mimalloc"]
with_mimalloc = ["dep:mimalloc"]
cli = ["dep:thiserror", "cairo-vm/std"]

[[bin]]
name = "cairo1-run"
path = "./src/main.rs"
required-features = ["cli"]
6 changes: 3 additions & 3 deletions cairo1-run/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
CAIRO_1_FOLDER=../cairo_programs/cairo-1-programs

$(CAIRO_1_FOLDER)/%.trace: $(CAIRO_1_FOLDER)/%.cairo
cargo run --release $< --trace_file $@ --layout all_cairo
cargo run --release --features cli $< --trace_file $@ --layout all_cairo

$(CAIRO_1_FOLDER)/%.memory: $(CAIRO_1_FOLDER)/%.cairo
cargo run --release $< --memory_file $@ --layout all_cairo
cargo run --release --features cli $< --memory_file $@ --layout all_cairo

CAIRO_1_PROGRAMS=$(wildcard ../cairo_programs/cairo-1-programs/*.cairo)
TRACES:=$(patsubst $(CAIRO_1_FOLDER)/%.cairo, $(CAIRO_1_FOLDER)/%.trace, $(CAIRO_1_PROGRAMS))
Expand All @@ -20,7 +20,7 @@ deps:
run: $(TRACES) $(MEMORY)

test:
cargo test
cargo test --features cli

clean:
rm -rf corelib
Expand Down
15 changes: 7 additions & 8 deletions cairo1-run/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Once you are inside the `./cairo1-run` folder, use the CLI with the following co
To install the required dependencies(cairo corelib) run

```bash
make deps
make deps
```

Now that you have the dependencies necessary to run the tests, you can run:
Expand All @@ -16,18 +16,17 @@ Now that you have the dependencies necessary to run the tests, you can run:
make test
```

To execute a Cairo 1 program (either as Cairo 1 source file or Sierra)
To execute a Cairo 1 program (either as Cairo 1 source file or Sierra). Make sure the `cli` feature is active in order to use `cairo1-run` as a binary.

```bash
cargo run ../cairo_programs/cairo-1-programs/fibonacci.cairo
cargo run --features cli ../cairo_programs/cairo-1-programs/fibonacci.cairo
```

Arguments to generate the trace and memory files

```bash
cargo run ../cairo_programs/cairo-1-programs/fibonacci.cairo --trace_file ../cairo_programs/cairo-1-programs/fibonacci.trace --memory_file ../cairo_programs/cairo-1-programs/fibonacci.memory
cargo run --features cli ../cairo_programs/cairo-1-programs/fibonacci.cairo --trace_file ../cairo_programs/cairo-1-programs/fibonacci.trace --memory_file ../cairo_programs/cairo-1-programs/fibonacci.memory
```

To pass arguments to `main`

* Separate arguments with a whitespace inbetween
Expand All @@ -37,14 +36,14 @@ Example:

```bash

cargo run ../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo --layout all_cairo --args '2 [1 2 3 4] 0 [9 8]'
cargo run --features cli ../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo --layout all_cairo --args '2 [1 2 3 4] 0 [9 8]'

```

To execute all the cairo 1 programs inside `../cairo_programs/cairo-1-programs/` and generate the corresponding trace and the memory files

```bash
make run
make run
```

## CLI argument list
Expand Down Expand Up @@ -86,7 +85,7 @@ Then run the compiled project's sierra file located at `project_name/target/proj

Example:
```bash
cargo run path-to-project/target/project_name.sierra.json
cargo run --features cli path-to-project/target/project_name.sierra.json
```

# Known bugs & issues
Expand Down
8 changes: 4 additions & 4 deletions cairo1-run/src/cairo_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
hint_processor::cairo_1_hint_processor::hint_processor::Cairo1HintProcessor,
math_utils::signed_felt,
serde::deserialize_program::{ApTracking, FlowTrackingData, HintParams, ReferenceManager},
stdlib::{cmp, collections::HashMap, iter::Peekable},
types::{
builtin_name::BuiltinName, layout::CairoLayoutParams, layout_name::LayoutName,
program::Program, relocatable::MaybeRelocatable,
Expand All @@ -51,7 +52,6 @@
use itertools::{chain, Itertools};
use num_bigint::{BigInt, Sign};
use num_traits::{cast::ToPrimitive, Zero};
use std::{collections::HashMap, iter::Peekable};

/// Representation of a cairo argument
/// Can consist of a single Felt or an array of Felts
Expand Down Expand Up @@ -142,7 +142,7 @@

let main_func = find_function(sierra_program, "::main")?;

let initial_gas = 9999999999999_usize;
let initial_gas = u32::MAX as usize;

// Fetch return type data
let return_type_id = match main_func.signature.ret_types.last() {
Expand Down Expand Up @@ -1234,7 +1234,7 @@
.expect("Missing return value")
.get_relocatable()
.expect("Box Pointer is not Relocatable");
let type_size = type_sizes[&info.ty].try_into().expect("could not parse to usize");
let type_size = type_sizes[&info.ty].try_into().expect("could not parse to usize");

Check warning on line 1237 in cairo1-run/src/cairo_run.rs

View check run for this annotation

Codecov / codecov/patch

cairo1-run/src/cairo_run.rs#L1237

Added line #L1237 was not covered by tests
let data = vm
.get_continuous_range(ptr, type_size)
.expect("Failed to extract value from nullable ptr");
Expand Down Expand Up @@ -1387,7 +1387,7 @@
let mut max_variant_size = 0;
for variant in &info.variants {
let variant_size = type_sizes.get(variant).unwrap();
max_variant_size = std::cmp::max(max_variant_size, *variant_size)
max_variant_size = cmp::max(max_variant_size, *variant_size)

Check warning on line 1390 in cairo1-run/src/cairo_run.rs

View check run for this annotation

Codecov / codecov/patch

cairo1-run/src/cairo_run.rs#L1390

Added line #L1390 was not covered by tests
}
for _ in 0..max_variant_size - type_sizes.get(variant_type_id).unwrap() {
// Remove padding
Expand Down
4 changes: 4 additions & 0 deletions cairo1-run/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ use cairo_vm::{
},
Felt252,
};
#[cfg(feature = "cli")]
use thiserror::Error;
#[cfg(not(feature = "cli"))]
use thiserror_no_std::Error;

#[derive(Debug, Error)]
pub enum Error {
#[error("Invalid arguments")]
Cli(#[from] clap::Error),
#[cfg(feature = "cli")]
#[error("Failed to interact with the file system")]
IO(#[from] std::io::Error),
#[error(transparent)]
Expand Down
33 changes: 33 additions & 0 deletions examples/wasm-demo-cairo1/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[package]
name = "wasm-demo-cairo1"
description = "A demo using cairo-vm in a WASM environment"
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
readme = "README.md"
keywords.workspace = true
publish = false

[lib]
crate-type = ["cdylib", "rlib"]

[features]
default = ["console_error_panic_hook"]

[dependencies]
serde_json.workspace = true
wasm-bindgen = "0.2.87"
cairo-lang-sierra = { workspace = true }

# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.6", optional = true }

cairo-vm = { workspace = true }
cairo1-run = { workspace = true }

[dev-dependencies]
wasm-bindgen-test = "0.3.34"
58 changes: 58 additions & 0 deletions examples/wasm-demo-cairo1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Demo of `cairo-vm` on WebAssembly

While cairo-vm is compatible with WebAssembly, it doesn't implement any bindings to it.
Instead, create a new WebAssembly crate with cairo-vm and cairo1-run as dependencies and implement the required functionality there.

Since mimalloc is not automatically compilable to WebAssembly, the cairo-vm dependency should disable the default features, which will in turn disable mimalloc.

A working example is provided in this repository.

## Dependencies

To compile and run the example you need:

- an either Cairo 1 or Cairo 2 compiler
- the _wasm-pack_ crate
- some HTTP server (for example: the `live-server` npm module)

> **Note**
> The first two dependencies can be installed via the repository's installation script (see ["Installation script"](../../README.md#installation-script))

## Building

To build the example, first compile your Cairo 1 / 2 program:

Cairo 1

```sh
../../cairo1/bin/cairo-compile -r ./bitwise.cairo bitwise.sierra
```

Cairo 2

```sh
../../cairo2/bin/cairo-compile -r ./bitwise.cairo bitwise.sierra
```

> It's important to use the `-r` flag. If not, the `main` function won't be recognized.

And then the WebAssembly package:

```sh
wasm-pack build --target=web
```

This will generate a javascript module that is directly loadable by the browser.

## Running

To run the example webpage, you need to run an HTTP server.
For example, using the _live-server_ npm module:

```sh
# while in <repo>/examples/wasm-demo-cairo1
npx live-server
```

> **Warning**
> Trying to run `index.html` directly (i.e. URL starts with `file://`) will result in a CORS error.
12 changes: 12 additions & 0 deletions examples/wasm-demo-cairo1/bitwise.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
fn main() -> u128 {
let a = 1234_u128;
let b = 5678_u128;

let c0 = a & b;
let c1 = a ^ b;
let c2 = a | b;

let c3 = c0 + c1 + c2;

c3
}
Loading
Loading